]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #54711 - kennytm:rollup, r=kennytm
authorbors <bors@rust-lang.org>
Mon, 1 Oct 2018 10:16:00 +0000 (10:16 +0000)
committerbors <bors@rust-lang.org>
Mon, 1 Oct 2018 10:16:00 +0000 (10:16 +0000)
Rollup of 13 pull requests

Successful merges:

 - #53784 (Document that slices cannot be larger than `isize::MAX` bytes)
 - #54308 (Better user experience when attempting to call associated functions with dot notation)
 - #54488 (in which we include attributes in unused `extern crate` suggestion spans)
 - #54544 (Indicate how to move value out of Box in docs.)
 - #54623 (Added help message for `impl_trait_in_bindings` feature gate)
 - #54641 (A few cleanups and minor improvements to rustc/infer)
 - #54656 (Correct doc for WorkQueue<T>::pop().)
 - #54674 (update miri)
 - #54676 (Remove `-Z disable_ast_check_for_mutation_in_guard`)
 - #54679 (Improve bug! message for impossible case in Relate)
 - #54681 (Rename sanitizer runtime libraries on OSX)
 - #54708 (Make ./x.py help <cmd> invoke ./x.py <cmd> -h on its own)
 - #54713 (Add nightly check for tool_lints warning)

40 files changed:
src/bootstrap/bootstrap.py
src/bootstrap/compile.rs
src/build_helper/lib.rs
src/liballoc/boxed.rs
src/libcore/slice/mod.rs
src/librustc/hir/lowering.rs
src/librustc/infer/canonical/query_result.rs
src/librustc/infer/equate.rs
src/librustc/infer/error_reporting/mod.rs
src/librustc/infer/error_reporting/need_type_info.rs
src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs
src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs
src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs
src/librustc/infer/error_reporting/nice_region_error/util.rs
src/librustc/infer/lexical_region_resolve/graphviz.rs
src/librustc/infer/lexical_region_resolve/mod.rs
src/librustc/infer/opaque_types/mod.rs
src/librustc/infer/region_constraints/mod.rs
src/librustc/infer/resolve.rs
src/librustc/infer/type_variable.rs
src/librustc/lint/levels.rs
src/librustc/session/config.rs
src/librustc/ty/context.rs
src/librustc/ty/relate.rs
src/librustc_asan/build.rs
src/librustc_data_structures/work_queue.rs
src/librustc_resolve/lib.rs
src/librustc_tsan/build.rs
src/librustc_typeck/check_unused.rs
src/test/run-pass/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs
src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr
src/test/ui/impl-trait/where-allowed.stderr
src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs
src/test/ui/nll/match-guards-partially-borrow.rs
src/test/ui/resolve/issue-22692.rs [new file with mode: 0644]
src/test/ui/resolve/issue-22692.stderr [new file with mode: 0644]
src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.fixed [new file with mode: 0644]
src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.rs [new file with mode: 0644]
src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr [new file with mode: 0644]
src/tools/miri

index d9c66ce2d77905614b5f242c68bfafc123bc7d48..c27f4f056d747c8f5ed52f74e703546290c1d99a 100644 (file)
@@ -844,6 +844,11 @@ def bootstrap(help_triggered):
 def main():
     """Entry point for the bootstrap process"""
     start_time = time()
+
+    # x.py help <cmd> ...
+    if len(sys.argv) > 1 and sys.argv[1] == 'help':
+        sys.argv = sys.argv[:1] + [sys.argv[2], '-h'] + sys.argv[3:]
+
     help_triggered = (
         '-h' in sys.argv) or ('--help' in sys.argv) or (len(sys.argv) == 1)
     try:
index 608f2c982c2a52485abfd8751054f189a759cf5f..7d235743c2c46834fc3a8ebfaabfa5f719b081be 100644 (file)
@@ -249,7 +249,7 @@ fn run(self, builder: &Builder) {
 
 fn copy_apple_sanitizer_dylibs(builder: &Builder, native_dir: &Path, platform: &str, into: &Path) {
     for &sanitizer in &["asan", "tsan"] {
-        let filename = format!("libclang_rt.{}_{}_dynamic.dylib", sanitizer, platform);
+        let filename = format!("lib__rustc__clang_rt.{}_{}_dynamic.dylib", sanitizer, platform);
         let mut src_path = native_dir.join(sanitizer);
         src_path.push("build");
         src_path.push("lib");
index 1cbb8e49bfa15e0579ebeb0e3b37aa0d0bda10db..ec94f57861dbeb1efce4a827795c0dfb954f73d9 100644 (file)
@@ -178,6 +178,37 @@ pub struct NativeLibBoilerplate {
     pub out_dir: PathBuf,
 }
 
+impl NativeLibBoilerplate {
+    /// On OSX we don't want to ship the exact filename that compiler-rt builds.
+    /// This conflicts with the system and ours is likely a wildly different
+    /// version, so they can't be substituted.
+    ///
+    /// As a result, we rename it here but we need to also use
+    /// `install_name_tool` on OSX to rename the commands listed inside of it to
+    /// ensure it's linked against correctly.
+    pub fn fixup_sanitizer_lib_name(&self, sanitizer_name: &str) {
+        if env::var("TARGET").unwrap() != "x86_64-apple-darwin" {
+            return
+        }
+
+        let dir = self.out_dir.join("build/lib/darwin");
+        let name = format!("clang_rt.{}_osx_dynamic", sanitizer_name);
+        let src = dir.join(&format!("lib{}.dylib", name));
+        let new_name = format!("lib__rustc__{}.dylib", name);
+        let dst = dir.join(&new_name);
+
+        println!("{} => {}", src.display(), dst.display());
+        fs::rename(&src, &dst).unwrap();
+        let status = Command::new("install_name_tool")
+            .arg("-id")
+            .arg(format!("@rpath/{}", new_name))
+            .arg(&dst)
+            .status()
+            .expect("failed to execute `install_name_tool`");
+        assert!(status.success());
+    }
+}
+
 impl Drop for NativeLibBoilerplate {
     fn drop(&mut self) {
         if !thread::panicking() {
@@ -229,7 +260,7 @@ pub fn native_lib_boilerplate(
 pub fn sanitizer_lib_boilerplate(sanitizer_name: &str)
     -> Result<(NativeLibBoilerplate, String), ()>
 {
-    let (link_name, search_path, dynamic) = match &*env::var("TARGET").unwrap() {
+    let (link_name, search_path, apple) = match &*env::var("TARGET").unwrap() {
         "x86_64-unknown-linux-gnu" => (
             format!("clang_rt.{}-x86_64", sanitizer_name),
             "build/lib/linux",
@@ -242,8 +273,8 @@ pub fn sanitizer_lib_boilerplate(sanitizer_name: &str)
         ),
         _ => return Err(()),
     };
-    let to_link = if dynamic {
-        format!("dylib={}", link_name)
+    let to_link = if apple {
+        format!("dylib=__rustc__{}", link_name)
     } else {
         format!("static={}", link_name)
     };
index d4cca387f0689ae43135f7c678a7e3580ef001d9..f989e701913a573750578d0a32bab6a6598f60fc 100644 (file)
 //!
 //! # Examples
 //!
-//! Creating a box:
+//! Move a value from the stack to the heap by creating a [`Box`]:
 //!
 //! ```
-//! let x = Box::new(5);
+//! let val: u8 = 5;
+//! let boxed: Box<u8> = Box::new(val);
+//! ```
+//!
+//! Move a value from a [`Box`] back to the stack by [dereferencing]:
+//!
+//! ```
+//! let boxed: Box<u8> = Box::new(5);
+//! let val: u8 = *boxed;
 //! ```
 //!
 //! Creating a recursive data structure:
@@ -52,6 +60,9 @@
 //! elements are in the list, and so we don't know how much memory to allocate
 //! for a `Cons`. By introducing a `Box`, which has a defined size, we know how
 //! big `Cons` needs to be.
+//!
+//! [dereferencing]: ../../std/ops/trait.Deref.html
+//! [`Box`]: struct.Box.html
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
index 05027bbe8989028af69162d5eb3b64891082cbea..d400bd49050a965835578b59a52da87ffd5b37a5 100644 (file)
@@ -34,6 +34,7 @@
 use cmp;
 use fmt;
 use intrinsics::assume;
+use isize;
 use iter::*;
 use ops::{FnMut, Try, self};
 use option::Option;
@@ -4080,6 +4081,9 @@ fn may_have_side_effect() -> bool { false }
 /// them from other data. You can obtain a pointer that is usable as `data`
 /// for zero-length slices using [`NonNull::dangling()`].
 ///
+/// The total size of the slice must be no larger than `isize::MAX` **bytes**
+/// in memory. See the safety documentation of [`pointer::offset`].
+///
 /// # Caveat
 ///
 /// The lifetime for the returned slice is inferred from its usage. To
@@ -4101,10 +4105,13 @@ fn may_have_side_effect() -> bool { false }
 /// ```
 ///
 /// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
+/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
     debug_assert!(data as usize % mem::align_of::<T>() == 0, "attempt to create unaligned slice");
+    debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
+                  "attempt to create slice covering half the address space");
     Repr { raw: FatPtr { data, len } }.rust
 }
 
@@ -4114,15 +4121,19 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
 /// This function is unsafe for the same reasons as [`from_raw_parts`], as well
 /// as not being able to provide a non-aliasing guarantee of the returned
 /// mutable slice. `data` must be non-null and aligned even for zero-length
-/// slices as with [`from_raw_parts`]. See the documentation of
-/// [`from_raw_parts`] for more details.
+/// slices as with [`from_raw_parts`]. The total size of the slice must be no
+/// larger than `isize::MAX` **bytes** in memory.
+///
+/// See the documentation of [`from_raw_parts`] for more details.
 ///
 /// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
     debug_assert!(data as usize % mem::align_of::<T>() == 0, "attempt to create unaligned slice");
-    Repr { raw: FatPtr { data, len} }.rust_mut
+    debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
+                  "attempt to create slice covering half the address space");
+    Repr { raw: FatPtr { data, len } }.rust_mut
 }
 
 /// Converts a reference to T into a slice of length 1 (without copying).
index 62b06f54301f384acd344bf8bd836e8e9d173c58..81d8a803c395870f2fb9516d24b7658cb8981755 100644 (file)
@@ -54,6 +54,7 @@
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::thin_vec::ThinVec;
 use session::Session;
+use session::config::nightly_options;
 use util::common::FN_OUTPUT_NAME;
 use util::nodemap::{DefIdMap, NodeMap};
 
@@ -188,16 +189,28 @@ enum ImplTraitContext<'a> {
     Existential(Option<DefId>),
 
     /// `impl Trait` is not accepted in this position.
-    Disallowed,
+    Disallowed(ImplTraitPosition),
+}
+
+/// Position in which `impl Trait` is disallowed. Used for error reporting.
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+enum ImplTraitPosition {
+    Binding,
+    Other,
 }
 
 impl<'a> ImplTraitContext<'a> {
+    #[inline]
+    fn disallowed() -> Self {
+        ImplTraitContext::Disallowed(ImplTraitPosition::Other)
+    }
+
     fn reborrow(&'b mut self) -> ImplTraitContext<'b> {
         use self::ImplTraitContext::*;
         match self {
             Universal(params) => Universal(params),
             Existential(did) => Existential(*did),
-            Disallowed => Disallowed,
+            Disallowed(pos) => Disallowed(*pos),
         }
     }
 }
@@ -1142,7 +1155,7 @@ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::T
                                 generic_params: this.lower_generic_params(
                                     &f.generic_params,
                                     &NodeMap(),
-                                    ImplTraitContext::Disallowed,
+                                    ImplTraitContext::disallowed(),
                                 ),
                                 unsafety: this.lower_unsafety(f.unsafety),
                                 abi: f.abi,
@@ -1255,20 +1268,27 @@ fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_>) -> hir::T
                             }),
                         ))
                     }
