From 7fb1c22da181426f6ea7662f5c7f47edbbe24f56 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Sat, 16 Mar 2019 17:40:41 +0530 Subject: [PATCH 01/38] promoted is still left in 2 places --- src/librustc/mir/mod.rs | 37 +++--- src/librustc/mir/tcx.rs | 1 - src/librustc/mir/visit.rs | 15 ++- .../borrow_check/error_reporting.rs | 17 +-- src/librustc_mir/borrow_check/mod.rs | 56 +++++---- .../borrow_check/mutability_errors.rs | 23 ++-- .../borrow_check/nll/type_check/mod.rs | 92 +++++++------- src/librustc_mir/borrow_check/path_utils.rs | 1 - src/librustc_mir/borrow_check/place_ext.rs | 10 +- .../borrow_check/places_conflict.rs | 67 +++++----- src/librustc_mir/borrow_check/prefixes.rs | 2 - src/librustc_mir/build/expr/as_place.rs | 1 + .../dataflow/impls/borrowed_locals.rs | 1 - .../dataflow/move_paths/builder.rs | 1 - src/librustc_mir/dataflow/move_paths/mod.rs | 1 - src/librustc_mir/interpret/place.rs | 59 ++++----- src/librustc_mir/transform/add_retag.rs | 1 - src/librustc_mir/transform/check_unsafety.rs | 50 ++++---- src/librustc_mir/transform/const_prop.rs | 42 ++++--- src/librustc_mir/transform/inline.rs | 12 +- src/librustc_mir/transform/qualify_consts.rs | 119 ++++++++++-------- .../transform/qualify_min_const_fn.rs | 11 +- 22 files changed, 336 insertions(+), 283 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 9f2027e7d0563..47b9535abc521 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1913,9 +1913,6 @@ pub enum PlaceBase<'tcx> { /// static or static mut variable Static(Box>), - - /// Constant code promoted to an injected static - Promoted(Box<(Promoted, Ty<'tcx>)>), } /// The `DefId` of a static, along with its normalized type (which is @@ -1924,11 +1921,13 @@ pub enum PlaceBase<'tcx> { pub struct Static<'tcx> { pub def_id: DefId, pub ty: Ty<'tcx>, + pub promoted: Option, } impl_stable_hash_for!(struct Static<'tcx> { def_id, - ty + ty, + promoted }); /// The `Projection` data structure defines things of the form `B.x` @@ -2048,7 +2047,7 @@ impl<'tcx> Place<'tcx> { match self { Place::Base(PlaceBase::Local(local)) => Some(*local), Place::Projection(box Projection { base, elem: _ }) => base.base_local(), - Place::Base(PlaceBase::Promoted(..)) | Place::Base(PlaceBase::Static(..)) => None, + Place::Base(PlaceBase::Static(..)) => None, } } } @@ -2059,18 +2058,22 @@ impl<'tcx> Debug for Place<'tcx> { match *self { Base(PlaceBase::Local(id)) => write!(fmt, "{:?}", id), - Base(PlaceBase::Static(box self::Static { def_id, ty })) => write!( - fmt, - "({}: {:?})", - ty::tls::with(|tcx| tcx.def_path_str(def_id)), - ty - ), - Base(PlaceBase::Promoted(ref promoted)) => write!( - fmt, - "({:?}: {:?})", - promoted.0, - promoted.1 - ), + Base(PlaceBase::Static(box self::Static { def_id, ty, promoted })) => { + match promoted { + None => write!( + fmt, + "({}: {:?})", + ty::tls::with(|tcx| tcx.def_path_str(def_id)), + ty + ), + Some(pr) => write!( + fmt, + "({:?}: {:?})", + pr, + ty + ), + } + }, Projection(ref data) => match data.elem { ProjectionElem::Downcast(ref adt_def, index) => { write!(fmt, "({:?} as {})", data.base, adt_def.variants[index].ident) diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index a6f153eaf6461..ac42eacacd7bf 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -160,7 +160,6 @@ impl<'tcx> Place<'tcx> { match *self { Place::Base(PlaceBase::Local(index)) => PlaceTy::Ty { ty: local_decls.local_decls()[index].ty }, - Place::Base(PlaceBase::Promoted(ref data)) => PlaceTy::Ty { ty: data.1 }, Place::Base(PlaceBase::Static(ref data)) => PlaceTy::Ty { ty: data.ty }, Place::Projection(ref proj) => diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 8bc0075c47719..cddf578212159 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -737,11 +737,18 @@ macro_rules! make_mir_visitor { self.visit_local(local, context, location); } Place::Base(PlaceBase::Static(static_)) => { + match static_.promoted { + None => { + self.visit_static(static_, context, location); + } + Some(_) => { + self.visit_ty( + & $($mutability)? static_.ty, TyContext::Location(location) + ); + } + } self.visit_static(static_, context, location); } - Place::Base(PlaceBase::Promoted(promoted)) => { - self.visit_ty(& $($mutability)? promoted.1, TyContext::Location(location)); - }, Place::Projection(proj) => { self.visit_projection(proj, context, location); } @@ -752,7 +759,7 @@ macro_rules! make_mir_visitor { static_: & $($mutability)? Static<'tcx>, _context: PlaceContext<'tcx>, location: Location) { - let Static { def_id, ty } = static_; + let Static { def_id, ty, promoted: _ } = static_; self.visit_def_id(def_id, location); self.visit_ty(ty, TyContext::Location(location)); } diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 14289381aef45..8f83c025ceb40 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -1598,14 +1598,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { including_downcast: &IncludingDowncast, ) -> Result<(), ()> { match *place { - Place::Base(PlaceBase::Promoted(_)) => { - buf.push_str("promoted"); - } Place::Base(PlaceBase::Local(local)) => { self.append_local_to_string(local, buf)?; } Place::Base(PlaceBase::Static(ref static_)) => { - buf.push_str(&self.infcx.tcx.item_name(static_.def_id).to_string()); + match static_.promoted { + Some(_) => { + buf.push_str("promoted"); + } + None => { + buf.push_str(&self.infcx.tcx.item_name(static_.def_id).to_string()); + } + } } Place::Projection(ref proj) => { match proj.elem { @@ -1744,8 +1748,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let local = &self.mir.local_decls[local]; self.describe_field_from_ty(&local.ty, field) } - Place::Base(PlaceBase::Promoted(ref prom)) => - self.describe_field_from_ty(&prom.1, field), Place::Base(PlaceBase::Static(ref static_)) => self.describe_field_from_ty(&static_.ty, field), Place::Projection(ref proj) => match proj.elem { @@ -1828,8 +1830,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let tcx = self.infcx.tcx; match place { Place::Base(PlaceBase::Local(_)) | - Place::Base(PlaceBase::Static(_)) | - Place::Base(PlaceBase::Promoted(_)) => { + Place::Base(PlaceBase::Static(_)) => { StorageDeadOrDrop::LocalStorageDead } Place::Projection(box PlaceProjection { base, elem }) => { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index c4e371d5afedb..5726eba9bdaf6 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1226,8 +1226,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } Operand::Move(Place::Base(PlaceBase::Static(..))) | Operand::Copy(Place::Base(PlaceBase::Static(..))) - | Operand::Move(Place::Base(PlaceBase::Promoted(..))) - | Operand::Copy(Place::Base(PlaceBase::Promoted(..))) | Operand::Constant(..) => {} } } @@ -1310,12 +1308,16 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // // FIXME: allow thread-locals to borrow other thread locals? let (might_be_alive, will_be_dropped) = match root_place { - Place::Base(PlaceBase::Promoted(_)) => (true, false), - Place::Base(PlaceBase::Static(_)) => { - // Thread-locals might be dropped after the function exits, but - // "true" statics will never be. - let is_thread_local = self.is_place_thread_local(&root_place); - (true, is_thread_local) + Place::Base(PlaceBase::Static(st)) => { + match st.promoted { + None => { + // Thread-locals might be dropped after the function exits, but + // "true" statics will never be. + let is_thread_local = self.is_place_thread_local(&root_place); + (true, is_thread_local) + } + Some(_) => (true, false), + } } Place::Base(PlaceBase::Local(_)) => { // Locals are always dropped at function exit, and if they @@ -1578,7 +1580,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { match *last_prefix { Place::Base(PlaceBase::Local(_)) => panic!("should have move path for every Local"), Place::Projection(_) => panic!("PrefixSet::All meant don't stop for Projection"), - Place::Base(PlaceBase::Promoted(_)) | Place::Base(PlaceBase::Static(_)) => Err(NoMovePathFound::ReachedStatic), } } @@ -1605,7 +1606,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let mut place = place; loop { match *place { - Place::Base(PlaceBase::Promoted(_)) | Place::Base(PlaceBase::Local(_)) | Place::Base(PlaceBase::Static(_)) => { // assigning to `x` does not require `x` be initialized. break; @@ -1953,10 +1953,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { self.used_mut_upvars.push(field); } } - RootPlace { - place: Place::Base(PlaceBase::Promoted(..)), - is_local_mutation_allowed: _, - } => {} RootPlace { place: Place::Base(PlaceBase::Static(..)), is_local_mutation_allowed: _, @@ -1994,18 +1990,28 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } // The rules for promotion are made by `qualify_consts`, there wouldn't even be a // `Place::Promoted` if the promotion weren't 100% legal. So we just forward this - Place::Base(PlaceBase::Promoted(_)) => Ok(RootPlace { - place, - is_local_mutation_allowed, - }), +// Place::Base(PlaceBase::Promoted(_)) => Ok(RootPlace { +// place, +// is_local_mutation_allowed, +// }), Place::Base(PlaceBase::Static(ref static_)) => { - if self.infcx.tcx.is_static(static_.def_id) != Some(hir::Mutability::MutMutable) { - Err(place) - } else { - Ok(RootPlace { - place, - is_local_mutation_allowed, - }) + match static_.promoted { + Some(_) => { + Ok(RootPlace { + place, + is_local_mutation_allowed, + }) + } + None => { + if self.infcx.tcx.is_static(static_.def_id) != Some(hir::Mutability::MutMutable) { + Err(place) + } else { + Ok(RootPlace { + place, + is_local_mutation_allowed, + }) + } + } } } Place::Projection(ref proj) => { diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index b8dae98ec64f2..d8c39e0715ad1 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -129,16 +129,19 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { } } - Place::Base(PlaceBase::Promoted(_)) => unreachable!(), - - Place::Base(PlaceBase::Static(box Static { def_id, ty: _ })) => { - if let Place::Base(PlaceBase::Static(_)) = access_place { - item_msg = format!("immutable static item `{}`", access_place_desc.unwrap()); - reason = String::new(); - } else { - item_msg = format!("`{}`", access_place_desc.unwrap()); - let static_name = &self.infcx.tcx.item_name(*def_id); - reason = format!(", as `{}` is an immutable static item", static_name); + Place::Base(PlaceBase::Static(box Static { def_id, ty: _, promoted })) => { + match promoted { + Some(_) => unreachable!(), + None => { + if let Place::Base(PlaceBase::Static(_)) = access_place { + item_msg = format!("immutable static item `{}`", access_place_desc.unwrap()); + reason = String::new(); + } else { + item_msg = format!("`{}`", access_place_desc.unwrap()); + let static_name = &self.infcx.tcx.item_name(*def_id); + reason = format!(", as `{}` is an immutable static item", static_name); + } + } } } diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 25a3160a498d3..334c20761e7bb 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -453,51 +453,55 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { Place::Base(PlaceBase::Local(index)) => PlaceTy::Ty { ty: self.mir.local_decls[index].ty, }, - Place::Base(PlaceBase::Promoted(box (index, sty))) => { - let sty = self.sanitize_type(place, sty); - - if !self.errors_reported { - let promoted_mir = &self.mir.promoted[index]; - self.sanitize_promoted(promoted_mir, location); - - let promoted_ty = promoted_mir.return_ty(); - - if let Err(terr) = self.cx.eq_types( - sty, - promoted_ty, - location.to_locations(), - ConstraintCategory::Boring, - ) { - span_mirbug!( - self, - place, - "bad promoted type ({:?}: {:?}): {:?}", - promoted_ty, - sty, - terr - ); - }; - } - PlaceTy::Ty { ty: sty } - } - Place::Base(PlaceBase::Static(box Static { def_id, ty: sty })) => { - let sty = self.sanitize_type(place, sty); - let ty = self.tcx().type_of(def_id); - let ty = self.cx.normalize(ty, location); - if let Err(terr) = - self.cx - .eq_types(ty, sty, location.to_locations(), ConstraintCategory::Boring) - { - span_mirbug!( - self, - place, - "bad static type ({:?}: {:?}): {:?}", - ty, - sty, - terr - ); + Place::Base(PlaceBase::Static(box Static { def_id, ty: sty, promoted })) => { + match promoted { + Some(pr) => { + let sty = self.sanitize_type(place, sty); + + if !self.errors_reported { + let promoted_mir = &self.mir.promoted[pr]; + self.sanitize_promoted(promoted_mir, location); + + let promoted_ty = promoted_mir.return_ty(); + + if let Err(terr) = self.cx.eq_types( + sty, + promoted_ty, + location.to_locations(), + ConstraintCategory::Boring, + ) { + span_mirbug!( + self, + place, + "bad promoted type ({:?}: {:?}): {:?}", + promoted_ty, + sty, + terr + ); + }; + } + PlaceTy::Ty { ty: sty } + } + None => { + let sty = self.sanitize_type(place, sty); + let ty = self.tcx().type_of(def_id); + let ty = self.cx.normalize(ty, location); + if let Err(terr) = + self.cx + .eq_types(ty, sty, location.to_locations(), ConstraintCategory::Boring) + { + span_mirbug!( + self, + place, + "bad static type ({:?}: {:?}): {:?}", + ty, + sty, + terr + ); + } + PlaceTy::Ty { ty: sty } + } } - PlaceTy::Ty { ty: sty } } Place::Projection(ref proj) => { let base_context = if context.is_mutating_use() { diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs index 9e0bb93c33a5d..42eb502b9076d 100644 --- a/src/librustc_mir/borrow_check/path_utils.rs +++ b/src/librustc_mir/borrow_check/path_utils.rs @@ -138,7 +138,6 @@ pub(super) fn is_active<'tcx>( /// This is called for all Yield statements on movable generators pub(super) fn borrow_of_local_data<'tcx>(place: &Place<'tcx>) -> bool { match place { - Place::Base(PlaceBase::Promoted(_)) | Place::Base(PlaceBase::Static(..)) => false, Place::Base(PlaceBase::Local(..)) => true, Place::Projection(box proj) => { diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs index c05ee3cf65b36..0bbd147d8243b 100644 --- a/src/librustc_mir/borrow_check/place_ext.rs +++ b/src/librustc_mir/borrow_check/place_ext.rs @@ -30,8 +30,6 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> { locals_state_at_exit: &LocalsStateAtExit, ) -> bool { match self { - Place::Base(PlaceBase::Promoted(_)) => false, - // If a local variable is immutable, then we only need to track borrows to guard // against two kinds of errors: // * The variable being dropped while still borrowed (e.g., because the fn returns @@ -52,7 +50,12 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> { } } Place::Base(PlaceBase::Static(static_)) => { - tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable) + match static_.promoted { + Some(_) => false, + None => { + tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable) + } + } } Place::Projection(proj) => match proj.elem { ProjectionElem::Field(..) @@ -88,7 +91,6 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> { loop { match p { Place::Projection(pi) => p = &pi.base, - Place::Base(PlaceBase::Promoted(_)) | Place::Base(PlaceBase::Static(_)) => return None, Place::Base(PlaceBase::Local(l)) => return Some(*l), } diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index 1d18ada1fb69c..7babdfcdd68ad 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -338,7 +338,6 @@ fn unroll_place<'tcx, R>( op, ), - Place::Base(PlaceBase::Promoted(_)) | Place::Base(PlaceBase::Local(_)) | Place::Base(PlaceBase::Static(_)) => { let list = PlaceComponents { component: place, @@ -371,41 +370,45 @@ fn place_element_conflict<'a, 'gcx: 'tcx, 'tcx>( Overlap::Disjoint } } - (Place::Base(PlaceBase::Static(static1)), Place::Base(PlaceBase::Static(static2))) => { - if static1.def_id != static2.def_id { - debug!("place_element_conflict: DISJOINT-STATIC"); - Overlap::Disjoint - } else if tcx.is_static(static1.def_id) == Some(hir::Mutability::MutMutable) { - // We ignore mutable statics - they can only be unsafe code. - debug!("place_element_conflict: IGNORE-STATIC-MUT"); - Overlap::Disjoint - } else { - debug!("place_element_conflict: DISJOINT-OR-EQ-STATIC"); - Overlap::EqualOrDisjoint - } - } - (Place::Base(PlaceBase::Promoted(p1)), Place::Base(PlaceBase::Promoted(p2))) => { - if p1.0 == p2.0 { - if let ty::Array(_, size) = p1.1.sty { - if size.unwrap_usize(tcx) == 0 { - // Ignore conflicts with promoted [T; 0]. - debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED"); - return Overlap::Disjoint; + (Place::Base(PlaceBase::Static(s1)), Place::Base(PlaceBase::Static(s2))) => { + match (s1.promoted, s2.promoted) { + (None, None) => { + if s1.def_id != s2.def_id { + debug!("place_element_conflict: DISJOINT-STATIC"); + Overlap::Disjoint + } else if tcx.is_static(s1.def_id) == Some(hir::Mutability::MutMutable) { + // We ignore mutable statics - they can only be unsafe code. + debug!("place_element_conflict: IGNORE-STATIC-MUT"); + Overlap::Disjoint + } else { + debug!("place_element_conflict: DISJOINT-OR-EQ-STATIC"); + Overlap::EqualOrDisjoint } + }, + (Some(p1), Some(p2)) => { + if p1 == p2 { + if let ty::Array(_, size) =s1.ty.sty { + if size.unwrap_usize(tcx) == 0 { + // Ignore conflicts with promoted [T; 0]. + debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED"); + return Overlap::Disjoint; + } + } + // the same promoted - base case, equal + debug!("place_element_conflict: DISJOINT-OR-EQ-PROMOTED"); + Overlap::EqualOrDisjoint + } else { + // different promoteds - base case, disjoint + debug!("place_element_conflict: DISJOINT-PROMOTED"); + Overlap::Disjoint + } + }, + (p1_, p2_) => { + debug!("place_element_conflict: DISJOINT-STATIC-LOCAL-PROMOTED"); + Overlap::Disjoint } - // the same promoted - base case, equal - debug!("place_element_conflict: DISJOINT-OR-EQ-PROMOTED"); - Overlap::EqualOrDisjoint - } else { - // different promoteds - base case, disjoint - debug!("place_element_conflict: DISJOINT-PROMOTED"); - Overlap::Disjoint } } - (Place::Base(PlaceBase::Local(_)), Place::Base(PlaceBase::Promoted(_))) | - (Place::Base(PlaceBase::Promoted(_)), Place::Base(PlaceBase::Local(_))) | - (Place::Base(PlaceBase::Promoted(_)), Place::Base(PlaceBase::Static(_))) | - (Place::Base(PlaceBase::Static(_)), Place::Base(PlaceBase::Promoted(_))) | (Place::Base(PlaceBase::Local(_)), Place::Base(PlaceBase::Static(_))) | (Place::Base(PlaceBase::Static(_)), Place::Base(PlaceBase::Local(_))) => { debug!("place_element_conflict: DISJOINT-STATIC-LOCAL-PROMOTED"); diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs index 384fd5c9987b8..e70c9e81ebd16 100644 --- a/src/librustc_mir/borrow_check/prefixes.rs +++ b/src/librustc_mir/borrow_check/prefixes.rs @@ -26,7 +26,6 @@ impl<'tcx> IsPrefixOf<'tcx> for Place<'tcx> { } match *cursor { - Place::Base(PlaceBase::Promoted(_)) | Place::Base(PlaceBase::Local(_)) | Place::Base(PlaceBase::Static(_)) => return false, Place::Projection(ref proj) => { @@ -87,7 +86,6 @@ impl<'cx, 'gcx, 'tcx> Iterator for Prefixes<'cx, 'gcx, 'tcx> { 'cursor: loop { let proj = match *cursor { - Place::Base(PlaceBase::Promoted(_)) | Place::Base(PlaceBase::Local(_)) | // search yielded this leaf Place::Base(PlaceBase::Static(_)) => { self.next = None; diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 20b95c363f5f7..83e1d3ebb3e06 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -128,6 +128,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ExprKind::StaticRef { id } => block.and(Place::Base(PlaceBase::Static(Box::new(Static { def_id: id, ty: expr.ty, + promoted: None, })))), ExprKind::PlaceTypeAscription { source, user_ty } => { diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs index b9c8879b3c364..9d4600d13ac13 100644 --- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs +++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs @@ -93,7 +93,6 @@ struct BorrowedLocalsVisitor<'b, 'c: 'b> { fn find_local<'tcx>(place: &Place<'tcx>) -> Option { match *place { Place::Base(PlaceBase::Local(l)) => Some(l), - Place::Base(PlaceBase::Promoted(_)) | Place::Base(PlaceBase::Static(..)) => None, Place::Projection(ref proj) => { match proj.elem { diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index 7a9140bce6288..71805fd02b857 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -97,7 +97,6 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> { debug!("lookup({:?})", place); match *place { Place::Base(PlaceBase::Local(local)) => Ok(self.builder.data.rev_lookup.locals[local]), - Place::Base(PlaceBase::Promoted(..)) | Place::Base(PlaceBase::Static(..)) => { Err(MoveError::cannot_move_out_of(self.loc, Static)) } diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index 97f84675f94bf..7eef68e5f8073 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -286,7 +286,6 @@ impl<'tcx> MovePathLookup<'tcx> { pub fn find(&self, place: &Place<'tcx>) -> LookupResult { match *place { Place::Base(PlaceBase::Local(local)) => LookupResult::Exact(self.locals[local]), - Place::Base(PlaceBase::Promoted(_)) | Place::Base(PlaceBase::Static(..)) => LookupResult::Parent(None), Place::Projection(ref proj) => { match self.find(&proj.base) { diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 755bbd96b02f9..62e2cdffadf34 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -583,35 +583,38 @@ where use rustc::mir::Place::*; use rustc::mir::PlaceBase; Ok(match *mir_place { - Base(PlaceBase::Promoted(ref promoted)) => { - let instance = self.frame().instance; - self.const_eval_raw(GlobalId { - instance, - promoted: Some(promoted.0), - })? - } - Base(PlaceBase::Static(ref static_)) => { - assert!(!static_.ty.needs_subst()); - let layout = self.layout_of(static_.ty)?; - let instance = ty::Instance::mono(*self.tcx, static_.def_id); - let cid = GlobalId { - instance, - promoted: None - }; - // Just create a lazy reference, so we can support recursive statics. - // tcx takes are of assigning every static one and only one unique AllocId. - // When the data here is ever actually used, memory will notice, - // and it knows how to deal with alloc_id that are present in the - // global table but not in its local memory: It calls back into tcx through - // a query, triggering the CTFE machinery to actually turn this lazy reference - // into a bunch of bytes. IOW, statics are evaluated with CTFE even when - // this EvalContext uses another Machine (e.g., in miri). This is what we - // want! This way, computing statics works concistently between codegen - // and miri: They use the same query to eventually obtain a `ty::Const` - // and use that for further computation. - let alloc = self.tcx.alloc_map.lock().intern_static(cid.instance.def_id()); - MPlaceTy::from_aligned_ptr(Pointer::from(alloc).with_default_tag(), layout) + match static_.promoted { + Some(promoted) => { + let instance = self.frame().instance; + self.const_eval_raw(GlobalId { + instance, + promoted: Some(promoted), + })? + } + None => { + assert!(!static_.ty.needs_subst()); + let layout = self.layout_of(static_.ty)?; + let instance = ty::Instance::mono(*self.tcx, static_.def_id); + let cid = GlobalId { + instance, + promoted: None + }; + // Just create a lazy reference, so we can support recursive statics. + // tcx takes are of assigning every static one and only one unique AllocId. + // When the data here is ever actually used, memory will notice, + // and it knows how to deal with alloc_id that are present in the + // global table but not in its local memory: It calls back into tcx through + // a query, triggering the CTFE machinery to actually turn this lazy reference + // into a bunch of bytes. IOW, statics are evaluated with CTFE even when + // this EvalContext uses another Machine (e.g., in miri). This is what we + // want! This way, computing statics works concistently between codegen + // and miri: They use the same query to eventually obtain a `ty::Const` + // and use that for further computation. + let alloc = self.tcx.alloc_map.lock().intern_static(cid.instance.def_id()); + MPlaceTy::from_aligned_ptr(Pointer::from(alloc).with_default_tag(), layout) + } + } } _ => bug!("eval_place_to_mplace called on {:?}", mir_place), diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs index 20b75c5586794..b13a5fd2fd1c0 100644 --- a/src/librustc_mir/transform/add_retag.rs +++ b/src/librustc_mir/transform/add_retag.rs @@ -22,7 +22,6 @@ fn is_stable<'tcx>( match *place { // Locals and statics have stable addresses, for sure Base(PlaceBase::Local { .. }) | - Base(PlaceBase::Promoted { .. }) | Base(PlaceBase::Static { .. }) => true, // Recurse for projections diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index b494592c89f43..01cb58a481a31 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -300,29 +300,33 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { &Place::Base(PlaceBase::Local(..)) => { // locals are safe } - &Place::Base(PlaceBase::Promoted(_)) => { - bug!("unsafety checking should happen before promotion") - } - &Place::Base(PlaceBase::Static(box Static { def_id, ty: _ })) => { - if self.tcx.is_static(def_id) == Some(hir::Mutability::MutMutable) { - self.require_unsafe("use of mutable static", - "mutable statics can be mutated by multiple threads: aliasing violations \ - or data races will cause undefined behavior", - UnsafetyViolationKind::General); - } else if self.tcx.is_foreign_item(def_id) { - let source_info = self.source_info; - let lint_root = - self.source_scope_local_data[source_info.scope].lint_root; - self.register_violations(&[UnsafetyViolation { - source_info, - description: Symbol::intern("use of extern static").as_interned_str(), - details: - Symbol::intern("extern statics are not controlled by the Rust type \ - system: invalid data, aliasing violations or data \ - races will cause undefined behavior") - .as_interned_str(), - kind: UnsafetyViolationKind::ExternStatic(lint_root) - }], &[]); + &Place::Base(PlaceBase::Static(box Static { def_id, ty: _, promoted })) => { + match promoted { + Some(..) => { + bug!("unsafety checking should happen before promotion") + } + None => { + if self.tcx.is_static(def_id) == Some(hir::Mutability::MutMutable) { + self.require_unsafe("use of mutable static", + "mutable statics can be mutated by multiple threads: aliasing violations \ + or data races will cause undefined behavior", + UnsafetyViolationKind::General); + } else if self.tcx.is_foreign_item(def_id) { + let source_info = self.source_info; + let lint_root = + self.source_scope_local_data[source_info.scope].lint_root; + self.register_violations(&[UnsafetyViolation { + source_info, + description: Symbol::intern("use of extern static").as_interned_str(), + details: + Symbol::intern("extern statics are not controlled by the Rust type \ + system: invalid data, aliasing violations or data \ + races will cause undefined behavior") + .as_interned_str(), + kind: UnsafetyViolationKind::ExternStatic(lint_root) + }], &[]); + } + } } } }; diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index d816968442058..bbe62fa2d7b37 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -282,25 +282,31 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { // an `Index` projection would throw us off-track. _ => None, }, - Place::Base(PlaceBase::Promoted(ref promoted)) => { - let generics = self.tcx.generics_of(self.source.def_id()); - if generics.requires_monomorphization(self.tcx) { - // FIXME: can't handle code with generics - return None; + Place::Base(PlaceBase::Static(ref static_)) => { + match static_.promoted { + Some(promoted) => { + let generics = self.tcx.generics_of(self.source.def_id()); + if generics.requires_monomorphization(self.tcx) { + // FIXME: can't handle code with generics + return None; + } + let substs = InternalSubsts::identity_for_item(self.tcx, self.source.def_id()); + let instance = Instance::new(self.source.def_id(), substs); + let cid = GlobalId { + instance, + promoted: Some(promoted), + }; + // cannot use `const_eval` here, because that would require having the MIR + // for the current function available, but we're producing said MIR right now + let res = self.use_ecx(source_info, |this| { + eval_promoted(this.tcx, cid, this.mir, this.param_env) + })?; + trace!("evaluated promoted {:?} to {:?}", promoted, res); + Some((res.into(), source_info.span)) + } + None => None } - let substs = InternalSubsts::identity_for_item(self.tcx, self.source.def_id()); - let instance = Instance::new(self.source.def_id(), substs); - let cid = GlobalId { - instance, - promoted: Some(promoted.0), - }; - // cannot use `const_eval` here, because that would require having the MIR - // for the current function available, but we're producing said MIR right now - let res = self.use_ecx(source_info, |this| { - eval_promoted(this.tcx, cid, this.mir, this.param_env) - })?; - trace!("evaluated promoted {:?} to {:?}", promoted, res); - Some((res.into(), source_info.span)) + }, _ => None, } diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 234483df13ada..0b2a34d5fb975 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -692,12 +692,16 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { // Return pointer; update the place itself *place = self.destination.clone(); }, - Place::Base(PlaceBase::Promoted(ref mut promoted)) => { - if let Some(p) = self.promoted_map.get(promoted.0).cloned() { - promoted.0 = p; + Place::Base(PlaceBase::Static(ref mut static_)) => { + match static_.promoted { + Some(promoted) => { + if let Some(p) = self.promoted_map.get(promoted).cloned() { + static_.promoted = Some(p); + } + } + None => self.super_place(place, _ctxt, _location) } }, - _ => self.super_place(place, _ctxt, _location), } } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index e96689809add7..f0ba1306c99fc 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -188,8 +188,12 @@ trait Qualif { fn in_place(cx: &ConstCx<'_, 'tcx>, place: &Place<'tcx>) -> bool { match *place { Place::Base(PlaceBase::Local(local)) => Self::in_local(cx, local), - Place::Base(PlaceBase::Promoted(_)) => bug!("qualifying already promoted MIR"), - Place::Base(PlaceBase::Static(ref static_)) => Self::in_static(cx, static_), + Place::Base(PlaceBase::Static(ref static_)) => { + match static_.promoted { + Some(..) => bug!("qualifying already promoted MIR"), + None => Self::in_static(cx, static_), + } + }, Place::Projection(ref proj) => Self::in_projection(cx, proj), } } @@ -768,17 +772,20 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { ); dest = &proj.base; }, - Place::Base(PlaceBase::Promoted(..)) => - bug!("promoteds don't exist yet during promotion"), - Place::Base(PlaceBase::Static(..)) => { - // Catch more errors in the destination. `visit_place` also checks that we - // do not try to access statics from constants or try to mutate statics - self.visit_place( - dest, - PlaceContext::MutatingUse(MutatingUseContext::Store), - location - ); - return; + Place::Base(PlaceBase::Static(st)) => { + match st.promoted { + Some(..) => bug!("promoteds don't exist yet during promotion"), + None => { + // Catch more errors in the destination. `visit_place` also checks that we + // do not try to access statics from constants or try to mutate statics + self.visit_place( + dest, + PlaceContext::MutatingUse(MutatingUseContext::Store), + location + ); + return; + } + } } } }; @@ -919,51 +926,55 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { debug!("visit_place: place={:?} context={:?} location={:?}", place, context, location); self.super_place(place, context, location); match *place { - Place::Base(PlaceBase::Local(_)) | - Place::Base(PlaceBase::Promoted(_)) => {} + Place::Base(PlaceBase::Local(_)) => {} Place::Base(PlaceBase::Static(ref global)) => { - if self.tcx - .get_attrs(global.def_id) - .iter() - .any(|attr| attr.check_name("thread_local")) { - if self.mode != Mode::Fn { - span_err!(self.tcx.sess, self.span, E0625, - "thread-local statics cannot be \ - accessed at compile-time"); - } - return; - } + match global.promoted { + Some(..) => {} + None => { + if self.tcx + .get_attrs(global.def_id) + .iter() + .any(|attr| attr.check_name("thread_local")) { + if self.mode != Mode::Fn { + span_err!(self.tcx.sess, self.span, E0625, + "thread-local statics cannot be \ + accessed at compile-time"); + } + return; + } - // Only allow statics (not consts) to refer to other statics. - if self.mode == Mode::Static || self.mode == Mode::StaticMut { - if self.mode == Mode::Static && context.is_mutating_use() { - // this is not strictly necessary as miri will also bail out - // For interior mutability we can't really catch this statically as that - // goes through raw pointers and intermediate temporaries, so miri has - // to catch this anyway - self.tcx.sess.span_err( - self.span, - "cannot mutate statics in the initializer of another static", - ); - } - return; - } - unleash_miri!(self); + // Only allow statics (not consts) to refer to other statics. + if self.mode == Mode::Static || self.mode == Mode::StaticMut { + if self.mode == Mode::Static && context.is_mutating_use() { + // this is not strictly necessary as miri will also bail out + // For interior mutability we can't really catch this statically as that + // goes through raw pointers and intermediate temporaries, so miri has + // to catch this anyway + self.tcx.sess.span_err( + self.span, + "cannot mutate statics in the initializer of another static", + ); + } + return; + } + unleash_miri!(self); - if self.mode != Mode::Fn { - let mut err = struct_span_err!(self.tcx.sess, self.span, E0013, - "{}s cannot refer to statics, use \ - a constant instead", self.mode); - if self.tcx.sess.teach(&err.get_code().unwrap()) { - err.note( - "Static and const variables can refer to other const variables. But a \ - const variable cannot refer to a static variable." - ); - err.help( - "To fix this, the value can be extracted as a const and then used." - ); + if self.mode != Mode::Fn { + let mut err = struct_span_err!(self.tcx.sess, self.span, E0013, + "{}s cannot refer to statics, use \ + a constant instead", self.mode); + if self.tcx.sess.teach(&err.get_code().unwrap()) { + err.note( + "Static and const variables can refer to other const variables. But a \ + const variable cannot refer to a static variable." + ); + err.help( + "To fix this, the value can be extracted as a const and then used." + ); + } + err.emit() + } } - err.emit() } } Place::Projection(ref proj) => { diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index f82e536ab2549..ea5bbaeb4008e 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -256,10 +256,13 @@ fn check_place( ) -> McfResult { match place { Place::Base(PlaceBase::Local(_)) => Ok(()), - // promoteds are always fine, they are essentially constants - Place::Base(PlaceBase::Promoted(_)) => Ok(()), - Place::Base(PlaceBase::Static(_)) => - Err((span, "cannot access `static` items in const fn".into())), + Place::Base(PlaceBase::Static(st)) => { + match st.promoted { + // promoteds are always fine, they are essentially constants + Some(..) => Ok(()), + None => Err((span, "cannot access `static` items in const fn".into())), + } + } Place::Projection(proj) => { match proj.elem { | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } From a837b8a3688d746bc392a65524fe7d06fdb61263 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Sun, 17 Mar 2019 11:12:39 +0530 Subject: [PATCH 02/38] cleaner code as per review --- src/librustc/mir/visit.rs | 10 -- .../borrow_check/error_reporting.rs | 11 +- src/librustc_mir/borrow_check/mod.rs | 35 ++---- .../borrow_check/mutability_errors.rs | 20 ++-- .../borrow_check/nll/type_check/mod.rs | 16 +-- src/librustc_mir/borrow_check/place_ext.rs | 9 +- .../borrow_check/places_conflict.rs | 4 +- src/librustc_mir/interpret/place.rs | 62 +++++----- src/librustc_mir/transform/check_unsafety.rs | 47 ++++---- src/librustc_mir/transform/const_prop.rs | 43 +++---- src/librustc_mir/transform/qualify_consts.rs | 112 ++++++++---------- 11 files changed, 158 insertions(+), 211 deletions(-) diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index cddf578212159..6761c70550ec8 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -737,16 +737,6 @@ macro_rules! make_mir_visitor { self.visit_local(local, context, location); } Place::Base(PlaceBase::Static(static_)) => { - match static_.promoted { - None => { - self.visit_static(static_, context, location); - } - Some(_) => { - self.visit_ty( - & $($mutability)? static_.ty, TyContext::Location(location) - ); - } - } self.visit_static(static_, context, location); } Place::Projection(proj) => { diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 8f83c025ceb40..b9877945e7eac 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -1602,13 +1602,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { self.append_local_to_string(local, buf)?; } Place::Base(PlaceBase::Static(ref static_)) => { - match static_.promoted { - Some(_) => { - buf.push_str("promoted"); - } - None => { - buf.push_str(&self.infcx.tcx.item_name(static_.def_id).to_string()); - } + if static_.promoted.is_some() { + buf.push_str("promoted"); + } else { + buf.push_str(&self.infcx.tcx.item_name(static_.def_id).to_string()); } } Place::Projection(ref proj) => { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 5726eba9bdaf6..e92ed1f2c7caa 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1309,15 +1309,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // FIXME: allow thread-locals to borrow other thread locals? let (might_be_alive, will_be_dropped) = match root_place { Place::Base(PlaceBase::Static(st)) => { - match st.promoted { - None => { - // Thread-locals might be dropped after the function exits, but - // "true" statics will never be. - let is_thread_local = self.is_place_thread_local(&root_place); - (true, is_thread_local) - } - Some(_) => (true, false), - } + (true, st.promoted.is_none() && self.is_place_thread_local(&root_place)) } Place::Base(PlaceBase::Local(_)) => { // Locals are always dropped at function exit, and if they @@ -1990,28 +1982,21 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } // The rules for promotion are made by `qualify_consts`, there wouldn't even be a // `Place::Promoted` if the promotion weren't 100% legal. So we just forward this -// Place::Base(PlaceBase::Promoted(_)) => Ok(RootPlace { -// place, -// is_local_mutation_allowed, -// }), Place::Base(PlaceBase::Static(ref static_)) => { - match static_.promoted { - Some(_) => { + if static_.promoted.is_some() { + Ok(RootPlace { + place, + is_local_mutation_allowed, + }) + } else { + if self.infcx.tcx.is_static(static_.def_id) != Some(hir::Mutability::MutMutable) { + Err(place) + } else { Ok(RootPlace { place, is_local_mutation_allowed, }) } - None => { - if self.infcx.tcx.is_static(static_.def_id) != Some(hir::Mutability::MutMutable) { - Err(place) - } else { - Ok(RootPlace { - place, - is_local_mutation_allowed, - }) - } - } } } Place::Projection(ref proj) => { diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index d8c39e0715ad1..2661d765718dd 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -130,18 +130,14 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { } Place::Base(PlaceBase::Static(box Static { def_id, ty: _, promoted })) => { - match promoted { - Some(_) => unreachable!(), - None => { - if let Place::Base(PlaceBase::Static(_)) = access_place { - item_msg = format!("immutable static item `{}`", access_place_desc.unwrap()); - reason = String::new(); - } else { - item_msg = format!("`{}`", access_place_desc.unwrap()); - let static_name = &self.infcx.tcx.item_name(*def_id); - reason = format!(", as `{}` is an immutable static item", static_name); - } - } + assert!(promoted.is_none()); + if let Place::Base(PlaceBase::Static(_)) = access_place { + item_msg = format!("immutable static item `{}`", access_place_desc.unwrap()); + reason = String::new(); + } else { + item_msg = format!("`{}`", access_place_desc.unwrap()); + let static_name = &self.infcx.tcx.item_name(*def_id); + reason = format!(", as `{}` is an immutable static item", static_name); } } diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 334c20761e7bb..c2efd3625c32b 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -454,10 +454,9 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { ty: self.mir.local_decls[index].ty, }, Place::Base(PlaceBase::Static(box Static { def_id, ty: sty, promoted })) => { + let sty = self.sanitize_type(place, sty); match promoted { Some(pr) => { - let sty = self.sanitize_type(place, sty); - if !self.errors_reported { let promoted_mir = &self.mir.promoted[pr]; self.sanitize_promoted(promoted_mir, location); @@ -480,15 +479,18 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { ); }; } - PlaceTy::Ty { ty: sty } } None => { - let sty = self.sanitize_type(place, sty); let ty = self.tcx().type_of(def_id); let ty = self.cx.normalize(ty, location); if let Err(terr) = self.cx - .eq_types(ty, sty, location.to_locations(), ConstraintCategory::Boring) + .eq_types( + ty, + sty, + location.to_locations(), + ConstraintCategory::Boring + ) { span_mirbug!( self, @@ -498,10 +500,10 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { sty, terr ); - } - PlaceTy::Ty { ty: sty } + }; } } + PlaceTy::Ty { ty: sty } } Place::Projection(ref proj) => { let base_context = if context.is_mutating_use() { diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs index 0bbd147d8243b..5e691db0a2e4e 100644 --- a/src/librustc_mir/borrow_check/place_ext.rs +++ b/src/librustc_mir/borrow_check/place_ext.rs @@ -50,11 +50,10 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> { } } Place::Base(PlaceBase::Static(static_)) => { - match static_.promoted { - Some(_) => false, - None => { - tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable) - } + if static_.promoted.is_none() { + tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable) + } else { + false } } Place::Projection(proj) => match proj.elem { diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index 7babdfcdd68ad..c4f9df0cfe579 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -387,7 +387,7 @@ fn place_element_conflict<'a, 'gcx: 'tcx, 'tcx>( }, (Some(p1), Some(p2)) => { if p1 == p2 { - if let ty::Array(_, size) =s1.ty.sty { + if let ty::Array(_, size) = s1.ty.sty { if size.unwrap_usize(tcx) == 0 { // Ignore conflicts with promoted [T; 0]. debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED"); @@ -404,7 +404,7 @@ fn place_element_conflict<'a, 'gcx: 'tcx, 'tcx>( } }, (p1_, p2_) => { - debug!("place_element_conflict: DISJOINT-STATIC-LOCAL-PROMOTED"); + debug!("place_element_conflict: DISJOINT-STATIC-PROMOTED"); Overlap::Disjoint } } diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 62e2cdffadf34..7adcb118f843c 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -582,39 +582,37 @@ where ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { use rustc::mir::Place::*; use rustc::mir::PlaceBase; + use rustc::mir::Static; Ok(match *mir_place { - Base(PlaceBase::Static(ref static_)) => { - match static_.promoted { - Some(promoted) => { - let instance = self.frame().instance; - self.const_eval_raw(GlobalId { - instance, - promoted: Some(promoted), - })? - } - None => { - assert!(!static_.ty.needs_subst()); - let layout = self.layout_of(static_.ty)?; - let instance = ty::Instance::mono(*self.tcx, static_.def_id); - let cid = GlobalId { - instance, - promoted: None - }; - // Just create a lazy reference, so we can support recursive statics. - // tcx takes are of assigning every static one and only one unique AllocId. - // When the data here is ever actually used, memory will notice, - // and it knows how to deal with alloc_id that are present in the - // global table but not in its local memory: It calls back into tcx through - // a query, triggering the CTFE machinery to actually turn this lazy reference - // into a bunch of bytes. IOW, statics are evaluated with CTFE even when - // this EvalContext uses another Machine (e.g., in miri). This is what we - // want! This way, computing statics works concistently between codegen - // and miri: They use the same query to eventually obtain a `ty::Const` - // and use that for further computation. - let alloc = self.tcx.alloc_map.lock().intern_static(cid.instance.def_id()); - MPlaceTy::from_aligned_ptr(Pointer::from(alloc).with_default_tag(), layout) - } - } + Base(PlaceBase::Static(box Static {promoted: Some(promoted), ty, ..})) => { + let instance = self.frame().instance; + self.const_eval_raw(GlobalId { + instance, + promoted: Some(promoted), + })? + } + + Base(PlaceBase::Static(box Static {promoted: None, ty, def_id})) => { + assert!(!ty.needs_subst()); + let layout = self.layout_of(ty)?; + let instance = ty::Instance::mono(*self.tcx, def_id); + let cid = GlobalId { + instance, + promoted: None + }; + // Just create a lazy reference, so we can support recursive statics. + // tcx takes are of assigning every static one and only one unique AllocId. + // When the data here is ever actually used, memory will notice, + // and it knows how to deal with alloc_id that are present in the + // global table but not in its local memory: It calls back into tcx through + // a query, triggering the CTFE machinery to actually turn this lazy reference + // into a bunch of bytes. IOW, statics are evaluated with CTFE even when + // this EvalContext uses another Machine (e.g., in miri). This is what we + // want! This way, computing statics works concistently between codegen + // and miri: They use the same query to eventually obtain a `ty::Const` + // and use that for further computation. + let alloc = self.tcx.alloc_map.lock().intern_static(cid.instance.def_id()); + MPlaceTy::from_aligned_ptr(Pointer::from(alloc).with_default_tag(), layout) } _ => bug!("eval_place_to_mplace called on {:?}", mir_place), diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 01cb58a481a31..2ebe28e6ac091 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -301,32 +301,27 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { // locals are safe } &Place::Base(PlaceBase::Static(box Static { def_id, ty: _, promoted })) => { - match promoted { - Some(..) => { - bug!("unsafety checking should happen before promotion") - } - None => { - if self.tcx.is_static(def_id) == Some(hir::Mutability::MutMutable) { - self.require_unsafe("use of mutable static", - "mutable statics can be mutated by multiple threads: aliasing violations \ - or data races will cause undefined behavior", - UnsafetyViolationKind::General); - } else if self.tcx.is_foreign_item(def_id) { - let source_info = self.source_info; - let lint_root = - self.source_scope_local_data[source_info.scope].lint_root; - self.register_violations(&[UnsafetyViolation { - source_info, - description: Symbol::intern("use of extern static").as_interned_str(), - details: - Symbol::intern("extern statics are not controlled by the Rust type \ - system: invalid data, aliasing violations or data \ - races will cause undefined behavior") - .as_interned_str(), - kind: UnsafetyViolationKind::ExternStatic(lint_root) - }], &[]); - } - } + assert!(promoted.is_none(), "unsafety checking should happen before promotion"); + + if self.tcx.is_static(def_id) == Some(hir::Mutability::MutMutable) { + self.require_unsafe("use of mutable static", + "mutable statics can be mutated by multiple threads: aliasing violations \ + or data races will cause undefined behavior", + UnsafetyViolationKind::General); + } else if self.tcx.is_foreign_item(def_id) { + let source_info = self.source_info; + let lint_root = + self.source_scope_local_data[source_info.scope].lint_root; + self.register_violations(&[UnsafetyViolation { + source_info, + description: Symbol::intern("use of extern static").as_interned_str(), + details: + Symbol::intern("extern statics are not controlled by the Rust type \ + system: invalid data, aliasing violations or data \ + races will cause undefined behavior") + .as_interned_str(), + kind: UnsafetyViolationKind::ExternStatic(lint_root) + }], &[]); } } }; diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index bbe62fa2d7b37..3ee26e7dd26d9 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -266,6 +266,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { } fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option> { + use rustc::mir::Static; match *place { Place::Base(PlaceBase::Local(loc)) => self.places[loc].clone(), Place::Projection(ref proj) => match proj.elem { @@ -282,31 +283,25 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { // an `Index` projection would throw us off-track. _ => None, }, - Place::Base(PlaceBase::Static(ref static_)) => { - match static_.promoted { - Some(promoted) => { - let generics = self.tcx.generics_of(self.source.def_id()); - if generics.requires_monomorphization(self.tcx) { - // FIXME: can't handle code with generics - return None; - } - let substs = InternalSubsts::identity_for_item(self.tcx, self.source.def_id()); - let instance = Instance::new(self.source.def_id(), substs); - let cid = GlobalId { - instance, - promoted: Some(promoted), - }; - // cannot use `const_eval` here, because that would require having the MIR - // for the current function available, but we're producing said MIR right now - let res = self.use_ecx(source_info, |this| { - eval_promoted(this.tcx, cid, this.mir, this.param_env) - })?; - trace!("evaluated promoted {:?} to {:?}", promoted, res); - Some((res.into(), source_info.span)) - } - None => None + Place::Base(PlaceBase::Static(box Static {promoted: Some(promoted), ty, ..})) => { + let generics = self.tcx.generics_of(self.source.def_id()); + if generics.requires_monomorphization(self.tcx) { + // FIXME: can't handle code with generics + return None; } - + let substs = InternalSubsts::identity_for_item(self.tcx, self.source.def_id()); + let instance = Instance::new(self.source.def_id(), substs); + let cid = GlobalId { + instance, + promoted: Some(promoted), + }; + // cannot use `const_eval` here, because that would require having the MIR + // for the current function available, but we're producing said MIR right now + let res = self.use_ecx(source_info, |this| { + eval_promoted(this.tcx, cid, this.mir, this.param_env) + })?; + trace!("evaluated promoted {:?} to {:?}", promoted, res); + Some((res.into(), source_info.span)) }, _ => None, } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index f0ba1306c99fc..9cbb891316dca 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -189,10 +189,8 @@ trait Qualif { match *place { Place::Base(PlaceBase::Local(local)) => Self::in_local(cx, local), Place::Base(PlaceBase::Static(ref static_)) => { - match static_.promoted { - Some(..) => bug!("qualifying already promoted MIR"), - None => Self::in_static(cx, static_), - } + assert!(static_.promoted.is_none(), "qualifying already promoted MIR"); + Self::in_static(cx, static_) }, Place::Projection(ref proj) => Self::in_projection(cx, proj), } @@ -773,19 +771,15 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { dest = &proj.base; }, Place::Base(PlaceBase::Static(st)) => { - match st.promoted { - Some(..) => bug!("promoteds don't exist yet during promotion"), - None => { - // Catch more errors in the destination. `visit_place` also checks that we - // do not try to access statics from constants or try to mutate statics - self.visit_place( - dest, - PlaceContext::MutatingUse(MutatingUseContext::Store), - location - ); - return; - } - } + assert!(st.promoted.is_none(), "promoteds don't exist yet during promotion"); + // Catch more errors in the destination. `visit_place` also checks that we + // do not try to access statics from constants or try to mutate statics + self.visit_place( + dest, + PlaceContext::MutatingUse(MutatingUseContext::Store), + location + ); + return; } } }; @@ -928,53 +922,49 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { match *place { Place::Base(PlaceBase::Local(_)) => {} Place::Base(PlaceBase::Static(ref global)) => { - match global.promoted { - Some(..) => {} - None => { - if self.tcx - .get_attrs(global.def_id) - .iter() - .any(|attr| attr.check_name("thread_local")) { - if self.mode != Mode::Fn { - span_err!(self.tcx.sess, self.span, E0625, - "thread-local statics cannot be \ - accessed at compile-time"); - } - return; - } + assert!(global.promoted.is_none(), {}); + if self.tcx + .get_attrs(global.def_id) + .iter() + .any(|attr| attr.check_name("thread_local")) { + if self.mode != Mode::Fn { + span_err!(self.tcx.sess, self.span, E0625, + "thread-local statics cannot be \ + accessed at compile-time"); + } + return; + } - // Only allow statics (not consts) to refer to other statics. - if self.mode == Mode::Static || self.mode == Mode::StaticMut { - if self.mode == Mode::Static && context.is_mutating_use() { - // this is not strictly necessary as miri will also bail out - // For interior mutability we can't really catch this statically as that - // goes through raw pointers and intermediate temporaries, so miri has - // to catch this anyway - self.tcx.sess.span_err( - self.span, - "cannot mutate statics in the initializer of another static", - ); - } - return; - } - unleash_miri!(self); + // Only allow statics (not consts) to refer to other statics. + if self.mode == Mode::Static || self.mode == Mode::StaticMut { + if self.mode == Mode::Static && context.is_mutating_use() { + // this is not strictly necessary as miri will also bail out + // For interior mutability we can't really catch this statically as that + // goes through raw pointers and intermediate temporaries, so miri has + // to catch this anyway + self.tcx.sess.span_err( + self.span, + "cannot mutate statics in the initializer of another static", + ); + } + return; + } + unleash_miri!(self); - if self.mode != Mode::Fn { - let mut err = struct_span_err!(self.tcx.sess, self.span, E0013, - "{}s cannot refer to statics, use \ - a constant instead", self.mode); - if self.tcx.sess.teach(&err.get_code().unwrap()) { - err.note( - "Static and const variables can refer to other const variables. But a \ - const variable cannot refer to a static variable." - ); - err.help( - "To fix this, the value can be extracted as a const and then used." - ); - } - err.emit() - } + if self.mode != Mode::Fn { + let mut err = struct_span_err!(self.tcx.sess, self.span, E0013, + "{}s cannot refer to statics, use \ + a constant instead", self.mode); + if self.tcx.sess.teach(&err.get_code().unwrap()) { + err.note( + "Static and const variables can refer to other const variables. But a \ + const variable cannot refer to a static variable." + ); + err.help( + "To fix this, the value can be extracted as a const and then used." + ); } + err.emit() } } Place::Projection(ref proj) => { From 23c87a1f53a502cfca3ced42a33cf1389f6c081e Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Mon, 18 Mar 2019 14:51:08 +0530 Subject: [PATCH 03/38] fixed all compilation errors --- src/librustc_codegen_ssa/mir/block.rs | 12 ++++++++---- src/librustc_codegen_ssa/mir/place.rs | 10 +++++++--- src/librustc_mir/borrow_check/mod.rs | 14 +++++--------- src/librustc_mir/borrow_check/place_ext.rs | 7 ++----- .../borrow_check/places_conflict.rs | 2 +- src/librustc_mir/interpret/place.rs | 2 +- src/librustc_mir/transform/const_prop.rs | 2 +- src/librustc_mir/transform/inline.rs | 1 + src/librustc_mir/transform/promote_consts.rs | 17 +++++++++++++---- src/librustc_mir/transform/qualify_consts.rs | 4 ++-- 10 files changed, 41 insertions(+), 30 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 35fd30f34ad24..62f454f1b9fea 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -1,7 +1,7 @@ use rustc::middle::lang_items; use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt}; -use rustc::mir; +use rustc::mir::{self, Place, PlaceBase}; use rustc::mir::interpret::EvalErrorKind; use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode}; use rustc_target::spec::abi::Abi; @@ -621,15 +621,19 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // but specified directly in the code. This means it gets promoted // and we can then extract the value by evaluating the promoted. mir::Operand::Copy( - mir::Place::Base(mir::PlaceBase::Promoted(box(index, ty))) + Place::Base(PlaceBase::Static( + box mir::Static {promoted: Some(promoted), ty, ..} + )) ) | mir::Operand::Move( - mir::Place::Base(mir::PlaceBase::Promoted(box(index, ty))) + Place::Base(PlaceBase::Static( + box mir::Static {promoted: Some(promoted), ty, ..} + )) ) => { let param_env = ty::ParamEnv::reveal_all(); let cid = mir::interpret::GlobalId { instance: self.instance, - promoted: Some(index), + promoted: Some(promoted), }; let c = bx.tcx().const_eval(param_env.and(cid)); let (llval, ty) = self.simd_shuffle_indices( diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 0408ccf039f34..1608429b07024 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -408,11 +408,13 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let result = match *place { mir::Place::Base(mir::PlaceBase::Local(_)) => bug!(), // handled above - mir::Place::Base(mir::PlaceBase::Promoted(box (index, ty))) => { + mir::Place::Base( + mir::PlaceBase::Static(box mir::Static { def_id: _, ty, promoted: Some(promoted) }) + ) => { let param_env = ty::ParamEnv::reveal_all(); let cid = mir::interpret::GlobalId { instance: self.instance, - promoted: Some(index), + promoted: Some(promoted), }; let layout = cx.layout_of(self.monomorphize(&ty)); match bx.tcx().const_eval(param_env.and(cid)) { @@ -435,7 +437,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } } - mir::Place::Base(mir::PlaceBase::Static(box mir::Static { def_id, ty })) => { + mir::Place::Base( + mir::PlaceBase::Static(box mir::Static { def_id, ty, promoted: None }) + ) => { // NB: The layout of a static may be unsized as is the case when working // with a static that is an extern_type. let layout = cx.layout_of(self.monomorphize(&ty)); diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index e92ed1f2c7caa..e538622103aca 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1983,20 +1983,16 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // The rules for promotion are made by `qualify_consts`, there wouldn't even be a // `Place::Promoted` if the promotion weren't 100% legal. So we just forward this Place::Base(PlaceBase::Static(ref static_)) => { - if static_.promoted.is_some() { + if static_.promoted.is_some() || + (static_.promoted.is_none() && + self.infcx.tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable) + ){ Ok(RootPlace { place, is_local_mutation_allowed, }) } else { - if self.infcx.tcx.is_static(static_.def_id) != Some(hir::Mutability::MutMutable) { - Err(place) - } else { - Ok(RootPlace { - place, - is_local_mutation_allowed, - }) - } + Err(place) } } Place::Projection(ref proj) => { diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs index 5e691db0a2e4e..0452465f0b9d7 100644 --- a/src/librustc_mir/borrow_check/place_ext.rs +++ b/src/librustc_mir/borrow_check/place_ext.rs @@ -50,11 +50,8 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> { } } Place::Base(PlaceBase::Static(static_)) => { - if static_.promoted.is_none() { - tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable) - } else { - false - } + static_.promoted.is_none() && + (tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable)) } Place::Projection(proj) => match proj.elem { ProjectionElem::Field(..) diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index c4f9df0cfe579..783751056d76b 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -403,7 +403,7 @@ fn place_element_conflict<'a, 'gcx: 'tcx, 'tcx>( Overlap::Disjoint } }, - (p1_, p2_) => { + (_, _) => { debug!("place_element_conflict: DISJOINT-STATIC-PROMOTED"); Overlap::Disjoint } diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 7adcb118f843c..6089e491684e9 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -584,7 +584,7 @@ where use rustc::mir::PlaceBase; use rustc::mir::Static; Ok(match *mir_place { - Base(PlaceBase::Static(box Static {promoted: Some(promoted), ty, ..})) => { + Base(PlaceBase::Static(box Static {promoted: Some(promoted), ty: _, ..})) => { let instance = self.frame().instance; self.const_eval_raw(GlobalId { instance, diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 3ee26e7dd26d9..c5c3a1b8eca18 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -283,7 +283,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { // an `Index` projection would throw us off-track. _ => None, }, - Place::Base(PlaceBase::Static(box Static {promoted: Some(promoted), ty, ..})) => { + Place::Base(PlaceBase::Static(box Static {promoted: Some(promoted), ty: _, ..})) => { let generics = self.tcx.generics_of(self.source.def_id()); if generics.requires_monomorphization(self.tcx) { // FIXME: can't handle code with generics diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 0b2a34d5fb975..86b7da1787919 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -702,6 +702,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { None => self.super_place(place, _ctxt, _location) } }, + _ => self.super_place(place, _ctxt, _location) } } diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 831d8b46a65c3..d777a7b362b90 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -12,6 +12,7 @@ //! initialization and can otherwise silence errors, if //! move analysis runs after promotion on broken MIR. +use rustc::hir::def_id::DefId; use rustc::mir::*; use rustc::mir::visit::{PlaceContext, MutatingUseContext, MutVisitor, Visitor}; use rustc::mir::traversal::ReversePostorder; @@ -151,7 +152,8 @@ struct Promoter<'a, 'tcx: 'a> { /// If true, all nested temps are also kept in the /// source MIR, not moved to the promoted MIR. - keep_original: bool + keep_original: bool, + def_id: DefId } impl<'a, 'tcx> Promoter<'a, 'tcx> { @@ -287,14 +289,19 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { } fn promote_candidate(mut self, candidate: Candidate) { + use rustc::mir::Static; let mut operand = { + let def_id = self.def_id.clone(); let promoted = &mut self.promoted; let promoted_id = Promoted::new(self.source.promoted.len()); let mut promoted_place = |ty, span| { promoted.span = span; promoted.local_decls[RETURN_PLACE] = LocalDecl::new_return_place(ty, span); - Place::Base(PlaceBase::Promoted(box (promoted_id, ty))) + Place::Base(PlaceBase::Static( + Box::new(Static { def_id: def_id, ty, promoted: Some(promoted_id) }) + ) + ) }; let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut(); match candidate { @@ -367,7 +374,8 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> { pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, mut temps: IndexVec, - candidates: Vec) { + candidates: Vec, + def_id: DefId) { // Visit candidates in reverse, in case they're nested. debug!("promote_candidates({:?})", candidates); @@ -412,7 +420,8 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>, tcx, source: mir, temps: &mut temps, - keep_original: false + keep_original: false, + def_id }; promoter.promote_candidate(candidate); } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 9cbb891316dca..c01ed4b1c59e8 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -922,7 +922,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { match *place { Place::Base(PlaceBase::Local(_)) => {} Place::Base(PlaceBase::Static(ref global)) => { - assert!(global.promoted.is_none(), {}); + assert!(global.promoted.is_none()); if self.tcx .get_attrs(global.def_id) .iter() @@ -1516,7 +1516,7 @@ impl MirPass for QualifyAndPromoteConstants { }; // Do the actual promotion, now that we know what's viable. - promote_consts::promote_candidates(mir, tcx, temps, candidates); + promote_consts::promote_candidates(mir, tcx, temps, candidates, def_id); } else { if !mir.control_flow_destroyed.is_empty() { let mut locals = mir.vars_iter(); From ac6ab6591384f77cb67813326f3509e71df5aeaa Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 18 Mar 2019 22:45:02 +0100 Subject: [PATCH 04/38] adjust MaybeUninit API to discussions uninitialized -> uninit into_initialized -> assume_init read_initialized -> read set -> write --- src/liballoc/collections/btree/node.rs | 10 +-- src/libcore/fmt/float.rs | 16 ++-- src/libcore/fmt/num.rs | 4 +- src/libcore/macros.rs | 4 +- src/libcore/mem.rs | 110 ++++++++++++++++--------- src/libcore/ptr.rs | 14 ++-- src/libcore/slice/rotate.rs | 2 +- 7 files changed, 97 insertions(+), 63 deletions(-) diff --git a/src/liballoc/collections/btree/node.rs b/src/liballoc/collections/btree/node.rs index 66d619b1298b4..581c66c7086a5 100644 --- a/src/liballoc/collections/btree/node.rs +++ b/src/liballoc/collections/btree/node.rs @@ -109,7 +109,7 @@ impl LeafNode { keys: uninitialized_array![_; CAPACITY], vals: uninitialized_array![_; CAPACITY], parent: ptr::null(), - parent_idx: MaybeUninit::uninitialized(), + parent_idx: MaybeUninit::uninit(), len: 0 } } @@ -129,7 +129,7 @@ unsafe impl Sync for NodeHeader<(), ()> {} // ever take a pointer past the first key. static EMPTY_ROOT_NODE: NodeHeader<(), ()> = NodeHeader { parent: ptr::null(), - parent_idx: MaybeUninit::uninitialized(), + parent_idx: MaybeUninit::uninit(), len: 0, keys_start: [], }; @@ -261,7 +261,7 @@ impl Root { -> NodeRef, K, V, marker::Internal> { debug_assert!(!self.is_shared_root()); let mut new_node = Box::new(unsafe { InternalNode::new() }); - new_node.edges[0].set(unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }); + new_node.edges[0].write(unsafe { BoxedNode::from_ptr(self.node.as_ptr()) }); self.node = BoxedNode::from_internal(new_node); self.height += 1; @@ -737,7 +737,7 @@ impl<'a, K, V> NodeRef, K, V, marker::Internal> { unsafe { ptr::write(self.keys_mut().get_unchecked_mut(idx), key); ptr::write(self.vals_mut().get_unchecked_mut(idx), val); - self.as_internal_mut().edges.get_unchecked_mut(idx + 1).set(edge.node); + self.as_internal_mut().edges.get_unchecked_mut(idx + 1).write(edge.node); (*self.as_leaf_mut()).len += 1; @@ -1080,7 +1080,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: let mut child = self.descend(); unsafe { (*child.as_leaf_mut()).parent = ptr; - (*child.as_leaf_mut()).parent_idx.set(idx); + (*child.as_leaf_mut()).parent_idx.write(idx); } } diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs index edeb65afd67b2..5f4c6f7b0a3f0 100644 --- a/src/libcore/fmt/float.rs +++ b/src/libcore/fmt/float.rs @@ -10,8 +10,8 @@ fn float_to_decimal_common_exact(fmt: &mut Formatter, num: &T, where T: flt2dec::DecodableFloat { unsafe { - let mut buf = MaybeUninit::<[u8; 1024]>::uninitialized(); // enough for f32 and f64 - let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized(); + let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64 + let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninit(); // FIXME(#53491): Technically, this is calling `get_mut` on an uninitialized // `MaybeUninit` (here and elsewhere in this file). Revisit this once // we decided whether that is valid or not. @@ -32,8 +32,8 @@ fn float_to_decimal_common_shortest(fmt: &mut Formatter, num: &T, { unsafe { // enough for f32 and f64 - let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninitialized(); - let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninitialized(); + let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit(); + let mut parts = MaybeUninit::<[flt2dec::Part; 4]>::uninit(); // FIXME(#53491) let formatted = flt2dec::to_shortest_str(flt2dec::strategy::grisu::format_shortest, *num, sign, precision, false, buf.get_mut(), @@ -71,8 +71,8 @@ fn float_to_exponential_common_exact(fmt: &mut Formatter, num: &T, where T: flt2dec::DecodableFloat { unsafe { - let mut buf = MaybeUninit::<[u8; 1024]>::uninitialized(); // enough for f32 and f64 - let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninitialized(); + let mut buf = MaybeUninit::<[u8; 1024]>::uninit(); // enough for f32 and f64 + let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninit(); // FIXME(#53491) let formatted = flt2dec::to_exact_exp_str(flt2dec::strategy::grisu::format_exact, *num, sign, precision, @@ -91,8 +91,8 @@ fn float_to_exponential_common_shortest(fmt: &mut Formatter, { unsafe { // enough for f32 and f64 - let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninitialized(); - let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninitialized(); + let mut buf = MaybeUninit::<[u8; flt2dec::MAX_SIG_DIGITS]>::uninit(); + let mut parts = MaybeUninit::<[flt2dec::Part; 6]>::uninit(); // FIXME(#53491) let formatted = flt2dec::to_shortest_exp_str(flt2dec::strategy::grisu::format_shortest, *num, sign, (0, 0), upper, diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index b9fa364037108..e96dbcaa14416 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -60,7 +60,7 @@ trait GenericRadix { for byte in buf.iter_mut().rev() { let n = x % base; // Get the current place value. x = x / base; // Deaccumulate the number. - byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer. + byte.write(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. @@ -72,7 +72,7 @@ trait GenericRadix { for byte in buf.iter_mut().rev() { let n = zero - (x % base); // Get the current place value. x = x / base; // Deaccumulate the number. - byte.set(Self::digit(n.to_u8())); // Store the digit in the buffer. + byte.write(Self::digit(n.to_u8())); // Store the digit in the buffer. curr -= 1; if x == zero { // No more digits left to accumulate. diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index b052f59b0f5c2..bbf75dd0d1b0c 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -567,12 +567,12 @@ macro_rules! unimplemented { #[macro_export] #[unstable(feature = "maybe_uninit_array", issue = "53491")] macro_rules! uninitialized_array { - // This `into_initialized` is safe because an array of `MaybeUninit` does not + // This `assume_init` is safe because an array of `MaybeUninit` does not // require initialization. // FIXME(#49147): Could be replaced by an array initializer, once those can // be any const expression. ($t:ty; $size:expr) => (unsafe { - MaybeUninit::<[MaybeUninit<$t>; $size]>::uninitialized().into_initialized() + MaybeUninit::<[MaybeUninit<$t>; $size]>::uninit().assume_init() }); } diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 3d2fcdc979377..66bcf1f7d0101 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -622,7 +622,7 @@ pub unsafe fn zeroed() -> T { /// [copy_no]: ../intrinsics/fn.copy_nonoverlapping.html /// [`Drop`]: ../ops/trait.Drop.html #[inline] -#[rustc_deprecated(since = "2.0.0", reason = "use `mem::MaybeUninit::uninitialized` instead")] +#[rustc_deprecated(since = "2.0.0", reason = "use `mem::MaybeUninit::uninit` instead")] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn uninitialized() -> T { intrinsics::panic_if_uninhabited::(); @@ -1058,7 +1058,7 @@ impl DerefMut for ManuallyDrop { /// /// let x: &i32 = unsafe { mem::zeroed() }; // undefined behavior! /// // The equivalent code with `MaybeUninit<&i32>`: -/// let x: &i32 = unsafe { MaybeUninit::zeroed().into_initialized() }; // undefined behavior! +/// let x: &i32 = unsafe { MaybeUninit::zeroed().assume_init() }; // undefined behavior! /// ``` /// /// This is exploited by the compiler for various optimizations, such as eliding @@ -1073,7 +1073,7 @@ impl DerefMut for ManuallyDrop { /// /// let b: bool = unsafe { mem::uninitialized() }; // undefined behavior! /// // The equivalent code with `MaybeUninit`: -/// let b: bool = unsafe { MaybeUninit::uninitialized().into_initialized() }; // undefined behavior! +/// let b: bool = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! /// ``` /// /// Moreover, uninitialized memory is special in that the compiler knows that @@ -1087,7 +1087,7 @@ impl DerefMut for ManuallyDrop { /// /// let x: i32 = unsafe { mem::uninitialized() }; // undefined behavior! /// // The equivalent code with `MaybeUninit`: -/// let x: i32 = unsafe { MaybeUninit::uninitialized().into_initialized() }; // undefined behavior! +/// let x: i32 = unsafe { MaybeUninit::uninit().assume_init() }; // undefined behavior! /// ``` /// (Notice that the rules around uninitialized integers are not finalized yet, but /// until they are, it is advisable to avoid them.) @@ -1102,12 +1102,12 @@ impl DerefMut for ManuallyDrop { /// /// // Create an explicitly uninitialized reference. The compiler knows that data inside /// // a `MaybeUninit` may be invalid, and hence this is not UB: -/// let mut x = MaybeUninit::<&i32>::uninitialized(); +/// let mut x = MaybeUninit::<&i32>::uninit(); /// // Set it to a valid value. -/// x.set(&0); +/// x.write(&0); /// // Extract the initialized data -- this is only allowed *after* properly /// // initializing `x`! -/// let x = unsafe { x.into_initialized() }; +/// let x = unsafe { x.assume_init() }; /// ``` /// /// The compiler then knows to not make any incorrect assumptions or optimizations on this code. @@ -1148,10 +1148,19 @@ impl MaybeUninit { /// It is your responsibility to make sure `T` gets dropped if it got initialized. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub const fn uninitialized() -> MaybeUninit { + pub const fn uninit() -> MaybeUninit { MaybeUninit { uninit: () } } + /// Deprecated before stabilization. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + // FIXME: still used by stdsimd + // #[rustc_deprecated(since = "1.35.0", reason = "use `uninit` instead")] + pub const fn uninitialized() -> MaybeUninit { + Self::uninit() + } + /// Creates a new `MaybeUninit` in an uninitialized state, with the memory being /// filled with `0` bytes. It depends on `T` whether that already makes for /// proper initialization. For example, `MaybeUninit::zeroed()` is initialized, @@ -1171,7 +1180,7 @@ impl MaybeUninit { /// use std::mem::MaybeUninit; /// /// let x = MaybeUninit::<(u8, bool)>::zeroed(); - /// let x = unsafe { x.into_initialized() }; + /// let x = unsafe { x.assume_init() }; /// assert_eq!(x, (0, false)); /// ``` /// @@ -1185,14 +1194,14 @@ impl MaybeUninit { /// enum NotZero { One = 1, Two = 2 }; /// /// let x = MaybeUninit::<(u8, NotZero)>::zeroed(); - /// let x = unsafe { x.into_initialized() }; + /// let x = unsafe { x.assume_init() }; /// // Inside a pair, we create a `NotZero` that does not have a valid discriminant. /// // This is undefined behavior. /// ``` #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline] pub fn zeroed() -> MaybeUninit { - let mut u = MaybeUninit::::uninitialized(); + let mut u = MaybeUninit::::uninit(); unsafe { u.as_mut_ptr().write_bytes(0u8, 1); } @@ -1205,13 +1214,21 @@ impl MaybeUninit { /// reference to the (now safely initialized) contents of `self`. #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub fn set(&mut self, val: T) -> &mut T { + pub fn write(&mut self, val: T) -> &mut T { unsafe { self.value = ManuallyDrop::new(val); self.get_mut() } } + /// Deprecated before stabilization. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + #[rustc_deprecated(since = "1.35.0", reason = "use `write` instead")] + pub fn set(&mut self, val: T) -> &mut T { + self.write(val) + } + /// Gets a pointer to the contained value. Reading from this pointer or turning it /// into a reference is undefined behavior unless the `MaybeUninit` is initialized. /// @@ -1223,7 +1240,7 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::>::uninitialized(); + /// let mut x = MaybeUninit::>::uninit(); /// unsafe { x.as_mut_ptr().write(vec![0,1,2]); } /// // Create a reference into the `MaybeUninit`. This is okay because we initialized it. /// let x_vec = unsafe { &*x.as_ptr() }; @@ -1236,7 +1253,7 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let x = MaybeUninit::>::uninitialized(); + /// let x = MaybeUninit::>::uninit(); /// let x_vec = unsafe { &*x.as_ptr() }; /// // We have created a reference to an uninitialized vector! This is undefined behavior. /// ``` @@ -1260,7 +1277,7 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::>::uninitialized(); + /// let mut x = MaybeUninit::>::uninit(); /// unsafe { x.as_mut_ptr().write(vec![0,1,2]); } /// // Create a reference into the `MaybeUninit>`. /// // This is okay because we initialized it. @@ -1275,7 +1292,7 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::>::uninitialized(); + /// let mut x = MaybeUninit::>::uninit(); /// let x_vec = unsafe { &mut *x.as_mut_ptr() }; /// // We have created a reference to an uninitialized vector! This is undefined behavior. /// ``` @@ -1306,9 +1323,9 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::::uninitialized(); + /// let mut x = MaybeUninit::::uninit(); /// unsafe { x.as_mut_ptr().write(true); } - /// let x_init = unsafe { x.into_initialized() }; + /// let x_init = unsafe { x.assume_init() }; /// assert_eq!(x_init, true); /// ``` /// @@ -1318,21 +1335,30 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let x = MaybeUninit::>::uninitialized(); - /// let x_init = unsafe { x.into_initialized() }; + /// let x = MaybeUninit::>::uninit(); + /// let x_init = unsafe { x.assume_init() }; /// // `x` had not been initialized yet, so this last line caused undefined behavior. /// ``` #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub unsafe fn into_initialized(self) -> T { + pub unsafe fn assume_init(self) -> T { intrinsics::panic_if_uninhabited::(); ManuallyDrop::into_inner(self.value) } + /// Deprecated before stabilization. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + // FIXME: still used by stdsimd + // #[rustc_deprecated(since = "1.35.0", reason = "use `assume_init` instead")] + pub unsafe fn into_initialized(self) -> T { + self.assume_init() + } + /// Reads the value from the `MaybeUninit` container. The resulting `T` is subject /// to the usual drop handling. /// - /// Whenever possible, it is preferrable to use [`into_initialized`] instead, which + /// Whenever possible, it is preferrable to use [`assume_init`] instead, which /// prevents duplicating the content of the `MaybeUninit`. /// /// # Safety @@ -1342,11 +1368,11 @@ impl MaybeUninit { /// behavior. /// /// Moreover, this leaves a copy of the same data behind in the `MaybeUninit`. When using - /// multiple copies of the data (by calling `read_initialized` multiple times, or first - /// calling `read_initialized` and then [`into_initialized`]), it is your responsibility + /// multiple copies of the data (by calling `read` multiple times, or first + /// calling `read` and then [`assume_init`]), it is your responsibility /// to ensure that that data may indeed be duplicated. /// - /// [`into_initialized`]: #method.into_initialized + /// [`assume_init`]: #method.assume_init /// /// # Examples /// @@ -1356,18 +1382,18 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::::uninitialized(); - /// x.set(13); - /// let x1 = unsafe { x.read_initialized() }; + /// let mut x = MaybeUninit::::uninit(); + /// x.write(13); + /// let x1 = unsafe { x.read() }; /// // `u32` is `Copy`, so we may read multiple times. - /// let x2 = unsafe { x.read_initialized() }; + /// let x2 = unsafe { x.read() }; /// assert_eq!(x1, x2); /// - /// let mut x = MaybeUninit::>>::uninitialized(); - /// x.set(None); - /// let x1 = unsafe { x.read_initialized() }; + /// let mut x = MaybeUninit::>>::uninit(); + /// x.write(None); + /// let x1 = unsafe { x.read() }; /// // Duplicating a `None` value is okay, so we may read multiple times. - /// let x2 = unsafe { x.read_initialized() }; + /// let x2 = unsafe { x.read() }; /// assert_eq!(x1, x2); /// ``` /// @@ -1377,20 +1403,28 @@ impl MaybeUninit { /// #![feature(maybe_uninit)] /// use std::mem::MaybeUninit; /// - /// let mut x = MaybeUninit::>>::uninitialized(); - /// x.set(Some(vec![0,1,2])); - /// let x1 = unsafe { x.read_initialized() }; - /// let x2 = unsafe { x.read_initialized() }; + /// let mut x = MaybeUninit::>>::uninit(); + /// x.write(Some(vec![0,1,2])); + /// let x1 = unsafe { x.read() }; + /// let x2 = unsafe { x.read() }; /// // We now created two copies of the same vector, leading to a double-free when /// // they both get dropped! /// ``` #[unstable(feature = "maybe_uninit", issue = "53491")] #[inline(always)] - pub unsafe fn read_initialized(&self) -> T { + pub unsafe fn read(&self) -> T { intrinsics::panic_if_uninhabited::(); self.as_ptr().read() } + /// Deprecated before stabilization. + #[unstable(feature = "maybe_uninit", issue = "53491")] + #[inline(always)] + #[rustc_deprecated(since = "1.35.0", reason = "use `read` instead")] + pub unsafe fn read_initialized(&self) -> T { + self.read() + } + /// Gets a reference to the contained value. /// /// # Safety diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index a9a029d606d6f..1cb21aa6be0a2 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -296,7 +296,7 @@ pub const fn null_mut() -> *mut T { 0 as *mut T } pub unsafe fn swap(x: *mut T, y: *mut T) { // Give ourselves some scratch space to work with. // We do not have to worry about drops: `MaybeUninit` does nothing when dropped. - let mut tmp = MaybeUninit::::uninitialized(); + let mut tmp = MaybeUninit::::uninit(); // Perform the swap copy_nonoverlapping(x, tmp.as_mut_ptr(), 1); @@ -388,7 +388,7 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) { while i + block_size <= len { // Create some uninitialized memory as scratch space // Declaring `t` here avoids aligning the stack when this loop is unused - let mut t = mem::MaybeUninit::::uninitialized(); + let mut t = mem::MaybeUninit::::uninit(); let t = t.as_mut_ptr() as *mut u8; let x = x.add(i); let y = y.add(i); @@ -403,7 +403,7 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) { if i < len { // Swap any remaining bytes - let mut t = mem::MaybeUninit::::uninitialized(); + let mut t = mem::MaybeUninit::::uninit(); let rem = len - i; let t = t.as_mut_ptr() as *mut u8; @@ -571,9 +571,9 @@ pub unsafe fn replace(dst: *mut T, mut src: T) -> T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn read(src: *const T) -> T { - let mut tmp = MaybeUninit::::uninitialized(); + let mut tmp = MaybeUninit::::uninit(); copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); - tmp.into_initialized() + tmp.assume_init() } /// Reads the value from `src` without moving it. This leaves the @@ -638,11 +638,11 @@ pub unsafe fn read(src: *const T) -> T { #[inline] #[stable(feature = "ptr_unaligned", since = "1.17.0")] pub unsafe fn read_unaligned(src: *const T) -> T { - let mut tmp = MaybeUninit::::uninitialized(); + let mut tmp = MaybeUninit::::uninit(); copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, mem::size_of::()); - tmp.into_initialized() + tmp.assume_init() } /// Overwrites a memory location with the given value without reading or diff --git a/src/libcore/slice/rotate.rs b/src/libcore/slice/rotate.rs index 9b35b51349a02..8f10c3576a787 100644 --- a/src/libcore/slice/rotate.rs +++ b/src/libcore/slice/rotate.rs @@ -72,7 +72,7 @@ pub unsafe fn ptr_rotate(mut left: usize, mid: *mut T, mut right: usize) { } } - let mut rawarray = MaybeUninit::>::uninitialized(); + let mut rawarray = MaybeUninit::>::uninit(); let buf = &mut (*rawarray.as_mut_ptr()).typed as *mut [T; 2] as *mut T; let dim = mid.sub(left).add(right); From 776407e4e65e537ee7471a90d8a48eb26e7f0fd7 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Tue, 19 Mar 2019 13:35:50 +0530 Subject: [PATCH 05/38] tidy checks --- src/librustc_mir/borrow_check/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index e538622103aca..0358fffcde587 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1985,7 +1985,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Place::Base(PlaceBase::Static(ref static_)) => { if static_.promoted.is_some() || (static_.promoted.is_none() && - self.infcx.tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable) + self.infcx.tcx.is_static(static_.def_id) + == Some(hir::Mutability::MutMutable) ){ Ok(RootPlace { place, From 9374efab17359efb8fdaf620db7f12b5ef7fcf4b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 19 Mar 2019 09:46:11 +0100 Subject: [PATCH 06/38] fix some uses I missed --- src/libstd/sys/sgx/ext/arch.rs | 8 ++++---- src/libstd/sys/sgx/rwlock.rs | 4 ++-- src/libstd/sys/windows/mutex.rs | 2 +- src/test/codegen/box-maybe-uninit.rs | 5 ++++- src/test/run-pass/panic-uninitialized-zeroed.rs | 6 +++--- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/libstd/sys/sgx/ext/arch.rs b/src/libstd/sys/sgx/ext/arch.rs index 53fb371947a99..5056e388112ce 100644 --- a/src/libstd/sys/sgx/ext/arch.rs +++ b/src/libstd/sys/sgx/ext/arch.rs @@ -28,7 +28,7 @@ const ENCLU_EGETKEY: u32 = 1; #[unstable(feature = "sgx_platform", issue = "56975")] pub fn egetkey(request: &Align512<[u8; 512]>) -> Result, u32> { unsafe { - let mut out = MaybeUninit::uninitialized(); + let mut out = MaybeUninit::uninit(); let error; asm!( @@ -41,7 +41,7 @@ pub fn egetkey(request: &Align512<[u8; 512]>) -> Result, u32> ); match error { - 0 => Ok(out.into_initialized()), + 0 => Ok(out.assume_init()), err => Err(err), } } @@ -58,7 +58,7 @@ pub fn ereport( reportdata: &Align128<[u8; 64]>, ) -> Align512<[u8; 432]> { unsafe { - let mut report = MaybeUninit::uninitialized(); + let mut report = MaybeUninit::uninit(); asm!( "enclu" @@ -69,6 +69,6 @@ pub fn ereport( "{rdx}"(report.as_mut_ptr()) ); - report.into_initialized() + report.assume_init() } } diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs index 372760bbf26b4..5b1b96fb60e23 100644 --- a/src/libstd/sys/sgx/rwlock.rs +++ b/src/libstd/sys/sgx/rwlock.rs @@ -252,9 +252,9 @@ mod tests { ]; let mut init = MaybeUninit::::zeroed(); - init.set(RWLock::new()); + init.write(RWLock::new()); assert_eq!( - mem::transmute::<_, [u8; 128]>(init.into_inner()).as_slice(), + mem::transmute::<_, [u8; 128]>(init.assume_init()).as_slice(), RWLOCK_INIT ); } diff --git a/src/libstd/sys/windows/mutex.rs b/src/libstd/sys/windows/mutex.rs index 1aa910f05c9c3..37cbdcefcedcc 100644 --- a/src/libstd/sys/windows/mutex.rs +++ b/src/libstd/sys/windows/mutex.rs @@ -154,7 +154,7 @@ unsafe impl Sync for ReentrantMutex {} impl ReentrantMutex { pub fn uninitialized() -> ReentrantMutex { - ReentrantMutex { inner: UnsafeCell::new(MaybeUninit::uninitialized()) } + ReentrantMutex { inner: UnsafeCell::new(MaybeUninit::uninit()) } } pub unsafe fn init(&mut self) { diff --git a/src/test/codegen/box-maybe-uninit.rs b/src/test/codegen/box-maybe-uninit.rs index ad1d259a0da21..0dd67bb95ccaa 100644 --- a/src/test/codegen/box-maybe-uninit.rs +++ b/src/test/codegen/box-maybe-uninit.rs @@ -12,5 +12,8 @@ pub fn box_uninitialized() -> Box> { // CHECK-NOT: alloca // CHECK-NOT: memcpy // CHECK-NOT: memset - Box::new(MaybeUninit::uninitialized()) + Box::new(MaybeUninit::uninit()) } + +// FIXME: add a test for a bigger box. Currently broken, see +// https://github.com/rust-lang/rust/issues/58201. diff --git a/src/test/run-pass/panic-uninitialized-zeroed.rs b/src/test/run-pass/panic-uninitialized-zeroed.rs index 31c0d2994d415..3f6e489bb8327 100644 --- a/src/test/run-pass/panic-uninitialized-zeroed.rs +++ b/src/test/run-pass/panic-uninitialized-zeroed.rs @@ -36,7 +36,7 @@ fn main() { assert_eq!( panic::catch_unwind(|| { - mem::MaybeUninit::::uninitialized().into_initialized() + mem::MaybeUninit::::uninit().assume_init() }).err().and_then(|a| a.downcast_ref::().map(|s| { s == "Attempted to instantiate uninhabited type !" })), @@ -63,7 +63,7 @@ fn main() { assert_eq!( panic::catch_unwind(|| { - mem::MaybeUninit::::uninitialized().into_initialized() + mem::MaybeUninit::::uninit().assume_init() }).err().and_then(|a| a.downcast_ref::().map(|s| { s == "Attempted to instantiate uninhabited type Foo" })), @@ -90,7 +90,7 @@ fn main() { assert_eq!( panic::catch_unwind(|| { - mem::MaybeUninit::::uninitialized().into_initialized() + mem::MaybeUninit::::uninit().assume_init() }).err().and_then(|a| a.downcast_ref::().map(|s| { s == "Attempted to instantiate uninhabited type Bar" })), From 8829ddadc4f82b43a8653dd1f40839513b6fb2f0 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Wed, 20 Mar 2019 19:05:03 +0530 Subject: [PATCH 07/38] remove visit_static from librustc::mir --- src/librustc/mir/visit.rs | 21 ++++------------- src/librustc_mir/monomorphize/collector.rs | 23 ++++++++++++------- .../transform/qualify_min_const_fn.rs | 11 ++++----- 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 6761c70550ec8..3f6133a7331a1 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -156,13 +156,6 @@ macro_rules! make_mir_visitor { self.super_place(place, context, location); } - fn visit_static(&mut self, - static_: & $($mutability)? Static<'tcx>, - context: PlaceContext<'tcx>, - location: Location) { - self.super_static(static_, context, location); - } - fn visit_projection(&mut self, place: & $($mutability)? PlaceProjection<'tcx>, context: PlaceContext<'tcx>, @@ -737,7 +730,10 @@ macro_rules! make_mir_visitor { self.visit_local(local, context, location); } Place::Base(PlaceBase::Static(static_)) => { - self.visit_static(static_, context, location); + if static_.promoted.is_none() { + self.visit_def_id(& $($mutability)? static_.def_id, location); + } + self.visit_ty(& $($mutability)? static_.ty, TyContext::Location(location)); } Place::Projection(proj) => { self.visit_projection(proj, context, location); @@ -745,15 +741,6 @@ macro_rules! make_mir_visitor { } } - fn super_static(&mut self, - static_: & $($mutability)? Static<'tcx>, - _context: PlaceContext<'tcx>, - location: Location) { - let Static { def_id, ty, promoted: _ } = static_; - self.visit_def_id(def_id, location); - self.visit_ty(ty, TyContext::Location(location)); - } - fn super_projection(&mut self, proj: & $($mutability)? PlaceProjection<'tcx>, context: PlaceContext<'tcx>, diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 4fe47a9666a68..075b81e9fd98f 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -650,19 +650,26 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { self.super_terminator_kind(block, kind, location); } - fn visit_static(&mut self, - static_: &mir::Static<'tcx>, + fn visit_place(&mut self, + place: &mir::Place<'tcx>, context: mir::visit::PlaceContext<'tcx>, location: Location) { - debug!("visiting static {:?} @ {:?}", static_.def_id, location); + match place { + mir::Place::Base( + mir::PlaceBase::Static(box mir::Static{def_id, promoted:None, ..}) + ) => { + debug!("visiting static {:?} @ {:?}", def_id, location); - let tcx = self.tcx; - let instance = Instance::mono(tcx, static_.def_id); - if should_monomorphize_locally(tcx, &instance) { - self.output.push(MonoItem::Static(static_.def_id)); + let tcx = self.tcx; + let instance = Instance::mono(tcx, *def_id); + if should_monomorphize_locally(tcx, &instance) { + self.output.push(MonoItem::Static(*def_id)); + } + } + _ => {} } - self.super_static(static_, context, location); + self.super_place(place, context, location); } } diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index ea5bbaeb4008e..da849faf40aae 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -256,13 +256,10 @@ fn check_place( ) -> McfResult { match place { Place::Base(PlaceBase::Local(_)) => Ok(()), - Place::Base(PlaceBase::Static(st)) => { - match st.promoted { - // promoteds are always fine, they are essentially constants - Some(..) => Ok(()), - None => Err((span, "cannot access `static` items in const fn".into())), - } - } + // promoteds are always fine, they are essentially constants + Place::Base(PlaceBase::Static(box Static {def_id: _, ty: _, promoted: Some(_)})) => Ok(()), + Place::Base(PlaceBase::Static(box Static {def_id: _, ty: _, promoted: None})) => + Err((span, "cannot access `static` items in const fn".into())), Place::Projection(proj) => { match proj.elem { | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } From 72f8d4e2220cc48061288b57d716f194567b4307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 20 Mar 2019 16:06:09 +0100 Subject: [PATCH 08/38] Add no_hash to query macro and move some queries over --- Cargo.lock | 1 + src/librustc/dep_graph/dep_node.rs | 6 -- src/librustc/query/mod.rs | 43 ++++++++++++++ src/librustc/ty/query/config.rs | 22 -------- src/librustc/ty/query/mod.rs | 32 ----------- src/librustc/ty/query/plumbing.rs | 10 +--- .../persist/dirty_clean.rs | 6 +- src/librustc_macros/Cargo.toml | 1 + src/librustc_macros/src/query.rs | 37 ++++++++++-- .../incremental/hashes/call_expressions.rs | 16 +++--- .../incremental/hashes/closure_expressions.rs | 8 +-- .../incremental/hashes/enum_constructors.rs | 28 +++++----- .../incremental/hashes/exported_vs_not.rs | 6 +- src/test/incremental/hashes/for_loops.rs | 16 +++--- .../incremental/hashes/function_interfaces.rs | 16 +++--- src/test/incremental/hashes/if_expressions.rs | 12 ++-- src/test/incremental/hashes/inherent_impls.rs | 22 ++++---- src/test/incremental/hashes/inline_asm.rs | 12 ++-- .../incremental/hashes/let_expressions.rs | 24 ++++---- .../incremental/hashes/loop_expressions.rs | 10 ++-- .../incremental/hashes/match_expressions.rs | 26 ++++----- src/test/incremental/hashes/panic_exprs.rs | 18 +++--- .../incremental/hashes/struct_constructors.rs | 16 +++--- .../hashes/unary_and_binary_exprs.rs | 56 +++++++++---------- .../incremental/hashes/while_let_loops.rs | 12 ++-- src/test/incremental/hashes/while_loops.rs | 12 ++-- .../incremental/spans_significant_w_panic.rs | 2 +- src/test/incremental/string_constant.rs | 6 +- 28 files changed, 241 insertions(+), 235 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d32d07569e42c..12fbd2f69f13c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2811,6 +2811,7 @@ dependencies = [ name = "rustc_macros" version = "0.1.0" dependencies = [ + "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.22 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 43e865ad08941..ab9c9b247189a 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -461,11 +461,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> // Represents the MIR for a fn; also used as the task node for // things read/modify that MIR. - [] MirConstQualif(DefId), - [] MirBuilt(DefId), - [] MirConst(DefId), - [] MirValidated(DefId), - [] MirOptimized(DefId), [] MirShim { instance_def: InstanceDef<'tcx> }, [] BorrowCheckKrate, @@ -485,7 +480,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [] CollectModItemTypes(DefId), [] Reachability, - [] MirKeys, [eval_always] CrateVariances, // Nodes representing bits of computed IR in the tcx. Each shared diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index ecc0089860002..b99bffd3bd3ba 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -63,4 +63,47 @@ rustc_queries! { desc { "checking if the crate is_panic_runtime" } } } + + Codegen { + /// Set of all the `DefId`s in this crate that have MIR associated with + /// them. This includes all the body owners, but also things like struct + /// constructors. + query mir_keys(_: CrateNum) -> Lrc { + desc { "getting a list of all mir_keys" } + } + + /// Maps DefId's that have an associated Mir to the result + /// of the MIR qualify_consts pass. The actual meaning of + /// the value isn't known except to the pass itself. + query mir_const_qualif(key: DefId) -> (u8, Lrc>) { + cache { key.is_local() } + } + + /// Fetch the MIR for a given `DefId` right after it's built - this includes + /// unreachable code. + query mir_built(_: DefId) -> &'tcx Steal> {} + + /// Fetch the MIR for a given `DefId` up till the point where it is + /// ready for const evaluation. + /// + /// See the README for the `mir` module for details. + query mir_const(_: DefId) -> &'tcx Steal> { + no_hash + } + + query mir_validated(_: DefId) -> &'tcx Steal> { + no_hash + } + + /// MIR after our optimization passes have run. This is MIR that is ready + /// for codegen. This is also the only query that can fetch non-local MIR, at present. + query optimized_mir(key: DefId) -> &'tcx mir::Mir<'tcx> { + cache { key.is_local() } + load_cached(tcx, id) { + let mir: Option> = tcx.queries.on_disk_cache + .try_load_query_result(tcx, id); + mir.map(|x| tcx.alloc_mir(x)) + } + } + } } diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index d8159f11acec0..4e07f400f82d2 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -431,12 +431,6 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval_raw<'tcx> { } } -impl<'tcx> QueryDescription<'tcx> for queries::mir_keys<'tcx> { - fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { - "getting a list of all mir_keys".into() - } -} - impl<'tcx> QueryDescription<'tcx> for queries::symbol_name<'tcx> { fn describe(_tcx: TyCtxt<'_, '_, '_>, instance: ty::Instance<'tcx>) -> Cow<'static, str> { format!("computing the symbol for `{}`", instance).into() @@ -898,21 +892,6 @@ impl<'tcx> QueryDescription<'tcx> for queries::typeck_tables_of<'tcx> { } } -impl<'tcx> QueryDescription<'tcx> for queries::optimized_mir<'tcx> { - #[inline] - fn cache_on_disk(_: TyCtxt<'_, 'tcx, 'tcx>, def_id: Self::Key) -> bool { - def_id.is_local() - } - - fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - id: SerializedDepNodeIndex) - -> Option { - let mir: Option> = tcx.queries.on_disk_cache - .try_load_query_result(tcx, id); - mir.map(|x| tcx.alloc_mir(x)) - } -} - impl<'tcx> QueryDescription<'tcx> for queries::substitute_normalize_and_test_predicates<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, key: (DefId, SubstsRef<'tcx>)) -> Cow<'static, str> { format!("testing substituted normalized predicates:`{}`", tcx.def_path_str(key.0)).into() @@ -997,7 +976,6 @@ impl_disk_cacheable_query!(mir_borrowck, |tcx, def_id| { impl_disk_cacheable_query!(unsafety_check_result, |_, def_id| def_id.is_local()); impl_disk_cacheable_query!(borrowck, |_, def_id| def_id.is_local()); -impl_disk_cacheable_query!(mir_const_qualif, |_, def_id| def_id.is_local()); impl_disk_cacheable_query!(check_match, |_, def_id| def_id.is_local()); impl_disk_cacheable_query!(def_symbol_name, |_, _| true); impl_disk_cacheable_query!(predicates_of, |_, def_id| def_id.is_local()); diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 2f085a973d202..1038401244f2c 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -205,34 +205,6 @@ rustc_query_append! { [define_queries!][ <'tcx> [] fn inherent_impls: InherentImpls(DefId) -> Lrc>, }, - Codegen { - /// Set of all the `DefId`s in this crate that have MIR associated with - /// them. This includes all the body owners, but also things like struct - /// constructors. - [] fn mir_keys: mir_keys(CrateNum) -> Lrc, - - /// Maps DefId's that have an associated Mir to the result - /// of the MIR qualify_consts pass. The actual meaning of - /// the value isn't known except to the pass itself. - [] fn mir_const_qualif: MirConstQualif(DefId) -> (u8, Lrc>), - - /// Fetch the MIR for a given `DefId` right after it's built - this includes - /// unreachable code. - [] fn mir_built: MirBuilt(DefId) -> &'tcx Steal>, - - /// Fetch the MIR for a given `DefId` up till the point where it is - /// ready for const evaluation. - /// - /// See the README for the `mir` module for details. - [no_hash] fn mir_const: MirConst(DefId) -> &'tcx Steal>, - - [no_hash] fn mir_validated: MirValidated(DefId) -> &'tcx Steal>, - - /// MIR after our optimization passes have run. This is MIR that is ready - /// for codegen. This is also the only query that can fetch non-local MIR, at present. - [] fn optimized_mir: MirOptimized(DefId) -> &'tcx mir::Mir<'tcx>, - }, - TypeChecking { /// The result of unsafety-checking this `DefId`. [] fn unsafety_check_result: UnsafetyCheckResult(DefId) -> mir::UnsafetyCheckResult, @@ -796,10 +768,6 @@ fn const_eval_raw_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, GlobalId<'tcx> DepConstructor::ConstEvalRaw { param_env } } -fn mir_keys<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { - DepConstructor::MirKeys -} - fn crate_variances<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { DepConstructor::CrateVariances } diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index e82e09c299765..9b4341e63552f 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1262,11 +1262,6 @@ pub fn force_from_dep_node<'tcx>( }, DepKind::PrivacyAccessLevels => { force!(privacy_access_levels, LOCAL_CRATE); } DepKind::CheckPrivateInPublic => { force!(check_private_in_public, LOCAL_CRATE); } - DepKind::MirBuilt => { force!(mir_built, def_id!()); } - DepKind::MirConstQualif => { force!(mir_const_qualif, def_id!()); } - DepKind::MirConst => { force!(mir_const, def_id!()); } - DepKind::MirValidated => { force!(mir_validated, def_id!()); } - DepKind::MirOptimized => { force!(optimized_mir, def_id!()); } DepKind::BorrowCheck => { force!(borrowck, def_id!()); } DepKind::MirBorrowCheck => { force!(mir_borrowck, def_id!()); } @@ -1282,7 +1277,6 @@ pub fn force_from_dep_node<'tcx>( DepKind::CheckModImplWf => { force!(check_mod_impl_wf, def_id!()); } DepKind::CollectModItemTypes => { force!(collect_mod_item_types, def_id!()); } DepKind::Reachability => { force!(reachable_set, LOCAL_CRATE); } - DepKind::MirKeys => { force!(mir_keys, LOCAL_CRATE); } DepKind::CrateVariances => { force!(crate_variances, LOCAL_CRATE); } DepKind::AssociatedItems => { force!(associated_item, def_id!()); } DepKind::PredicatesDefinedOnItem => { force!(predicates_defined_on, def_id!()); } @@ -1491,11 +1485,11 @@ macro_rules! impl_load_from_cache { impl_load_from_cache!( TypeckTables => typeck_tables_of, - MirOptimized => optimized_mir, + optimized_mir => optimized_mir, UnsafetyCheckResult => unsafety_check_result, BorrowCheck => borrowck, MirBorrowCheck => mir_borrowck, - MirConstQualif => mir_const_qualif, + mir_const_qualif => mir_const_qualif, SymbolName => def_symbol_name, ConstIsRvaluePromotableToStatic => const_is_rvalue_promotable_to_static, CheckMatch => check_match, diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index 6b5e19ca49b76..ac76ed8cb93cf 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -66,11 +66,11 @@ const BASE_IMPL: &[&str] = &[ label_strs::ImplTraitRef, ]; -/// DepNodes for MirBuilt/Optimized, which is relevant in "executable" +/// DepNodes for mir_built/Optimized, which is relevant in "executable" /// code, i.e., functions+methods const BASE_MIR: &[&str] = &[ - label_strs::MirOptimized, - label_strs::MirBuilt, + label_strs::optimized_mir, + label_strs::mir_built, ]; /// Struct, Enum and Union DepNodes diff --git a/src/librustc_macros/Cargo.toml b/src/librustc_macros/Cargo.toml index 2fe51a22fb484..6e32a53c364a6 100644 --- a/src/librustc_macros/Cargo.toml +++ b/src/librustc_macros/Cargo.toml @@ -12,3 +12,4 @@ synstructure = "0.10.1" syn = { version = "0.15.22", features = ["full"] } proc-macro2 = "0.4.24" quote = "0.6.10" +itertools = "0.8" diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs index 3849e47d40365..c7d164d329788 100644 --- a/src/librustc_macros/src/query.rs +++ b/src/librustc_macros/src/query.rs @@ -8,6 +8,7 @@ use syn::parse::{Result, Parse, ParseStream}; use syn::punctuated::Punctuated; use syn; use quote::quote; +use itertools::Itertools; #[allow(non_camel_case_types)] mod kw { @@ -41,6 +42,9 @@ enum QueryModifier { /// A cycle error for this query aborting the compilation with a fatal error. FatalCycle, + + /// Don't hash the result, instead just mark a query red if it runs + NoHash, } impl Parse for QueryModifier { @@ -88,6 +92,8 @@ impl Parse for QueryModifier { Ok(QueryModifier::LoadCached(tcx, id, block)) } else if modifier == "fatal_cycle" { Ok(QueryModifier::FatalCycle) + } else if modifier == "no_hash" { + Ok(QueryModifier::NoHash) } else { Err(Error::new(modifier.span(), "unknown query modifier")) } @@ -185,6 +191,9 @@ struct QueryModifiers { /// A cycle error for this query aborting the compilation with a fatal error. fatal_cycle: bool, + + /// Don't hash the result, instead just mark a query red if it runs + no_hash: bool, } /// Process query modifiers into a struct, erroring on duplicates @@ -193,6 +202,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { let mut cache = None; let mut desc = None; let mut fatal_cycle = false; + let mut no_hash = false; for modifier in query.modifiers.0.drain(..) { match modifier { QueryModifier::LoadCached(tcx, id, block) => { @@ -219,6 +229,12 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { } fatal_cycle = true; } + QueryModifier::NoHash => { + if no_hash { + panic!("duplicate modifier `no_hash` for query `{}`", query.name); + } + no_hash = true; + } } } QueryModifiers { @@ -226,6 +242,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { cache, desc, fatal_cycle, + no_hash, } } @@ -325,16 +342,26 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { _ => quote! { #result_full }, }; + let mut attributes = Vec::new(); + // Pass on the fatal_cycle modifier - let fatal_cycle = if modifiers.fatal_cycle { - quote! { fatal_cycle } - } else { - quote! {} + if modifiers.fatal_cycle { + attributes.push(quote! { fatal_cycle }); + }; + // Pass on the no_hash modifier + if modifiers.no_hash { + attributes.push(quote! { no_hash }); }; + let mut attribute_stream = quote! {}; + + for e in attributes.into_iter().intersperse(quote! {,}) { + attribute_stream.extend(e); + } + // Add the query to the group group_stream.extend(quote! { - [#fatal_cycle] fn #name: #name(#arg) #result, + [#attribute_stream] fn #name: #name(#arg) #result, }); add_query_description_impl(&query, modifiers, &mut query_description_stream); diff --git a/src/test/incremental/hashes/call_expressions.rs b/src/test/incremental/hashes/call_expressions.rs index f0f1f09a8388b..05cc945bbaf00 100644 --- a/src/test/incremental/hashes/call_expressions.rs +++ b/src/test/incremental/hashes/call_expressions.rs @@ -25,7 +25,7 @@ pub fn change_callee_function() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_callee_function() { callee2(1, 2) @@ -40,7 +40,7 @@ pub fn change_argument_function() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_argument_function() { callee1(1, 3) @@ -81,7 +81,7 @@ pub fn change_callee_method() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_callee_method() { let s = Struct; @@ -98,7 +98,7 @@ pub fn change_argument_method() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_argument_method() { let s = Struct; @@ -115,7 +115,7 @@ pub fn change_ufcs_callee_method() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_ufcs_callee_method() { let s = Struct; @@ -132,7 +132,7 @@ pub fn change_argument_method_ufcs() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_argument_method_ufcs() { let s = Struct; @@ -149,7 +149,7 @@ pub fn change_to_ufcs() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] // One might think this would be expanded in the HirBody/Mir, but it actually // results in slightly different Hir/Mir. @@ -171,7 +171,7 @@ pub mod change_ufcs_callee_indirectly { #[cfg(not(cfail1))] use super::Struct2 as Struct; - #[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] + #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] diff --git a/src/test/incremental/hashes/closure_expressions.rs b/src/test/incremental/hashes/closure_expressions.rs index 4e82729aa3be1..b8e84173ec06c 100644 --- a/src/test/incremental/hashes/closure_expressions.rs +++ b/src/test/incremental/hashes/closure_expressions.rs @@ -37,7 +37,7 @@ pub fn add_parameter() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_parameter() { let x = 0u32; @@ -53,7 +53,7 @@ pub fn change_parameter_pattern() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_parameter_pattern() { let _ = |&x: &u32| x; @@ -84,7 +84,7 @@ pub fn add_type_ascription_to_parameter() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_type_ascription_to_parameter() { let closure = |x: u32| x + 1u32; @@ -101,7 +101,7 @@ pub fn change_parameter_type() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_parameter_type() { let closure = |x: u16| (x as u64) + 1; diff --git a/src/test/incremental/hashes/enum_constructors.rs b/src/test/incremental/hashes/enum_constructors.rs index a74c3ab04e2af..d3f96c9947b89 100644 --- a/src/test/incremental/hashes/enum_constructors.rs +++ b/src/test/incremental/hashes/enum_constructors.rs @@ -34,7 +34,7 @@ pub fn change_field_value_struct_like() -> Enum { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] +#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")] #[rustc_clean(cfg="cfail3")] pub fn change_field_value_struct_like() -> Enum { Enum::Struct { @@ -96,7 +96,7 @@ pub fn change_constructor_path_struct_like() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_path_struct_like() { let _ = Enum2::Struct { @@ -119,7 +119,7 @@ pub fn change_constructor_variant_struct_like() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] +#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_variant_struct_like() { let _ = Enum2::Struct2 { @@ -139,7 +139,7 @@ pub mod change_constructor_path_indirectly_struct_like { #[rustc_clean( cfg="cfail2", - except="FnSignature,Hir,HirBody,MirOptimized,MirBuilt,\ + except="FnSignature,Hir,HirBody,optimized_mir,mir_built,\ TypeckTables" )] #[rustc_clean(cfg="cfail3")] @@ -161,7 +161,7 @@ pub mod change_constructor_variant_indirectly_struct_like { #[cfg(not(cfail1))] use super::Enum2::Struct2 as Variant; - #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] + #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")] #[rustc_clean(cfg="cfail3")] pub fn function() -> Enum2 { Variant { @@ -180,7 +180,7 @@ pub fn change_field_value_tuple_like() -> Enum { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] +#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")] #[rustc_clean(cfg="cfail3")] pub fn change_field_value_tuple_like() -> Enum { Enum::Tuple(0, 1, 3) @@ -197,7 +197,7 @@ pub fn change_constructor_path_tuple_like() { #[cfg(not(cfail1))] #[rustc_clean( cfg="cfail2", - except="HirBody,MirOptimized,MirBuilt,TypeckTables" + except="HirBody,optimized_mir,mir_built,TypeckTables" )] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_path_tuple_like() { @@ -215,7 +215,7 @@ pub fn change_constructor_variant_tuple_like() { #[cfg(not(cfail1))] #[rustc_clean( cfg="cfail2", - except="HirBody,MirOptimized,MirBuilt,TypeckTables" + except="HirBody,optimized_mir,mir_built,TypeckTables" )] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_variant_tuple_like() { @@ -232,7 +232,7 @@ pub mod change_constructor_path_indirectly_tuple_like { #[rustc_clean( cfg="cfail2", - except="FnSignature,Hir,HirBody,MirOptimized,MirBuilt,\ + except="FnSignature,Hir,HirBody,optimized_mir,mir_built,\ TypeckTables" )] #[rustc_clean(cfg="cfail3")] @@ -251,7 +251,7 @@ pub mod change_constructor_variant_indirectly_tuple_like { #[cfg(not(cfail1))] use super::Enum2::Tuple2 as Variant; - #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] + #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn function() -> Enum2 { Variant(0, 1, 2) @@ -278,7 +278,7 @@ pub fn change_constructor_path_c_like() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_path_c_like() { let _ = Clike2::B; @@ -293,7 +293,7 @@ pub fn change_constructor_variant_c_like() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] +#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_variant_c_like() { let _ = Clike::C; @@ -309,7 +309,7 @@ pub mod change_constructor_path_indirectly_c_like { #[rustc_clean( cfg="cfail2", - except="FnSignature,Hir,HirBody,MirOptimized,MirBuilt,\ + except="FnSignature,Hir,HirBody,optimized_mir,mir_built,\ TypeckTables" )] #[rustc_clean(cfg="cfail3")] @@ -328,7 +328,7 @@ pub mod change_constructor_variant_indirectly_c_like { #[cfg(not(cfail1))] use super::Clike::B as Variant; - #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] + #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")] #[rustc_clean(cfg="cfail3")] pub fn function() -> Clike { Variant diff --git a/src/test/incremental/hashes/exported_vs_not.rs b/src/test/incremental/hashes/exported_vs_not.rs index c9f844f96ebd7..dc919abc02d44 100644 --- a/src/test/incremental/hashes/exported_vs_not.rs +++ b/src/test/incremental/hashes/exported_vs_not.rs @@ -16,7 +16,7 @@ pub fn body_not_exported_to_metadata() -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn body_not_exported_to_metadata() -> u32 { 2 @@ -35,7 +35,7 @@ pub fn body_exported_to_metadata_because_of_inline() -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] #[inline] pub fn body_exported_to_metadata_because_of_inline() -> u32 { @@ -55,7 +55,7 @@ pub fn body_exported_to_metadata_because_of_generic() -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] #[inline] pub fn body_exported_to_metadata_because_of_generic() -> u32 { diff --git a/src/test/incremental/hashes/for_loops.rs b/src/test/incremental/hashes/for_loops.rs index da093ded63566..91abca3312bc2 100644 --- a/src/test/incremental/hashes/for_loops.rs +++ b/src/test/incremental/hashes/for_loops.rs @@ -25,7 +25,7 @@ pub fn change_loop_body() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_loop_body() { let mut _x = 0; @@ -48,7 +48,7 @@ pub fn change_iteration_variable_name() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_iteration_variable_name() { let mut _x = 0; @@ -71,7 +71,7 @@ pub fn change_iteration_variable_pattern() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_iteration_variable_pattern() { let mut _x = 0; @@ -94,7 +94,7 @@ pub fn change_iterable() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_iterable() { let mut _x = 0; @@ -116,7 +116,7 @@ pub fn add_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_break() { let mut _x = 0; @@ -187,7 +187,7 @@ pub fn change_break_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_break_label() { let mut _x = 0; @@ -237,7 +237,7 @@ pub fn change_continue_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_label() { let mut _x = 0; @@ -262,7 +262,7 @@ pub fn change_continue_to_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_to_break() { let mut _x = 0; diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs index fccec704d6356..db8fa9ced113c 100644 --- a/src/test/incremental/hashes/function_interfaces.rs +++ b/src/test/incremental/hashes/function_interfaces.rs @@ -24,7 +24,7 @@ pub fn add_parameter() {} #[cfg(not(cfail1))] #[rustc_clean(cfg = "cfail2", - except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")] + except = "Hir, HirBody, mir_built, optimized_mir, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub fn add_parameter(p: i32) {} @@ -47,7 +47,7 @@ pub fn type_of_parameter(p: i32) {} #[cfg(not(cfail1))] #[rustc_clean(cfg = "cfail2", - except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")] + except = "Hir, HirBody, mir_built, optimized_mir, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub fn type_of_parameter(p: i64) {} @@ -59,7 +59,7 @@ pub fn type_of_parameter_ref(p: &i32) {} #[cfg(not(cfail1))] #[rustc_clean(cfg = "cfail2", - except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")] + except = "Hir, HirBody, mir_built, optimized_mir, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub fn type_of_parameter_ref(p: &mut i32) {} @@ -71,7 +71,7 @@ pub fn order_of_parameters(p1: i32, p2: i64) {} #[cfg(not(cfail1))] #[rustc_clean(cfg = "cfail2", - except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")] + except = "Hir, HirBody, mir_built, optimized_mir, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub fn order_of_parameters(p2: i64, p1: i32) {} @@ -83,7 +83,7 @@ pub fn make_unsafe() {} #[cfg(not(cfail1))] #[rustc_clean(cfg = "cfail2", - except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")] + except = "Hir, HirBody, mir_built, optimized_mir, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub unsafe fn make_unsafe() {} @@ -94,7 +94,7 @@ pub unsafe fn make_unsafe() {} pub fn make_extern() {} #[cfg(not(cfail1))] -#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, MirBuilt, TypeckTables, FnSignature")] +#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, mir_built, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub extern "C" fn make_extern() {} @@ -292,7 +292,7 @@ pub mod change_return_type_indirectly { use super::ReferencedType2 as ReturnType; #[rustc_clean(cfg = "cfail2", - except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")] + except = "Hir, HirBody, mir_built, optimized_mir, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub fn indirect_return_type() -> ReturnType { ReturnType {} @@ -309,7 +309,7 @@ pub mod change_parameter_type_indirectly { use super::ReferencedType2 as ParameterType; #[rustc_clean(cfg = "cfail2", - except = "Hir, HirBody, MirBuilt, MirOptimized, TypeckTables, FnSignature")] + except = "Hir, HirBody, mir_built, optimized_mir, TypeckTables, FnSignature")] #[rustc_clean(cfg = "cfail3")] pub fn indirect_parameter_type(p: ParameterType) {} } diff --git a/src/test/incremental/hashes/if_expressions.rs b/src/test/incremental/hashes/if_expressions.rs index a01247ff4243c..32a0c8b6b7e79 100644 --- a/src/test/incremental/hashes/if_expressions.rs +++ b/src/test/incremental/hashes/if_expressions.rs @@ -25,7 +25,7 @@ pub fn change_condition(x: bool) -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_condition(x: bool) -> u32 { if !x { @@ -46,7 +46,7 @@ pub fn change_then_branch(x: bool) -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_then_branch(x: bool) -> u32 { if x { @@ -69,7 +69,7 @@ pub fn change_else_branch(x: bool) -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_else_branch(x: bool) -> u32 { if x { @@ -120,7 +120,7 @@ pub fn change_condition_if_let(x: Option) -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_condition_if_let(x: Option) -> u32 { if let Some(_) = x { @@ -143,7 +143,7 @@ pub fn change_then_branch_if_let(x: Option) -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_then_branch_if_let(x: Option) -> u32 { if let Some(x) = x { @@ -166,7 +166,7 @@ pub fn change_else_branch_if_let(x: Option) -> u32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_else_branch_if_let(x: Option) -> u32 { if let Some(x) = x { diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs index ebafd07dbef57..1b6b41ce05b78 100644 --- a/src/test/incremental/hashes/inherent_impls.rs +++ b/src/test/incremental/hashes/inherent_impls.rs @@ -42,7 +42,7 @@ impl Foo { #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] impl Foo { - #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] + #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn method_body() { println!("Hello, world!"); @@ -63,7 +63,7 @@ impl Foo { #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] impl Foo { - #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] + #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")] #[rustc_clean(cfg="cfail3")] #[inline] pub fn method_body_inlined() { @@ -114,7 +114,7 @@ impl Foo { impl Foo { #[rustc_clean( cfg="cfail2", - except="Hir,HirBody,FnSignature,TypeckTables,MirOptimized,MirBuilt" + except="Hir,HirBody,FnSignature,TypeckTables,optimized_mir,mir_built" )] #[rustc_clean(cfg="cfail3")] pub fn method_selfmutness(&mut self) { } @@ -154,7 +154,7 @@ impl Foo { impl Foo { #[rustc_clean( cfg="cfail2", - except="Hir,HirBody,FnSignature,TypeckTables,MirOptimized,MirBuilt" + except="Hir,HirBody,FnSignature,TypeckTables,optimized_mir,mir_built" )] #[rustc_clean(cfg="cfail3")] pub fn add_method_parameter(&self, _: i32) { } @@ -172,7 +172,7 @@ impl Foo { #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] impl Foo { - #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] + #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")] #[rustc_clean(cfg="cfail3")] pub fn change_method_parameter_name(&self, b: i64) { } } @@ -191,7 +191,7 @@ impl Foo { impl Foo { #[rustc_clean( cfg="cfail2", - except="Hir,HirBody,FnSignature,MirOptimized,MirBuilt,TypeckTables")] + except="Hir,HirBody,FnSignature,optimized_mir,mir_built,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_method_return_type(&self) -> u8 { 0 } } @@ -226,7 +226,7 @@ impl Foo { #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] impl Foo { - #[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] + #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")] #[rustc_clean(cfg="cfail3")] pub fn change_method_parameter_order(&self, b: i64, a: i64) { } } @@ -245,7 +245,7 @@ impl Foo { impl Foo { #[rustc_clean( cfg="cfail2", - except="Hir,HirBody,FnSignature,TypeckTables,MirOptimized,MirBuilt" + except="Hir,HirBody,FnSignature,TypeckTables,optimized_mir,mir_built" )] #[rustc_clean(cfg="cfail3")] pub unsafe fn make_method_unsafe(&self) { } @@ -263,7 +263,7 @@ impl Foo { #[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] impl Foo { - #[rustc_clean(cfg="cfail2", except="Hir,HirBody,MirBuilt,FnSignature,TypeckTables")] + #[rustc_clean(cfg="cfail2", except="Hir,HirBody,mir_built,FnSignature,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub extern fn make_method_extern(&self) { } } @@ -447,7 +447,7 @@ impl Bar { impl Bar { #[rustc_clean( cfg="cfail2", - except="generics_of,FnSignature,TypeckTables,type_of,MirOptimized,MirBuilt" + except="generics_of,FnSignature,TypeckTables,type_of,optimized_mir,mir_built" )] #[rustc_clean(cfg="cfail3")] pub fn add_type_parameter_to_impl(&self) { } @@ -465,7 +465,7 @@ impl Bar { #[rustc_clean(cfg="cfail2", except="Hir,HirBody")] #[rustc_clean(cfg="cfail3")] impl Bar { - #[rustc_clean(cfg="cfail2", except="FnSignature,MirOptimized,MirBuilt,TypeckTables")] + #[rustc_clean(cfg="cfail2", except="FnSignature,optimized_mir,mir_built,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_impl_self_type(&self) { } } diff --git a/src/test/incremental/hashes/inline_asm.rs b/src/test/incremental/hashes/inline_asm.rs index c5e7f525fd0fb..53e77a370a334 100644 --- a/src/test/incremental/hashes/inline_asm.rs +++ b/src/test/incremental/hashes/inline_asm.rs @@ -33,7 +33,7 @@ pub fn change_template(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_template(a: i32) -> i32 { @@ -69,7 +69,7 @@ pub fn change_output(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_output(a: i32) -> i32 { @@ -105,7 +105,7 @@ pub fn change_input(_a: i32, _b: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_input(_a: i32, _b: i32) -> i32 { @@ -140,7 +140,7 @@ pub fn change_input_constraint(_a: i32, _b: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_input_constraint(_a: i32, _b: i32) -> i32 { @@ -175,7 +175,7 @@ pub fn change_clobber(_a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_clobber(_a: i32) -> i32 { @@ -210,7 +210,7 @@ pub fn change_options(_a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_options(_a: i32) -> i32 { diff --git a/src/test/incremental/hashes/let_expressions.rs b/src/test/incremental/hashes/let_expressions.rs index a2b33fecea865..76be2ccbf608c 100644 --- a/src/test/incremental/hashes/let_expressions.rs +++ b/src/test/incremental/hashes/let_expressions.rs @@ -22,7 +22,7 @@ pub fn change_name() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirBuilt,MirOptimized")] + except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_name() { let _y = 2u64; @@ -38,7 +38,7 @@ pub fn add_type() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirBuilt,MirOptimized")] + except="HirBody,TypeckTables,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn add_type() { let _x: u32 = 2u32; @@ -54,7 +54,7 @@ pub fn change_type() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirBuilt,MirOptimized")] + except="HirBody,TypeckTables,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_type() { let _x: u8 = 2; @@ -70,7 +70,7 @@ pub fn change_mutability_of_reference_type() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirBuilt,MirOptimized")] + except="HirBody,TypeckTables,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_mutability_of_reference_type() { let _x: &mut u64; @@ -86,7 +86,7 @@ pub fn change_mutability_of_slot() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirBuilt,MirOptimized")] + except="HirBody,TypeckTables,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_mutability_of_slot() { let _x: u64 = 0; @@ -102,7 +102,7 @@ pub fn change_simple_binding_to_pattern() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirBuilt,MirOptimized")] + except="HirBody,TypeckTables,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_simple_binding_to_pattern() { let (_a, _b) = (0u8, 'x'); @@ -118,7 +118,7 @@ pub fn change_name_in_pattern() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirBuilt,MirOptimized")] + except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_name_in_pattern() { let (_a, _c) = (1u8, 'y'); @@ -134,7 +134,7 @@ pub fn add_ref_in_pattern() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirBuilt,MirOptimized")] + except="HirBody,TypeckTables,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn add_ref_in_pattern() { let (ref _a, _b) = (1u8, 'y'); @@ -150,7 +150,7 @@ pub fn add_amp_in_pattern() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirBuilt,MirOptimized")] + except="HirBody,TypeckTables,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn add_amp_in_pattern() { let (&_a, _b) = (&1u8, 'y'); @@ -166,7 +166,7 @@ pub fn change_mutability_of_binding_in_pattern() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirBuilt,MirOptimized")] + except="HirBody,TypeckTables,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_mutability_of_binding_in_pattern() { let (mut _a, _b) = (99u8, 'q'); @@ -182,7 +182,7 @@ pub fn add_initializer() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,TypeckTables,MirBuilt,MirOptimized")] + except="HirBody,TypeckTables,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn add_initializer() { let _x: i16 = 3i16; @@ -198,7 +198,7 @@ pub fn change_initializer() { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirBuilt,MirOptimized")] + except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_initializer() { let _x = 5u16; diff --git a/src/test/incremental/hashes/loop_expressions.rs b/src/test/incremental/hashes/loop_expressions.rs index a48d150b8b0f2..63cf1e9d5e826 100644 --- a/src/test/incremental/hashes/loop_expressions.rs +++ b/src/test/incremental/hashes/loop_expressions.rs @@ -25,7 +25,7 @@ pub fn change_loop_body() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_loop_body() { let mut _x = 0; @@ -47,7 +47,7 @@ pub fn add_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_break() { let mut _x = 0; @@ -118,7 +118,7 @@ pub fn change_break_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_break_label() { let mut _x = 0; @@ -168,7 +168,7 @@ pub fn change_continue_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_label() { let mut _x = 0; @@ -193,7 +193,7 @@ pub fn change_continue_to_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_to_break() { let mut _x = 0; diff --git a/src/test/incremental/hashes/match_expressions.rs b/src/test/incremental/hashes/match_expressions.rs index 11fe84d88e9b3..37f6aa9ee9bdc 100644 --- a/src/test/incremental/hashes/match_expressions.rs +++ b/src/test/incremental/hashes/match_expressions.rs @@ -26,7 +26,7 @@ pub fn add_arm(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirBuilt,MirOptimized,TypeckTables")] + except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_arm(x: u32) -> u32 { match x { @@ -51,7 +51,7 @@ pub fn change_order_of_arms(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirBuilt,MirOptimized")] + except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_order_of_arms(x: u32) -> u32 { match x { @@ -75,7 +75,7 @@ pub fn add_guard_clause(x: u32, y: bool) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirBuilt,MirOptimized,TypeckTables")] + except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_guard_clause(x: u32, y: bool) -> u32 { match x { @@ -99,7 +99,7 @@ pub fn change_guard_clause(x: u32, y: bool) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirBuilt,MirOptimized,TypeckTables")] + except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_guard_clause(x: u32, y: bool) -> u32 { match x { @@ -123,7 +123,7 @@ pub fn add_at_binding(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirBuilt,MirOptimized,TypeckTables")] + except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_at_binding(x: u32) -> u32 { match x { @@ -147,7 +147,7 @@ pub fn change_name_of_at_binding(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirBuilt,MirOptimized")] + except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_name_of_at_binding(x: u32) -> u32 { match x { @@ -170,7 +170,7 @@ pub fn change_simple_name_to_pattern(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirBuilt,MirOptimized,TypeckTables")] + except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_simple_name_to_pattern(x: u32) -> u32 { match (x, x & 1) { @@ -193,7 +193,7 @@ pub fn change_name_in_pattern(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirBuilt,MirOptimized")] + except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_name_in_pattern(x: u32) -> u32 { match (x, x & 1) { @@ -216,7 +216,7 @@ pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirBuilt,MirOptimized,TypeckTables")] + except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_mutability_of_binding_in_pattern(x: u32) -> u32 { match (x, x & 1) { @@ -238,7 +238,7 @@ pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirBuilt,MirOptimized,TypeckTables")] + except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_ref_to_binding_in_pattern(x: u32) -> u32 { match (x, x & 1) { @@ -260,7 +260,7 @@ pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", -except="HirBody,MirBuilt,MirOptimized,TypeckTables")] +except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_amp_to_binding_in_pattern(x: u32) -> u32 { match (&x, x & 1) { @@ -283,7 +283,7 @@ pub fn change_rhs_of_arm(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirBuilt,MirOptimized")] + except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_rhs_of_arm(x: u32) -> u32 { match x { @@ -307,7 +307,7 @@ pub fn add_alternative_to_arm(x: u32) -> u32 { #[cfg(not(cfail1))] #[rustc_clean(cfg="cfail2", - except="HirBody,MirBuilt,MirOptimized,TypeckTables")] + except="HirBody,mir_built,optimized_mir,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_alternative_to_arm(x: u32) -> u32 { match x { diff --git a/src/test/incremental/hashes/panic_exprs.rs b/src/test/incremental/hashes/panic_exprs.rs index 9a3c93147a098..0803f4e01d63b 100644 --- a/src/test/incremental/hashes/panic_exprs.rs +++ b/src/test/incremental/hashes/panic_exprs.rs @@ -18,7 +18,7 @@ // Indexing expression --------------------------------------------------------- -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn indexing(slice: &[u8]) -> u8 { #[cfg(cfail1)] @@ -33,7 +33,7 @@ pub fn indexing(slice: &[u8]) -> u8 { // Arithmetic overflow plus ---------------------------------------------------- -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn arithmetic_overflow_plus(val: i32) -> i32 { #[cfg(cfail1)] @@ -48,7 +48,7 @@ pub fn arithmetic_overflow_plus(val: i32) -> i32 { // Arithmetic overflow minus ---------------------------------------------------- -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn arithmetic_overflow_minus(val: i32) -> i32 { #[cfg(cfail1)] @@ -63,7 +63,7 @@ pub fn arithmetic_overflow_minus(val: i32) -> i32 { // Arithmetic overflow mult ---------------------------------------------------- -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn arithmetic_overflow_mult(val: i32) -> i32 { #[cfg(cfail1)] @@ -78,7 +78,7 @@ pub fn arithmetic_overflow_mult(val: i32) -> i32 { // Arithmetic overflow negation ------------------------------------------------ -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn arithmetic_overflow_negation(val: i32) -> i32 { #[cfg(cfail1)] @@ -93,7 +93,7 @@ pub fn arithmetic_overflow_negation(val: i32) -> i32 { // Division by zero ------------------------------------------------------------ -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn division_by_zero(val: i32) -> i32 { #[cfg(cfail1)] @@ -107,7 +107,7 @@ pub fn division_by_zero(val: i32) -> i32 { } // Division by zero ------------------------------------------------------------ -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn mod_by_zero(val: i32) -> i32 { #[cfg(cfail1)] @@ -122,7 +122,7 @@ pub fn mod_by_zero(val: i32) -> i32 { // shift left ------------------------------------------------------------------ -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn shift_left(val: i32, shift: usize) -> i32 { #[cfg(cfail1)] @@ -137,7 +137,7 @@ pub fn shift_left(val: i32, shift: usize) -> i32 { // shift right ------------------------------------------------------------------ -#[rustc_clean(cfg="cfail2", except="HirBody,MirBuilt,MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn shift_right(val: i32, shift: usize) -> i32 { #[cfg(cfail1)] diff --git a/src/test/incremental/hashes/struct_constructors.rs b/src/test/incremental/hashes/struct_constructors.rs index a42fda3188520..3190f65a81731 100644 --- a/src/test/incremental/hashes/struct_constructors.rs +++ b/src/test/incremental/hashes/struct_constructors.rs @@ -31,7 +31,7 @@ pub fn change_field_value_regular_struct() -> RegularStruct { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] +#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")] #[rustc_clean(cfg="cfail3")] pub fn change_field_value_regular_struct() -> RegularStruct { RegularStruct { @@ -82,7 +82,7 @@ pub fn add_field_regular_struct() -> RegularStruct { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_field_regular_struct() -> RegularStruct { let struct1 = RegularStruct { @@ -117,7 +117,7 @@ pub fn change_field_label_regular_struct() -> RegularStruct { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_field_label_regular_struct() -> RegularStruct { let struct1 = RegularStruct { @@ -152,7 +152,7 @@ pub fn change_constructor_path_regular_struct() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_path_regular_struct() { let _ = RegularStruct2 { @@ -173,7 +173,7 @@ pub mod change_constructor_path_indirectly_regular_struct { #[rustc_clean( cfg="cfail2", - except="FnSignature,Hir,HirBody,MirOptimized,MirBuilt,TypeckTables" + except="FnSignature,Hir,HirBody,optimized_mir,mir_built,TypeckTables" )] #[rustc_clean(cfg="cfail3")] pub fn function() -> Struct { @@ -196,7 +196,7 @@ pub fn change_field_value_tuple_struct() -> TupleStruct { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt")] +#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built")] #[rustc_clean(cfg="cfail3")] pub fn change_field_value_tuple_struct() -> TupleStruct { TupleStruct(0, 1, 3) @@ -213,7 +213,7 @@ pub fn change_constructor_path_tuple_struct() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody,MirOptimized,MirBuilt,TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_constructor_path_tuple_struct() { let _ = TupleStruct2(0, 1, 2); @@ -230,7 +230,7 @@ pub mod change_constructor_path_indirectly_tuple_struct { #[rustc_clean( cfg="cfail2", - except="FnSignature,Hir,HirBody,MirOptimized,MirBuilt,TypeckTables" + except="FnSignature,Hir,HirBody,optimized_mir,mir_built,TypeckTables" )] #[rustc_clean(cfg="cfail3")] pub fn function() -> Struct { diff --git a/src/test/incremental/hashes/unary_and_binary_exprs.rs b/src/test/incremental/hashes/unary_and_binary_exprs.rs index ef8035a300a43..f3331ec61cb6a 100644 --- a/src/test/incremental/hashes/unary_and_binary_exprs.rs +++ b/src/test/incremental/hashes/unary_and_binary_exprs.rs @@ -21,7 +21,7 @@ pub fn const_negation() -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn const_negation() -> i32 { -1 @@ -36,7 +36,7 @@ pub fn const_bitwise_not() -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn const_bitwise_not() -> i32 { !99 @@ -51,7 +51,7 @@ pub fn var_negation(x: i32, y: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn var_negation(x: i32, y: i32) -> i32 { -y @@ -66,7 +66,7 @@ pub fn var_bitwise_not(x: i32, y: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn var_bitwise_not(x: i32, y: i32) -> i32 { !y @@ -81,7 +81,7 @@ pub fn var_deref(x: &i32, y: &i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt,TypeckTables", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built,TypeckTables", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn var_deref(x: &i32, y: &i32) -> i32 { *y @@ -96,7 +96,7 @@ pub fn first_const_add() -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn first_const_add() -> i32 { 2 + 3 @@ -111,7 +111,7 @@ pub fn second_const_add() -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn second_const_add() -> i32 { 1 + 3 @@ -126,7 +126,7 @@ pub fn first_var_add(a: i32, b: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn first_var_add(a: i32, b: i32) -> i32 { b + 2 @@ -141,7 +141,7 @@ pub fn second_var_add(a: i32, b: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn second_var_add(a: i32, b: i32) -> i32 { 1 + b @@ -156,7 +156,7 @@ pub fn plus_to_minus(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn plus_to_minus(a: i32) -> i32 { 1 - a @@ -171,7 +171,7 @@ pub fn plus_to_mult(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn plus_to_mult(a: i32) -> i32 { 1 * a @@ -186,7 +186,7 @@ pub fn plus_to_div(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn plus_to_div(a: i32) -> i32 { 1 / a @@ -201,7 +201,7 @@ pub fn plus_to_mod(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn plus_to_mod(a: i32) -> i32 { 1 % a @@ -216,7 +216,7 @@ pub fn and_to_or(a: bool, b: bool) -> bool { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn and_to_or(a: bool, b: bool) -> bool { a || b @@ -231,7 +231,7 @@ pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn bitwise_and_to_bitwise_or(a: i32) -> i32 { 1 | a @@ -246,7 +246,7 @@ pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn bitwise_and_to_bitwise_xor(a: i32) -> i32 { 1 ^ a @@ -261,7 +261,7 @@ pub fn bitwise_and_to_lshift(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn bitwise_and_to_lshift(a: i32) -> i32 { a << 1 @@ -276,7 +276,7 @@ pub fn bitwise_and_to_rshift(a: i32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn bitwise_and_to_rshift(a: i32) -> i32 { a >> 1 @@ -291,7 +291,7 @@ pub fn eq_to_uneq(a: i32) -> bool { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn eq_to_uneq(a: i32) -> bool { a != 1 @@ -306,7 +306,7 @@ pub fn eq_to_lt(a: i32) -> bool { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn eq_to_lt(a: i32) -> bool { a < 1 @@ -321,7 +321,7 @@ pub fn eq_to_gt(a: i32) -> bool { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn eq_to_gt(a: i32) -> bool { a > 1 @@ -336,7 +336,7 @@ pub fn eq_to_le(a: i32) -> bool { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn eq_to_le(a: i32) -> bool { a <= 1 @@ -351,7 +351,7 @@ pub fn eq_to_ge(a: i32) -> bool { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn eq_to_ge(a: i32) -> bool { a >= 1 @@ -368,7 +368,7 @@ pub fn type_cast(a: u8) -> u64 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt,TypeckTables", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built,TypeckTables", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn type_cast(a: u8) -> u64 { let b = a as u32; @@ -385,7 +385,7 @@ pub fn value_cast(a: u32) -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn value_cast(a: u32) -> i32 { 2 as i32 @@ -403,7 +403,7 @@ pub fn place() -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn place() -> i32 { let mut x = 10; @@ -423,7 +423,7 @@ pub fn rvalue() -> i32 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn rvalue() -> i32 { let mut x = 10; @@ -440,7 +440,7 @@ pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 { } #[cfg(not(cfail1))] -#[rustc_clean(except="HirBody,MirOptimized,MirBuilt", cfg="cfail2")] +#[rustc_clean(except="HirBody,optimized_mir,mir_built", cfg="cfail2")] #[rustc_clean(cfg="cfail3")] pub fn index_to_slice(s: &[u8], i: usize, j: usize) -> u8 { s[j] diff --git a/src/test/incremental/hashes/while_let_loops.rs b/src/test/incremental/hashes/while_let_loops.rs index c708d5b969df5..7e866ae925ed9 100644 --- a/src/test/incremental/hashes/while_let_loops.rs +++ b/src/test/incremental/hashes/while_let_loops.rs @@ -25,7 +25,7 @@ pub fn change_loop_body() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_loop_body() { let mut _x = 0; @@ -48,7 +48,7 @@ pub fn change_loop_condition() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_loop_condition() { let mut _x = 0; @@ -70,7 +70,7 @@ pub fn add_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_break() { let mut _x = 0; @@ -141,7 +141,7 @@ pub fn change_break_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_break_label() { let mut _x = 0; @@ -191,7 +191,7 @@ pub fn change_continue_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_label() { let mut _x = 0; @@ -216,7 +216,7 @@ pub fn change_continue_to_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_to_break() { let mut _x = 0; diff --git a/src/test/incremental/hashes/while_loops.rs b/src/test/incremental/hashes/while_loops.rs index c7b84a120c8df..cbd1341fdd4fb 100644 --- a/src/test/incremental/hashes/while_loops.rs +++ b/src/test/incremental/hashes/while_loops.rs @@ -25,7 +25,7 @@ pub fn change_loop_body() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_loop_body() { let mut _x = 0; @@ -48,7 +48,7 @@ pub fn change_loop_condition() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_loop_condition() { let mut _x = 0; @@ -70,7 +70,7 @@ pub fn add_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_break() { let mut _x = 0; @@ -141,7 +141,7 @@ pub fn change_break_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_break_label() { let mut _x = 0; @@ -191,7 +191,7 @@ pub fn change_continue_label() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_label() { let mut _x = 0; @@ -216,7 +216,7 @@ pub fn change_continue_to_break() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, MirBuilt, MirOptimized")] +#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn change_continue_to_break() { let mut _x = 0; diff --git a/src/test/incremental/spans_significant_w_panic.rs b/src/test/incremental/spans_significant_w_panic.rs index ecda56f7e942e..2574ef5199c86 100644 --- a/src/test/incremental/spans_significant_w_panic.rs +++ b/src/test/incremental/spans_significant_w_panic.rs @@ -13,7 +13,7 @@ pub fn main() { } #[cfg(rpass2)] -#[rustc_dirty(label="MirOptimized", cfg="rpass2")] +#[rustc_dirty(label="optimized_mir", cfg="rpass2")] pub fn main() { let _ = 0u8 + 1; } diff --git a/src/test/incremental/string_constant.rs b/src/test/incremental/string_constant.rs index 41c72335d6305..db2660bb66129 100644 --- a/src/test/incremental/string_constant.rs +++ b/src/test/incremental/string_constant.rs @@ -19,7 +19,7 @@ pub mod x { #[cfg(cfail2)] #[rustc_dirty(label="HirBody", cfg="cfail2")] - #[rustc_dirty(label="MirOptimized", cfg="cfail2")] + #[rustc_dirty(label="optimized_mir", cfg="cfail2")] pub fn x() { println!("{}", "2"); } @@ -29,7 +29,7 @@ pub mod y { use x; #[rustc_clean(label="TypeckTables", cfg="cfail2")] - #[rustc_clean(label="MirOptimized", cfg="cfail2")] + #[rustc_clean(label="optimized_mir", cfg="cfail2")] pub fn y() { x::x(); } @@ -39,7 +39,7 @@ pub mod z { use y; #[rustc_clean(label="TypeckTables", cfg="cfail2")] - #[rustc_clean(label="MirOptimized", cfg="cfail2")] + #[rustc_clean(label="optimized_mir", cfg="cfail2")] pub fn z() { y::y(); } From b440041a19d3f7f49ede32ae26e0e1de865cf041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 20 Mar 2019 16:34:30 +0100 Subject: [PATCH 09/38] Allow itertools --- src/tools/tidy/src/deps.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index d7683aae841cd..30fe327cac4ff 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -87,6 +87,7 @@ const WHITELIST: &[Crate<'_>] = &[ Crate("fuchsia-zircon-sys"), Crate("getopts"), Crate("humantime"), + Crate("itertools"), Crate("jobserver"), Crate("kernel32-sys"), Crate("lazy_static"), From d060e7df444923a015df58295fd1bc2a7150a807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 20 Mar 2019 16:53:55 +0100 Subject: [PATCH 10/38] Add no_force to query macro and move some queries over --- src/librustc/dep_graph/dep_node.rs | 4 --- src/librustc/query/mod.rs | 25 ++++++++++++- src/librustc/ty/query/config.rs | 26 +------------- src/librustc/ty/query/mod.rs | 16 --------- src/librustc/ty/query/plumbing.rs | 9 +---- src/librustc_macros/src/query.rs | 56 ++++++++++++++++++++++++------ 6 files changed, 71 insertions(+), 65 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index ab9c9b247189a..a4950c01162ee 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -538,7 +538,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [anon] TraitSelect, [] ParamEnv(DefId), - [] Environment(DefId), [] DescribeDef(DefId), // FIXME(mw): DefSpans are not really inputs since they are derived from @@ -661,9 +660,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [input] Features, - [] ProgramClausesFor(DefId), - [] ProgramClausesForEnv(traits::Environment<'tcx>), - [] WasmImportModuleMap(CrateNum), [] ForeignModules(CrateNum), [] UpstreamMonomorphizations(CrateNum), diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index b99bffd3bd3ba..361d812900232 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -2,8 +2,9 @@ use crate::ty::query::QueryDescription; use crate::ty::query::queries; use crate::ty::TyCtxt; use crate::ty; -use crate::hir::def_id::CrateNum; +use crate::hir::def_id::{DefId, CrateNum}; use crate::dep_graph::SerializedDepNodeIndex; +use crate::traits; use std::borrow::Cow; // Each of these queries corresponds to a function pointer field in the @@ -106,4 +107,26 @@ rustc_queries! { } } } + + TypeChecking { + query program_clauses_for(_: DefId) -> Clauses<'tcx> { + desc { "generating chalk-style clauses" } + } + + query program_clauses_for_env(_: traits::Environment<'tcx>) -> Clauses<'tcx> { + no_force + desc { "generating chalk-style clauses for environment" } + } + + // Get the chalk-style environment of the given item. + query environment(_: DefId) -> traits::Environment<'tcx> { + desc { "return a chalk-style environment" } + } + } + + Linking { + query wasm_import_module_map(_: CrateNum) -> Lrc> { + desc { "wasm import module map" } + } + } } diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 4e07f400f82d2..72fb649a9466f 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -916,33 +916,9 @@ impl<'tcx> QueryDescription<'tcx> for queries::instance_def_size_estimate<'tcx> } } -impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> { - "generating chalk-style clauses".into() - } -} - -impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for_env<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: traits::Environment<'tcx>) -> Cow<'static, str> { - "generating chalk-style clauses for environment".into() - } -} - -impl<'tcx> QueryDescription<'tcx> for queries::environment<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: DefId) -> Cow<'static, str> { - "return a chalk-style environment".into() - } -} - -impl<'tcx> QueryDescription<'tcx> for queries::wasm_import_module_map<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { - "wasm import module map".into() - } -} - impl<'tcx> QueryDescription<'tcx> for queries::dllimport_foreign_items<'tcx> { fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { - "wasm import module map".into() + "dllimport_foreign_items".into() } } diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 1038401244f2c..4cfddf08461f8 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -683,22 +683,6 @@ rustc_query_append! { [define_queries!][ <'tcx> [] fn features_query: features_node(CrateNum) -> Lrc, }, - - TypeChecking { - [] fn program_clauses_for: ProgramClausesFor(DefId) -> Clauses<'tcx>, - - [] fn program_clauses_for_env: ProgramClausesForEnv( - traits::Environment<'tcx> - ) -> Clauses<'tcx>, - - // Get the chalk-style environment of the given item. - [] fn environment: Environment(DefId) -> traits::Environment<'tcx>, - }, - - Linking { - [] fn wasm_import_module_map: WasmImportModuleMap(CrateNum) - -> Lrc>, - }, ]} ////////////////////////////////////////////////////////////////////// diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 9b4341e63552f..331f68c11d0ac 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1240,11 +1240,7 @@ pub fn force_from_dep_node<'tcx>( DepKind::TypeOpNormalizeFnSig | DepKind::SubstituteNormalizeAndTestPredicates | DepKind::MethodAutoderefSteps | - DepKind::InstanceDefSizeEstimate | - DepKind::ProgramClausesForEnv | - - // This one should never occur in this context - DepKind::Null => { + DepKind::InstanceDefSizeEstimate => { bug!("force_from_dep_node() - Encountered {:?}", dep_node) } @@ -1311,7 +1307,6 @@ pub fn force_from_dep_node<'tcx>( DepKind::CheckMatch => { force!(check_match, def_id!()); } DepKind::ParamEnv => { force!(param_env, def_id!()); } - DepKind::Environment => { force!(environment, def_id!()); } DepKind::DescribeDef => { force!(describe_def, def_id!()); } DepKind::DefSpan => { force!(def_span, def_id!()); } DepKind::LookupStability => { force!(lookup_stability, def_id!()); } @@ -1419,8 +1414,6 @@ pub fn force_from_dep_node<'tcx>( DepKind::Features => { force!(features_query, LOCAL_CRATE); } - DepKind::ProgramClausesFor => { force!(program_clauses_for, def_id!()); } - DepKind::WasmImportModuleMap => { force!(wasm_import_module_map, krate!()); } DepKind::ForeignModules => { force!(foreign_modules, krate!()); } DepKind::UpstreamMonomorphizations => { diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs index c7d164d329788..90bd46d035062 100644 --- a/src/librustc_macros/src/query.rs +++ b/src/librustc_macros/src/query.rs @@ -45,6 +45,9 @@ enum QueryModifier { /// Don't hash the result, instead just mark a query red if it runs NoHash, + + /// Don't force the query + NoForce, } impl Parse for QueryModifier { @@ -94,6 +97,8 @@ impl Parse for QueryModifier { Ok(QueryModifier::FatalCycle) } else if modifier == "no_hash" { Ok(QueryModifier::NoHash) + } else if modifier == "no_force" { + Ok(QueryModifier::NoForce) } else { Err(Error::new(modifier.span(), "unknown query modifier")) } @@ -194,6 +199,9 @@ struct QueryModifiers { /// Don't hash the result, instead just mark a query red if it runs no_hash: bool, + + /// Don't force the query + no_force: bool, } /// Process query modifiers into a struct, erroring on duplicates @@ -203,6 +211,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { let mut desc = None; let mut fatal_cycle = false; let mut no_hash = false; + let mut no_force = false; for modifier in query.modifiers.0.drain(..) { match modifier { QueryModifier::LoadCached(tcx, id, block) => { @@ -235,6 +244,12 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { } no_hash = true; } + QueryModifier::NoForce => { + if no_force { + panic!("duplicate modifier `no_force` for query `{}`", query.name); + } + no_force = true; + } } } QueryModifiers { @@ -243,6 +258,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { desc, fatal_cycle, no_hash, + no_force, } } @@ -329,6 +345,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { let mut query_description_stream = quote! {}; let mut dep_node_def_stream = quote! {}; let mut dep_node_force_stream = quote! {}; + let mut no_force_queries = Vec::new(); for group in groups.0 { let mut group_stream = quote! {}; @@ -364,29 +381,46 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { [#attribute_stream] fn #name: #name(#arg) #result, }); - add_query_description_impl(&query, modifiers, &mut query_description_stream); - // Create a dep node for the query dep_node_def_stream.extend(quote! { [] #name(#arg), }); - // Add a match arm to force the query given the dep node - dep_node_force_stream.extend(quote! { - DepKind::#name => { - if let Some(key) = RecoverKey::recover($tcx, $dep_node) { - force_ex!($tcx, #name, key); - } else { - return false; + if modifiers.no_force { + no_force_queries.push(name.clone()); + } else { + // Add a match arm to force the query given the dep node + dep_node_force_stream.extend(quote! { + DepKind::#name => { + if let Some(key) = RecoverKey::recover($tcx, $dep_node) { + force_ex!($tcx, #name, key); + } else { + return false; + } } - } - }); + }); + } + + add_query_description_impl(&query, modifiers, &mut query_description_stream); } let name = &group.name; query_stream.extend(quote! { #name { #group_stream }, }); } + + // Add an arm for the no force queries to panic when trying to force them + for query in no_force_queries { + dep_node_force_stream.extend(quote! { + DepKind::#query | + }); + } + dep_node_force_stream.extend(quote! { + DepKind::Null => { + bug!("Cannot force dep node: {:?}", $dep_node) + } + }); + TokenStream::from(quote! { macro_rules! rustc_query_append { ([$($macro:tt)*][$($other:tt)*]) => { From 52374a6462e225cdc4a0487b6c843ce72ab8551f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 20 Mar 2019 17:13:44 +0100 Subject: [PATCH 11/38] Add anon to query macro and move a query over --- src/librustc/dep_graph/dep_node.rs | 8 -------- src/librustc/query/mod.rs | 18 ++++++++++++++++-- src/librustc/ty/query/config.rs | 6 ------ src/librustc/ty/query/mod.rs | 9 --------- src/librustc/ty/query/plumbing.rs | 1 - src/librustc_macros/src/query.rs | 29 ++++++++++++++++++++++++++++- 6 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index a4950c01162ee..cdbd01620fb3c 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -614,14 +614,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [input] UsedCrateSource(CrateNum), [input] PostorderCnums, - // These queries are not expected to have inputs -- as a result, they - // are not good candidates for "replay" because they are essentially - // pure functions of their input (and hence the expectation is that - // no caller would be green **apart** from just these - // queries). Making them anonymous avoids hashing the result, which - // may save a bit of time. - [anon] EraseRegionsTy { ty: Ty<'tcx> }, - [input] Freevars(DefId), [input] MaybeUnusedTraitImport(DefId), [input] MaybeUnusedExternCrates, diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 361d812900232..b8c91f9193495 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -1,7 +1,6 @@ use crate::ty::query::QueryDescription; use crate::ty::query::queries; -use crate::ty::TyCtxt; -use crate::ty; +use crate::ty::{self, Ty, TyCtxt}; use crate::hir::def_id::{DefId, CrateNum}; use crate::dep_graph::SerializedDepNodeIndex; use crate::traits; @@ -109,6 +108,21 @@ rustc_queries! { } TypeChecking { + // Erases regions from `ty` to yield a new type. + // Normally you would just use `tcx.erase_regions(&value)`, + // however, which uses this query as a kind of cache. + query erase_regions_ty(ty: Ty<'tcx>) -> Ty<'tcx> { + // This query is not expected to have input -- as a result, it + // is not a good candidates for "replay" because it is essentially a + // pure function of its input (and hence the expectation is that + // no caller would be green **apart** from just these + // queries). Making it anonymous avoids hashing the result, which + // may save a bit of time. + anon + no_force + desc { "erasing regions from `{:?}`", ty } + } + query program_clauses_for(_: DefId) -> Clauses<'tcx> { desc { "generating chalk-style clauses" } } diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 72fb649a9466f..47ef09820b08d 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -305,12 +305,6 @@ impl<'tcx> QueryDescription<'tcx> for queries::super_predicates_of<'tcx> { } } -impl<'tcx> QueryDescription<'tcx> for queries::erase_regions_ty<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, ty: Ty<'tcx>) -> Cow<'static, str> { - format!("erasing regions from `{:?}`", ty).into() - } -} - impl<'tcx> QueryDescription<'tcx> for queries::type_param_predicates<'tcx> { fn describe(tcx: TyCtxt<'_, '_, '_>, (_, def_id): (DefId, DefId)) -> Cow<'static, str> { let id = tcx.hir().as_local_hir_id(def_id).unwrap(); diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 4cfddf08461f8..5eafb87592e8a 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -555,11 +555,6 @@ rustc_query_append! { [define_queries!][ <'tcx> }, TypeChecking { - // Erases regions from `ty` to yield a new type. - // Normally you would just use `tcx.erase_regions(&value)`, - // however, which uses this query as a kind of cache. - [] fn erase_regions_ty: erase_regions_ty(Ty<'tcx>) -> Ty<'tcx>, - /// Do not call this query directly: invoke `normalize` instead. [] fn normalize_projection_ty: NormalizeProjectionTy( CanonicalProjectionGoal<'tcx> @@ -698,10 +693,6 @@ fn codegen_fn_attrs<'tcx>(id: DefId) -> DepConstructor<'tcx> { DepConstructor::CodegenFnAttrs { 0: id } } -fn erase_regions_ty<'tcx>(ty: Ty<'tcx>) -> DepConstructor<'tcx> { - DepConstructor::EraseRegionsTy { ty } -} - fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> { DepConstructor::TypeParamPredicates { item_id, diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index 331f68c11d0ac..c364d15027d57 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1223,7 +1223,6 @@ pub fn force_from_dep_node<'tcx>( DepKind::CompileCodegenUnit | DepKind::FulfillObligation | DepKind::VtableMethods | - DepKind::EraseRegionsTy | DepKind::NormalizeProjectionTy | DepKind::NormalizeTyAfterErasingRegions | DepKind::ImpliedOutlivesBounds | diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs index 90bd46d035062..fa5ab4737d890 100644 --- a/src/librustc_macros/src/query.rs +++ b/src/librustc_macros/src/query.rs @@ -48,6 +48,9 @@ enum QueryModifier { /// Don't force the query NoForce, + + /// Generate a dep node based on the dependencies of the query + Anon, } impl Parse for QueryModifier { @@ -99,6 +102,8 @@ impl Parse for QueryModifier { Ok(QueryModifier::NoHash) } else if modifier == "no_force" { Ok(QueryModifier::NoForce) + } else if modifier == "anon" { + Ok(QueryModifier::Anon) } else { Err(Error::new(modifier.span(), "unknown query modifier")) } @@ -202,6 +207,9 @@ struct QueryModifiers { /// Don't force the query no_force: bool, + + /// Generate a dep node based on the dependencies of the query + anon: bool, } /// Process query modifiers into a struct, erroring on duplicates @@ -212,6 +220,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { let mut fatal_cycle = false; let mut no_hash = false; let mut no_force = false; + let mut anon = false; for modifier in query.modifiers.0.drain(..) { match modifier { QueryModifier::LoadCached(tcx, id, block) => { @@ -250,6 +259,12 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { } no_force = true; } + QueryModifier::Anon => { + if anon { + panic!("duplicate modifier `anon` for query `{}`", query.name); + } + anon = true; + } } } QueryModifiers { @@ -259,6 +274,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { fatal_cycle, no_hash, no_force, + anon, } } @@ -381,9 +397,20 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { [#attribute_stream] fn #name: #name(#arg) #result, }); + let mut attributes = Vec::new(); + + // Pass on the anon modifier + if modifiers.anon { + attributes.push(quote! { anon }); + }; + + let mut attribute_stream = quote! {}; + for e in attributes.into_iter().intersperse(quote! {,}) { + attribute_stream.extend(e); + } // Create a dep node for the query dep_node_def_stream.extend(quote! { - [] #name(#arg), + [#attribute_stream] #name(#arg), }); if modifiers.no_force { From 4d0a1e418c8ba90adc9703b1adf735d6d134c2b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 20 Mar 2019 17:22:16 +0100 Subject: [PATCH 12/38] Add eval_always to query macro and move a query over --- src/librustc/dep_graph/dep_node.rs | 1 - src/librustc/query/mod.rs | 5 +++++ src/librustc/ty/query/config.rs | 6 ------ src/librustc/ty/query/mod.rs | 5 ----- src/librustc/ty/query/plumbing.rs | 1 - src/librustc_macros/src/query.rs | 20 ++++++++++++++++++++ 6 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index cdbd01620fb3c..4babadb67bce6 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -564,7 +564,6 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx> [] HasGlobalAllocator(CrateNum), [] HasPanicHandler(CrateNum), [input] ExternCrate(DefId), - [eval_always] LintLevels, [] Specializes { impl1: DefId, impl2: DefId }, [input] InScopeTraits(DefIndex), [input] ModuleExports(DefId), diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index b8c91f9193495..8d64818f49b18 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -55,6 +55,11 @@ rustc_queries! { query native_libraries(_: CrateNum) -> Lrc> { desc { "looking up the native libraries of a linked crate" } } + + query lint_levels(_: CrateNum) -> Lrc { + eval_always + desc { "computing the lint levels for items in this crate" } + } } Codegen { diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index 47ef09820b08d..5cb5a0030f4eb 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -605,12 +605,6 @@ impl<'tcx> QueryDescription<'tcx> for queries::analysis<'tcx> { } } -impl<'tcx> QueryDescription<'tcx> for queries::lint_levels<'tcx> { - fn describe(_tcx: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> { - "computing the lint levels for items in this crate".into() - } -} - impl<'tcx> QueryDescription<'tcx> for queries::specializes<'tcx> { fn describe(_tcx: TyCtxt<'_, '_, '_>, _: (DefId, DefId)) -> Cow<'static, str> { "computing whether impls specialize one another".into() diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 5eafb87592e8a..dbc81a4235d71 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -415,7 +415,6 @@ rustc_query_append! { [define_queries!][ <'tcx> Other { [] fn module_exports: ModuleExports(DefId) -> Option>>, - [] fn lint_levels: lint_levels_node(CrateNum) -> Lrc, }, TypeChecking { @@ -767,10 +766,6 @@ fn layout_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> DepConst DepConstructor::Layout { param_env } } -fn lint_levels_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> { - DepConstructor::LintLevels -} - fn specializes_node<'tcx>((a, b): (DefId, DefId)) -> DepConstructor<'tcx> { DepConstructor::Specializes { impl1: a, impl2: b } } diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index c364d15027d57..adac19d3410b2 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -1332,7 +1332,6 @@ pub fn force_from_dep_node<'tcx>( DepKind::HasGlobalAllocator => { force!(has_global_allocator, krate!()); } DepKind::HasPanicHandler => { force!(has_panic_handler, krate!()); } DepKind::ExternCrate => { force!(extern_crate, def_id!()); } - DepKind::LintLevels => { force!(lint_levels, LOCAL_CRATE); } DepKind::InScopeTraits => { force!(in_scope_traits_map, def_id!().index); } DepKind::ModuleExports => { force!(module_exports, def_id!()); } DepKind::IsSanitizerRuntime => { force!(is_sanitizer_runtime, krate!()); } diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs index fa5ab4737d890..0800579231fde 100644 --- a/src/librustc_macros/src/query.rs +++ b/src/librustc_macros/src/query.rs @@ -51,6 +51,9 @@ enum QueryModifier { /// Generate a dep node based on the dependencies of the query Anon, + + // Always evaluate the query, ignoring its depdendencies + EvalAlways, } impl Parse for QueryModifier { @@ -104,6 +107,8 @@ impl Parse for QueryModifier { Ok(QueryModifier::NoForce) } else if modifier == "anon" { Ok(QueryModifier::Anon) + } else if modifier == "eval_always" { + Ok(QueryModifier::EvalAlways) } else { Err(Error::new(modifier.span(), "unknown query modifier")) } @@ -210,6 +215,9 @@ struct QueryModifiers { /// Generate a dep node based on the dependencies of the query anon: bool, + + // Always evaluate the query, ignoring its depdendencies + eval_always: bool, } /// Process query modifiers into a struct, erroring on duplicates @@ -221,6 +229,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { let mut no_hash = false; let mut no_force = false; let mut anon = false; + let mut eval_always = false; for modifier in query.modifiers.0.drain(..) { match modifier { QueryModifier::LoadCached(tcx, id, block) => { @@ -265,6 +274,12 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { } anon = true; } + QueryModifier::EvalAlways => { + if eval_always { + panic!("duplicate modifier `eval_always` for query `{}`", query.name); + } + eval_always = true; + } } } QueryModifiers { @@ -275,6 +290,7 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers { no_hash, no_force, anon, + eval_always, } } @@ -403,6 +419,10 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { if modifiers.anon { attributes.push(quote! { anon }); }; + // Pass on the eval_always modifier + if modifiers.eval_always { + attributes.push(quote! { eval_always }); + }; let mut attribute_stream = quote! {}; for e in attributes.into_iter().intersperse(quote! {,}) { From 75677c45c315d03fc9eb2cd51aaf2eb21814f95f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 20 Mar 2019 18:00:08 +0100 Subject: [PATCH 13/38] Fix whitespace --- src/librustc_macros/src/query.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_macros/src/query.rs b/src/librustc_macros/src/query.rs index 0800579231fde..bd5be831ff68d 100644 --- a/src/librustc_macros/src/query.rs +++ b/src/librustc_macros/src/query.rs @@ -215,7 +215,7 @@ struct QueryModifiers { /// Generate a dep node based on the dependencies of the query anon: bool, - + // Always evaluate the query, ignoring its depdendencies eval_always: bool, } @@ -403,7 +403,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { }; let mut attribute_stream = quote! {}; - + for e in attributes.into_iter().intersperse(quote! {,}) { attribute_stream.extend(e); } @@ -447,7 +447,7 @@ pub fn rustc_queries(input: TokenStream) -> TokenStream { } }); } - + add_query_description_impl(&query, modifiers, &mut query_description_stream); } let name = &group.name; From 71dfb01e8f8e36aaafa3139e264a42c421d79d28 Mon Sep 17 00:00:00 2001 From: Eddie Kovsky Date: Wed, 20 Mar 2019 22:21:53 -0600 Subject: [PATCH 14/38] Update build instructions in README.md Add additional instructions when `sudo ./x.py install` fails to complete the build. This resolves issues #40108 and #49269. --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index 514e420ca457c..55e6e8d7f1889 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,22 @@ of the rustc-guide instead._ $ ./x.py build && sudo ./x.py install ``` + If after running `sudo ./x.py install` you see an error message like + + ``` + error: failed to load source for a dependency on 'cc' + ``` + + then run these two commands and then try `sudo ./x.py install` again: + + ``` + $ cargo install cargo-vendor + ``` + + ``` + $ cargo vendor + ``` + > ***Note:*** Install locations can be adjusted by copying the config file > from `./config.toml.example` to `./config.toml`, and > adjusting the `prefix` option under `[install]`. Various other options, such From cf2f1bb072c76ed45882e1a69ed7b8ec96bad0e9 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Thu, 21 Mar 2019 00:37:08 +0530 Subject: [PATCH 15/38] review fixes --- src/librustc_codegen_ssa/mir/block.rs | 8 +-- .../borrow_check/nll/type_check/mod.rs | 58 ++++++++----------- src/librustc_mir/transform/const_prop.rs | 2 +- src/librustc_mir/transform/inline.rs | 11 +--- src/librustc_mir/transform/promote_consts.rs | 15 ++--- 5 files changed, 38 insertions(+), 56 deletions(-) diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 62f454f1b9fea..066b38be3dbc2 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -622,13 +622,13 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // and we can then extract the value by evaluating the promoted. mir::Operand::Copy( Place::Base(PlaceBase::Static( - box mir::Static {promoted: Some(promoted), ty, ..} - )) + box mir::Static {promoted: Some(promoted), ty, ..} + )) ) | mir::Operand::Move( Place::Base(PlaceBase::Static( - box mir::Static {promoted: Some(promoted), ty, ..} - )) + box mir::Static {promoted: Some(promoted), ty, ..} + )) ) => { let param_env = ty::ParamEnv::reveal_all(); let cid = mir::interpret::GlobalId { diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index c2efd3625c32b..2a32b475c7991 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -455,6 +455,27 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { }, Place::Base(PlaceBase::Static(box Static { def_id, ty: sty, promoted })) => { let sty = self.sanitize_type(place, sty); + let check_err = + |verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx> , + place: &Place<'tcx>, + ty, + sty| { + if let Err(terr) = verifier.cx.eq_types( + sty, + ty, + location.to_locations(), + ConstraintCategory::Boring, + ) { + span_mirbug!( + verifier, + place, + "bad promoted type ({:?}: {:?}): {:?}", + ty, + sty, + terr + ); + }; + }; match promoted { Some(pr) => { if !self.errors_reported { @@ -462,45 +483,14 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { self.sanitize_promoted(promoted_mir, location); let promoted_ty = promoted_mir.return_ty(); - - if let Err(terr) = self.cx.eq_types( - sty, - promoted_ty, - location.to_locations(), - ConstraintCategory::Boring, - ) { - span_mirbug!( - self, - place, - "bad promoted type ({:?}: {:?}): {:?}", - promoted_ty, - sty, - terr - ); - }; + check_err(self, place, promoted_ty, sty); } } None => { let ty = self.tcx().type_of(def_id); let ty = self.cx.normalize(ty, location); - if let Err(terr) = - self.cx - .eq_types( - ty, - sty, - location.to_locations(), - ConstraintCategory::Boring - ) - { - span_mirbug!( - self, - place, - "bad static type ({:?}: {:?}): {:?}", - ty, - sty, - terr - ); - }; + + check_err(self, place, ty, sty); } } PlaceTy::Ty { ty: sty } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index c5c3a1b8eca18..81cdb00100595 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -283,7 +283,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { // an `Index` projection would throw us off-track. _ => None, }, - Place::Base(PlaceBase::Static(box Static {promoted: Some(promoted), ty: _, ..})) => { + Place::Base(PlaceBase::Static(box Static {promoted: Some(promoted), ..})) => { let generics = self.tcx.generics_of(self.source.def_id()); if generics.requires_monomorphization(self.tcx) { // FIXME: can't handle code with generics diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 86b7da1787919..ec2cf8a4c0348 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -692,14 +692,9 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { // Return pointer; update the place itself *place = self.destination.clone(); }, - Place::Base(PlaceBase::Static(ref mut static_)) => { - match static_.promoted { - Some(promoted) => { - if let Some(p) = self.promoted_map.get(promoted).cloned() { - static_.promoted = Some(p); - } - } - None => self.super_place(place, _ctxt, _location) + Place::Base(PlaceBase::Static(box Static { promoted: Some(promoted), .. })) => { + if let Some(p) = self.promoted_map.get(*promoted).cloned() { + *promoted = p; } }, _ => self.super_place(place, _ctxt, _location) diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index d777a7b362b90..2344f070ea670 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -153,7 +153,7 @@ struct Promoter<'a, 'tcx: 'a> { /// If true, all nested temps are also kept in the /// source MIR, not moved to the promoted MIR. keep_original: bool, - def_id: DefId + def_id: DefId, } impl<'a, 'tcx> Promoter<'a, 'tcx> { @@ -291,17 +291,14 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { fn promote_candidate(mut self, candidate: Candidate) { use rustc::mir::Static; let mut operand = { - let def_id = self.def_id.clone(); + let def_id = self.def_id; let promoted = &mut self.promoted; let promoted_id = Promoted::new(self.source.promoted.len()); let mut promoted_place = |ty, span| { promoted.span = span; - promoted.local_decls[RETURN_PLACE] = - LocalDecl::new_return_place(ty, span); - Place::Base(PlaceBase::Static( - Box::new(Static { def_id: def_id, ty, promoted: Some(promoted_id) }) - ) - ) + promoted.local_decls[RETURN_PLACE] = LocalDecl::new_return_place(ty, span); + Place::Base( + PlaceBase::Static(Box::new(Static { def_id, ty, promoted: Some(promoted_id) }))) }; let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut(); match candidate { @@ -421,7 +418,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>, source: mir, temps: &mut temps, keep_original: false, - def_id + def_id, }; promoter.promote_candidate(candidate); } From 48af7189c2f0e69c16611c261c4ded84c0ac305d Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 20 Mar 2019 13:08:54 +0100 Subject: [PATCH 16/38] Expand `impl FromIterator for Option` doc to include example of early termination. --- src/libcore/option.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index dfc388409a84b..4fad65f3ae28f 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -1315,6 +1315,26 @@ impl> FromIterator> for Option { /// Since the last element is zero, it would underflow. Thus, the resulting /// value is `None`. /// + /// Here is a variation on the previous example, showing that no + /// further elements are taken from `iter` after the first `None`. + /// + /// ``` + /// let items = vec![3_u16, 2, 1, 10]; + /// + /// let mut shared = 0; + /// + /// let res: Option> = items + /// .iter() + /// .map(|x| shared += x; x.checked_sub(2)) + /// .collect(); + /// + /// assert_eq!(res, None); + /// assert_eq!(shared, 6); + /// ``` + /// + /// Since the third element caused an underflow, no further elements were taken, + /// so the final value of `shared` is 6 (= `3 + 2 + 1`), not 16. + /// /// [`Iterator`]: ../iter/trait.Iterator.html #[inline] fn from_iter>>(iter: I) -> Option { From d5a61c0be25d47c39ab7909b83b3a2765a282eb1 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 20 Mar 2019 13:09:22 +0100 Subject: [PATCH 17/38] Expand `impl FromIterator for Result` doc to include examples of `Err` and early termination. --- src/libcore/result.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 967f7e3e2fe72..490cd5bb3fe1d 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -1202,6 +1202,34 @@ impl> FromIterator> for Result { /// ).collect(); /// assert_eq!(res, Ok(vec![2, 3])); /// ``` + /// + /// Here is another example that tries to subtract one from another list + /// of integers, this time checking for underflow: + /// + /// ``` + /// let v = vec![1, 2, 0]; + /// let res: Result, &'static str> = v.iter().map(|x: &u32| + /// x.checked_sub(1).ok_or("Underflow!") + /// ).collect(); + /// assert_eq!(res, Err("Underflow!")); + /// ``` + /// + /// Here is a variation on the previous example, showing that no + /// further elements are taken from `iter` after the first `Err`. + /// + /// ``` + /// let v = vec![3, 2, 1, 10]; + /// let mut shared = 0; + /// let res: Result, &'static str> = v.iter().map(|x: &u32| + /// shared += x; + /// x.checked_sub(2).ok_or("Underflow!") + /// ).collect(); + /// assert_eq!(res, Err("Underflow!")); + /// assert_eq!(shared, 6); + /// ``` + /// + /// Since the third element caused an underflow, no further elements were taken, + /// so the final value of `shared` is 6 (= `3 + 2 + 1`), not 16. #[inline] fn from_iter>>(iter: I) -> Result { // FIXME(#11084): This could be replaced with Iterator::scan when this From b34a71b7daf0f770cd5e7f9c36be960e32d2b167 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Fri, 22 Mar 2019 14:56:08 -0400 Subject: [PATCH 18/38] add suggestions to trim_{left,right} deprecations --- src/libcore/str/mod.rs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 528281d317be3..f54d7badc3ae0 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -3601,7 +3601,11 @@ impl str { /// assert!(Some('ע') == s.trim_left().chars().next()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_deprecated(reason = "superseded by `trim_start`", since = "1.33.0")] + #[rustc_deprecated( + since = "1.33.0", + reason = "superseded by `trim_start`", + suggestion = "trim_start", + )] pub fn trim_left(&self) -> &str { self.trim_start() } @@ -3638,7 +3642,11 @@ impl str { /// assert!(Some('ת') == s.trim_right().chars().rev().next()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_deprecated(reason = "superseded by `trim_end`", since = "1.33.0")] + #[rustc_deprecated( + since = "1.33.0", + reason = "superseded by `trim_end`", + suggestion = "trim_end", + )] pub fn trim_right(&self) -> &str { self.trim_end() } @@ -3802,7 +3810,11 @@ impl str { /// assert_eq!("12foo1bar12".trim_left_matches(x), "foo1bar12"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_deprecated(reason = "superseded by `trim_start_matches`", since = "1.33.0")] + #[rustc_deprecated( + since = "1.33.0", + reason = "superseded by `trim_start_matches`", + suggestion = "trim_start_matches", + )] pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str { self.trim_start_matches(pat) } @@ -3840,7 +3852,11 @@ impl str { /// assert_eq!("1fooX".trim_right_matches(|c| c == '1' || c == 'X'), "1foo"); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_deprecated(reason = "superseded by `trim_end_matches`", since = "1.33.0")] + #[rustc_deprecated( + since = "1.33.0", + reason = "superseded by `trim_end_matches`", + suggestion = "trim_end_matches", + )] pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str where P::Searcher: ReverseSearcher<'a> { From 37cfeb271074ec31d65fef968edf24dd56b1e6aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Fri, 22 Mar 2019 22:11:32 +0100 Subject: [PATCH 19/38] Add/rename checked_duration_since tests --- src/libstd/time.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 4c86f70ad871d..5abaac51da39b 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -664,20 +664,23 @@ mod tests { #[test] #[should_panic] - fn instant_duration_panic() { + fn instant_duration_since_panic() { let a = Instant::now(); (a - Duration::new(1, 0)).duration_since(a); } #[test] - fn checked_instant_duration_nopanic() { - let a = Instant::now(); - let ret = (a - Duration::new(1, 0)).checked_duration_since(a); - assert_eq!(ret, None); + fn instant_checked_duration_since_nopanic() { + let now = Instant::now(); + let earlier = now - Duration::new(1, 0); + let later = now + Duration::new(1, 0); + assert_eq!(earlier.checked_duration_since(now), None); + assert_eq!(later.checked_duration_since(now), Some(Duration::new(1, 0))); + assert_eq!(now.checked_duration_since(now), Some(Duration::new(0, 0))); } #[test] - fn saturating_instant_duration_nopanic() { + fn instant_saturating_duration_since_nopanic() { let a = Instant::now(); let ret = (a - Duration::new(1, 0)).saturating_duration_since(a); assert_eq!(ret, Duration::new(0,0)); From d56b1fd0e7c09445574bae34332eeefa93713e44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Fri, 22 Mar 2019 22:12:32 +0100 Subject: [PATCH 20/38] Make duration_since use checked_duration_since --- src/libstd/time.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 5abaac51da39b..ab1a43d6672e4 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -212,7 +212,7 @@ impl Instant { /// ``` #[stable(feature = "time2", since = "1.8.0")] pub fn duration_since(&self, earlier: Instant) -> Duration { - self.0.sub_instant(&earlier.0) + self.0.checked_sub_instant(&earlier.0).expect("supplied instant is later than self") } /// Returns the amount of time elapsed from another instant to this one, @@ -233,11 +233,7 @@ impl Instant { /// ``` #[unstable(feature = "checked_duration_since", issue = "58402")] pub fn checked_duration_since(&self, earlier: Instant) -> Option { - if self >= &earlier { - Some(self.0.sub_instant(&earlier.0)) - } else { - None - } + self.0.checked_sub_instant(&earlier.0) } /// Returns the amount of time elapsed from another instant to this one, From 1ccad16231f58b09f127e679d54162acbc2f0dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Fri, 22 Mar 2019 22:14:35 +0100 Subject: [PATCH 21/38] Update sys::time impls to have checked_sub_instant --- src/libstd/sys/cloudabi/time.rs | 8 +++----- src/libstd/sys/redox/time.rs | 6 ++---- src/libstd/sys/sgx/time.rs | 4 ++-- src/libstd/sys/unix/time.rs | 13 +++++-------- src/libstd/sys/wasm/time.rs | 4 ++-- src/libstd/sys/windows/time.rs | 8 ++++---- 6 files changed, 18 insertions(+), 25 deletions(-) diff --git a/src/libstd/sys/cloudabi/time.rs b/src/libstd/sys/cloudabi/time.rs index d7502c61eff2c..49a234e115804 100644 --- a/src/libstd/sys/cloudabi/time.rs +++ b/src/libstd/sys/cloudabi/time.rs @@ -33,11 +33,9 @@ impl Instant { Instant { t: 0 } } - pub fn sub_instant(&self, other: &Instant) -> Duration { - let diff = self.t - .checked_sub(other.t) - .expect("second instant is later than self"); - Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32) + pub fn checked_sub_instant(&self, other: &Instant) -> Option { + let diff = self.t.checked_sub(other.t)?; + Some(Duration::new(diff / NSEC_PER_SEC, (diff % NSEC_PER_SEC) as u32)) } pub fn checked_add_duration(&self, other: &Duration) -> Option { diff --git a/src/libstd/sys/redox/time.rs b/src/libstd/sys/redox/time.rs index 9db3e85ca9c8b..881ad5c0aeb14 100644 --- a/src/libstd/sys/redox/time.rs +++ b/src/libstd/sys/redox/time.rs @@ -137,10 +137,8 @@ impl Instant { false } - pub fn sub_instant(&self, other: &Instant) -> Duration { - self.t.sub_timespec(&other.t).unwrap_or_else(|_| { - panic!("specified instant was later than self") - }) + pub fn checked_sub_instant(&self, other: &Instant) -> Option { + self.t.sub_timespec(&other.t).ok() } pub fn checked_add_duration(&self, other: &Duration) -> Option { diff --git a/src/libstd/sys/sgx/time.rs b/src/libstd/sys/sgx/time.rs index e4f789c3e3656..4659f7ba71fe0 100644 --- a/src/libstd/sys/sgx/time.rs +++ b/src/libstd/sys/sgx/time.rs @@ -14,8 +14,8 @@ impl Instant { Instant(usercalls::insecure_time()) } - pub fn sub_instant(&self, other: &Instant) -> Duration { - self.0 - other.0 + pub fn checked_sub_instant(&self, other: &Instant) -> Option { + self.0.checked_sub(other.0) } pub fn checked_add_duration(&self, other: &Duration) -> Option { diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs index cbb0615911adf..6b5a89aee7d69 100644 --- a/src/libstd/sys/unix/time.rs +++ b/src/libstd/sys/unix/time.rs @@ -149,12 +149,11 @@ mod inner { true } - pub fn sub_instant(&self, other: &Instant) -> Duration { + pub fn checked_sub_instant(&self, other: &Instant) -> Option { + let diff = self.t.checked_sub(other.t)?; let info = info(); - let diff = self.t.checked_sub(other.t) - .expect("second instant is later than self"); let nanos = mul_div_u64(diff, info.numer as u64, info.denom as u64); - Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32) + Some(Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32)) } pub fn checked_add_duration(&self, other: &Duration) -> Option { @@ -285,10 +284,8 @@ mod inner { false // last clause, used so `||` is always trailing above } - pub fn sub_instant(&self, other: &Instant) -> Duration { - self.t.sub_timespec(&other.t).unwrap_or_else(|_| { - panic!("specified instant was later than self") - }) + pub fn checked_sub_instant(&self, other: &Instant) -> Option { + self.t.sub_timespec(&other.t).ok() } pub fn checked_add_duration(&self, other: &Duration) -> Option { diff --git a/src/libstd/sys/wasm/time.rs b/src/libstd/sys/wasm/time.rs index c1228a1b75e39..3f71461eea487 100644 --- a/src/libstd/sys/wasm/time.rs +++ b/src/libstd/sys/wasm/time.rs @@ -22,8 +22,8 @@ impl Instant { false } - pub fn sub_instant(&self, other: &Instant) -> Duration { - self.0 - other.0 + pub fn checked_sub_instant(&self, other: &Instant) -> Option { + self.0.checked_sub(other.0) } pub fn checked_add_duration(&self, other: &Duration) -> Option { diff --git a/src/libstd/sys/windows/time.rs b/src/libstd/sys/windows/time.rs index 2c99bca70095c..aa53f1194fdb4 100644 --- a/src/libstd/sys/windows/time.rs +++ b/src/libstd/sys/windows/time.rs @@ -49,17 +49,17 @@ impl Instant { Instant { t: Duration::from_secs(0) } } - pub fn sub_instant(&self, other: &Instant) -> Duration { + pub fn checked_sub_instant(&self, other: &Instant) -> Option { // On windows there's a threshold below which we consider two timestamps // equivalent due to measurement error. For more details + doc link, // check the docs on epsilon. let epsilon = perf_counter::PerformanceCounterInstant::epsilon(); if other.t > self.t && other.t - self.t <= epsilon { - return Duration::new(0, 0) + Some(Duration::new(0, 0)) + } else { + self.t.checked_sub(other.t) } - self.t.checked_sub(other.t) - .expect("specified instant was later than self") } pub fn checked_add_duration(&self, other: &Duration) -> Option { From 8ba1a97e375451f51d0657e2135d4e6e657fd72e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 12 Mar 2019 19:27:10 -0700 Subject: [PATCH 22/38] Expand suggestions for type ascription parse errors --- src/librustc_resolve/lib.rs | 41 ++++++++-- src/libsyntax/parse/parser.rs | 79 ++++++++++++++++--- src/test/ui/error-codes/E0423.stderr | 26 ++++++ src/test/ui/issues/issue-22644.stderr | 13 +++ src/test/ui/issues/issue-34255-1.rs | 10 +++ src/test/ui/issues/issue-34255-1.stderr | 21 +++++ .../ui/lifetime_starts_expressions.stderr | 13 +++ .../ui/parser/struct-literal-in-for.stderr | 13 +++ .../ui/parser/struct-literal-in-if.stderr | 13 +++ .../ui/parser/struct-literal-in-while.stderr | 13 +++ ...truct-literal-restrictions-in-lamda.stderr | 13 +++ .../type-ascription-instead-of-let.rs | 11 +++ .../type-ascription-instead-of-let.stderr | 28 +++++++ .../type-ascription-instead-of-method.rs | 4 + .../type-ascription-instead-of-method.stderr | 10 +++ .../type-ascription-instead-of-path.rs | 6 ++ .../type-ascription-instead-of-path.stderr | 35 ++++++++ .../type-ascription-instead-of-variant.rs | 4 + .../type-ascription-instead-of-variant.stderr | 10 +++ ...ascription-instead-of-statement-end.stderr | 13 +++ 20 files changed, 358 insertions(+), 18 deletions(-) create mode 100644 src/test/ui/issues/issue-34255-1.rs create mode 100644 src/test/ui/issues/issue-34255-1.stderr create mode 100644 src/test/ui/suggestions/type-ascription-instead-of-let.rs create mode 100644 src/test/ui/suggestions/type-ascription-instead-of-let.stderr create mode 100644 src/test/ui/suggestions/type-ascription-instead-of-method.rs create mode 100644 src/test/ui/suggestions/type-ascription-instead-of-method.stderr create mode 100644 src/test/ui/suggestions/type-ascription-instead-of-path.rs create mode 100644 src/test/ui/suggestions/type-ascription-instead-of-path.stderr create mode 100644 src/test/ui/suggestions/type-ascription-instead-of-variant.rs create mode 100644 src/test/ui/suggestions/type-ascription-instead-of-variant.stderr diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ac149be4b2a89..1a03292290288 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3264,11 +3264,21 @@ impl<'a> Resolver<'a> { resolution } - fn type_ascription_suggestion(&self, - err: &mut DiagnosticBuilder<'_>, - base_span: Span) { + /// Only used in a specific case of type ascription suggestions + #[doc(hidden)] + fn get_colon_suggestion_span(&self, start: Span) -> Span { + let cm = self.session.source_map(); + start.to(cm.next_point(start)) + } + + fn type_ascription_suggestion( + &self, + err: &mut DiagnosticBuilder<'_>, + base_span: Span, + ) { debug!("type_ascription_suggetion {:?}", base_span); let cm = self.session.source_map(); + let base_snippet = cm.span_to_snippet(base_span); debug!("self.current_type_ascription {:?}", self.current_type_ascription); if let Some(sp) = self.current_type_ascription.last() { let mut sp = *sp; @@ -3276,10 +3286,8 @@ impl<'a> Resolver<'a> { // Try to find the `:`; bail on first non-':' / non-whitespace. sp = cm.next_point(sp); if let Ok(snippet) = cm.span_to_snippet(sp.to(cm.next_point(sp))) { - debug!("snippet {:?}", snippet); let line_sp = cm.lookup_char_pos(sp.hi()).line; let line_base_sp = cm.lookup_char_pos(base_span.lo()).line; - debug!("{:?} {:?}", line_sp, line_base_sp); if snippet == ":" { err.span_label(base_span, "expecting a type here because of type ascription"); @@ -3290,6 +3298,29 @@ impl<'a> Resolver<'a> { ";".to_string(), Applicability::MaybeIncorrect, ); + } else { + let colon_sp = self.get_colon_suggestion_span(sp); + let after_colon_sp = self.get_colon_suggestion_span( + colon_sp.shrink_to_hi(), + ); + if !cm.span_to_snippet(after_colon_sp).map(|s| s == " ") + .unwrap_or(false) + { + err.span_suggestion( + colon_sp, + "maybe you meant to write a path separator here", + "::".to_string(), + Applicability::MaybeIncorrect, + ); + } + if let Ok(base_snippet) = base_snippet { + err.span_suggestion( + base_span, + "maybe you meant to write an assignment here", + format!("let {}", base_snippet), + Applicability::MaybeIncorrect, + ); + } } break; } else if !snippet.trim().is_empty() { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 5627ac3fcf245..d052abf96d799 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3546,22 +3546,19 @@ impl<'a> Parser<'a> { lhs = self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Cast)?; continue } else if op == AssocOp::Colon { + let maybe_path = self.could_ascription_be_path(&lhs.node); + let next_sp = self.span; + lhs = match self.parse_assoc_op_cast(lhs, lhs_span, ExprKind::Type) { Ok(lhs) => lhs, Err(mut err) => { - err.span_label(self.span, - "expecting a type here because of type ascription"); - let cm = self.sess.source_map(); - let cur_pos = cm.lookup_char_pos(self.span.lo()); - let op_pos = cm.lookup_char_pos(cur_op_span.hi()); - if cur_pos.line != op_pos.line { - err.span_suggestion( - cur_op_span, - "try using a semicolon", - ";".to_string(), - Applicability::MaybeIncorrect // speculative - ); - } + self.bad_type_ascription( + &mut err, + lhs_span, + cur_op_span, + next_sp, + maybe_path, + ); return Err(err); } }; @@ -3666,6 +3663,62 @@ impl<'a> Parser<'a> { Ok(lhs) } + fn could_ascription_be_path(&self, node: &ast::ExprKind) -> bool { + self.token.is_ident() && + if let ast::ExprKind::Path(..) = node { true } else { false } && + !self.token.is_reserved_ident() && // v `foo:bar(baz)` + self.look_ahead(1, |t| t == &token::OpenDelim(token::Paren)) || + self.look_ahead(1, |t| t == &token::Lt) && // `foo:bar, + lhs_span: Span, + cur_op_span: Span, + next_sp: Span, + maybe_path: bool, + ) { + err.span_label(self.span, "expecting a type here because of type ascription"); + let cm = self.sess.source_map(); + let next_pos = cm.lookup_char_pos(next_sp.lo()); + let op_pos = cm.lookup_char_pos(cur_op_span.hi()); + if op_pos.line != next_pos.line { + err.span_suggestion( + cur_op_span, + "try using a semicolon", + ";".to_string(), + Applicability::MaybeIncorrect, + ); + } else { + if maybe_path { + err.span_suggestion( + cur_op_span, + "maybe you meant to write a path separator here", + "::".to_string(), + Applicability::MaybeIncorrect, + ); + } else { + err.note("type ascription is a nightly only feature that lets \ + you annotate expressions with a type: `: `"); + err.span_note( + lhs_span, + "this expression is annotated with type ascription...", + ); + err.span_note( + cur_op_span, + "...due to this, which is why a type is expected after", + ); + err.help("this might be indicative of a syntax error elsewhere"); + } + } + } + fn parse_assoc_op_cast(&mut self, lhs: P, lhs_span: Span, expr_kind: fn(P, P) -> ExprKind) -> PResult<'a, P> { diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index bdcfaae60a010..af5f88f4ce5f3 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -3,6 +3,19 @@ error: expected type, found `1` | LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } | ^ expecting a type here because of type ascription + | + = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` +note: this expression is annotated with type ascription... + --> $DIR/E0423.rs:12:36 + | +LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } + | ^ +note: ...due to this, which is why a type is expected after + --> $DIR/E0423.rs:12:37 + | +LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } + | ^ + = help: this might be indicative of a syntax error elsewhere error: expected expression, found `==` --> $DIR/E0423.rs:15:13 @@ -15,6 +28,19 @@ error: expected type, found `0` | LL | for _ in std::ops::Range { start: 0, end: 10 } {} | ^ expecting a type here because of type ascription + | + = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` +note: this expression is annotated with type ascription... + --> $DIR/E0423.rs:21:32 + | +LL | for _ in std::ops::Range { start: 0, end: 10 } {} + | ^^^^^ +note: ...due to this, which is why a type is expected after + --> $DIR/E0423.rs:21:37 + | +LL | for _ in std::ops::Range { start: 0, end: 10 } {} + | ^ + = help: this might be indicative of a syntax error elsewhere error[E0423]: expected function, found struct `Foo` --> $DIR/E0423.rs:4:13 diff --git a/src/test/ui/issues/issue-22644.stderr b/src/test/ui/issues/issue-22644.stderr index cbff5575ed20e..08758ce9c9458 100644 --- a/src/test/ui/issues/issue-22644.stderr +++ b/src/test/ui/issues/issue-22644.stderr @@ -88,6 +88,19 @@ error: expected type, found `4` | LL | println!("{}", a: &mut 4); | ^ expecting a type here because of type ascription + | + = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` +note: this expression is annotated with type ascription... + --> $DIR/issue-22644.rs:34:20 + | +LL | println!("{}", a: &mut 4); + | ^ +note: ...due to this, which is why a type is expected after + --> $DIR/issue-22644.rs:34:21 + | +LL | println!("{}", a: &mut 4); + | ^ + = help: this might be indicative of a syntax error elsewhere error: aborting due to 9 previous errors diff --git a/src/test/ui/issues/issue-34255-1.rs b/src/test/ui/issues/issue-34255-1.rs new file mode 100644 index 0000000000000..b1071934bb2f3 --- /dev/null +++ b/src/test/ui/issues/issue-34255-1.rs @@ -0,0 +1,10 @@ +enum Test { + Drill { + field: i32, + } +} + +fn main() { + Test::Drill(field: 42); + //~^ ERROR expected type, found +} diff --git a/src/test/ui/issues/issue-34255-1.stderr b/src/test/ui/issues/issue-34255-1.stderr new file mode 100644 index 0000000000000..ea324302d4043 --- /dev/null +++ b/src/test/ui/issues/issue-34255-1.stderr @@ -0,0 +1,21 @@ +error: expected type, found `42` + --> $DIR/issue-34255-1.rs:8:24 + | +LL | Test::Drill(field: 42); + | ^^ expecting a type here because of type ascription + | + = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` +note: this expression is annotated with type ascription... + --> $DIR/issue-34255-1.rs:8:17 + | +LL | Test::Drill(field: 42); + | ^^^^^ +note: ...due to this, which is why a type is expected after + --> $DIR/issue-34255-1.rs:8:22 + | +LL | Test::Drill(field: 42); + | ^ + = help: this might be indicative of a syntax error elsewhere + +error: aborting due to previous error + diff --git a/src/test/ui/lifetime_starts_expressions.stderr b/src/test/ui/lifetime_starts_expressions.stderr index fa0a7ac002b2f..3de3298e3b52b 100644 --- a/src/test/ui/lifetime_starts_expressions.stderr +++ b/src/test/ui/lifetime_starts_expressions.stderr @@ -13,6 +13,19 @@ error: expected type, found keyword `loop` | LL | loop { break 'label: loop { break 'label 42; }; } | ^^^^ expecting a type here because of type ascription + | + = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` +note: this expression is annotated with type ascription... + --> $DIR/lifetime_starts_expressions.rs:6:12 + | +LL | loop { break 'label: loop { break 'label 42; }; } + | ^^^^^^^^^^^^ +note: ...due to this, which is why a type is expected after + --> $DIR/lifetime_starts_expressions.rs:6:24 + | +LL | loop { break 'label: loop { break 'label 42; }; } + | ^ + = help: this might be indicative of a syntax error elsewhere error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/struct-literal-in-for.stderr b/src/test/ui/parser/struct-literal-in-for.stderr index b319c64f406f1..2940f465826b6 100644 --- a/src/test/ui/parser/struct-literal-in-for.stderr +++ b/src/test/ui/parser/struct-literal-in-for.stderr @@ -3,6 +3,19 @@ error: expected type, found `3` | LL | x: 3 | ^ expecting a type here because of type ascription + | + = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` +note: this expression is annotated with type ascription... + --> $DIR/struct-literal-in-for.rs:13:9 + | +LL | x: 3 + | ^ +note: ...due to this, which is why a type is expected after + --> $DIR/struct-literal-in-for.rs:13:10 + | +LL | x: 3 + | ^ + = help: this might be indicative of a syntax error elsewhere error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{` --> $DIR/struct-literal-in-for.rs:14:12 diff --git a/src/test/ui/parser/struct-literal-in-if.stderr b/src/test/ui/parser/struct-literal-in-if.stderr index 27672eeda830b..e7d22ae0292e6 100644 --- a/src/test/ui/parser/struct-literal-in-if.stderr +++ b/src/test/ui/parser/struct-literal-in-if.stderr @@ -3,6 +3,19 @@ error: expected type, found `3` | LL | x: 3 | ^ expecting a type here because of type ascription + | + = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` +note: this expression is annotated with type ascription... + --> $DIR/struct-literal-in-if.rs:13:9 + | +LL | x: 3 + | ^ +note: ...due to this, which is why a type is expected after + --> $DIR/struct-literal-in-if.rs:13:10 + | +LL | x: 3 + | ^ + = help: this might be indicative of a syntax error elsewhere error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{` --> $DIR/struct-literal-in-if.rs:14:12 diff --git a/src/test/ui/parser/struct-literal-in-while.stderr b/src/test/ui/parser/struct-literal-in-while.stderr index 8a130f441a3ee..038e30956ff53 100644 --- a/src/test/ui/parser/struct-literal-in-while.stderr +++ b/src/test/ui/parser/struct-literal-in-while.stderr @@ -3,6 +3,19 @@ error: expected type, found `3` | LL | x: 3 | ^ expecting a type here because of type ascription + | + = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` +note: this expression is annotated with type ascription... + --> $DIR/struct-literal-in-while.rs:13:9 + | +LL | x: 3 + | ^ +note: ...due to this, which is why a type is expected after + --> $DIR/struct-literal-in-while.rs:13:10 + | +LL | x: 3 + | ^ + = help: this might be indicative of a syntax error elsewhere error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{` --> $DIR/struct-literal-in-while.rs:14:12 diff --git a/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr index 3505d00b64b76..b3a6f6ac73483 100644 --- a/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr +++ b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr @@ -3,6 +3,19 @@ error: expected type, found `3` | LL | x: 3 | ^ expecting a type here because of type ascription + | + = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` +note: this expression is annotated with type ascription... + --> $DIR/struct-literal-restrictions-in-lamda.rs:13:9 + | +LL | x: 3 + | ^ +note: ...due to this, which is why a type is expected after + --> $DIR/struct-literal-restrictions-in-lamda.rs:13:10 + | +LL | x: 3 + | ^ + = help: this might be indicative of a syntax error elsewhere error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{` --> $DIR/struct-literal-restrictions-in-lamda.rs:14:12 diff --git a/src/test/ui/suggestions/type-ascription-instead-of-let.rs b/src/test/ui/suggestions/type-ascription-instead-of-let.rs new file mode 100644 index 0000000000000..51d3d32565f8a --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-let.rs @@ -0,0 +1,11 @@ +fn fun(x: i32) -> i32 { x } + +fn main() { + let closure_annotated = |value: i32| -> i32 { + temp: i32 = fun(5i32); + //~^ ERROR cannot find value `temp` in this scope + //~| ERROR type ascription is experimental + temp + value + 1 + //~^ ERROR cannot find value `temp` in this scope + }; +} diff --git a/src/test/ui/suggestions/type-ascription-instead-of-let.stderr b/src/test/ui/suggestions/type-ascription-instead-of-let.stderr new file mode 100644 index 0000000000000..1efa94a553212 --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-let.stderr @@ -0,0 +1,28 @@ +error[E0425]: cannot find value `temp` in this scope + --> $DIR/type-ascription-instead-of-let.rs:5:9 + | +LL | temp: i32 = fun(5i32); + | ^^^^ + | | + | not found in this scope + | expecting a type here because of type ascription + | help: maybe you meant to write an assignment here: `let temp` + +error[E0425]: cannot find value `temp` in this scope + --> $DIR/type-ascription-instead-of-let.rs:8:9 + | +LL | temp + value + 1 + | ^^^^ not found in this scope + +error[E0658]: type ascription is experimental (see issue #23416) + --> $DIR/type-ascription-instead-of-let.rs:5:9 + | +LL | temp: i32 = fun(5i32); + | ^^^^^^^^^ + | + = help: add #![feature(type_ascription)] to the crate attributes to enable + +error: aborting due to 3 previous errors + +Some errors occurred: E0425, E0658. +For more information about an error, try `rustc --explain E0425`. diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.rs b/src/test/ui/suggestions/type-ascription-instead-of-method.rs new file mode 100644 index 0000000000000..361729d50c2f3 --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-method.rs @@ -0,0 +1,4 @@ +fn main() { + Box:new("foo".to_string()) + //~^ ERROR expected type, found +} diff --git a/src/test/ui/suggestions/type-ascription-instead-of-method.stderr b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr new file mode 100644 index 0000000000000..15ec087b1cc01 --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-method.stderr @@ -0,0 +1,10 @@ +error: expected type, found `"foo"` + --> $DIR/type-ascription-instead-of-method.rs:2:13 + | +LL | Box:new("foo".to_string()) + | - ^^^^^ expecting a type here because of type ascription + | | + | help: maybe you meant to write a path separator here: `::` + +error: aborting due to previous error + diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path.rs b/src/test/ui/suggestions/type-ascription-instead-of-path.rs new file mode 100644 index 0000000000000..a81996ed7bb6b --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-path.rs @@ -0,0 +1,6 @@ +fn main() { + std:io::stdin(); + //~^ ERROR failed to resolve: use of undeclared type or module `io` + //~| ERROR expected value, found module + //~| ERROR type ascription is experimental +} diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path.stderr b/src/test/ui/suggestions/type-ascription-instead-of-path.stderr new file mode 100644 index 0000000000000..e371611ccff63 --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-path.stderr @@ -0,0 +1,35 @@ +error[E0433]: failed to resolve: use of undeclared type or module `io` + --> $DIR/type-ascription-instead-of-path.rs:2:9 + | +LL | std:io::stdin(); + | ^^ use of undeclared type or module `io` + +error[E0423]: expected value, found module `std` + --> $DIR/type-ascription-instead-of-path.rs:2:5 + | +LL | std:io::stdin(); + | ^^^ + | | + | not a value + | expecting a type here because of type ascription +help: maybe you meant to write a path separator here + | +LL | std::io::stdin(); + | ^^ +help: maybe you meant to write an assignment here + | +LL | let std:io::stdin(); + | ^^^^^^^ + +error[E0658]: type ascription is experimental (see issue #23416) + --> $DIR/type-ascription-instead-of-path.rs:2:5 + | +LL | std:io::stdin(); + | ^^^^^^^^^^^^^^^ + | + = help: add #![feature(type_ascription)] to the crate attributes to enable + +error: aborting due to 3 previous errors + +Some errors occurred: E0423, E0433, E0658. +For more information about an error, try `rustc --explain E0423`. diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.rs b/src/test/ui/suggestions/type-ascription-instead-of-variant.rs new file mode 100644 index 0000000000000..b90867fef6b51 --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.rs @@ -0,0 +1,4 @@ +fn main() { + let _ = Option:Some(""); + //~^ ERROR expected type, found +} diff --git a/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr new file mode 100644 index 0000000000000..5719a667a8415 --- /dev/null +++ b/src/test/ui/suggestions/type-ascription-instead-of-variant.stderr @@ -0,0 +1,10 @@ +error: expected type, found `""` + --> $DIR/type-ascription-instead-of-variant.rs:2:25 + | +LL | let _ = Option:Some(""); + | - ^^ expecting a type here because of type ascription + | | + | help: maybe you meant to write a path separator here: `::` + +error: aborting due to previous error + diff --git a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr index bc5a923a3f32f..4077be9d08280 100644 --- a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr +++ b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr @@ -11,6 +11,19 @@ error: expected type, found `0` | LL | println!("test"): 0; | ^ expecting a type here because of type ascription + | + = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` +note: this expression is annotated with type ascription... + --> $DIR/type-ascription-instead-of-statement-end.rs:9:5 + | +LL | println!("test"): 0; + | ^^^^^^^^^^^^^^^^ +note: ...due to this, which is why a type is expected after + --> $DIR/type-ascription-instead-of-statement-end.rs:9:21 + | +LL | println!("test"): 0; + | ^ + = help: this might be indicative of a syntax error elsewhere error: aborting due to 2 previous errors From b1a6c3266003698c6ac8153619e6059faf7fbac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 13 Mar 2019 15:27:47 -0700 Subject: [PATCH 23/38] Tweak labels --- src/librustc_resolve/lib.rs | 9 +++++++-- .../ui/suggestions/type-ascription-instead-of-let.stderr | 1 - .../suggestions/type-ascription-instead-of-path.stderr | 5 +---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 1a03292290288..5c5a27a6b43d2 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3289,8 +3289,7 @@ impl<'a> Resolver<'a> { let line_sp = cm.lookup_char_pos(sp.hi()).line; let line_base_sp = cm.lookup_char_pos(base_span.lo()).line; if snippet == ":" { - err.span_label(base_span, - "expecting a type here because of type ascription"); + let mut show_label = true; if line_sp != line_base_sp { err.span_suggestion_short( sp, @@ -3312,6 +3311,7 @@ impl<'a> Resolver<'a> { "::".to_string(), Applicability::MaybeIncorrect, ); + show_label = false; } if let Ok(base_snippet) = base_snippet { err.span_suggestion( @@ -3320,8 +3320,13 @@ impl<'a> Resolver<'a> { format!("let {}", base_snippet), Applicability::MaybeIncorrect, ); + show_label = false; } } + if show_label { + err.span_label(base_span, + "expecting a type here because of type ascription"); + } break; } else if !snippet.trim().is_empty() { debug!("tried to find type ascription `:` token, couldn't find it"); diff --git a/src/test/ui/suggestions/type-ascription-instead-of-let.stderr b/src/test/ui/suggestions/type-ascription-instead-of-let.stderr index 1efa94a553212..7f6aaef49f72b 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-let.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-let.stderr @@ -5,7 +5,6 @@ LL | temp: i32 = fun(5i32); | ^^^^ | | | not found in this scope - | expecting a type here because of type ascription | help: maybe you meant to write an assignment here: `let temp` error[E0425]: cannot find value `temp` in this scope diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path.stderr b/src/test/ui/suggestions/type-ascription-instead-of-path.stderr index e371611ccff63..9fe0c3b743c1f 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-path.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-path.stderr @@ -8,10 +8,7 @@ error[E0423]: expected value, found module `std` --> $DIR/type-ascription-instead-of-path.rs:2:5 | LL | std:io::stdin(); - | ^^^ - | | - | not a value - | expecting a type here because of type ascription + | ^^^ not a value help: maybe you meant to write a path separator here | LL | std::io::stdin(); From 72a3089092da16c247d57915f5e4b99adf2fea4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 13 Mar 2019 16:07:44 -0700 Subject: [PATCH 24/38] Only suggest let assignment for type ascription if we find an equals sign --- src/librustc_resolve/lib.rs | 28 ++++++++++++++----- .../type-ascription-instead-of-path.stderr | 12 ++------ 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 5c5a27a6b43d2..12ded62a5d9aa 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3314,13 +3314,27 @@ impl<'a> Resolver<'a> { show_label = false; } if let Ok(base_snippet) = base_snippet { - err.span_suggestion( - base_span, - "maybe you meant to write an assignment here", - format!("let {}", base_snippet), - Applicability::MaybeIncorrect, - ); - show_label = false; + let mut sp = after_colon_sp; + for _ in 0..100 { + // Try to find an assignment + sp = cm.next_point(sp); + let snippet = cm.span_to_snippet(sp.to(cm.next_point(sp))); + match snippet { + Ok(ref x) if x.as_str() == "=" => { + err.span_suggestion( + base_span, + "maybe you meant to write an assignment here", + format!("let {}", base_snippet), + Applicability::MaybeIncorrect, + ); + show_label = false; + break; + } + Ok(ref x) if x.as_str() == "\n" => break, + Err(_) => break, + Ok(_) => {} + } + } } } if show_label { diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path.stderr b/src/test/ui/suggestions/type-ascription-instead-of-path.stderr index 9fe0c3b743c1f..9908b3f679893 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-path.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-path.stderr @@ -8,15 +8,9 @@ error[E0423]: expected value, found module `std` --> $DIR/type-ascription-instead-of-path.rs:2:5 | LL | std:io::stdin(); - | ^^^ not a value -help: maybe you meant to write a path separator here - | -LL | std::io::stdin(); - | ^^ -help: maybe you meant to write an assignment here - | -LL | let std:io::stdin(); - | ^^^^^^^ + | ^^^- help: maybe you meant to write a path separator here: `::` + | | + | not a value error[E0658]: type ascription is experimental (see issue #23416) --> $DIR/type-ascription-instead-of-path.rs:2:5 From 81b876b6a3e3e489fdad8514f69b67264ab1d338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 13 Mar 2019 16:47:55 -0700 Subject: [PATCH 25/38] Hide "type ascription is experimental error" unless it's the only one In order to minimize the verbosity of common syntax errors that are parsed as type ascription, hide the feature gate error unless there are no other errors being emitted by the parser. --- src/libsyntax/feature_gate.rs | 8 ++++++-- .../suggestions/type-ascription-instead-of-let.rs | 1 - .../type-ascription-instead-of-let.stderr | 15 +++------------ .../type-ascription-instead-of-path.rs | 1 - .../type-ascription-instead-of-path.stderr | 12 ++---------- 5 files changed, 11 insertions(+), 26 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 9beaabb0cd58b..2816efaeb70e0 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1836,8 +1836,12 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, box_syntax, e.span, EXPLAIN_BOX_SYNTAX); } ast::ExprKind::Type(..) => { - gate_feature_post!(&self, type_ascription, e.span, - "type ascription is experimental"); + // To avoid noise about type ascription in common syntax errors, only emit if it + // is the *only* error. + if self.context.parse_sess.span_diagnostic.err_count() == 0 { + gate_feature_post!(&self, type_ascription, e.span, + "type ascription is experimental"); + } } ast::ExprKind::ObsoleteInPlace(..) => { // these get a hard error in ast-validation diff --git a/src/test/ui/suggestions/type-ascription-instead-of-let.rs b/src/test/ui/suggestions/type-ascription-instead-of-let.rs index 51d3d32565f8a..0e1c307502728 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-let.rs +++ b/src/test/ui/suggestions/type-ascription-instead-of-let.rs @@ -4,7 +4,6 @@ fn main() { let closure_annotated = |value: i32| -> i32 { temp: i32 = fun(5i32); //~^ ERROR cannot find value `temp` in this scope - //~| ERROR type ascription is experimental temp + value + 1 //~^ ERROR cannot find value `temp` in this scope }; diff --git a/src/test/ui/suggestions/type-ascription-instead-of-let.stderr b/src/test/ui/suggestions/type-ascription-instead-of-let.stderr index 7f6aaef49f72b..92e4b5798c889 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-let.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-let.stderr @@ -8,20 +8,11 @@ LL | temp: i32 = fun(5i32); | help: maybe you meant to write an assignment here: `let temp` error[E0425]: cannot find value `temp` in this scope - --> $DIR/type-ascription-instead-of-let.rs:8:9 + --> $DIR/type-ascription-instead-of-let.rs:7:9 | LL | temp + value + 1 | ^^^^ not found in this scope -error[E0658]: type ascription is experimental (see issue #23416) - --> $DIR/type-ascription-instead-of-let.rs:5:9 - | -LL | temp: i32 = fun(5i32); - | ^^^^^^^^^ - | - = help: add #![feature(type_ascription)] to the crate attributes to enable - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors occurred: E0425, E0658. -For more information about an error, try `rustc --explain E0425`. +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path.rs b/src/test/ui/suggestions/type-ascription-instead-of-path.rs index a81996ed7bb6b..4c0fe6d8b5b4e 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-path.rs +++ b/src/test/ui/suggestions/type-ascription-instead-of-path.rs @@ -2,5 +2,4 @@ fn main() { std:io::stdin(); //~^ ERROR failed to resolve: use of undeclared type or module `io` //~| ERROR expected value, found module - //~| ERROR type ascription is experimental } diff --git a/src/test/ui/suggestions/type-ascription-instead-of-path.stderr b/src/test/ui/suggestions/type-ascription-instead-of-path.stderr index 9908b3f679893..1beb822d6a749 100644 --- a/src/test/ui/suggestions/type-ascription-instead-of-path.stderr +++ b/src/test/ui/suggestions/type-ascription-instead-of-path.stderr @@ -12,15 +12,7 @@ LL | std:io::stdin(); | | | not a value -error[E0658]: type ascription is experimental (see issue #23416) - --> $DIR/type-ascription-instead-of-path.rs:2:5 - | -LL | std:io::stdin(); - | ^^^^^^^^^^^^^^^ - | - = help: add #![feature(type_ascription)] to the crate attributes to enable - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors occurred: E0423, E0433, E0658. +Some errors occurred: E0423, E0433. For more information about an error, try `rustc --explain E0423`. From 44a086ef39b2a6e6ed231869a5166bec7c4b7511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 19 Mar 2019 18:16:55 -0700 Subject: [PATCH 26/38] Review comment --- src/libsyntax/parse/parser.rs | 4 ++-- src/test/ui/error-codes/E0423.stderr | 4 ++-- src/test/ui/issues/issue-22644.stderr | 2 +- src/test/ui/issues/issue-34255-1.stderr | 2 +- src/test/ui/lifetime_starts_expressions.stderr | 2 +- src/test/ui/parser/struct-literal-in-for.stderr | 2 +- src/test/ui/parser/struct-literal-in-if.stderr | 2 +- src/test/ui/parser/struct-literal-in-while.stderr | 2 +- .../ui/parser/struct-literal-restrictions-in-lamda.stderr | 2 +- .../ui/type/type-ascription-instead-of-statement-end.stderr | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d052abf96d799..d5b64eaaef549 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3704,8 +3704,8 @@ impl<'a> Parser<'a> { Applicability::MaybeIncorrect, ); } else { - err.note("type ascription is a nightly only feature that lets \ - you annotate expressions with a type: `: `"); + err.note("type ascription is a nightly-only feature that lets \ + you annotate an expression with a type: `: `"); err.span_note( lhs_span, "this expression is annotated with type ascription...", diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index af5f88f4ce5f3..29a264ba1628d 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -4,7 +4,7 @@ error: expected type, found `1` LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/E0423.rs:12:36 | @@ -29,7 +29,7 @@ error: expected type, found `0` LL | for _ in std::ops::Range { start: 0, end: 10 } {} | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/E0423.rs:21:32 | diff --git a/src/test/ui/issues/issue-22644.stderr b/src/test/ui/issues/issue-22644.stderr index 08758ce9c9458..5d40909f09743 100644 --- a/src/test/ui/issues/issue-22644.stderr +++ b/src/test/ui/issues/issue-22644.stderr @@ -89,7 +89,7 @@ error: expected type, found `4` LL | println!("{}", a: &mut 4); | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/issue-22644.rs:34:20 | diff --git a/src/test/ui/issues/issue-34255-1.stderr b/src/test/ui/issues/issue-34255-1.stderr index ea324302d4043..1577970542608 100644 --- a/src/test/ui/issues/issue-34255-1.stderr +++ b/src/test/ui/issues/issue-34255-1.stderr @@ -4,7 +4,7 @@ error: expected type, found `42` LL | Test::Drill(field: 42); | ^^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/issue-34255-1.rs:8:17 | diff --git a/src/test/ui/lifetime_starts_expressions.stderr b/src/test/ui/lifetime_starts_expressions.stderr index 3de3298e3b52b..850e3563cab28 100644 --- a/src/test/ui/lifetime_starts_expressions.stderr +++ b/src/test/ui/lifetime_starts_expressions.stderr @@ -14,7 +14,7 @@ error: expected type, found keyword `loop` LL | loop { break 'label: loop { break 'label 42; }; } | ^^^^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/lifetime_starts_expressions.rs:6:12 | diff --git a/src/test/ui/parser/struct-literal-in-for.stderr b/src/test/ui/parser/struct-literal-in-for.stderr index 2940f465826b6..9056fac422691 100644 --- a/src/test/ui/parser/struct-literal-in-for.stderr +++ b/src/test/ui/parser/struct-literal-in-for.stderr @@ -4,7 +4,7 @@ error: expected type, found `3` LL | x: 3 | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/struct-literal-in-for.rs:13:9 | diff --git a/src/test/ui/parser/struct-literal-in-if.stderr b/src/test/ui/parser/struct-literal-in-if.stderr index e7d22ae0292e6..558f5a15cc5b5 100644 --- a/src/test/ui/parser/struct-literal-in-if.stderr +++ b/src/test/ui/parser/struct-literal-in-if.stderr @@ -4,7 +4,7 @@ error: expected type, found `3` LL | x: 3 | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/struct-literal-in-if.rs:13:9 | diff --git a/src/test/ui/parser/struct-literal-in-while.stderr b/src/test/ui/parser/struct-literal-in-while.stderr index 038e30956ff53..ae6e1d4577c3b 100644 --- a/src/test/ui/parser/struct-literal-in-while.stderr +++ b/src/test/ui/parser/struct-literal-in-while.stderr @@ -4,7 +4,7 @@ error: expected type, found `3` LL | x: 3 | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/struct-literal-in-while.rs:13:9 | diff --git a/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr index b3a6f6ac73483..6dbf7eb1b10f7 100644 --- a/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr +++ b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr @@ -4,7 +4,7 @@ error: expected type, found `3` LL | x: 3 | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/struct-literal-restrictions-in-lamda.rs:13:9 | diff --git a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr index 4077be9d08280..c80056e448795 100644 --- a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr +++ b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr @@ -12,7 +12,7 @@ error: expected type, found `0` LL | println!("test"): 0; | ^ expecting a type here because of type ascription | - = note: type ascription is a nightly only feature that lets you annotate expressions with a type: `: ` + = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` note: this expression is annotated with type ascription... --> $DIR/type-ascription-instead-of-statement-end.rs:9:5 | From d72ef21ddd4d56b3ec169a5ed64fa4cbf778c5c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 22 Mar 2019 20:14:20 -0700 Subject: [PATCH 27/38] Reword type ascription note to reduce verbosity --- src/libsyntax/parse/parser.rs | 6 +----- src/test/ui/error-codes/E0423.stderr | 14 ++------------ src/test/ui/issues/issue-22644.stderr | 7 +------ src/test/ui/issues/issue-34255-1.stderr | 7 +------ src/test/ui/lifetime_starts_expressions.stderr | 7 +------ src/test/ui/parser/struct-literal-in-for.stderr | 7 +------ src/test/ui/parser/struct-literal-in-if.stderr | 7 +------ src/test/ui/parser/struct-literal-in-while.stderr | 7 +------ .../struct-literal-restrictions-in-lamda.stderr | 7 +------ ...type-ascription-instead-of-statement-end.stderr | 7 +------ 10 files changed, 11 insertions(+), 65 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d5b64eaaef549..ea81094a996fb 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3708,11 +3708,7 @@ impl<'a> Parser<'a> { you annotate an expression with a type: `: `"); err.span_note( lhs_span, - "this expression is annotated with type ascription...", - ); - err.span_note( - cur_op_span, - "...due to this, which is why a type is expected after", + "this expression expects an ascribed type after the colon", ); err.help("this might be indicative of a syntax error elsewhere"); } diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr index 29a264ba1628d..b0ef4e1b25413 100644 --- a/src/test/ui/error-codes/E0423.stderr +++ b/src/test/ui/error-codes/E0423.stderr @@ -5,16 +5,11 @@ LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/E0423.rs:12:36 | LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } | ^ -note: ...due to this, which is why a type is expected after - --> $DIR/E0423.rs:12:37 - | -LL | if let S { x: _x, y: 2 } = S { x: 1, y: 2 } { println!("Ok"); } - | ^ = help: this might be indicative of a syntax error elsewhere error: expected expression, found `==` @@ -30,16 +25,11 @@ LL | for _ in std::ops::Range { start: 0, end: 10 } {} | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/E0423.rs:21:32 | LL | for _ in std::ops::Range { start: 0, end: 10 } {} | ^^^^^ -note: ...due to this, which is why a type is expected after - --> $DIR/E0423.rs:21:37 - | -LL | for _ in std::ops::Range { start: 0, end: 10 } {} - | ^ = help: this might be indicative of a syntax error elsewhere error[E0423]: expected function, found struct `Foo` diff --git a/src/test/ui/issues/issue-22644.stderr b/src/test/ui/issues/issue-22644.stderr index 5d40909f09743..a28ea0d09f8f0 100644 --- a/src/test/ui/issues/issue-22644.stderr +++ b/src/test/ui/issues/issue-22644.stderr @@ -90,16 +90,11 @@ LL | println!("{}", a: &mut 4); | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/issue-22644.rs:34:20 | LL | println!("{}", a: &mut 4); | ^ -note: ...due to this, which is why a type is expected after - --> $DIR/issue-22644.rs:34:21 - | -LL | println!("{}", a: &mut 4); - | ^ = help: this might be indicative of a syntax error elsewhere error: aborting due to 9 previous errors diff --git a/src/test/ui/issues/issue-34255-1.stderr b/src/test/ui/issues/issue-34255-1.stderr index 1577970542608..7899c8d30f1dd 100644 --- a/src/test/ui/issues/issue-34255-1.stderr +++ b/src/test/ui/issues/issue-34255-1.stderr @@ -5,16 +5,11 @@ LL | Test::Drill(field: 42); | ^^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/issue-34255-1.rs:8:17 | LL | Test::Drill(field: 42); | ^^^^^ -note: ...due to this, which is why a type is expected after - --> $DIR/issue-34255-1.rs:8:22 - | -LL | Test::Drill(field: 42); - | ^ = help: this might be indicative of a syntax error elsewhere error: aborting due to previous error diff --git a/src/test/ui/lifetime_starts_expressions.stderr b/src/test/ui/lifetime_starts_expressions.stderr index 850e3563cab28..cb5a52a3e081a 100644 --- a/src/test/ui/lifetime_starts_expressions.stderr +++ b/src/test/ui/lifetime_starts_expressions.stderr @@ -15,16 +15,11 @@ LL | loop { break 'label: loop { break 'label 42; }; } | ^^^^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/lifetime_starts_expressions.rs:6:12 | LL | loop { break 'label: loop { break 'label 42; }; } | ^^^^^^^^^^^^ -note: ...due to this, which is why a type is expected after - --> $DIR/lifetime_starts_expressions.rs:6:24 - | -LL | loop { break 'label: loop { break 'label 42; }; } - | ^ = help: this might be indicative of a syntax error elsewhere error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/struct-literal-in-for.stderr b/src/test/ui/parser/struct-literal-in-for.stderr index 9056fac422691..07f2e41ac4fb0 100644 --- a/src/test/ui/parser/struct-literal-in-for.stderr +++ b/src/test/ui/parser/struct-literal-in-for.stderr @@ -5,16 +5,11 @@ LL | x: 3 | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/struct-literal-in-for.rs:13:9 | LL | x: 3 | ^ -note: ...due to this, which is why a type is expected after - --> $DIR/struct-literal-in-for.rs:13:10 - | -LL | x: 3 - | ^ = help: this might be indicative of a syntax error elsewhere error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{` diff --git a/src/test/ui/parser/struct-literal-in-if.stderr b/src/test/ui/parser/struct-literal-in-if.stderr index 558f5a15cc5b5..3dd61e74f12ed 100644 --- a/src/test/ui/parser/struct-literal-in-if.stderr +++ b/src/test/ui/parser/struct-literal-in-if.stderr @@ -5,16 +5,11 @@ LL | x: 3 | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/struct-literal-in-if.rs:13:9 | LL | x: 3 | ^ -note: ...due to this, which is why a type is expected after - --> $DIR/struct-literal-in-if.rs:13:10 - | -LL | x: 3 - | ^ = help: this might be indicative of a syntax error elsewhere error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{` diff --git a/src/test/ui/parser/struct-literal-in-while.stderr b/src/test/ui/parser/struct-literal-in-while.stderr index ae6e1d4577c3b..d48244654cd02 100644 --- a/src/test/ui/parser/struct-literal-in-while.stderr +++ b/src/test/ui/parser/struct-literal-in-while.stderr @@ -5,16 +5,11 @@ LL | x: 3 | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/struct-literal-in-while.rs:13:9 | LL | x: 3 | ^ -note: ...due to this, which is why a type is expected after - --> $DIR/struct-literal-in-while.rs:13:10 - | -LL | x: 3 - | ^ = help: this might be indicative of a syntax error elsewhere error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{` diff --git a/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr index 6dbf7eb1b10f7..a8c93233dbc53 100644 --- a/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr +++ b/src/test/ui/parser/struct-literal-restrictions-in-lamda.stderr @@ -5,16 +5,11 @@ LL | x: 3 | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/struct-literal-restrictions-in-lamda.rs:13:9 | LL | x: 3 | ^ -note: ...due to this, which is why a type is expected after - --> $DIR/struct-literal-restrictions-in-lamda.rs:13:10 - | -LL | x: 3 - | ^ = help: this might be indicative of a syntax error elsewhere error: expected one of `.`, `;`, `?`, `}`, or an operator, found `{` diff --git a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr index c80056e448795..2084cbcce4f62 100644 --- a/src/test/ui/type/type-ascription-instead-of-statement-end.stderr +++ b/src/test/ui/type/type-ascription-instead-of-statement-end.stderr @@ -13,16 +13,11 @@ LL | println!("test"): 0; | ^ expecting a type here because of type ascription | = note: type ascription is a nightly-only feature that lets you annotate an expression with a type: `: ` -note: this expression is annotated with type ascription... +note: this expression expects an ascribed type after the colon --> $DIR/type-ascription-instead-of-statement-end.rs:9:5 | LL | println!("test"): 0; | ^^^^^^^^^^^^^^^^ -note: ...due to this, which is why a type is expected after - --> $DIR/type-ascription-instead-of-statement-end.rs:9:21 - | -LL | println!("test"): 0; - | ^ = help: this might be indicative of a syntax error elsewhere error: aborting due to 2 previous errors From 752544b28411540d7beb6fe4d1e2f1d8c775e05b Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Sat, 23 Mar 2019 18:29:02 +0530 Subject: [PATCH 28/38] adding mir::StaticKind enum for static and promoted --- src/librustc/mir/mod.rs | 47 ++++---- src/librustc/mir/visit.rs | 13 ++- src/librustc_codegen_ssa/mir/block.rs | 18 ++-- src/librustc_codegen_ssa/mir/place.rs | 8 +- .../borrow_check/error_reporting.rs | 19 ++-- src/librustc_mir/borrow_check/mod.rs | 30 ++++-- .../borrow_check/mutability_errors.rs | 10 +- .../borrow_check/nll/type_check/mod.rs | 62 ++++++----- src/librustc_mir/borrow_check/place_ext.rs | 9 +- .../borrow_check/places_conflict.rs | 100 +++++++++++------- src/librustc_mir/build/expr/as_place.rs | 3 +- src/librustc_mir/interpret/place.rs | 6 +- src/librustc_mir/monomorphize/collector.rs | 6 +- src/librustc_mir/transform/check_unsafety.rs | 9 +- src/librustc_mir/transform/const_prop.rs | 7 +- src/librustc_mir/transform/inline.rs | 4 +- src/librustc_mir/transform/promote_consts.rs | 18 ++-- src/librustc_mir/transform/qualify_consts.rs | 31 ++++-- .../transform/qualify_min_const_fn.rs | 4 +- 19 files changed, 238 insertions(+), 166 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 47b9535abc521..12f14cfbb9afa 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1915,19 +1915,22 @@ pub enum PlaceBase<'tcx> { Static(Box>), } -/// The `DefId` of a static, along with its normalized type (which is -/// stored to avoid requiring normalization when reading MIR). +/// We store the normalized type to avoid requiring normalization when reading MIR #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] pub struct Static<'tcx> { - pub def_id: DefId, pub ty: Ty<'tcx>, - pub promoted: Option, + pub kind: StaticKind, +} + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, RustcEncodable, RustcDecodable)] +pub enum StaticKind { + Promoted(Promoted), + Static(DefId), } impl_stable_hash_for!(struct Static<'tcx> { - def_id, ty, - promoted + kind }); /// The `Projection` data structure defines things of the form `B.x` @@ -2058,21 +2061,23 @@ impl<'tcx> Debug for Place<'tcx> { match *self { Base(PlaceBase::Local(id)) => write!(fmt, "{:?}", id), - Base(PlaceBase::Static(box self::Static { def_id, ty, promoted })) => { - match promoted { - None => write!( - fmt, - "({}: {:?})", - ty::tls::with(|tcx| tcx.def_path_str(def_id)), - ty - ), - Some(pr) => write!( - fmt, - "({:?}: {:?})", - pr, - ty - ), - } + Base(PlaceBase::Static(box self::Static { ty, kind: StaticKind::Static(def_id) })) => { + write!( + fmt, + "({}: {:?})", + ty::tls::with(|tcx| tcx.def_path_str(def_id)), + ty + ) + }, + Base(PlaceBase::Static( + box self::Static { ty, kind: StaticKind::Promoted(promoted) }) + ) => { + write!( + fmt, + "({:?}: {:?})", + promoted, + ty + ) }, Projection(ref data) => match data.elem { ProjectionElem::Downcast(ref adt_def, index) => { diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 3f6133a7331a1..b1e2df0ae986b 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -725,15 +725,18 @@ macro_rules! make_mir_visitor { place: & $($mutability)? Place<'tcx>, context: PlaceContext<'tcx>, location: Location) { + use crate::mir::{Static, StaticKind}; match place { Place::Base(PlaceBase::Local(local)) => { self.visit_local(local, context, location); } - Place::Base(PlaceBase::Static(static_)) => { - if static_.promoted.is_none() { - self.visit_def_id(& $($mutability)? static_.def_id, location); - } - self.visit_ty(& $($mutability)? static_.ty, TyContext::Location(location)); + Place::Base( + PlaceBase::Static(box Static{kind: StaticKind::Static(def_id), ..}) + ) => { + self.visit_def_id(& $($mutability)? *def_id, location) + } + Place::Base(PlaceBase::Static(box Static{ty, ..})) => { + self.visit_ty(& $($mutability)? *ty, TyContext::Location(location)); } Place::Projection(proj) => { self.visit_projection(proj, context, location); diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 066b38be3dbc2..4774f8fe5a380 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -1,7 +1,7 @@ use rustc::middle::lang_items; use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt}; -use rustc::mir::{self, Place, PlaceBase}; +use rustc::mir::{self, Place, PlaceBase, Static, StaticKind}; use rustc::mir::interpret::EvalErrorKind; use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode}; use rustc_target::spec::abi::Abi; @@ -621,14 +621,18 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // but specified directly in the code. This means it gets promoted // and we can then extract the value by evaluating the promoted. mir::Operand::Copy( - Place::Base(PlaceBase::Static( - box mir::Static {promoted: Some(promoted), ty, ..} - )) + Place::Base( + PlaceBase::Static( + box Static { kind: StaticKind::Promoted(promoted), ty } + ) + ) ) | mir::Operand::Move( - Place::Base(PlaceBase::Static( - box mir::Static {promoted: Some(promoted), ty, ..} - )) + Place::Base( + PlaceBase::Static( + box Static { kind: StaticKind::Promoted(promoted), ty } + ) + ) ) => { let param_env = ty::ParamEnv::reveal_all(); let cid = mir::interpret::GlobalId { diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 1608429b07024..7cafa0088a012 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -409,7 +409,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let result = match *place { mir::Place::Base(mir::PlaceBase::Local(_)) => bug!(), // handled above mir::Place::Base( - mir::PlaceBase::Static(box mir::Static { def_id: _, ty, promoted: Some(promoted) }) + mir::PlaceBase::Static( + box mir::Static { ty, kind: mir::StaticKind::Promoted(promoted) } + ) ) => { let param_env = ty::ParamEnv::reveal_all(); let cid = mir::interpret::GlobalId { @@ -438,7 +440,9 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } } mir::Place::Base( - mir::PlaceBase::Static(box mir::Static { def_id, ty, promoted: None }) + mir::PlaceBase::Static( + box mir::Static { ty, kind: mir::StaticKind::Static(def_id) } + ) ) => { // NB: The layout of a static may be unsized as is the case when working // with a static that is an extern_type. diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index b9877945e7eac..fac75989aa590 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -10,7 +10,7 @@ use rustc::mir::{ self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, Constant, ConstraintCategory, Field, Local, LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, PlaceProjection, ProjectionElem, Rvalue, Statement, StatementKind, - TerminatorKind, VarBindingForm, + Static, StaticKind, TerminatorKind, VarBindingForm, }; use rustc::ty::{self, DefIdTree}; use rustc::ty::print::Print; @@ -1601,12 +1601,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Place::Base(PlaceBase::Local(local)) => { self.append_local_to_string(local, buf)?; } - Place::Base(PlaceBase::Static(ref static_)) => { - if static_.promoted.is_some() { - buf.push_str("promoted"); - } else { - buf.push_str(&self.infcx.tcx.item_name(static_.def_id).to_string()); - } + Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => { + buf.push_str("promoted"); + } + Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => { + buf.push_str(&self.infcx.tcx.item_name(def_id).to_string()); } Place::Projection(ref proj) => { match proj.elem { @@ -1808,8 +1807,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { /// Checks if a place is a thread-local static. pub fn is_place_thread_local(&self, place: &Place<'tcx>) -> bool { - if let Place::Base(PlaceBase::Static(statik)) = place { - let attrs = self.infcx.tcx.get_attrs(statik.def_id); + if let Place::Base( + PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. }) + ) = place { + let attrs = self.infcx.tcx.get_attrs(*def_id); let is_thread_local = attrs.iter().any(|attr| attr.check_name("thread_local")); debug!( diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 0358fffcde587..40b329c108401 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -8,7 +8,9 @@ use rustc::infer::InferCtxt; use rustc::lint::builtin::UNUSED_MUT; use rustc::middle::borrowck::SignalledError; use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; -use rustc::mir::{ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Place, PlaceBase}; +use rustc::mir::{ + ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Place, PlaceBase, Static, StaticKind +}; use rustc::mir::{Field, Projection, ProjectionElem, Rvalue, Statement, StatementKind}; use rustc::mir::{Terminator, TerminatorKind}; use rustc::ty::query::Providers; @@ -1308,8 +1310,13 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // // FIXME: allow thread-locals to borrow other thread locals? let (might_be_alive, will_be_dropped) = match root_place { - Place::Base(PlaceBase::Static(st)) => { - (true, st.promoted.is_none() && self.is_place_thread_local(&root_place)) + Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => { + (true, false) + } + Place::Base(PlaceBase::Static(box Static{ kind: _, .. })) => { + // Thread-locals might be dropped after the function exits, but + // "true" statics will never be. + (true, self.is_place_thread_local(&root_place)) } Place::Base(PlaceBase::Local(_)) => { // Locals are always dropped at function exit, and if they @@ -1982,18 +1989,19 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } // The rules for promotion are made by `qualify_consts`, there wouldn't even be a // `Place::Promoted` if the promotion weren't 100% legal. So we just forward this - Place::Base(PlaceBase::Static(ref static_)) => { - if static_.promoted.is_some() || - (static_.promoted.is_none() && - self.infcx.tcx.is_static(static_.def_id) - == Some(hir::Mutability::MutMutable) - ){ + Place::Base(PlaceBase::Static(box Static{kind: StaticKind::Promoted(_), ..})) => + Ok(RootPlace { + place, + is_local_mutation_allowed, + }), + Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => { + if self.infcx.tcx.is_static(def_id) != Some(hir::Mutability::MutMutable) { + Err(place) + } else { Ok(RootPlace { place, is_local_mutation_allowed, }) - } else { - Err(place) } } Place::Projection(ref proj) => { diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index 2661d765718dd..f351212e9d587 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -1,7 +1,9 @@ use rustc::hir; use rustc::hir::Node; use rustc::mir::{self, BindingForm, Constant, ClearCrossCrate, Local, Location, Mir}; -use rustc::mir::{Mutability, Operand, Place, PlaceBase, Projection, ProjectionElem, Static}; +use rustc::mir::{ + Mutability, Operand, Place, PlaceBase, Projection, ProjectionElem, Static, StaticKind, +}; use rustc::mir::{Terminator, TerminatorKind}; use rustc::ty::{self, Const, DefIdTree, TyS, TyKind, TyCtxt}; use rustc_data_structures::indexed_vec::Idx; @@ -129,8 +131,10 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { } } - Place::Base(PlaceBase::Static(box Static { def_id, ty: _, promoted })) => { - assert!(promoted.is_none()); + Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) => + unreachable!(), + + Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. })) => { if let Place::Base(PlaceBase::Static(_)) = access_place { item_msg = format!("immutable static item `{}`", access_place_desc.unwrap()); reason = String::new(); diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 2a32b475c7991..e12077fd5f7ae 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -453,45 +453,53 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { Place::Base(PlaceBase::Local(index)) => PlaceTy::Ty { ty: self.mir.local_decls[index].ty, }, - Place::Base(PlaceBase::Static(box Static { def_id, ty: sty, promoted })) => { + Place::Base( + PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted), ty: sty }) + ) => { let sty = self.sanitize_type(place, sty); - let check_err = - |verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx> , - place: &Place<'tcx>, - ty, - sty| { - if let Err(terr) = verifier.cx.eq_types( + + if !self.errors_reported { + let promoted_mir = &self.mir.promoted[promoted]; + self.sanitize_promoted(promoted_mir, location); + + let promoted_ty = promoted_mir.return_ty(); + + if let Err(terr) = self.cx.eq_types( sty, - ty, + promoted_ty, location.to_locations(), ConstraintCategory::Boring, ) { span_mirbug!( - verifier, + self, place, "bad promoted type ({:?}: {:?}): {:?}", - ty, + promoted_ty, sty, terr ); }; - }; - match promoted { - Some(pr) => { - if !self.errors_reported { - let promoted_mir = &self.mir.promoted[pr]; - self.sanitize_promoted(promoted_mir, location); - - let promoted_ty = promoted_mir.return_ty(); - check_err(self, place, promoted_ty, sty); - } - } - None => { - let ty = self.tcx().type_of(def_id); - let ty = self.cx.normalize(ty, location); - - check_err(self, place, ty, sty); - } + } + PlaceTy::Ty { ty: sty } + } + Place::Base( + PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), ty: sty }) + ) => { + let sty = self.sanitize_type(place, sty); + let ty = self.tcx().type_of(def_id); + let ty = self.cx.normalize(ty, location); + if let Err(terr) = + self.cx + .eq_types(ty, sty, location.to_locations(), ConstraintCategory::Boring) + { + span_mirbug!( + self, + place, + "bad static type ({:?}: {:?}): {:?}", + ty, + sty, + terr + ); } PlaceTy::Ty { ty: sty } } diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs index 0452465f0b9d7..6bc56ab721f98 100644 --- a/src/librustc_mir/borrow_check/place_ext.rs +++ b/src/librustc_mir/borrow_check/place_ext.rs @@ -1,6 +1,6 @@ use rustc::hir; use rustc::mir::ProjectionElem; -use rustc::mir::{Local, Mir, Place, PlaceBase, Mutability}; +use rustc::mir::{Local, Mir, Place, PlaceBase, Mutability, Static, StaticKind}; use rustc::ty::{self, TyCtxt}; use crate::borrow_check::borrow_set::LocalsStateAtExit; @@ -49,9 +49,10 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> { } } } - Place::Base(PlaceBase::Static(static_)) => { - static_.promoted.is_none() && - (tcx.is_static(static_.def_id) == Some(hir::Mutability::MutMutable)) + Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => + false, + Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => { + tcx.is_static(*def_id) == Some(hir::Mutability::MutMutable) } Place::Projection(proj) => match proj.elem { ProjectionElem::Field(..) diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index 783751056d76b..dc9b059de4657 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -2,7 +2,7 @@ use crate::borrow_check::ArtificialField; use crate::borrow_check::Overlap; use crate::borrow_check::{Deep, Shallow, AccessDepth}; use rustc::hir; -use rustc::mir::{BorrowKind, Mir, Place, PlaceBase, Projection, ProjectionElem}; +use rustc::mir::{BorrowKind, Mir, Place, PlaceBase, Projection, ProjectionElem, Static, StaticKind}; use rustc::ty::{self, TyCtxt}; use std::cmp::max; @@ -370,47 +370,71 @@ fn place_element_conflict<'a, 'gcx: 'tcx, 'tcx>( Overlap::Disjoint } } - (Place::Base(PlaceBase::Static(s1)), Place::Base(PlaceBase::Static(s2))) => { - match (s1.promoted, s2.promoted) { - (None, None) => { - if s1.def_id != s2.def_id { - debug!("place_element_conflict: DISJOINT-STATIC"); - Overlap::Disjoint - } else if tcx.is_static(s1.def_id) == Some(hir::Mutability::MutMutable) { - // We ignore mutable statics - they can only be unsafe code. - debug!("place_element_conflict: IGNORE-STATIC-MUT"); - Overlap::Disjoint - } else { - debug!("place_element_conflict: DISJOINT-OR-EQ-STATIC"); - Overlap::EqualOrDisjoint - } - }, - (Some(p1), Some(p2)) => { - if p1 == p2 { - if let ty::Array(_, size) = s1.ty.sty { - if size.unwrap_usize(tcx) == 0 { - // Ignore conflicts with promoted [T; 0]. - debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED"); - return Overlap::Disjoint; - } - } - // the same promoted - base case, equal - debug!("place_element_conflict: DISJOINT-OR-EQ-PROMOTED"); - Overlap::EqualOrDisjoint - } else { - // different promoteds - base case, disjoint - debug!("place_element_conflict: DISJOINT-PROMOTED"); - Overlap::Disjoint + ( + Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id_1), .. })), + Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id_2), .. })), + ) => { + if *def_id_1 != *def_id_2 { + debug!("place_element_conflict: DISJOINT-STATIC"); + Overlap::Disjoint + } else if tcx.is_static(*def_id_1) == Some(hir::Mutability::MutMutable) { + // We ignore mutable statics - they can only be unsafe code. + debug!("place_element_conflict: IGNORE-STATIC-MUT"); + Overlap::Disjoint + } else { + debug!("place_element_conflict: DISJOINT-OR-EQ-STATIC"); + Overlap::EqualOrDisjoint + } + } + ( + Place::Base( + PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted_1), ty }) + ), + Place::Base( + PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted_2), .. }) + ), + ) => { + if *promoted_1 == *promoted_2 { + if let ty::Array(_, size) = ty.sty { + if size.unwrap_usize(tcx) == 0 { + // Ignore conflicts with promoted [T; 0]. + debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED"); + return Overlap::Disjoint; } - }, - (_, _) => { - debug!("place_element_conflict: DISJOINT-STATIC-PROMOTED"); - Overlap::Disjoint } + // the same promoted - base case, equal + debug!("place_element_conflict: DISJOINT-OR-EQ-PROMOTED"); + Overlap::EqualOrDisjoint + } else { + // different promoteds - base case, disjoint + debug!("place_element_conflict: DISJOINT-PROMOTED"); + Overlap::Disjoint } } - (Place::Base(PlaceBase::Local(_)), Place::Base(PlaceBase::Static(_))) | - (Place::Base(PlaceBase::Static(_)), Place::Base(PlaceBase::Local(_))) => { + ( + Place::Base(PlaceBase::Local(_)), + Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) + ) | + ( + Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })), + Place::Base(PlaceBase::Local(_)) + ) | + ( + Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })), + Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(_), .. })) + ) | + ( + Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(_), .. })), + Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) + ) | + ( + Place::Base(PlaceBase::Local(_)), + Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(_), .. })) + ) | + ( + Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(_), .. })), + Place::Base(PlaceBase::Local(_)) + ) => { debug!("place_element_conflict: DISJOINT-STATIC-LOCAL-PROMOTED"); Overlap::Disjoint } diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 83e1d3ebb3e06..199d03ac445ba 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -126,9 +126,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { block.and(place) } ExprKind::StaticRef { id } => block.and(Place::Base(PlaceBase::Static(Box::new(Static { - def_id: id, ty: expr.ty, - promoted: None, + kind: StaticKind::Static(id), })))), ExprKind::PlaceTypeAscription { source, user_ty } => { diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 6089e491684e9..d2c279e48fe28 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -582,9 +582,9 @@ where ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { use rustc::mir::Place::*; use rustc::mir::PlaceBase; - use rustc::mir::Static; + use rustc::mir::{Static, StaticKind}; Ok(match *mir_place { - Base(PlaceBase::Static(box Static {promoted: Some(promoted), ty: _, ..})) => { + Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted), .. })) => { let instance = self.frame().instance; self.const_eval_raw(GlobalId { instance, @@ -592,7 +592,7 @@ where })? } - Base(PlaceBase::Static(box Static {promoted: None, ty, def_id})) => { + Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), ty })) => { assert!(!ty.needs_subst()); let layout = self.layout_of(ty)?; let instance = ty::Instance::mono(*self.tcx, def_id); diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 075b81e9fd98f..0ad6962cc4ac5 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -184,7 +184,7 @@ use rustc::ty::subst::{InternalSubsts, SubstsRef}; use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind}; use rustc::ty::adjustment::CustomCoerceUnsized; use rustc::session::config::EntryFnType; -use rustc::mir::{self, Location, Promoted}; +use rustc::mir::{self, Location, Place, PlaceBase, Promoted, Static, StaticKind}; use rustc::mir::visit::Visitor as MirVisitor; use rustc::mir::mono::MonoItem; use rustc::mir::interpret::{Scalar, GlobalId, AllocKind, ErrorHandled}; @@ -655,8 +655,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { context: mir::visit::PlaceContext<'tcx>, location: Location) { match place { - mir::Place::Base( - mir::PlaceBase::Static(box mir::Static{def_id, promoted:None, ..}) + Place::Base( + PlaceBase::Static(box Static{ kind:StaticKind::Static(def_id), .. }) ) => { debug!("visiting static {:?} @ {:?}", def_id, location); diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 2ebe28e6ac091..0e31515e4af90 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -300,9 +300,12 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { &Place::Base(PlaceBase::Local(..)) => { // locals are safe } - &Place::Base(PlaceBase::Static(box Static { def_id, ty: _, promoted })) => { - assert!(promoted.is_none(), "unsafety checking should happen before promotion"); - + &Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) => { + bug!("unsafety checking should happen before promotion") + } + &Place::Base( + PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. }) + ) => { if self.tcx.is_static(def_id) == Some(hir::Mutability::MutMutable) { self.require_unsafe("use of mutable static", "mutable statics can be mutated by multiple threads: aliasing violations \ diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 81cdb00100595..c2d594ba7b7fe 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -4,7 +4,7 @@ use rustc::hir::def::Def; use rustc::mir::{Constant, Location, Place, PlaceBase, Mir, Operand, Rvalue, Local}; -use rustc::mir::{NullOp, UnOp, StatementKind, Statement, BasicBlock, LocalKind}; +use rustc::mir::{NullOp, UnOp, StatementKind, Statement, BasicBlock, LocalKind, Static, StaticKind}; use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem}; use rustc::mir::visit::{Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext}; use rustc::mir::interpret::{EvalErrorKind, Scalar, GlobalId, EvalResult}; @@ -266,7 +266,6 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { } fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option> { - use rustc::mir::Static; match *place { Place::Base(PlaceBase::Local(loc)) => self.places[loc].clone(), Place::Projection(ref proj) => match proj.elem { @@ -283,7 +282,9 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { // an `Index` projection would throw us off-track. _ => None, }, - Place::Base(PlaceBase::Static(box Static {promoted: Some(promoted), ..})) => { + Place::Base( + PlaceBase::Static(box Static {kind: StaticKind::Promoted(promoted), ..}) + ) => { let generics = self.tcx.generics_of(self.source.def_id()); if generics.requires_monomorphization(self.tcx) { // FIXME: can't handle code with generics diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index ec2cf8a4c0348..1063381d6aa57 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -692,7 +692,9 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> { // Return pointer; update the place itself *place = self.destination.clone(); }, - Place::Base(PlaceBase::Static(box Static { promoted: Some(promoted), .. })) => { + Place::Base( + PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted), .. }) + ) => { if let Some(p) = self.promoted_map.get(*promoted).cloned() { *promoted = p; } diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 2344f070ea670..92039618d85d9 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -12,7 +12,6 @@ //! initialization and can otherwise silence errors, if //! move analysis runs after promotion on broken MIR. -use rustc::hir::def_id::DefId; use rustc::mir::*; use rustc::mir::visit::{PlaceContext, MutatingUseContext, MutVisitor, Visitor}; use rustc::mir::traversal::ReversePostorder; @@ -152,8 +151,7 @@ struct Promoter<'a, 'tcx: 'a> { /// If true, all nested temps are also kept in the /// source MIR, not moved to the promoted MIR. - keep_original: bool, - def_id: DefId, + keep_original: bool } impl<'a, 'tcx> Promoter<'a, 'tcx> { @@ -289,16 +287,16 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { } fn promote_candidate(mut self, candidate: Candidate) { - use rustc::mir::Static; let mut operand = { - let def_id = self.def_id; let promoted = &mut self.promoted; let promoted_id = Promoted::new(self.source.promoted.len()); let mut promoted_place = |ty, span| { promoted.span = span; - promoted.local_decls[RETURN_PLACE] = LocalDecl::new_return_place(ty, span); + promoted.local_decls[RETURN_PLACE] = + LocalDecl::new_return_place(ty, span); Place::Base( - PlaceBase::Static(Box::new(Static { def_id, ty, promoted: Some(promoted_id) }))) + PlaceBase::Static(box Static{ kind: StaticKind::Promoted(promoted_id), ty }) + ) }; let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut(); match candidate { @@ -371,8 +369,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> { pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, mut temps: IndexVec, - candidates: Vec, - def_id: DefId) { + candidates: Vec) { // Visit candidates in reverse, in case they're nested. debug!("promote_candidates({:?})", candidates); @@ -417,8 +414,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>, tcx, source: mir, temps: &mut temps, - keep_original: false, - def_id, + keep_original: false }; promoter.promote_candidate(candidate); } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index c01ed4b1c59e8..c35bf80bb2eda 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -188,8 +188,9 @@ trait Qualif { fn in_place(cx: &ConstCx<'_, 'tcx>, place: &Place<'tcx>) -> bool { match *place { Place::Base(PlaceBase::Local(local)) => Self::in_local(cx, local), + Place::Base(PlaceBase::Static(box Static {kind: StaticKind::Promoted(_), .. })) => + bug!("qualifying already promoted MIR"), Place::Base(PlaceBase::Static(ref static_)) => { - assert!(static_.promoted.is_none(), "qualifying already promoted MIR"); Self::in_static(cx, static_) }, Place::Projection(ref proj) => Self::in_projection(cx, proj), @@ -372,11 +373,18 @@ impl Qualif for IsNotConst { const IDX: usize = 2; fn in_static(cx: &ConstCx<'_, 'tcx>, static_: &Static<'tcx>) -> bool { - // Only allow statics (not consts) to refer to other statics. - let allowed = cx.mode == Mode::Static || cx.mode == Mode::StaticMut; + match static_.kind { + StaticKind::Promoted(_) => unreachable!(), + StaticKind::Static(def_id) => { + // Only allow statics (not consts) to refer to other statics. + let allowed = cx.mode == Mode::Static || cx.mode == Mode::StaticMut; - !allowed || - cx.tcx.get_attrs(static_.def_id).iter().any(|attr| attr.check_name("thread_local")) + !allowed || + cx.tcx.get_attrs(def_id).iter().any( + |attr| attr.check_name("thread_local" + )) + } + } } fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &PlaceProjection<'tcx>) -> bool { @@ -770,8 +778,9 @@ impl<'a, 'tcx> Checker<'a, 'tcx> { ); dest = &proj.base; }, - Place::Base(PlaceBase::Static(st)) => { - assert!(st.promoted.is_none(), "promoteds don't exist yet during promotion"); + Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => + bug!("promoteds don't exist yet during promotion"), + Place::Base(PlaceBase::Static(box Static{ kind: _, .. })) => { // Catch more errors in the destination. `visit_place` also checks that we // do not try to access statics from constants or try to mutate statics self.visit_place( @@ -921,10 +930,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { self.super_place(place, context, location); match *place { Place::Base(PlaceBase::Local(_)) => {} - Place::Base(PlaceBase::Static(ref global)) => { - assert!(global.promoted.is_none()); + Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => {} + Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => { if self.tcx - .get_attrs(global.def_id) + .get_attrs(def_id) .iter() .any(|attr| attr.check_name("thread_local")) { if self.mode != Mode::Fn { @@ -1516,7 +1525,7 @@ impl MirPass for QualifyAndPromoteConstants { }; // Do the actual promotion, now that we know what's viable. - promote_consts::promote_candidates(mir, tcx, temps, candidates, def_id); + promote_consts::promote_candidates(mir, tcx, temps, candidates); } else { if !mir.control_flow_destroyed.is_empty() { let mut locals = mir.vars_iter(); diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index da849faf40aae..8742c5d759c8f 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -257,8 +257,8 @@ fn check_place( match place { Place::Base(PlaceBase::Local(_)) => Ok(()), // promoteds are always fine, they are essentially constants - Place::Base(PlaceBase::Static(box Static {def_id: _, ty: _, promoted: Some(_)})) => Ok(()), - Place::Base(PlaceBase::Static(box Static {def_id: _, ty: _, promoted: None})) => + Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) => Ok(()), + Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(_), .. })) => Err((span, "cannot access `static` items in const fn".into())), Place::Projection(proj) => { match proj.elem { From fb93f10dac46376b706643a74f3ebbabaf46c48f Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Sun, 24 Mar 2019 08:59:11 +0530 Subject: [PATCH 29/38] code review fixes --- src/librustc/mir/visit.rs | 11 +- src/librustc_mir/borrow_check/mod.rs | 2 +- .../borrow_check/nll/type_check/mod.rs | 76 ++++++------- .../borrow_check/places_conflict.rs | 100 +++++++----------- src/librustc_mir/transform/promote_consts.rs | 3 +- src/librustc_mir/transform/qualify_consts.rs | 4 +- 6 files changed, 81 insertions(+), 115 deletions(-) diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index b1e2df0ae986b..54e5bfc4397e8 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -725,17 +725,14 @@ macro_rules! make_mir_visitor { place: & $($mutability)? Place<'tcx>, context: PlaceContext<'tcx>, location: Location) { - use crate::mir::{Static, StaticKind}; match place { Place::Base(PlaceBase::Local(local)) => { self.visit_local(local, context, location); } - Place::Base( - PlaceBase::Static(box Static{kind: StaticKind::Static(def_id), ..}) - ) => { - self.visit_def_id(& $($mutability)? *def_id, location) - } - Place::Base(PlaceBase::Static(box Static{ty, ..})) => { + Place::Base(PlaceBase::Static(box Static { kind, ty })) => { + if let StaticKind::Static(def_id) = kind { + self.visit_def_id(& $($mutability)? *def_id, location) + } self.visit_ty(& $($mutability)? *ty, TyContext::Location(location)); } Place::Projection(proj) => { diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 40b329c108401..a3909486610e0 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1313,7 +1313,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => { (true, false) } - Place::Base(PlaceBase::Static(box Static{ kind: _, .. })) => { + Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(_), .. })) => { // Thread-locals might be dropped after the function exits, but // "true" statics will never be. (true, self.is_place_thread_local(&root_place)) diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index e12077fd5f7ae..aab650383cfec 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -449,57 +449,49 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { context: PlaceContext<'_>, ) -> PlaceTy<'tcx> { debug!("sanitize_place: {:?}", place); - let place_ty = match *place { + let place_ty = match place { Place::Base(PlaceBase::Local(index)) => PlaceTy::Ty { - ty: self.mir.local_decls[index].ty, + ty: self.mir.local_decls[*index].ty, }, - Place::Base( - PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted), ty: sty }) - ) => { + Place::Base(PlaceBase::Static(box Static { kind, ty: sty })) => { let sty = self.sanitize_type(place, sty); - - if !self.errors_reported { - let promoted_mir = &self.mir.promoted[promoted]; - self.sanitize_promoted(promoted_mir, location); - - let promoted_ty = promoted_mir.return_ty(); - - if let Err(terr) = self.cx.eq_types( - sty, - promoted_ty, - location.to_locations(), - ConstraintCategory::Boring, - ) { - span_mirbug!( - self, + let check_err = + |verifier: &mut TypeVerifier<'a, 'b, 'gcx, 'tcx>, + place: &Place<'tcx>, + ty, + sty| { + if let Err(terr) = verifier.cx.eq_types( + sty, + ty, + location.to_locations(), + ConstraintCategory::Boring, + ) { + span_mirbug!( + verifier, place, "bad promoted type ({:?}: {:?}): {:?}", - promoted_ty, + ty, sty, terr ); + }; }; - } - PlaceTy::Ty { ty: sty } - } - Place::Base( - PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), ty: sty }) - ) => { - let sty = self.sanitize_type(place, sty); - let ty = self.tcx().type_of(def_id); - let ty = self.cx.normalize(ty, location); - if let Err(terr) = - self.cx - .eq_types(ty, sty, location.to_locations(), ConstraintCategory::Boring) - { - span_mirbug!( - self, - place, - "bad static type ({:?}: {:?}): {:?}", - ty, - sty, - terr - ); + match kind { + StaticKind::Promoted(promoted) => { + if !self.errors_reported { + let promoted_mir = &self.mir.promoted[*promoted]; + self.sanitize_promoted(promoted_mir, location); + + let promoted_ty = promoted_mir.return_ty(); + check_err(self, place, promoted_ty, sty); + } + } + StaticKind::Static(def_id) => { + let ty = self.tcx().type_of(*def_id); + let ty = self.cx.normalize(ty, location); + + check_err(self, place, ty, sty); + } } PlaceTy::Ty { ty: sty } } diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs index dc9b059de4657..52119d6b19bc0 100644 --- a/src/librustc_mir/borrow_check/places_conflict.rs +++ b/src/librustc_mir/borrow_check/places_conflict.rs @@ -2,7 +2,7 @@ use crate::borrow_check::ArtificialField; use crate::borrow_check::Overlap; use crate::borrow_check::{Deep, Shallow, AccessDepth}; use rustc::hir; -use rustc::mir::{BorrowKind, Mir, Place, PlaceBase, Projection, ProjectionElem, Static, StaticKind}; +use rustc::mir::{BorrowKind, Mir, Place, PlaceBase, Projection, ProjectionElem, StaticKind}; use rustc::ty::{self, TyCtxt}; use std::cmp::max; @@ -370,71 +370,47 @@ fn place_element_conflict<'a, 'gcx: 'tcx, 'tcx>( Overlap::Disjoint } } - ( - Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id_1), .. })), - Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id_2), .. })), - ) => { - if *def_id_1 != *def_id_2 { - debug!("place_element_conflict: DISJOINT-STATIC"); - Overlap::Disjoint - } else if tcx.is_static(*def_id_1) == Some(hir::Mutability::MutMutable) { - // We ignore mutable statics - they can only be unsafe code. - debug!("place_element_conflict: IGNORE-STATIC-MUT"); - Overlap::Disjoint - } else { - debug!("place_element_conflict: DISJOINT-OR-EQ-STATIC"); - Overlap::EqualOrDisjoint - } - } - ( - Place::Base( - PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted_1), ty }) - ), - Place::Base( - PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted_2), .. }) - ), - ) => { - if *promoted_1 == *promoted_2 { - if let ty::Array(_, size) = ty.sty { - if size.unwrap_usize(tcx) == 0 { - // Ignore conflicts with promoted [T; 0]. - debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED"); - return Overlap::Disjoint; + (Place::Base(PlaceBase::Static(s1)), Place::Base(PlaceBase::Static(s2))) => { + match (&s1.kind, &s2.kind) { + (StaticKind::Static(def_id_1), StaticKind::Static(def_id_2)) => { + if def_id_1 != def_id_2 { + debug!("place_element_conflict: DISJOINT-STATIC"); + Overlap::Disjoint + } else if tcx.is_static(*def_id_1) == Some(hir::Mutability::MutMutable) { + // We ignore mutable statics - they can only be unsafe code. + debug!("place_element_conflict: IGNORE-STATIC-MUT"); + Overlap::Disjoint + } else { + debug!("place_element_conflict: DISJOINT-OR-EQ-STATIC"); + Overlap::EqualOrDisjoint } + }, + (StaticKind::Promoted(promoted_1), StaticKind::Promoted(promoted_2)) => { + if promoted_1 == promoted_2 { + if let ty::Array(_, size) = s1.ty.sty { + if size.unwrap_usize(tcx) == 0 { + // Ignore conflicts with promoted [T; 0]. + debug!("place_element_conflict: IGNORE-LEN-0-PROMOTED"); + return Overlap::Disjoint; + } + } + // the same promoted - base case, equal + debug!("place_element_conflict: DISJOINT-OR-EQ-PROMOTED"); + Overlap::EqualOrDisjoint + } else { + // different promoteds - base case, disjoint + debug!("place_element_conflict: DISJOINT-PROMOTED"); + Overlap::Disjoint + } + }, + (_, _) => { + debug!("place_element_conflict: DISJOINT-STATIC-PROMOTED"); + Overlap::Disjoint } - // the same promoted - base case, equal - debug!("place_element_conflict: DISJOINT-OR-EQ-PROMOTED"); - Overlap::EqualOrDisjoint - } else { - // different promoteds - base case, disjoint - debug!("place_element_conflict: DISJOINT-PROMOTED"); - Overlap::Disjoint } } - ( - Place::Base(PlaceBase::Local(_)), - Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) - ) | - ( - Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })), - Place::Base(PlaceBase::Local(_)) - ) | - ( - Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })), - Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(_), .. })) - ) | - ( - Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(_), .. })), - Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. })) - ) | - ( - Place::Base(PlaceBase::Local(_)), - Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(_), .. })) - ) | - ( - Place::Base(PlaceBase::Static(box Static { kind: StaticKind::Static(_), .. })), - Place::Base(PlaceBase::Local(_)) - ) => { + (Place::Base(PlaceBase::Local(_)), Place::Base(PlaceBase::Static(_))) | + (Place::Base(PlaceBase::Static(_)), Place::Base(PlaceBase::Local(_))) => { debug!("place_element_conflict: DISJOINT-STATIC-LOCAL-PROMOTED"); Overlap::Disjoint } diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 92039618d85d9..73b88e9904bf2 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -292,8 +292,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let promoted_id = Promoted::new(self.source.promoted.len()); let mut promoted_place = |ty, span| { promoted.span = span; - promoted.local_decls[RETURN_PLACE] = - LocalDecl::new_return_place(ty, span); + promoted.local_decls[RETURN_PLACE] = LocalDecl::new_return_place(ty, span); Place::Base( PlaceBase::Static(box Static{ kind: StaticKind::Promoted(promoted_id), ty }) ) diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index c35bf80bb2eda..0b9ad85e6b1c7 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -930,7 +930,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> { self.super_place(place, context, location); match *place { Place::Base(PlaceBase::Local(_)) => {} - Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => {} + Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. })) => { + unreachable!() + } Place::Base(PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. })) => { if self.tcx .get_attrs(def_id) From 8d7c2bb06a6829a96204912e5bd9e00e71195ffb Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Sat, 23 Mar 2019 21:13:57 -0400 Subject: [PATCH 30/38] replace redundant note in deprecation warning --- src/librustc/middle/stability.rs | 2 +- .../ui/deprecation/atomic_initializers.stderr | 6 +--- src/test/ui/deprecation/suggestion.fixed | 28 +++++++++++++++++++ src/test/ui/deprecation/suggestion.rs | 28 +++++++++++++++++++ src/test/ui/deprecation/suggestion.stderr | 14 ++++++++++ 5 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/deprecation/suggestion.fixed create mode 100644 src/test/ui/deprecation/suggestion.rs create mode 100644 src/test/ui/deprecation/suggestion.stderr diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 72c90b258608d..54e593deb3289 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -576,7 +576,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { if let hir::Node::Expr(_) = self.hir().get_by_hir_id(id) { diag.span_suggestion( span, - &msg, + "replace the use of the deprecated item", suggestion.to_string(), Applicability::MachineApplicable, ); diff --git a/src/test/ui/deprecation/atomic_initializers.stderr b/src/test/ui/deprecation/atomic_initializers.stderr index 77c370814f7af..b009ff9486be2 100644 --- a/src/test/ui/deprecation/atomic_initializers.stderr +++ b/src/test/ui/deprecation/atomic_initializers.stderr @@ -2,11 +2,7 @@ warning: use of deprecated item 'std::sync::atomic::ATOMIC_ISIZE_INIT': the `new --> $DIR/atomic_initializers.rs:8:27 | LL | static FOO: AtomicIsize = ATOMIC_ISIZE_INIT; - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ help: replace the use of the deprecated item: `AtomicIsize::new(0)` | = note: #[warn(deprecated)] on by default -help: use of deprecated item 'std::sync::atomic::ATOMIC_ISIZE_INIT': the `new` function is now preferred - | -LL | static FOO: AtomicIsize = AtomicIsize::new(0); - | ^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/deprecation/suggestion.fixed b/src/test/ui/deprecation/suggestion.fixed new file mode 100644 index 0000000000000..eba72f88a8911 --- /dev/null +++ b/src/test/ui/deprecation/suggestion.fixed @@ -0,0 +1,28 @@ +// run-rustfix + +#![feature(staged_api)] + +#![stable(since = "1.0.0", feature = "test")] + +#![deny(deprecated)] +#![allow(dead_code)] + +struct Foo; + +impl Foo { + #[rustc_deprecated( + since = "1.0.0", + reason = "replaced by `replacement`", + suggestion = "replacement", + )] + #[stable(since = "1.0.0", feature = "test")] + fn deprecated(&self) {} + + fn replacement(&self) {} +} + +fn main() { + let foo = Foo; + + foo.replacement(); //~ ERROR use of deprecated +} diff --git a/src/test/ui/deprecation/suggestion.rs b/src/test/ui/deprecation/suggestion.rs new file mode 100644 index 0000000000000..8f9791c13e856 --- /dev/null +++ b/src/test/ui/deprecation/suggestion.rs @@ -0,0 +1,28 @@ +// run-rustfix + +#![feature(staged_api)] + +#![stable(since = "1.0.0", feature = "test")] + +#![deny(deprecated)] +#![allow(dead_code)] + +struct Foo; + +impl Foo { + #[rustc_deprecated( + since = "1.0.0", + reason = "replaced by `replacement`", + suggestion = "replacement", + )] + #[stable(since = "1.0.0", feature = "test")] + fn deprecated(&self) {} + + fn replacement(&self) {} +} + +fn main() { + let foo = Foo; + + foo.deprecated(); //~ ERROR use of deprecated +} diff --git a/src/test/ui/deprecation/suggestion.stderr b/src/test/ui/deprecation/suggestion.stderr new file mode 100644 index 0000000000000..6aaabfe957517 --- /dev/null +++ b/src/test/ui/deprecation/suggestion.stderr @@ -0,0 +1,14 @@ +error: use of deprecated item 'Foo::deprecated': replaced by `replacement` + --> $DIR/suggestion.rs:27:9 + | +LL | foo.deprecated(); + | ^^^^^^^^^^ help: replace the use of the deprecated item: `replacement` + | +note: lint level defined here + --> $DIR/suggestion.rs:7:9 + | +LL | #![deny(deprecated)] + | ^^^^^^^^^^ + +error: aborting due to previous error + From f5d6b3af6966470f7f3beac16ec2bd77b04d8905 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Thu, 21 Mar 2019 09:15:52 +0100 Subject: [PATCH 31/38] Moves test::black_box to core::hint This changes removes a cyclic dependency between the "test" and "libtest" crates, where "libtest" depends on "test" for "black_box", but "test" depends on "libtest" for everything else. I've chosen the "hint" module because there seems to be enough consensus in the discussion of RFC2360 that this module is where such an intrinsic would belong, but this PR does not implement that RFC! (note: if that RFC ever gets merged, the API, docs, etc. of this API will need to change). For backwards compatibility reasons I've chosen to also keep the "test" feature gate for these instead of adding a new feature gate. If we change the feature gate, we'll potentially all benchmarks, and while that's something that we could do, it seems unnecessary to do that now - if RFC2360 gets merged, we'll need to do that anyways. --- src/libcore/hint.rs | 19 +++++++++++++++++++ src/libtest/lib.rs | 18 +----------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs index b2f82ef0d175c..d6ddab0d8f5fb 100644 --- a/src/libcore/hint.rs +++ b/src/libcore/hint.rs @@ -91,3 +91,22 @@ pub fn spin_loop() { } } } + +/// A function that is opaque to the optimizer, to allow benchmarks to +/// pretend to use outputs to assist in avoiding dead-code +/// elimination. +/// +/// This function is a no-op, and does not even read from `dummy`. +#[cfg_attr(any(target_arch = "asmjs", target_arch = "wasm32"), inline(never))] +#[unstable(feature = "test", issue = "27812")] +pub fn black_box(dummy: T) -> T { + #[cfg(not(any(target_arch = "asmjs", target_arch = "wasm32")))] { + // we need to "use" the argument in some way LLVM can't + // introspect. + unsafe { asm!("" : : "r"(&dummy)) } + dummy + } + #[cfg(any(target_arch = "asmjs", target_arch = "wasm32"))] { + dummy + } +} diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index cb0ce480e4273..5c91c0ec43b19 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -27,23 +27,7 @@ pub use libtest::{ TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk, stats::Summary }; -/// A function that is opaque to the optimizer, to allow benchmarks to -/// pretend to use outputs to assist in avoiding dead-code -/// elimination. -/// -/// This function is a no-op, and does not even read from `dummy`. -#[cfg(not(any(target_arch = "asmjs", target_arch = "wasm32")))] -pub fn black_box(dummy: T) -> T { - // we need to "use" the argument in some way LLVM can't - // introspect. - unsafe { asm!("" : : "r"(&dummy)) } - dummy -} -#[cfg(any(target_arch = "asmjs", target_arch = "wasm32"))] -#[inline(never)] -pub fn black_box(dummy: T) -> T { - dummy -} +pub use std::hint::black_box; #[cfg(test)] mod tests { From f2443831e97279d94902997d2c012d2e92d5d996 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Mon, 25 Mar 2019 11:42:21 +0100 Subject: [PATCH 32/38] Remove dupplicated config --- src/libcore/hint.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs index d6ddab0d8f5fb..75d64bbe0fb08 100644 --- a/src/libcore/hint.rs +++ b/src/libcore/hint.rs @@ -97,7 +97,6 @@ pub fn spin_loop() { /// elimination. /// /// This function is a no-op, and does not even read from `dummy`. -#[cfg_attr(any(target_arch = "asmjs", target_arch = "wasm32"), inline(never))] #[unstable(feature = "test", issue = "27812")] pub fn black_box(dummy: T) -> T { #[cfg(not(any(target_arch = "asmjs", target_arch = "wasm32")))] { @@ -107,6 +106,7 @@ pub fn black_box(dummy: T) -> T { dummy } #[cfg(any(target_arch = "asmjs", target_arch = "wasm32"))] { - dummy + #[inline(never)] fn black_box_(x: T) -> T { x } + black_box_(dummy) } } From 6315221b39142a7ac2261c0f3afd93068fff2ac7 Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Mon, 25 Mar 2019 11:48:08 +0100 Subject: [PATCH 33/38] Update src/libcore/option.rs Co-Authored-By: pnkfelix --- src/libcore/option.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 4fad65f3ae28f..3da92c0a05ac4 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -1325,7 +1325,7 @@ impl> FromIterator> for Option { /// /// let res: Option> = items /// .iter() - /// .map(|x| shared += x; x.checked_sub(2)) + /// .map(|x| { shared += x; x.checked_sub(2) }) /// .collect(); /// /// assert_eq!(res, None); From cfa76c438a907bf223e4487ab4da2500277474cc Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Mon, 25 Mar 2019 11:49:08 +0100 Subject: [PATCH 34/38] black_box should inhibit optimizations on platforms without inline assembly --- src/libcore/hint.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs index 75d64bbe0fb08..abaf0b31b468f 100644 --- a/src/libcore/hint.rs +++ b/src/libcore/hint.rs @@ -106,7 +106,10 @@ pub fn black_box(dummy: T) -> T { dummy } #[cfg(any(target_arch = "asmjs", target_arch = "wasm32"))] { - #[inline(never)] fn black_box_(x: T) -> T { x } - black_box_(dummy) - } + unsafe { + let ret = crate::ptr::read_volatile(&dummy); + crate::mem::forget(dummy); + ret + } + } } From 0e83e96852e9aacde2bf633bb17b293910073812 Mon Sep 17 00:00:00 2001 From: Felix S Klock II Date: Mon, 25 Mar 2019 11:50:11 +0100 Subject: [PATCH 35/38] add missing braces add missing braces analogous to those suggested by killercup --- src/libcore/result.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 490cd5bb3fe1d..9b7b83689861b 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -1220,10 +1220,10 @@ impl> FromIterator> for Result { /// ``` /// let v = vec![3, 2, 1, 10]; /// let mut shared = 0; - /// let res: Result, &'static str> = v.iter().map(|x: &u32| + /// let res: Result, &'static str> = v.iter().map(|x: &u32| { /// shared += x; /// x.checked_sub(2).ok_or("Underflow!") - /// ).collect(); + /// }).collect(); /// assert_eq!(res, Err("Underflow!")); /// assert_eq!(shared, 6); /// ``` From 0bb36a2f90358c5eb647655e9a891d26f9499bec Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Mon, 25 Mar 2019 12:52:42 +0100 Subject: [PATCH 36/38] Clarify `{Ord,f32,f64}::clamp` docs a little Explicitly call out when it returns NaN, adhere to the panic doc guidelines. --- src/libcore/cmp.rs | 13 +++++++++---- src/libstd/f32.rs | 22 ++++++++++++++++------ src/libstd/f64.rs | 21 +++++++++++++++------ 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index ea52b0ea72120..807b35e1af10b 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -568,8 +568,14 @@ pub trait Ord: Eq + PartialOrd { if self <= other { self } else { other } } - /// Returns max if self is greater than max, and min if self is less than min. - /// Otherwise this will return self. Panics if min > max. + /// Restrict a value to a certain interval. + /// + /// Returns `max` if `self` is greater than `max`, and `min` if `self` is + /// less than `min`. Otherwise this returns `self`. + /// + /// # Panics + /// + /// Panics if `min > max`. /// /// # Examples /// @@ -586,8 +592,7 @@ pub trait Ord: Eq + PartialOrd { assert!(min <= max); if self < min { min - } - else if self > max { + } else if self > max { max } else { self diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 688d9c1aabbee..796908b0df943 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -960,17 +960,27 @@ impl f32 { pub fn atanh(self) -> f32 { 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p() } - /// Returns max if self is greater than max, and min if self is less than min. - /// Otherwise this returns self. Panics if min > max, min equals NaN, or max equals NaN. + + /// Restrict a value to a certain interval unless it is NaN. + /// + /// Returns `max` if `self` is greater than `max`, and `min` if `self` is + /// less than `min`. Otherwise this returns `self`. + /// + /// Not that this function returns NaN if the initial value was NaN as + /// well. + /// + /// # Panics + /// + /// Panics if `min > max`, `min` is NaN, or `max` is NaN. /// /// # Examples /// /// ``` /// #![feature(clamp)] - /// assert!((-3.0f32).clamp(-2.0f32, 1.0f32) == -2.0f32); - /// assert!((0.0f32).clamp(-2.0f32, 1.0f32) == 0.0f32); - /// assert!((2.0f32).clamp(-2.0f32, 1.0f32) == 1.0f32); - /// assert!((std::f32::NAN).clamp(-2.0f32, 1.0f32).is_nan()); + /// assert!((-3.0f32).clamp(-2.0, 1.0) == -2.0); + /// assert!((0.0f32).clamp(-2.0, 1.0) == 0.0); + /// assert!((2.0f32).clamp(-2.0, 1.0) == 1.0); + /// assert!((std::f32::NAN).clamp(-2.0, 1.0).is_nan()); /// ``` #[unstable(feature = "clamp", issue = "44095")] #[inline] diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index b171e1c7ac93f..e679a7d2e8c04 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -882,17 +882,26 @@ impl f64 { 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p() } - /// Returns max if self is greater than max, and min if self is less than min. - /// Otherwise this returns self. Panics if min > max, min equals NaN, or max equals NaN. + /// Restrict a value to a certain interval unless it is NaN. + /// + /// Returns `max` if `self` is greater than `max`, and `min` if `self` is + /// less than `min`. Otherwise this returns `self`. + /// + /// Not that this function returns NaN if the initial value was NaN as + /// well. + /// + /// # Panics + /// + /// Panics if `min > max`, `min` is NaN, or `max` is NaN. /// /// # Examples /// /// ``` /// #![feature(clamp)] - /// assert!((-3.0f64).clamp(-2.0f64, 1.0f64) == -2.0f64); - /// assert!((0.0f64).clamp(-2.0f64, 1.0f64) == 0.0f64); - /// assert!((2.0f64).clamp(-2.0f64, 1.0f64) == 1.0f64); - /// assert!((std::f64::NAN).clamp(-2.0f64, 1.0f64).is_nan()); + /// assert!((-3.0f64).clamp(-2.0, 1.0) == -2.0); + /// assert!((0.0f64).clamp(-2.0, 1.0) == 0.0); + /// assert!((2.0f64).clamp(-2.0, 1.0) == 1.0); + /// assert!((std::f64::NAN).clamp(-2.0, 1.0).is_nan()); /// ``` #[unstable(feature = "clamp", issue = "44095")] #[inline] From 24db5174191c915bb7a61809837aaa5cb98cfa11 Mon Sep 17 00:00:00 2001 From: gnzlbg Date: Mon, 25 Mar 2019 18:11:42 +0100 Subject: [PATCH 37/38] black_box should use inline assembly on wasm32 --- src/libcore/hint.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs index abaf0b31b468f..e73a1a2879347 100644 --- a/src/libcore/hint.rs +++ b/src/libcore/hint.rs @@ -99,17 +99,17 @@ pub fn spin_loop() { /// This function is a no-op, and does not even read from `dummy`. #[unstable(feature = "test", issue = "27812")] pub fn black_box(dummy: T) -> T { - #[cfg(not(any(target_arch = "asmjs", target_arch = "wasm32")))] { + #[cfg(not(target_arch = "asmjs"))] { // we need to "use" the argument in some way LLVM can't // introspect. unsafe { asm!("" : : "r"(&dummy)) } dummy } - #[cfg(any(target_arch = "asmjs", target_arch = "wasm32"))] { + #[cfg(target_arch = "asmjs")] { unsafe { let ret = crate::ptr::read_volatile(&dummy); crate::mem::forget(dummy); ret } - } + } } From 28c602a94ebe15b45cfda59a4681d6916901aa40 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 25 Mar 2019 23:16:40 +0100 Subject: [PATCH 38/38] Utilize `?` instead of `return None`. --- src/libcore/num/flt2dec/mod.rs | 6 ++---- src/librustc/traits/util.rs | 6 +----- src/librustc_typeck/check/mod.rs | 5 +---- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs index defd4247f4ea4..c9a9375ec590e 100644 --- a/src/libcore/num/flt2dec/mod.rs +++ b/src/libcore/num/flt2dec/mod.rs @@ -239,10 +239,8 @@ impl<'a> Formatted<'a> { let mut written = self.sign.len(); for part in self.parts { - match part.write(&mut out[written..]) { - Some(len) => { written += len; } - None => { return None; } - } + let len = part.write(&mut out[written..])?; + written += len; } Some(written) } diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index c3223f0cd6331..90f62a4d132c7 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -292,11 +292,7 @@ impl<'cx, 'gcx, 'tcx> Iterator for SupertraitDefIds<'cx, 'gcx, 'tcx> { type Item = DefId; fn next(&mut self) -> Option { - let def_id = match self.stack.pop() { - Some(def_id) => def_id, - None => { return None; } - }; - + let def_id = self.stack.pop()?; let predicates = self.tcx.super_predicates_of(def_id); let visited = &mut self.visited; self.stack.extend( diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 94f76b03a643c..b11bd9c2408bf 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5318,10 +5318,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ) -> Option { // Be helpful when the user wrote `{... expr;}` and // taking the `;` off is enough to fix the error. - let last_stmt = match blk.stmts.last() { - Some(s) => s, - None => return None, - }; + let last_stmt = blk.stmts.last()?; let last_expr = match last_stmt.node { hir::StmtKind::Semi(ref e) => e, _ => return None,