diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index d9c66ce2d7790..c27f4f056d747 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -844,6 +844,11 @@ def bootstrap(help_triggered): def main(): """Entry point for the bootstrap process""" start_time = time() + + # x.py help ... + 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: diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 608f2c982c2a5..7d235743c2c46 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -249,7 +249,7 @@ impl Step for StdLink { 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"); diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index 1cbb8e49bfa15..ec94f57861dbe 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -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) }; diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index d4cca387f0689..f989e701913a5 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -16,10 +16,18 @@ //! //! # 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 = Box::new(val); +//! ``` +//! +//! Move a value from a [`Box`] back to the stack by [dereferencing]: +//! +//! ``` +//! let boxed: Box = 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")] diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 05027bbe89890..d400bd49050a9 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -34,6 +34,7 @@ use cmp::Ordering::{self, Less, Equal, Greater}; use cmp; use fmt; use intrinsics::assume; +use isize; use iter::*; use ops::{FnMut, Try, self}; use option::Option; @@ -4080,6 +4081,9 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> { /// 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 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> { /// ``` /// /// [`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::() == 0, "attempt to create unaligned slice"); + debug_assert!(mem::size_of::().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::() == 0, "attempt to create unaligned slice"); - Repr { raw: FatPtr { data, len} }.rust_mut + debug_assert!(mem::size_of::().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). diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 62b06f54301f3..81d8a803c3958 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -54,6 +54,7 @@ use rustc_data_structures::fx::FxHashSet; 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), /// `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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { }), )) } - 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 @@ impl<'a> LoweringContext<'a> { param_mode, 0, ParenthesizedGenericArgs::Err, - ImplTraitContext::Disallowed, + ImplTraitContext::disallowed(), ) }) .chain(ident.map(|ident| hir::PathSegment::from_ident(ident))) @@ -1872,9 +1892,11 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { 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::>(); @@ -1999,9 +2021,12 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { GenericBound::Trait(_, TraitBoundModifier::Maybe) => None, _ => Some(this.lower_param_bound( bound, - ImplTraitContext::Disallowed, + ImplTraitContext::disallowed(), )), }) .collect(), @@ -2499,7 +2524,7 @@ impl<'a> LoweringContext<'a> { }) => 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { if self.sess.features_untracked().impl_trait_in_bindings { ImplTraitContext::Existential(None) } else { - ImplTraitContext::Disallowed + ImplTraitContext::Disallowed(ImplTraitPosition::Binding) } ), value @@ -2740,12 +2765,12 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { .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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { } } - 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 @@ impl<'a> LoweringContext<'a> { ) } 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { (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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { (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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { &None, path, ParamMode::Optional, - ImplTraitContext::Disallowed, + ImplTraitContext::disallowed(), ); self.check_self_struct_ctor_feature(&qpath); hir::PatKind::TupleStruct( @@ -3503,7 +3529,7 @@ impl<'a> LoweringContext<'a> { qself, path, ParamMode::Optional, - ImplTraitContext::Disallowed, + ImplTraitContext::disallowed(), ); self.check_self_struct_ctor_feature(&qpath); hir::PatKind::Path(qpath) @@ -3514,7 +3540,7 @@ impl<'a> LoweringContext<'a> { &None, path, ParamMode::Optional, - ImplTraitContext::Disallowed, + ImplTraitContext::disallowed(), ); let fs = fields @@ -3608,7 +3634,7 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { 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 @@ impl<'a> LoweringContext<'a> { qself, path, ParamMode::Optional, - ImplTraitContext::Disallowed, + ImplTraitContext::disallowed(), ); self.check_self_struct_ctor_feature(&qpath); hir::ExprKind::Path(qpath) @@ -3965,7 +3991,7 @@ impl<'a> LoweringContext<'a> { &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))), diff --git a/src/librustc/infer/canonical/query_result.rs b/src/librustc/infer/canonical/query_result.rs index 65d42c0888d5d..a327f1f5c9d50 100644 --- a/src/librustc/infer/canonical/query_result.rs +++ b/src/librustc/infer/canonical/query_result.rs @@ -135,10 +135,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { ); // 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 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { } // 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 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { } // ...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 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { .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 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { 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> } @@ -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 } diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs index 26eb2ffbf6aba..854960492c9bd 100644 --- a/src/librustc/infer/equate.rs +++ b/src/librustc/infer/equate.rs @@ -77,24 +77,22 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, '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>) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 09059090e2e35..a68241ff2c020 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -406,10 +406,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { 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) => { diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index 505b1bc032d20..efb316243fad0 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -100,7 +100,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // ``` 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 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { 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())); } } diff --git a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs index 97b1978cb2eb2..1f84c73a71583 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -113,12 +113,12 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { (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 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { 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), ), diff --git a/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs index 5c27cdb6fb553..009a823568131 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs @@ -58,18 +58,17 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { &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 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { // ------------ ... 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 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { // ...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); } } } diff --git a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs index 3393eb65089c0..766173bf66283 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -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 { 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 diff --git a/src/librustc/infer/error_reporting/nice_region_error/util.rs b/src/librustc/infer/error_reporting/nice_region_error/util.rs index a6efb5e678332..013c02f75b883 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/util.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/util.rs @@ -119,16 +119,13 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { decl: &hir::FnDecl, ) -> Option { 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 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> { 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) } } diff --git a/src/librustc/infer/lexical_region_resolve/graphviz.rs b/src/librustc/infer/lexical_region_resolve/graphviz.rs index 3f17c9bb020ef..b55727d2c84f0 100644 --- a/src/librustc/infer/lexical_region_resolve/graphviz.rs +++ b/src/librustc/infer/lexical_region_resolve/graphviz.rs @@ -112,12 +112,9 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>( } }; - match dump_region_data_to(region_rels, ®ion_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, ®ion_data.constraints, &output_path) { + let msg = format!("io error dumping region constraints: {}", e); + tcx.sess.err(&msg) } } @@ -187,12 +184,9 @@ impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> { 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 @@ impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> { 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()), } } } diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 2046f66f99f66..ca49d053210c7 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -147,9 +147,7 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> { 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()) } } diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index e5220aad0562e..49858972416d8 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -803,6 +803,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { ); 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. diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs index 95893a7117892..87bfbaef54c4e 100644 --- a/src/librustc/infer/region_constraints/mod.rs +++ b/src/librustc/infer/region_constraints/mod.rs @@ -443,7 +443,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> { 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 @@ impl<'tcx> RegionConstraintCollector<'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(); diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs index be13fb9a2a5eb..0ef9761857264 100644 --- a/src/librustc/infer/resolve.rs +++ b/src/librustc/infer/resolve.rs @@ -153,8 +153,8 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, '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 { diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index b1e4fc7c7fc7b..970b6e096ffe4 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -273,11 +273,8 @@ impl<'tcx> TypeVariableTable<'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) } } }); diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index 80365a5610212..87d33e473e7f6 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -18,7 +18,7 @@ use lint::context::CheckLintNameResult; 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 @@ impl<'a> LintLevelsBuilder<'a> { "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 { diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 5ca2bfebbeb27..c532b5ee56f47 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1322,8 +1322,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, useful for profiling / PGO."), relro_level: Option = (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], diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 63408d809ec29..64e9d15092eb8 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1467,11 +1467,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// 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 diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 98042e18d32d9..547f7cecc4e06 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -702,7 +702,12 @@ impl<'tcx> Relate<'tcx> for Kind<'tcx> { (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) + } } } } diff --git a/src/librustc_asan/build.rs b/src/librustc_asan/build.rs index b8614c520e7cf..a5905df57c8cf 100644 --- a/src/librustc_asan/build.rs +++ b/src/librustc_asan/build.rs @@ -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"); } diff --git a/src/librustc_data_structures/work_queue.rs b/src/librustc_data_structures/work_queue.rs index af9ed9306ebb2..eff80a98c9de9 100644 --- a/src/librustc_data_structures/work_queue.rs +++ b/src/librustc_data_structures/work_queue.rs @@ -53,7 +53,7 @@ impl WorkQueue { } } - /// 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 { if let Some(element) = self.deque.pop_front() { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 8c4eb90eb261f..15bf837b526b1 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3147,11 +3147,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { // 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 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { _ => 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); diff --git a/src/librustc_tsan/build.rs b/src/librustc_tsan/build.rs index 38595478c7433..d23c71e2c1286 100644 --- a/src/librustc_tsan/build.rs +++ b/src/librustc_tsan/build.rs @@ -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"); } diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index de4ab527e1559..62ffffab07661 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -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) diff --git a/src/test/run-pass/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs b/src/test/run-pass/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs index 3f46b0e312d10..10a4678107e1c 100644 --- a/src/test/run-pass/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs +++ b/src/test/run-pass/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs @@ -12,12 +12,11 @@ // 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(); diff --git a/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr b/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr index 52c99a7b159e3..82bc6194483c0 100644 --- a/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr +++ b/src/test/ui/feature-gates/feature-gate-impl_trait_in_bindings.stderr @@ -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 diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr index b15893e7c28cf..c43271c7371d2 100644 --- a/src/test/ui/impl-trait/where-allowed.stderr +++ b/src/test/ui/impl-trait/where-allowed.stderr @@ -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 diff --git a/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs b/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs index 39d54f6e7ae28..6cbd493b99182 100644 --- a/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs +++ b/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs @@ -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() { diff --git a/src/test/ui/nll/match-guards-partially-borrow.rs b/src/test/ui/nll/match-guards-partially-borrow.rs index 49846f620f0c0..f359800812c87 100644 --- a/src/test/ui/nll/match-guards-partially-borrow.rs +++ b/src/test/ui/nll/match-guards-partially-borrow.rs @@ -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 index 0000000000000..06648c599534f --- /dev/null +++ b/src/test/ui/resolve/issue-22692.rs @@ -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 or the MIT license +// , 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 index 0000000000000..ecdd4ff855fb9 --- /dev/null +++ b/src/test/ui/resolve/issue-22692.stderr @@ -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 index 0000000000000..20ebe6bb54336 --- /dev/null +++ b/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.fixed @@ -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 or the MIT license +// , 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 index 0000000000000..11febe5e87d86 --- /dev/null +++ b/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.rs @@ -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 or the MIT license +// , 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 index 0000000000000..cb945ba1c78d1 --- /dev/null +++ b/src/test/ui/rust-2018/issue-54400-unused-extern-crate-attr-span.stderr @@ -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 + diff --git a/src/tools/miri b/src/tools/miri index 130d803b3243a..e8f6973e2d40a 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 130d803b3243a92f5c2d9230935cba7fa88e263e +Subproject commit e8f6973e2d40ab39e30cdbe0cf8e77a72c867d4f