-                    ImplTraitContext::Disallowed => {
+                    ImplTraitContext::Disallowed(pos) => {
                         let allowed_in = if self.sess.features_untracked()
                                                 .impl_trait_in_bindings {
                             "bindings or function and inherent method return types"
                         } else {
                             "function and inherent method return types"
                         };
-                        span_err!(
+                        let mut err = struct_span_err!(
                             self.sess,
                             t.span,
                             E0562,
                             "`impl Trait` not allowed outside of {}",
                             allowed_in,
                         );
+                        if pos == ImplTraitPosition::Binding &&
+                            nightly_options::is_nightly_build() {
+                            help!(err,
+                                  "add #![feature(impl_trait_in_bindings)] to the crate attributes \
+                                   to enable");
+                        }
+                        err.emit();
                         hir::TyKind::Err
                     }
                 }
@@ -1742,7 +1762,7 @@ fn lower_path_extra(
                         param_mode,
                         0,
                         ParenthesizedGenericArgs::Err,
-                        ImplTraitContext::Disallowed,
+                        ImplTraitContext::disallowed(),
                     )
                 })
                 .chain(ident.map(|ident| hir::PathSegment::from_ident(ident)))
@@ -1872,9 +1892,11 @@ fn lower_parenthesized_parameter_data(
         self.with_anonymous_lifetime_mode(
             AnonymousLifetimeMode::PassThrough,
             |this| {
-                const DISALLOWED: ImplTraitContext<'_> = ImplTraitContext::Disallowed;
                 let &ParenthesisedArgs { ref inputs, ref output, span } = data;
-                let inputs = inputs.iter().map(|ty| this.lower_ty_direct(ty, DISALLOWED)).collect();
+                let inputs = inputs
+                    .iter()
+                    .map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed()))
+                    .collect();
                 let mk_tup = |this: &mut Self, tys, span| {
                     let LoweredNodeId { node_id, hir_id } = this.next_id();
                     hir::Ty { node: hir::TyKind::Tup(tys), id: node_id, hir_id, span }
@@ -1889,7 +1911,7 @@ fn lower_parenthesized_parameter_data(
                                 ident: Ident::from_str(FN_OUTPUT_NAME),
                                 ty: output
                                     .as_ref()
-                                    .map(|ty| this.lower_ty(&ty, DISALLOWED))
+                                    .map(|ty| this.lower_ty(&ty, ImplTraitContext::disallowed()))
                                     .unwrap_or_else(|| P(mk_tup(this, hir::HirVec::new(), span))),
                                 span: output.as_ref().map_or(span, |ty| ty.span),
                             }
@@ -1921,7 +1943,7 @@ fn lower_parenthesized_parameter_data(
                     if self.sess.features_untracked().impl_trait_in_bindings {
                         ImplTraitContext::Existential(Some(parent_def_id))
                     } else {
-                        ImplTraitContext::Disallowed
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
                     }
                 )),
             pat: self.lower_pat(&l.pat),
@@ -1983,7 +2005,7 @@ fn lower_fn_decl(
                 if let Some((_, ref mut ibty)) = in_band_ty_params {
                     self.lower_ty_direct(&arg.ty, ImplTraitContext::Universal(ibty))
                 } else {
-                    self.lower_ty_direct(&arg.ty, ImplTraitContext::Disallowed)
+                    self.lower_ty_direct(&arg.ty, ImplTraitContext::disallowed())
                 }
             })
             .collect::<HirVec<_>>();
@@ -1999,9 +2021,12 @@ fn lower_fn_decl(
             match decl.output {
                 FunctionRetTy::Ty(ref ty) => match in_band_ty_params {
                     Some((def_id, _)) if impl_trait_return_allow => {
-                        hir::Return(self.lower_ty(ty, ImplTraitContext::Existential(Some(def_id))))
+                        hir::Return(self.lower_ty(ty,
+                            ImplTraitContext::Existential(Some(def_id))))
+                    }
+                    _ => {
+                        hir::Return(self.lower_ty(ty, ImplTraitContext::disallowed()))
                     }
-                    _ => hir::Return(self.lower_ty(ty, ImplTraitContext::Disallowed)),
                 },
                 FunctionRetTy::Default(span) => hir::DefaultReturn(span),
             }
@@ -2369,7 +2394,7 @@ fn lower_generic_param(&mut self,
                     span: ident.span,
                     kind: hir::GenericParamKind::Type {
                         default: default.as_ref().map(|x| {
-                            self.lower_ty(x, ImplTraitContext::Disallowed)
+                            self.lower_ty(x, ImplTraitContext::disallowed())
                         }),
                         synthetic: param.attrs.iter()
                                               .filter(|attr| attr.check_name("rustc_synthetic"))
@@ -2472,9 +2497,9 @@ fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicat
                             bound_generic_params: this.lower_generic_params(
                                 bound_generic_params,
                                 &NodeMap(),
-                                ImplTraitContext::Disallowed,
+                                ImplTraitContext::disallowed(),
                             ),
-                            bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::Disallowed),
+                            bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::disallowed()),
                             bounds: bounds
                                 .iter()
                                 .filter_map(|bound| match *bound {
@@ -2483,7 +2508,7 @@ fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicat
                                     GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
                                     _ => Some(this.lower_param_bound(
                                         bound,
-                                        ImplTraitContext::Disallowed,
+                                        ImplTraitContext::disallowed(),
                                     )),
                                 })
                                 .collect(),
@@ -2499,7 +2524,7 @@ fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicat
             }) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
                 span,
                 lifetime: self.lower_lifetime(lifetime),
-                bounds: self.lower_param_bounds(bounds, ImplTraitContext::Disallowed),
+                bounds: self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
             }),
             WherePredicate::EqPredicate(WhereEqPredicate {
                 id,
@@ -2508,8 +2533,8 @@ fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicat
                 span,
             }) => hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
                 id: self.lower_node_id(id).node_id,
-                lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::Disallowed),
-                rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::Disallowed),
+                lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::disallowed()),
+                rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::disallowed()),
                 span,
             }),
         }
@@ -2579,7 +2604,7 @@ fn lower_struct_field(&mut self, (index, f): (usize, &StructField)) -> hir::Stru
                 None => Ident::new(Symbol::intern(&index.to_string()), f.span),
             },
             vis: self.lower_visibility(&f.vis, None),
-            ty: self.lower_ty(&f.ty, ImplTraitContext::Disallowed),
+            ty: self.lower_ty(&f.ty, ImplTraitContext::disallowed()),
             attrs: self.lower_attrs(&f.attrs),
         }
     }
@@ -2686,7 +2711,7 @@ fn lower_item_kind(
                         if self.sess.features_untracked().impl_trait_in_bindings {
                             ImplTraitContext::Existential(None)
                         } else {
-                            ImplTraitContext::Disallowed
+                            ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
                         }
                     ),
                     self.lower_mutability(m),
@@ -2701,7 +2726,7 @@ fn lower_item_kind(
                         if self.sess.features_untracked().impl_trait_in_bindings {
                             ImplTraitContext::Existential(None)
                         } else {
-                            ImplTraitContext::Disallowed
+                            ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
                         }
                     ),
                     value
@@ -2740,12 +2765,12 @@ fn lower_item_kind(
             ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)),
             ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
             ItemKind::Ty(ref t, ref generics) => hir::ItemKind::Ty(
-                self.lower_ty(t, ImplTraitContext::Disallowed),
-                self.lower_generics(generics, ImplTraitContext::Disallowed),
+                self.lower_ty(t, ImplTraitContext::disallowed()),
+                self.lower_generics(generics, ImplTraitContext::disallowed()),
             ),
             ItemKind::Existential(ref b, ref generics) => hir::ItemKind::Existential(hir::ExistTy {
-                generics: self.lower_generics(generics, ImplTraitContext::Disallowed),
-                bounds: self.lower_param_bounds(b, ImplTraitContext::Disallowed),
+                generics: self.lower_generics(generics, ImplTraitContext::disallowed()),
+                bounds: self.lower_param_bounds(b, ImplTraitContext::disallowed()),
                 impl_trait_fn: None,
             }),
             ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum(
@@ -2756,20 +2781,20 @@ fn lower_item_kind(
                         .map(|x| self.lower_variant(x))
                         .collect(),
                 },
-                self.lower_generics(generics, ImplTraitContext::Disallowed),
+                self.lower_generics(generics, ImplTraitContext::disallowed()),
             ),
             ItemKind::Struct(ref struct_def, ref generics) => {
                 let struct_def = self.lower_variant_data(struct_def);
                 hir::ItemKind::Struct(
                     struct_def,
-                    self.lower_generics(generics, ImplTraitContext::Disallowed),
+                    self.lower_generics(generics, ImplTraitContext::disallowed()),
                 )
             }
             ItemKind::Union(ref vdata, ref generics) => {
                 let vdata = self.lower_variant_data(vdata);
                 hir::ItemKind::Union(
                     vdata,
-                    self.lower_generics(generics, ImplTraitContext::Disallowed),
+                    self.lower_generics(generics, ImplTraitContext::disallowed()),
                 )
             }
             ItemKind::Impl(
@@ -2802,7 +2827,7 @@ fn lower_item_kind(
                     AnonymousLifetimeMode::CreateParameter,
                     |this, _| {
                         let trait_ref = trait_ref.as_ref().map(|trait_ref| {
-                            this.lower_trait_ref(trait_ref, ImplTraitContext::Disallowed)
+                            this.lower_trait_ref(trait_ref, ImplTraitContext::disallowed())
                         });
 
                         if let Some(ref trait_ref) = trait_ref {
@@ -2811,7 +2836,7 @@ fn lower_item_kind(
                             }
                         }
 
-                        let lowered_ty = this.lower_ty(ty, ImplTraitContext::Disallowed);
+                        let lowered_ty = this.lower_ty(ty, ImplTraitContext::disallowed());
 
                         (trait_ref, lowered_ty)
                     },
@@ -2838,7 +2863,7 @@ fn lower_item_kind(
                 )
             }
             ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
-                let bounds = self.lower_param_bounds(bounds, ImplTraitContext::Disallowed);
+                let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed());
                 let items = items
                     .iter()
                     .map(|item| self.lower_trait_item_ref(item))
@@ -2846,14 +2871,14 @@ fn lower_item_kind(
                 hir::ItemKind::Trait(
                     self.lower_is_auto(is_auto),
                     self.lower_unsafety(unsafety),
-                    self.lower_generics(generics, ImplTraitContext::Disallowed),
+                    self.lower_generics(generics, ImplTraitContext::disallowed()),
                     bounds,
                     items,
                 )
             }
             ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemKind::TraitAlias(
-                self.lower_generics(generics, ImplTraitContext::Disallowed),
-                self.lower_param_bounds(bounds, ImplTraitContext::Disallowed),
+                self.lower_generics(generics, ImplTraitContext::disallowed()),
+                self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
             ),
             ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"),
         }
@@ -3043,9 +3068,9 @@ fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
 
         let (generics, node) = match i.node {
             TraitItemKind::Const(ref ty, ref default) => (
-                self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
+                self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
                 hir::TraitItemKind::Const(
-                    self.lower_ty(ty, ImplTraitContext::Disallowed),
+                    self.lower_ty(ty, ImplTraitContext::disallowed()),
                     default
                         .as_ref()
                         .map(|x| self.lower_body(None, |this| this.lower_expr(x))),
@@ -3077,12 +3102,12 @@ fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
                 (generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Provided(body_id)))
             }
             TraitItemKind::Type(ref bounds, ref default) => (
-                self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
+                self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
                 hir::TraitItemKind::Type(
-                    self.lower_param_bounds(bounds, ImplTraitContext::Disallowed),
+                    self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
                     default
                         .as_ref()
-                        .map(|x| self.lower_ty(x, ImplTraitContext::Disallowed)),
+                        .map(|x| self.lower_ty(x, ImplTraitContext::disallowed())),
                 ),
             ),
             TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"),
@@ -3132,9 +3157,9 @@ fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
             ImplItemKind::Const(ref ty, ref expr) => {
                 let body_id = self.lower_body(None, |this| this.lower_expr(expr));
                 (
-                    self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
+                    self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
                     hir::ImplItemKind::Const(
-                        self.lower_ty(ty, ImplTraitContext::Disallowed),
+                        self.lower_ty(ty, ImplTraitContext::disallowed()),
                         body_id,
                     ),
                 )
@@ -3152,13 +3177,13 @@ fn lower_impl_item(&mut self, i: &ImplItem) -> hir::ImplItem {
                 (generics, hir::ImplItemKind::Method(sig, body_id))
             }
             ImplItemKind::Type(ref ty) => (
-                self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
-                hir::ImplItemKind::Type(self.lower_ty(ty, ImplTraitContext::Disallowed)),
+                self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
+                hir::ImplItemKind::Type(self.lower_ty(ty, ImplTraitContext::disallowed())),
             ),
             ImplItemKind::Existential(ref bounds) => (
-                self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
+                self.lower_generics(&i.generics, ImplTraitContext::disallowed()),
                 hir::ImplItemKind::Existential(
-                    self.lower_param_bounds(bounds, ImplTraitContext::Disallowed),
+                    self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
                 ),
             ),
             ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
@@ -3349,7 +3374,8 @@ fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
                     hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
                 }
                 ForeignItemKind::Static(ref t, m) => {
-                    hir::ForeignItemKind::Static(self.lower_ty(t, ImplTraitContext::Disallowed), m)
+                    hir::ForeignItemKind::Static(
+                        self.lower_ty(t, ImplTraitContext::disallowed()), m)
                 }
                 ForeignItemKind::Ty => hir::ForeignItemKind::Type,
                 ForeignItemKind::Macro(_) => panic!("shouldn't exist here"),
@@ -3488,7 +3514,7 @@ fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
                     &None,
                     path,
                     ParamMode::Optional,
-                    ImplTraitContext::Disallowed,
+                    ImplTraitContext::disallowed(),
                 );
                 self.check_self_struct_ctor_feature(&qpath);
                 hir::PatKind::TupleStruct(
@@ -3503,7 +3529,7 @@ fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
                     qself,
                     path,
                     ParamMode::Optional,
-                    ImplTraitContext::Disallowed,
+                    ImplTraitContext::disallowed(),
                 );
                 self.check_self_struct_ctor_feature(&qpath);
                 hir::PatKind::Path(qpath)
@@ -3514,7 +3540,7 @@ fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
                     &None,
                     path,
                     ParamMode::Optional,
-                    ImplTraitContext::Disallowed,
+                    ImplTraitContext::disallowed(),
                 );
 
                 let fs = fields
@@ -3608,7 +3634,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     ParamMode::Optional,
                     0,
                     ParenthesizedGenericArgs::Err,
-                    ImplTraitContext::Disallowed,
+                    ImplTraitContext::disallowed(),
                 );
                 let args = args.iter().map(|x| self.lower_expr(x)).collect();
                 hir::ExprKind::MethodCall(hir_seg, seg.ident.span, args)
@@ -3627,11 +3653,11 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
             ExprKind::Lit(ref l) => hir::ExprKind::Lit(P((**l).clone())),
             ExprKind::Cast(ref expr, ref ty) => {
                 let expr = P(self.lower_expr(expr));
-                hir::ExprKind::Cast(expr, self.lower_ty(ty, ImplTraitContext::Disallowed))
+                hir::ExprKind::Cast(expr, self.lower_ty(ty, ImplTraitContext::disallowed()))
             }
             ExprKind::Type(ref expr, ref ty) => {
                 let expr = P(self.lower_expr(expr));
-                hir::ExprKind::Type(expr, self.lower_ty(ty, ImplTraitContext::Disallowed))
+                hir::ExprKind::Type(expr, self.lower_ty(ty, ImplTraitContext::disallowed()))
             }
             ExprKind::AddrOf(m, ref ohs) => {
                 let m = self.lower_mutability(m);
@@ -3900,7 +3926,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     qself,
                     path,
                     ParamMode::Optional,
-                    ImplTraitContext::Disallowed,
+                    ImplTraitContext::disallowed(),
                 );
                 self.check_self_struct_ctor_feature(&qpath);
                 hir::ExprKind::Path(qpath)
@@ -3965,7 +3991,7 @@ fn lower_expr(&mut self, e: &Expr) -> hir::Expr {
                     &None,
                     path,
                     ParamMode::Optional,
-                    ImplTraitContext::Disallowed,
+                    ImplTraitContext::disallowed(),
                 ),
                 fields.iter().map(|x| self.lower_field(x)).collect(),
                 maybe_expr.as_ref().map(|x| P(self.lower_expr(x))),
index 65d42c0888d5d85ce08056353b4054498fcdc4a5..a327f1f5c9d50b462a5e1319da2eb57ac9d879cf 100644 (file)
@@ -135,10 +135,7 @@ fn make_query_result<T>(
         );
 
         // Select everything, returning errors.
-        let true_errors = match fulfill_cx.select_where_possible(self) {
-            Ok(()) => vec![],
-            Err(errors) => errors,
-        };
+        let true_errors = fulfill_cx.select_where_possible(self).err().unwrap_or_else(Vec::new);
         debug!("true_errors = {:#?}", true_errors);
 
         if !true_errors.is_empty() {
@@ -148,10 +145,7 @@ fn make_query_result<T>(
         }
 
         // Anything left unselected *now* must be an ambiguity.
-        let ambig_errors = match fulfill_cx.select_all_or_error(self) {
-            Ok(()) => vec![],
-            Err(errors) => errors,
-        };
+        let ambig_errors = fulfill_cx.select_all_or_error(self).err().unwrap_or_else(Vec::new);
         debug!("ambig_errors = {:#?}", ambig_errors);
 
         let region_obligations = self.take_registered_region_obligations();
@@ -316,16 +310,18 @@ pub fn instantiate_nll_query_result_and_region_obligations<R>(
         }
 
         // ...also include the other query region constraints from the query.
-        output_query_region_constraints.reserve(query_result.value.region_constraints.len());
-        for r_c in query_result.value.region_constraints.iter() {
-            let &ty::OutlivesPredicate(k1, r2) = r_c.skip_binder(); // reconstructed below
-            let k1 = substitute_value(self.tcx, &result_subst, &k1);
-            let r2 = substitute_value(self.tcx, &result_subst, &r2);
-            if k1 != r2.into() {
-                output_query_region_constraints
-                    .push(ty::Binder::bind(ty::OutlivesPredicate(k1, r2)));
-            }
-        }
+        output_query_region_constraints.extend(
+            query_result.value.region_constraints.iter().filter_map(|r_c| {
+                let &ty::OutlivesPredicate(k1, r2) = r_c.skip_binder(); // reconstructed below
+                let k1 = substitute_value(self.tcx, &result_subst, &k1);
+                let r2 = substitute_value(self.tcx, &result_subst, &r2);
+                if k1 != r2.into() {
+                    Some(ty::Binder::bind(ty::OutlivesPredicate(k1, r2)))
+                } else {
+                    None
+                }
+            })
+        );
 
         let user_result: R =
             query_result.substitute_projected(self.tcx, &result_subst, |q_r| &q_r.value);
@@ -448,10 +444,9 @@ fn query_result_substitution_guess<R>(
                 .variables
                 .iter()
                 .enumerate()
-                .map(|(index, info)| match opt_values[CanonicalVar::new(index)] {
-                    Some(k) => k,
-                    None => self.fresh_inference_var_for_canonical_var(cause.span, *info),
-                })
+                .map(|(index, info)| opt_values[CanonicalVar::new(index)].unwrap_or_else(||
+                    self.fresh_inference_var_for_canonical_var(cause.span, *info)
+                ))
                 .collect(),
         };
 
@@ -504,24 +499,22 @@ fn query_region_constraints_into_obligations<'a>(
                     let ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below
                     let k1 = substitute_value(self.tcx, result_subst, k1);
                     let r2 = substitute_value(self.tcx, result_subst, r2);
-                    match k1.unpack() {
-                        UnpackedKind::Lifetime(r1) => Obligation::new(
-                            cause.clone(),
-                            param_env,
-                            ty::Predicate::RegionOutlives(ty::Binder::dummy(
-                                ty::OutlivesPredicate(r1, r2),
+
+                    Obligation::new(
+                        cause.clone(),
+                        param_env,
+                        match k1.unpack() {
+                            UnpackedKind::Lifetime(r1) => ty::Predicate::RegionOutlives(
+                                ty::Binder::dummy(
+                                    ty::OutlivesPredicate(r1, r2)
                             )),
-                        ),
-
-                        UnpackedKind::Type(t1) => Obligation::new(
-                            cause.clone(),
-                            param_env,
-                            ty::Predicate::TypeOutlives(ty::Binder::dummy(ty::OutlivesPredicate(
-                                t1, r2,
-                            ))),
-                        ),
-                    }
-                }),
+                            UnpackedKind::Type(t1) => ty::Predicate::TypeOutlives(
+                                ty::Binder::dummy(ty::OutlivesPredicate(
+                                    t1, r2
+                            )))
+                        }
+                    )
+                })
         ) as Box<dyn Iterator<Item = _>>
     }
 
@@ -583,31 +576,30 @@ pub fn make_query_outlives<'tcx>(
     assert!(verifys.is_empty());
     assert!(givens.is_empty());
 
-    let mut outlives: Vec<_> = constraints
-            .into_iter()
-            .map(|(k, _)| match *k {
-                // Swap regions because we are going from sub (<=) to outlives
-                // (>=).
-                Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
-                    tcx.mk_region(ty::ReVar(v2)).into(),
-                    tcx.mk_region(ty::ReVar(v1)),
-                ),
-                Constraint::VarSubReg(v1, r2) => {
-                    ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1)))
-                }
-                Constraint::RegSubVar(r1, v2) => {
-                    ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1)
-                }
-                Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
-            })
-            .map(ty::Binder::dummy) // no bound regions in the code above
-            .collect();
-
-    outlives.extend(
-        outlives_obligations
-            .map(|(ty, r)| ty::OutlivesPredicate(ty.into(), r))
-            .map(ty::Binder::dummy), // no bound regions in the code above
-    );
+    let outlives: Vec<_> = constraints
+        .into_iter()
+        .map(|(k, _)| match *k {
+            // Swap regions because we are going from sub (<=) to outlives
+            // (>=).
+            Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
+                tcx.mk_region(ty::ReVar(v2)).into(),
+                tcx.mk_region(ty::ReVar(v1)),
+            ),
+            Constraint::VarSubReg(v1, r2) => {
+                ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1)))
+            }
+            Constraint::RegSubVar(r1, v2) => {
+                ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1)
+            }
+            Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
+        })
+        .map(ty::Binder::dummy) // no bound regions in the code above
+        .chain(
+            outlives_obligations
+                .map(|(ty, r)| ty::OutlivesPredicate(ty.into(), r))
+                .map(ty::Binder::dummy), // no bound regions in the code above
+        )
+        .collect();
 
     outlives
 }
index 26eb2ffbf6aba763e12245a9d92c53d3fa52ba96..854960492c9bd4c897e3f357747a3c1dcdbbecf5 100644 (file)
@@ -77,24 +77,22 @@ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
         match (&a.sty, &b.sty) {
             (&ty::Infer(TyVar(a_id)), &ty::Infer(TyVar(b_id))) => {
                 infcx.type_variables.borrow_mut().equate(a_id, b_id);
-                Ok(a)
             }
 
             (&ty::Infer(TyVar(a_id)), _) => {
                 self.fields.instantiate(b, RelationDir::EqTo, a_id, self.a_is_expected)?;
-                Ok(a)
             }
 
             (_, &ty::Infer(TyVar(b_id))) => {
                 self.fields.instantiate(a, RelationDir::EqTo, b_id, self.a_is_expected)?;
-                Ok(a)
             }
 
             _ => {
                 self.fields.infcx.super_combine_tys(self, a, b)?;
-                Ok(a)
             }
         }
+
+        Ok(a)
     }
 
     fn regions(&mut self, a: ty::Region<'tcx>, b: ty::Region<'tcx>)
index 09059090e2e35421c5dd9f3104dd89388b3b57a9..a68241ff2c0201c761894a3736e9d4c72aa44f2d 100644 (file)
@@ -406,10 +406,10 @@ fn process_errors(
             errors.clone()
         } else {
             errors
-                .iter()
-                .filter(|&e| !is_bound_failure(e))
-                .cloned()
-                .collect()
+            .iter()
+            .filter(|&e| !is_bound_failure(e))
+            .cloned()
+            .collect()
         };
 
         // sort the errors by span, for better error message stability.
@@ -455,11 +455,10 @@ fn check_and_note_conflicting_crates(
             TypeError::Sorts(ref exp_found) => {
                 // if they are both "path types", there's a chance of ambiguity
                 // due to different versions of the same crate
-                match (&exp_found.expected.sty, &exp_found.found.sty) {
-                    (&ty::Adt(exp_adt, _), &ty::Adt(found_adt, _)) => {
-                        report_path_match(err, exp_adt.did, found_adt.did);
-                    }
-                    _ => (),
+                if let (&ty::Adt(exp_adt, _), &ty::Adt(found_adt, _))
+                     = (&exp_found.expected.sty, &exp_found.found.sty)
+                {
+                    report_path_match(err, exp_adt.did, found_adt.did);
                 }
             }
             TypeError::Traits(ref exp_found) => {
index 505b1bc032d2021b9dbe6457c07b8015b460c049..efb316243fad036933d94c2cee3436074323fb9f 100644 (file)
@@ -100,7 +100,7 @@ pub fn need_type_info_err(&self,
         let mut labels = vec![(
             span,
             if &name == "_" {
-                "cannot infer type".to_string()
+                "cannot infer type".to_owned()
             } else {
                 format!("cannot infer type for `{}`", name)
             },
@@ -138,7 +138,7 @@ pub fn need_type_info_err(&self,
             // ```
             labels.clear();
             labels.push(
-                (pattern.span, "consider giving this closure parameter a type".to_string()));
+                (pattern.span, "consider giving this closure parameter a type".to_owned()));
         } else if let Some(pattern) = local_visitor.found_local_pattern {
             if let Some(simple_ident) = pattern.simple_ident() {
                 match pattern.span.compiler_desugaring_kind() {
@@ -146,12 +146,12 @@ pub fn need_type_info_err(&self,
                                          format!("consider giving `{}` a type", simple_ident))),
                     Some(CompilerDesugaringKind::ForLoop) => labels.push((
                         pattern.span,
-                        "the element type for this iterator is not specified".to_string(),
+                        "the element type for this iterator is not specified".to_owned(),
                     )),
                     _ => {}
                 }
             } else {
-                labels.push((pattern.span, "consider giving the pattern a type".to_string()));
+                labels.push((pattern.span, "consider giving the pattern a type".to_owned()));
             }
         }
 
index 97b1978cb2eb2223af8e437504a15ee63945b470..1f84c73a715833fae46ac4cd09fea46b17f8bd1b 100644 (file)
@@ -113,12 +113,12 @@ pub(super) fn try_report_anon_anon_conflict(&self) -> Option<ErrorReported> {
             (None, None) => {
                 let (main_label_1, span_label_1) = if ty_sup.id == ty_sub.id {
                     (
-                        "this type is declared with multiple lifetimes...".to_string(),
-                        "...but data with one lifetime flows into the other here".to_string()
+                        "this type is declared with multiple lifetimes...".to_owned(),
+                        "...but data with one lifetime flows into the other here".to_owned()
                     )
                 } else {
                     (
-                        "these two types are declared with different lifetimes...".to_string(),
+                        "these two types are declared with different lifetimes...".to_owned(),
                         format!(
                             "...but data{} flows{} here",
                             span_label_var1,
@@ -133,7 +133,7 @@ pub(super) fn try_report_anon_anon_conflict(&self) -> Option<ErrorReported> {
                 ty_sub.span,
                 ret_span,
                 "this parameter and the return type are declared \
-                 with different lifetimes...".to_string()
+                 with different lifetimes...".to_owned()
                 ,
                 format!("...but data{} is returned here", span_label_var1),
             ),
@@ -141,7 +141,7 @@ pub(super) fn try_report_anon_anon_conflict(&self) -> Option<ErrorReported> {
                 ty_sup.span,
                 ret_span,
                 "this parameter and the return type are declared \
-                 with different lifetimes...".to_string()
+                 with different lifetimes...".to_owned()
                 ,
                 format!("...but data{} is returned here", span_label_var1),
             ),
index 5c27cdb6fb55392198cb30678f1895d81b4ff040..009a823568131fb6b007e44aabd6b58c2ecce3cd 100644 (file)
@@ -58,18 +58,17 @@ pub(super) fn try_report_outlives_closure(&self) -> Option<ErrorReported> {
                     &RegionKind::ReFree(ref free_region)) = (&sub_origin, sup_region) {
                 let hir = &self.tcx.hir;
                 if let Some(node_id) = hir.as_local_node_id(free_region.scope) {
-                    match hir.get(node_id) {
-                        Node::Expr(Expr {
-                            node: Closure(_, _, _, closure_span, None),
-                            ..
-                        }) => {
-                            let sup_sp = sup_origin.span();
-                            let origin_sp = origin.span();
-                            let mut err = self.tcx.sess.struct_span_err(
-                                sup_sp,
-                                "borrowed data cannot be stored outside of its closure");
-                            err.span_label(sup_sp, "cannot be stored outside of its closure");
-                            if origin_sp == sup_sp || origin_sp.contains(sup_sp) {
+                    if let Node::Expr(Expr {
+                        node: Closure(_, _, _, closure_span, None),
+                        ..
+                    }) = hir.get(node_id) {
+                        let sup_sp = sup_origin.span();
+                        let origin_sp = origin.span();
+                        let mut err = self.tcx.sess.struct_span_err(
+                            sup_sp,
+                            "borrowed data cannot be stored outside of its closure");
+                        err.span_label(sup_sp, "cannot be stored outside of its closure");
+                        if origin_sp == sup_sp || origin_sp.contains(sup_sp) {
 // // sup_sp == origin.span():
 //
 // let mut x = None;
@@ -87,11 +86,11 @@ pub(super) fn try_report_outlives_closure(&self) -> Option<ErrorReported> {
 //                         ------------ ... because it cannot outlive this closure
 //     f = Some(x);
 //              ^ cannot be stored outside of its closure
-                                err.span_label(*external_span,
-                                               "borrowed data cannot be stored into here...");
-                                err.span_label(*closure_span,
-                                               "...because it cannot outlive this closure");
-                            } else {
+                            err.span_label(*external_span,
+                                           "borrowed data cannot be stored into here...");
+                            err.span_label(*closure_span,
+                                           "...because it cannot outlive this closure");
+                        } else {
 // FIXME: the wording for this case could be much improved
 //
 // let mut lines_to_use: Vec<&CrateId> = Vec::new();
@@ -102,18 +101,16 @@ pub(super) fn try_report_outlives_closure(&self) -> Option<ErrorReported> {
 //     ...so that variable is valid at time of its declaration
 //     lines_to_use.push(installed_id);
 //                       ^^^^^^^^^^^^ cannot be stored outside of its closure
-                                err.span_label(origin_sp,
-                                               "cannot infer an appropriate lifetime...");
-                                err.span_label(*external_span,
-                                               "...so that variable is valid at time of its \
-                                                declaration");
-                                err.span_label(*closure_span,
-                                               "borrowed data cannot outlive this closure");
-                            }
-                            err.emit();
-                            return Some(ErrorReported);
+                            err.span_label(origin_sp,
+                                           "cannot infer an appropriate lifetime...");
+                            err.span_label(*external_span,
+                                           "...so that variable is valid at time of its \
+                                            declaration");
+                            err.span_label(*closure_span,
+                                           "borrowed data cannot outlive this closure");
                         }
-                        _ => {}
+                        err.emit();
+                        return Some(ErrorReported);
                     }
                 }
             }
index 3393eb65089c05a55e3b6cf337ff6cd98b0860c0..766173bf66283d4118d8250137a5e19daaf04381 100644 (file)
@@ -20,64 +20,62 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
     /// Print the error message for lifetime errors when the return type is a static impl Trait.
     pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> {
         if let Some(ref error) = self.error {
-            match error.clone() {
-                RegionResolutionError::SubSupConflict(
+            if let RegionResolutionError::SubSupConflict(
                     var_origin,
                     sub_origin,
                     sub_r,
                     sup_origin,
                     sup_r,
-                ) => {
-                    let anon_reg_sup = self.tcx.is_suitable_region(sup_r)?;
-                    if sub_r == &RegionKind::ReStatic &&
-                        self.tcx.return_type_impl_trait(anon_reg_sup.def_id).is_some()
-                    {
-                        let sp = var_origin.span();
-                        let return_sp = sub_origin.span();
-                        let mut err = self.tcx.sess.struct_span_err(
-                            sp,
-                            "cannot infer an appropriate lifetime",
+                ) = error.clone()
+            {
+                let anon_reg_sup = self.tcx.is_suitable_region(sup_r)?;
+                if sub_r == &RegionKind::ReStatic &&
+                    self.tcx.return_type_impl_trait(anon_reg_sup.def_id).is_some()
+                {
+                    let sp = var_origin.span();
+                    let return_sp = sub_origin.span();
+                    let mut err = self.tcx.sess.struct_span_err(
+                        sp,
+                        "cannot infer an appropriate lifetime",
+                    );
+                    err.span_label(
+                        return_sp,
+                        "this return type evaluates to the `'static` lifetime...",
+                    );
+                    err.span_label(
+                        sup_origin.span(),
+                        "...but this borrow...",
+                    );
+
+                    let (lifetime, lt_sp_opt) = self.tcx.msg_span_from_free_region(sup_r);
+                    if let Some(lifetime_sp) = lt_sp_opt {
+                        err.span_note(
+                            lifetime_sp,
+                            &format!("...can't outlive {}", lifetime),
                         );
-                        err.span_label(
+                    }
+
+                    let lifetime_name = match sup_r {
+                        RegionKind::ReFree(FreeRegion {
+                            bound_region: BoundRegion::BrNamed(_, ref name), ..
+                        }) => name.to_string(),
+                        _ => "'_".to_owned(),
+                    };
+                    if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(return_sp) {
+                        err.span_suggestion_with_applicability(
                             return_sp,
-                            "this return type evaluates to the `'static` lifetime...",
+                            &format!(
+                                "you can add a constraint to the return type to make it last \
+                                 less than `'static` and match {}",
+                                lifetime,
+                            ),
+                            format!("{} + {}", snippet, lifetime_name),
+                            Applicability::Unspecified,
                         );
-                        err.span_label(
-                            sup_origin.span(),
-                            "...but this borrow...",
-                        );
-
-                        let (lifetime, lt_sp_opt) = self.tcx.msg_span_from_free_region(sup_r);
-                        if let Some(lifetime_sp) = lt_sp_opt {
-                            err.span_note(
-                                lifetime_sp,
-                                &format!("...can't outlive {}", lifetime),
-                            );
-                        }
-
-                        let lifetime_name = match sup_r {
-                            RegionKind::ReFree(FreeRegion {
-                                bound_region: BoundRegion::BrNamed(_, ref name), ..
-                            }) => name.to_string(),
-                            _ => "'_".to_owned(),
-                        };
-                        if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(return_sp) {
-                            err.span_suggestion_with_applicability(
-                                return_sp,
-                                &format!(
-                                    "you can add a constraint to the return type to make it last \
-                                     less than `'static` and match {}",
-                                    lifetime,
-                                ),
-                                format!("{} + {}", snippet, lifetime_name),
-                                Applicability::Unspecified,
-                            );
-                        }
-                        err.emit();
-                        return Some(ErrorReported);
                     }
+                    err.emit();
+                    return Some(ErrorReported);
                 }
-                _ => {}
             }
         }
         None
index a6efb5e678332fc24d11e9115f850944ee70ca6a..013c02f75b88315f1a7f776d2ed8d70c93e4522d 100644 (file)
@@ -119,16 +119,13 @@ pub(super) fn is_return_type_anon(
         decl: &hir::FnDecl,
     ) -> Option<Span> {
         let ret_ty = self.tcx.type_of(scope_def_id);
-        match ret_ty.sty {
-            ty::FnDef(_, _) => {
-                let sig = ret_ty.fn_sig(self.tcx);
-                let late_bound_regions = self.tcx
-                    .collect_referenced_late_bound_regions(&sig.output());
-                if late_bound_regions.iter().any(|r| *r == br) {
-                    return Some(decl.output.span());
-                }
+        if let ty::FnDef(_, _) = ret_ty.sty {
+            let sig = ret_ty.fn_sig(self.tcx);
+            let late_bound_regions = self.tcx
+                .collect_referenced_late_bound_regions(&sig.output());
+            if late_bound_regions.iter().any(|r| *r == br) {
+                return Some(decl.output.span());
             }
-            _ => {}
         }
         None
     }
@@ -140,8 +137,8 @@ pub(super) fn is_return_type_anon(
     pub(super) fn is_self_anon(&self, is_first: bool, scope_def_id: DefId) -> bool {
         is_first
             && self.tcx
-                .opt_associated_item(scope_def_id)
-                .map(|i| i.method_has_self_argument) == Some(true)
+                   .opt_associated_item(scope_def_id)
+                   .map(|i| i.method_has_self_argument) == Some(true)
     }
 
 }
index 3f17c9bb020ef11c8e288acd1a724452ddace469..b55727d2c84f0902a5d8f266d783c6d77314400e 100644 (file)
@@ -112,12 +112,9 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
         }
     };
 
-    match dump_region_data_to(region_rels, &region_data.constraints, &output_path) {
-        Ok(()) => {}
-        Err(e) => {
-            let msg = format!("io error dumping region constraints: {}", e);
-            tcx.sess.err(&msg)
-        }
+    if let Err(e) = dump_region_data_to(region_rels, &region_data.constraints, &output_path) {
+        let msg = format!("io error dumping region constraints: {}", e);
+        tcx.sess.err(&msg)
     }
 }
 
@@ -187,12 +184,9 @@ fn node_id(&self, n: &Node) -> dot::Id<'_> {
             None => bug!("no node_id found for node: {:?}", n),
         };
         let name = || format!("node_{}", node_id);
-        match dot::Id::new(name()) {
-            Ok(id) => id,
-            Err(_) => {
-                bug!("failed to create graphviz node identified by {}", name());
-            }
-        }
+
+        dot::Id::new(name()).unwrap_or_else(|_|
+            bug!("failed to create graphviz node identified by {}", name()))
     }
     fn node_label(&self, n: &Node) -> dot::LabelText<'_> {
         match *n {
@@ -204,7 +198,7 @@ fn edge_label(&self, e: &Edge<'_>) -> dot::LabelText<'_> {
         match *e {
             Edge::Constraint(ref c) =>
                 dot::LabelText::label(format!("{:?}", self.map.get(c).unwrap())),
-            Edge::EnclScope(..) => dot::LabelText::label("(enclosed)".to_string()),
+            Edge::EnclScope(..) => dot::LabelText::label("(enclosed)".to_owned()),
         }
     }
 }
index 2046f66f99f66c91ed4086adb5445e15ff4a2b35..ca49d053210c7c0026ada442afc0ca14f55bed34 100644 (file)
@@ -147,9 +147,7 @@ fn num_vars(&self) -> usize {
     fn construct_var_data(&self, tcx: TyCtxt<'_, '_, 'tcx>) -> LexicalRegionResolutions<'tcx> {
         LexicalRegionResolutions {
             error_region: tcx.types.re_static,
-            values: (0..self.num_vars())
-                .map(|_| VarValue::Value(tcx.types.re_empty))
-                .collect(),
+            values: IndexVec::from_elem_n(VarValue::Value(tcx.types.re_empty), self.num_vars())
         }
     }
 
index e5220aad0562e0273da036e10916a0d49262ba76..49858972416d8f1c025b18e4fbd256d9a47bf87a 100644 (file)
@@ -803,6 +803,7 @@ fn fold_opaque_ty(
         );
         debug!("instantiate_opaque_types: ty_var={:?}", ty_var);
 
+        self.obligations.reserve(bounds.predicates.len());
         for predicate in bounds.predicates {
             // Change the predicate to refer to the type variable,
             // which will be the concrete type instead of the opaque type.
index 95893a7117892c4a7d45dfacd57b66fe5063ec6b..87bfbaef54c4e7748bf3cb6dee249b4fcf2b3ea2 100644 (file)
@@ -443,7 +443,7 @@ pub fn commit(&mut self, snapshot: RegionSnapshot) {
         assert!(self.undo_log[snapshot.length] == OpenSnapshot);
 
         if snapshot.length == 0 {
-            self.undo_log.truncate(0);
+            self.undo_log.clear();
         } else {
             (*self.undo_log)[snapshot.length] = CommitedSnapshot;
         }
@@ -661,11 +661,10 @@ fn add_verify(&mut self, verify: Verify<'tcx>) {
         debug!("RegionConstraintCollector: add_verify({:?})", verify);
 
         // skip no-op cases known to be satisfied
-        match verify.bound {
-            VerifyBound::AllBounds(ref bs) if bs.len() == 0 => {
+        if let VerifyBound::AllBounds(ref bs) = verify.bound {
+            if bs.len() == 0 {
                 return;
             }
-            _ => {}
         }
 
         let index = self.data.verifys.len();
index be13fb9a2a5ebf8818925001a71e5d0bea08e7e4..0ef97618572640f4ac5e1003963d1a3e56c7971b 100644 (file)
@@ -153,8 +153,8 @@ fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
         if !t.needs_infer() && !ty::keep_local(&t) {
             t // micro-optimize -- if there is nothing in this type that this fold affects...
-                // ^ we need to have the `keep_local` check to un-default
-                // defaulted tuples.
+              // ^ we need to have the `keep_local` check to un-default
+              // defaulted tuples.
         } else {
             let t = self.infcx.shallow_resolve(t);
             match t.sty {
index b1e4fc7c7fc7b1127e9192bf3dcbbd72162ceb17..970b6e096ffe4d04370e482d43e079e29daa214e 100644 (file)
@@ -273,11 +273,8 @@ pub fn snapshot(&mut self) -> Snapshot<'tcx> {
     pub fn rollback_to(&mut self, s: Snapshot<'tcx>) {
         debug!("rollback_to{:?}", {
             for action in self.values.actions_since_snapshot(&s.snapshot) {
-                match *action {
-                    sv::UndoLog::NewElem(index) => {
-                        debug!("inference variable _#{}t popped", index)
-                    }
-                    _ => { }
+                if let sv::UndoLog::NewElem(index) = *action {
+                    debug!("inference variable _#{}t popped", index)
                 }
             }
         });
index 80365a56102126ad892e6acc4d1011333239e826..87d33e473e7f6cd97bc392e3f6bf926518744264 100644 (file)
@@ -18,7 +18,7 @@
 use lint::{self, Lint, LintId, Level, LintSource};
 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
                                            StableHasher, StableHasherResult};
-use session::Session;
+use session::{config::nightly_options, Session};
 use syntax::ast;
 use syntax::attr;
 use syntax::source_map::MultiSpan;
@@ -299,7 +299,13 @@ pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush {
                                     "change it to",
                                     new_lint_name.to_string(),
                                     Applicability::MachineApplicable,
-                                ).emit();
+                                );
+
+                                if nightly_options::is_nightly_build() {
+                                    err.emit();
+                                } else {
+                                    err.cancel();
+                                }
 
                                 let src = LintSource::Node(Symbol::intern(&new_lint_name), li.span);
                                 for id in ids {
index 5ca2bfebbeb27a84fd899409820f1409f0572eda..c532b5ee56f47d2d908cf442795842f84b0182e5 100644 (file)
@@ -1322,8 +1322,6 @@ fn parse_cross_lang_lto(slot: &mut CrossLangLto, v: Option<&str>) -> bool {
         useful for profiling / PGO."),
     relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED],
         "choose which RELRO level to use"),
-    disable_ast_check_for_mutation_in_guard: bool = (false, parse_bool, [UNTRACKED],
-        "skip AST-based mutation-in-guard check (mir-borrowck provides more precise check)"),
     nll_subminimal_causes: bool = (false, parse_bool, [UNTRACKED],
         "when tracking region error causes, accept subminimal results for faster execution."),
     nll_facts: bool = (false, parse_bool, [UNTRACKED],
index 63408d809ec2989fb528b1be16a16ff83eb7cf05..64e9d15092eb8d0aa74524ec0931bfdbc9531f39 100644 (file)
@@ -1467,11 +1467,6 @@ pub fn allow_bind_by_move_patterns_with_guards(self) -> bool {
     /// If true, we should use a naive AST walk to determine if match
     /// guard could perform bad mutations (or mutable-borrows).
     pub fn check_for_mutation_in_guard_via_ast_walk(self) -> bool {
-        // If someone passes the `-Z` flag, they're asking for the footgun.
-        if self.sess.opts.debugging_opts.disable_ast_check_for_mutation_in_guard {
-            return false;
-        }
-
         // If someone requests the feature, then be a little more
         // careful and ensure that MIR-borrowck is enabled (which can
         // happen via edition selection, via `feature(nll)`, or via an
index 98042e18d32d9bd0913a4913aa6b59caf52bb84b..547f7cecc4e060c404ab65ee49b6a5b23722790d 100644 (file)
@@ -702,7 +702,12 @@ fn relate<'a, 'gcx, R>(
             (UnpackedKind::Type(a_ty), UnpackedKind::Type(b_ty)) => {
                 Ok(relation.relate(&a_ty, &b_ty)?.into())
             }
-            (UnpackedKind::Lifetime(_), _) | (UnpackedKind::Type(_), _) => bug!()
+            (UnpackedKind::Lifetime(unpacked), x) => {
+                bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x)
+            }
+            (UnpackedKind::Type(unpacked), x) => {
+                bug!("impossible case reached: can't relate: {:?} with {:?}", unpacked, x)
+            }
         }
     }
 }
index b8614c520e7cfa601857b4f6017d44a3e58ccdfe..a5905df57c8cfd62f9624adb2bc030ab39d76cd6 100644 (file)
@@ -31,6 +31,7 @@ fn main() {
             .out_dir(&native.out_dir)
             .build_target(&target)
             .build();
+        native.fixup_sanitizer_lib_name("asan");
     }
     println!("cargo:rerun-if-env-changed=LLVM_CONFIG");
 }
index af9ed9306ebb2f29be1396d21a22a64c9a097db8..eff80a98c9de905a6b293fea73d7c2c8aa08743f 100644 (file)
@@ -53,7 +53,7 @@ pub fn insert(&mut self, element: T) -> bool {
         }
     }
 
-    /// Attempt to enqueue `element` in the work queue. Returns false if it was already present.
+    /// Attempt to pop an element from the work queue.
     #[inline]
     pub fn pop(&mut self) -> Option<T> {
         if let Some(element) = self.deque.pop_front() {
index 8c4eb90eb261fa253b1909a807c5b70f579ee31c..15bf837b526b1b2e8fdc436346f2884cbbff5e0c 100644 (file)
@@ -3147,11 +3147,11 @@ fn smart_resolve_path_fragment(&mut self,
                             // parser issue where a struct literal is being used on an expression
                             // where a brace being opened means a block is being started. Look
                             // ahead for the next text to see if `span` is followed by a `{`.
-                            let cm = this.session.source_map();
+                            let sm = this.session.source_map();
                             let mut sp = span;
                             loop {
-                                sp = cm.next_point(sp);
-                                match cm.span_to_snippet(sp) {
+                                sp = sm.next_point(sp);
+                                match sm.span_to_snippet(sp) {
                                     Ok(ref snippet) => {
                                         if snippet.chars().any(|c| { !c.is_whitespace() }) {
                                             break;
@@ -3160,20 +3160,51 @@ fn smart_resolve_path_fragment(&mut self,
                                     _ => break,
                                 }
                             }
-                            let followed_by_brace = match cm.span_to_snippet(sp) {
+                            let followed_by_brace = match sm.span_to_snippet(sp) {
                                 Ok(ref snippet) if snippet == "{" => true,
                                 _ => false,
                             };
-                            if let (PathSource::Expr(None), true) = (source, followed_by_brace) {
-                                err.span_label(
-                                    span,
-                                    format!("did you mean `({} {{ /* fields */ }})`?", path_str),
-                                );
-                            } else {
-                                err.span_label(
-                                    span,
-                                    format!("did you mean `{} {{ /* fields */ }}`?", path_str),
-                                );
+                            match source {
+                                PathSource::Expr(Some(parent)) => {
+                                    match parent.node {
+                                        ExprKind::MethodCall(ref path_assignment, _)  => {
+                                            err.span_suggestion_with_applicability(
+                                                sm.start_point(parent.span)
+                                                  .to(path_assignment.ident.span),
+                                                "use `::` to access an associated function",
+                                                format!("{}::{}",
+                                                        path_str,
+                                                        path_assignment.ident),
+                                                Applicability::MaybeIncorrect
+                                            );
+                                            return (err, candidates);
+                                        },
+                                        _ => {
+                                            err.span_label(
+                                                span,
+                                                format!("did you mean `{} {{ /* fields */ }}`?",
+                                                        path_str),
+                                            );
+                                            return (err, candidates);
+                                        },
+                                    }
+                                },
+                                PathSource::Expr(None) if followed_by_brace == true => {
+                                    err.span_label(
+                                        span,
+                                        format!("did you mean `({} {{ /* fields */ }})`?",
+                                                path_str),
+                                    );
+                                    return (err, candidates);
+                                },
+                                _ => {
+                                    err.span_label(
+                                        span,
+                                        format!("did you mean `{} {{ /* fields */ }}`?",
+                                                path_str),
+                                    );
+                                    return (err, candidates);
+                                },
                             }
                         }
                         return (err, candidates);
index 38595478c74337edde1bcc413704c37e190211b3..d23c71e2c1286cf9fdecf0eff3948e2a9fa70dc4 100644 (file)
@@ -31,6 +31,7 @@ fn main() {
             .out_dir(&native.out_dir)
             .build_target(&target)
             .build();
+        native.fixup_sanitizer_lib_name("tsan");
     }
     println!("cargo:rerun-if-env-changed=LLVM_CONFIG");
 }
index de4ab527e1559c155702bf5057bf312b8fa8b78d..62ffffab07661304f48df4af1bdd9a0baa587413 100644 (file)
@@ -138,9 +138,15 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) {
         if extern_crate.warn_if_unused {
             if let Some(&span) = unused_extern_crates.get(&extern_crate.def_id) {
                 let msg = "unused extern crate";
+
+                // Removal suggestion span needs to include attributes (Issue #54400)
+                let span_with_attrs = tcx.get_attrs(extern_crate.def_id).iter()
+                    .map(|attr| attr.span)
+                    .fold(span, |acc, attr_span| acc.to(attr_span));
+
                 tcx.struct_span_lint_node(lint, id, span, msg)
                     .span_suggestion_short_with_applicability(
-                        span,
+                        span_with_attrs,
                         "remove it",
                         String::new(),
                         Applicability::MachineApplicable)
index 3f46b0e312d103787b5575cd836aa0d7681710b6..10a4678107e1c88cb44f69313055f20ced709ac8 100644 (file)
 // This test illustrates that under NLL, we can remove our overly
 // conservative approach for disallowing mutations of match inputs.
 
-// See further discussion on rust-lang/rust#24535 and
-// rust-lang/rfcs#1006.
-
-// compile-flags: -Z disable-ast-check-for-mutation-in-guard
+// See further discussion on rust-lang/rust#24535,
+// rust-lang/rfcs#1006, and rust-lang/rfcs#107
 
 #![feature(nll)]
+#![feature(bind_by_move_pattern_guards)]
 
 fn main() {
     rust_issue_24535();
index 52c99a7b159e381e8369aaa3630d8f9145124b1b..82bc6194483c04234e920f1ed53e019a9545134b 100644 (file)
@@ -9,12 +9,16 @@ error[E0562]: `impl Trait` not allowed outside of function and inherent method r
    |
 LL | const FOO: impl Copy = 42;
    |            ^^^^^^^^^
+   |
+   = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
   --> $DIR/feature-gate-impl_trait_in_bindings.rs:13:13
    |
 LL | static BAR: impl Copy = 42;
    |             ^^^^^^^^^
+   |
+   = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable
 
 error: aborting due to 3 previous errors
 
index b15893e7c28cf5d45a731555fe612fa3406e0470..c43271c7371d27b27ff05c5815882206f37ec9cc 100644 (file)
@@ -231,6 +231,8 @@ error[E0562]: `impl Trait` not allowed outside of function and inherent method r
    |
 LL |     let _in_local_variable: impl Fn() = || {};
    |                             ^^^^^^^^^
+   |
+   = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable
 
 error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
   --> $DIR/where-allowed.rs:232:46
index 39d54f6e7ae28f65df90fda4a4f04ea7561ce7f4..6cbd493b9918207623952629ac01f00eb983f83b 100644 (file)
@@ -15,8 +15,8 @@
 // reject it. But I want to make sure that we continue to reject it
 // (under NLL) even when that conservaive check goes away.
 
-// compile-flags: -Z disable-ast-check-for-mutation-in-guard
 
+#![feature(bind_by_move_pattern_guards)]
 #![feature(nll)]
 
 fn main() {
index 49846f620f0c010cbfd339f3d2a9651a54074679..f359800812c87a733ccf55b00b75a79cbcd0a041 100644 (file)
@@ -5,8 +5,8 @@
 // Test that we don't allow mutating the value being matched on in a way that
 // changes which patterns it matches, until we have chosen an arm.
 
-// compile-flags: -Zdisable-ast-check-for-mutation-in-guard
 
+#![feature(bind_by_move_pattern_guards)]
 #![feature(nll)]
 
 fn ok_mutation_in_guard(mut q: i32) {
diff --git a/src/test/ui/resolve/issue-22692.rs b/src/test/ui/resolve/issue-22692.rs
new file mode 100644 (file)
index 0000000..06648c5
--- /dev/null
@@ -0,0 +1,13 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let _ = String.new();
+}
diff --git a/src/test/ui/resolve/issue-22692.stderr b/src/test/ui/resolve/issue-22692.stderr
new file mode 100644 (file)
index 0000000..ecdd4ff
--- /dev/null
@@ -0,0 +1,11 @@
+error[E0423]: expected value, found struct `String`
+  --> $DIR/issue-22692.rs:12:13
+   |
+LL |     let _ = String.new();
+   |             ^^^^^^----
+   |             |
+   |             help: use `::` to access an associated function: `String::new`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0423`.
diff --git a/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.fixed b/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.fixed
new file mode 100644 (file)
index 0000000..20ebe6b
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:edition-lint-paths.rs
+// run-rustfix
+// compile-flags:--extern edition_lint_paths --cfg blandiloquence
+// edition:2018
+
+#![deny(rust_2018_idioms)]
+#![allow(dead_code)]
+
+// The suggestion span should include the attribute.
+
+
+//~^ ERROR unused extern crate
+
+fn main() {}
diff --git a/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.rs b/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.rs
new file mode 100644 (file)
index 0000000..11febe5
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:edition-lint-paths.rs
+// run-rustfix
+// compile-flags:--extern edition_lint_paths --cfg blandiloquence
+// edition:2018
+
+#![deny(rust_2018_idioms)]
+#![allow(dead_code)]
+
+// The suggestion span should include the attribute.
+
+#[cfg(blandiloquence)] //~ HELP remove it
+extern crate edition_lint_paths;
+//~^ ERROR unused extern crate
+
+fn main() {}
diff --git a/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr b/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr
new file mode 100644 (file)
index 0000000..cb945ba
--- /dev/null
@@ -0,0 +1,18 @@
+error: unused extern crate
+  --> $DIR/issue-54400-unused-extern-crate-attr-span.rs:22:1
+   |
+LL | / #[cfg(blandiloquence)] //~ HELP remove it
+LL | | extern crate edition_lint_paths;
+   | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+   | |________________________________|
+   |                                  help: remove it
+   |
+note: lint level defined here
+  --> $DIR/issue-54400-unused-extern-crate-attr-span.rs:16:9
+   |
+LL | #![deny(rust_2018_idioms)]
+   |         ^^^^^^^^^^^^^^^^
+   = note: #[deny(unused_extern_crates)] implied by #[deny(rust_2018_idioms)]
+
+error: aborting due to previous error
+
index 130d803b3243a92f5c2d9230935cba7fa88e263e..e8f6973e2d40ab39e30cdbe0cf8e77a72c867d4f 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 130d803b3243a92f5c2d9230935cba7fa88e263e
+Subproject commit e8f6973e2d40ab39e30cdbe0cf8e77a72c867d4f