From 7fb1c22da181426f6ea7662f5c7f47edbbe24f56 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Sat, 16 Mar 2019 17:40:41 +0530 Subject: [PATCH 01/33] 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 | 86 +++++++------ 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, 333 insertions(+), 280 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 9f2027e7d05..47b9535abc5 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 a6f153eaf64..ac42eacacd7 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 8bc0075c477..cddf5782121 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 14289381aef..8f83c025ceb 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 c4e371d5afe..5726eba9bda 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 b8dae98ec64..d8c39e0715a 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 25a3160a498..334c20761e7 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); + 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[index]; - self.sanitize_promoted(promoted_mir, location); + if !self.errors_reported { + let promoted_mir = &self.mir.promoted[pr]; + self.sanitize_promoted(promoted_mir, location); - let promoted_ty = promoted_mir.return_ty(); + 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 - ); - }; + 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::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 - ); - } - 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 9e0bb93c33a..42eb502b907 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 c05ee3cf65b..0bbd147d824 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 1d18ada1fb6..7babdfcdd68 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 384fd5c9987..e70c9e81ebd 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 20b95c363f5..83e1d3ebb3e 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 b9c8879b3c3..9d4600d13ac 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 7a9140bce62..71805fd02b8 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 97f84675f94..7eef68e5f80 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 755bbd96b02..62e2cdffadf 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 20b75c55867..b13a5fd2fd1 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 b494592c89f..01cb58a481a 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 d8169684420..bbe62fa2d7b 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 234483df13a..0b2a34d5fb9 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 e96689809ad..f0ba1306c99 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 f82e536ab25..ea5bbaeb400 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/33] 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 | 116 ++++++++---------- 11 files changed, 160 insertions(+), 213 deletions(-) diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index cddf5782121..6761c70550e 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 8f83c025ceb..b9877945e7e 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 5726eba9bda..e92ed1f2c7c 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 d8c39e0715a..2661d765718 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 334c20761e7..c2efd3625c3 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 0bbd147d824..5e691db0a2e 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 7babdfcdd68..c4f9df0cfe5 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 62e2cdffadf..7adcb118f84 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 01cb58a481a..2ebe28e6ac0 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 bbe62fa2d7b..3ee26e7dd26 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 f0ba1306c99..9cbb891316d 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; - } - - // 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() - } + 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); + + 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/33] 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 35fd30f34ad..62f454f1b9f 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 0408ccf039f..1608429b070 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 e92ed1f2c7c..e538622103a 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 5e691db0a2e..0452465f0b9 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 c4f9df0cfe5..783751056d7 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 7adcb118f84..6089e491684 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 3ee26e7dd26..c5c3a1b8eca 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 0b2a34d5fb9..86b7da17879 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 831d8b46a65..d777a7b362b 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 9cbb891316d..c01ed4b1c59 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 776407e4e65e537ee7471a90d8a48eb26e7f0fd7 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Tue, 19 Mar 2019 13:35:50 +0530 Subject: [PATCH 04/33] 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 e538622103a..0358fffcde5 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 8829ddadc4f82b43a8653dd1f40839513b6fb2f0 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Wed, 20 Mar 2019 19:05:03 +0530 Subject: [PATCH 05/33] 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 6761c70550e..3f6133a7331 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 4fe47a9666a..075b81e9fd9 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 ea5bbaeb400..da849faf40a 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 06/33] 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 d32d07569e4..12fbd2f69f1 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 43e865ad089..ab9c9b24718 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 ecc00898600..b99bffd3bd3 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 d8159f11ace..4e07f400f82 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 2f085a973d2..1038401244f 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 e82e09c2997..9b4341e6355 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 6b5e19ca49b..ac76ed8cb93 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 2fe51a22fb4..6e32a53c364 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 3849e47d403..c7d164d3297 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 f0f1f09a838..05cc945bbaf 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 4e82729aa3b..b8e84173ec0 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 a74c3ab04e2..d3f96c9947b 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 c9f844f96eb..dc919abc02d 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 da093ded635..91abca3312b 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 fccec704d63..db8fa9ced11 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 a01247ff424..32a0c8b6b7e 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 ebafd07dbef..1b6b41ce05b 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 c5e7f525fd0..53e77a370a3 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 a2b33fecea8..76be2ccbf60 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 a48d150b8b0..63cf1e9d5e8 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 11fe84d88e9..37f6aa9ee9b 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 9a3c93147a0..0803f4e01d6 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 a42fda31885..3190f65a817 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 ef8035a300a..f3331ec61cb 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 c708d5b969d..7e866ae925e 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 c7b84a120c8..cbd1341fdd4 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 ecda56f7e94..2574ef5199c 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 41c72335d63..db2660bb661 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 07/33] 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 d7683aae841..30fe327cac4 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 08/33] 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 ab9c9b24718..a4950c01162 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 b99bffd3bd3..361d8129002 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 4e07f400f82..72fb649a946 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 1038401244f..4cfddf08461 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 9b4341e6355..331f68c11d0 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 c7d164d3297..90bd46d0350 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 09/33] 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 a4950c01162..cdbd01620fb 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 361d8129002..b8c91f91934 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 72fb649a946..47ef09820b0 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 4cfddf08461..5eafb87592e 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 331f68c11d0..c364d15027d 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 90bd46d0350..fa5ab4737d8 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 10/33] 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 cdbd01620fb..4babadb67bc 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 b8c91f91934..8d64818f49b 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 47ef09820b0..5cb5a0030f4 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 5eafb87592e..dbc81a4235d 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 c364d15027d..adac19d3410 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 fa5ab4737d8..0800579231f 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 11/33] 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 0800579231f..bd5be831ff6 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 12/33] 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 514e420ca45..55e6e8d7f18 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 13/33] 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 62f454f1b9f..066b38be3db 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 c2efd3625c3..2a32b475c79 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 c5c3a1b8eca..81cdb001005 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 86b7da17879..ec2cf8a4c03 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 d777a7b362b..2344f070ea6 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 14/33] 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 dfc388409a8..4fad65f3ae2 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 15/33] 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 967f7e3e2fe..490cd5bb3fe 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 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 16/33] 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 4c86f70ad87..5abaac51da3 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 17/33] 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 5abaac51da3..ab1a43d6672 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 18/33] 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 d7502c61eff..49a234e1158 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 9db3e85ca9c..881ad5c0aeb 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 e4f789c3e36..4659f7ba71f 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 cbb0615911a..6b5a89aee7d 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 c1228a1b75e..3f71461eea4 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 2c99bca7009..aa53f1194fd 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 19/33] 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 ac149be4b2a..1a032922902 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 5627ac3fcf2..d052abf96d7 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 bdcfaae60a0..af5f88f4ce5 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 cbff5575ed2..08758ce9c94 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 00000000000..b1071934bb2 --- /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 00000000000..ea324302d40 --- /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 fa0a7ac002b..3de3298e3b5 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 b319c64f406..2940f465826 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 27672eeda83..e7d22ae0292 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 8a130f441a3..038e30956ff 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 3505d00b64b..b3a6f6ac734 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 00000000000..51d3d32565f --- /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 00000000000..1efa94a5532 --- /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 00000000000..361729d50c2 --- /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 00000000000..15ec087b1cc --- /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 00000000000..a81996ed7bb --- /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 00000000000..e371611ccff --- /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 00000000000..b90867fef6b --- /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 00000000000..5719a667a84 --- /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 bc5a923a3f3..4077be9d082 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 20/33] 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 1a032922902..5c5a27a6b43 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 1efa94a5532..7f6aaef49f7 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 e371611ccff..9fe0c3b743c 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 21/33] 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 5c5a27a6b43..12ded62a5d9 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 9fe0c3b743c..9908b3f6798 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 22/33] 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 9beaabb0cd5..2816efaeb70 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 51d3d32565f..0e1c3075027 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 7f6aaef49f7..92e4b5798c8 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 2 previous errors -error: aborting due to 3 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 a81996ed7bb..4c0fe6d8b5b 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 9908b3f6798..1beb822d6a7 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 2 previous errors -error: aborting due to 3 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 23/33] 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 d052abf96d7..d5b64eaaef5 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 af5f88f4ce5..29a264ba162 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 08758ce9c94..5d40909f097 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 ea324302d40..15779705426 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 3de3298e3b5..850e3563cab 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 2940f465826..9056fac4226 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 e7d22ae0292..558f5a15cc5 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 038e30956ff..ae6e1d4577c 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 b3a6f6ac734..6dbf7eb1b10 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 4077be9d082..c80056e4487 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 24/33] 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 d5b64eaaef5..ea81094a996 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 29a264ba162..b0ef4e1b254 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 5d40909f097..a28ea0d09f8 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 15779705426..7899c8d30f1 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 850e3563cab..cb5a52a3e08 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 9056fac4226..07f2e41ac4f 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 558f5a15cc5..3dd61e74f12 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 ae6e1d4577c..d48244654cd 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 6dbf7eb1b10..a8c93233dbc 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 c80056e4487..2084cbcce4f 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 25/33] 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 | 104 +++++++++++------- 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, 240 insertions(+), 168 deletions(-) diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 47b9535abc5..12f14cfbb9a 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 3f6133a7331..b1e2df0ae98 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 066b38be3db..4774f8fe5a3 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 1608429b070..7cafa0088a0 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 b9877945e7e..fac75989aa5 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 0358fffcde5..40b329c1084 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 2661d765718..f351212e9d5 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 2a32b475c79..e12077fd5f7 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 0452465f0b9..6bc56ab721f 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 783751056d7..dc9b059de46 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 - } - }, - (_, _) => { - debug!("place_element_conflict: DISJOINT-STATIC-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::Local(_)), Place::Base(PlaceBase::Static(_))) | - (Place::Base(PlaceBase::Static(_)), Place::Base(PlaceBase::Local(_))) => { + ( + 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; + } + } + // 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(_)) + ) => { 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 83e1d3ebb3e..199d03ac445 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 6089e491684..d2c279e48fe 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 075b81e9fd9..0ad6962cc4a 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 2ebe28e6ac0..0e31515e4af 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 81cdb001005..c2d594ba7b7 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 ec2cf8a4c03..1063381d6aa 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 2344f070ea6..92039618d85 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 c01ed4b1c59..c35bf80bb2e 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 da849faf40a..8742c5d759c 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 26/33] 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 b1e2df0ae98..54e5bfc4397 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 40b329c1084..a3909486610 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 e12077fd5f7..aab650383cf 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 dc9b059de46..52119d6b19b 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 92039618d85..73b88e9904b 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 c35bf80bb2e..0b9ad85e6b1 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 27/33] 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 72c90b25860..54e593deb32 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 77c370814f7..b009ff9486b 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 00000000000..eba72f88a89 --- /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 00000000000..8f9791c13e8 --- /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 00000000000..6aaabfe9575 --- /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 539041437956abf05bd4ad0b6ecb253591df3085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 17 Mar 2019 21:18:06 -0700 Subject: [PATCH 28/33] Provide suggestion when using field access instead of path When trying to access an associated constant as if it were a field of an instance, provide a suggestion for the correct syntax. --- src/librustc_resolve/error_reporting.rs | 8 ++++++++ src/test/ui/suggestions/assoc-const-as-field.rs | 13 +++++++++++++ src/test/ui/suggestions/assoc-const-as-field.stderr | 11 +++++++++++ 3 files changed, 32 insertions(+) create mode 100644 src/test/ui/suggestions/assoc-const-as-field.rs create mode 100644 src/test/ui/suggestions/assoc-const-as-field.stderr diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index fc8452e49ad..0da10176d29 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -379,6 +379,14 @@ impl<'a> Resolver<'a> { Applicability::MaybeIncorrect ); }, + ExprKind::Field(ref _expr, ident) => { + err.span_suggestion( + sm.start_point(parent.span).to(ident.span), + "use `::` to access an associated item", + format!("{}::{}", path_str, ident), + Applicability::MaybeIncorrect + ); + } _ => { err.span_label( span, diff --git a/src/test/ui/suggestions/assoc-const-as-field.rs b/src/test/ui/suggestions/assoc-const-as-field.rs new file mode 100644 index 00000000000..678b58936a8 --- /dev/null +++ b/src/test/ui/suggestions/assoc-const-as-field.rs @@ -0,0 +1,13 @@ +pub mod Mod { + pub struct Foo {} + impl Foo { + pub const BAR: usize = 42; + } +} + +fn foo(_: usize) {} + +fn main() { + foo(Mod::Foo.Bar); + //~^ ERROR expected value, found +} diff --git a/src/test/ui/suggestions/assoc-const-as-field.stderr b/src/test/ui/suggestions/assoc-const-as-field.stderr new file mode 100644 index 00000000000..3f23ae57c3d --- /dev/null +++ b/src/test/ui/suggestions/assoc-const-as-field.stderr @@ -0,0 +1,11 @@ +error[E0423]: expected value, found struct `Mod::Foo` + --> $DIR/assoc-const-as-field.rs:11:9 + | +LL | foo(Mod::Foo.Bar); + | ^^^^^^^^---- + | | + | help: use `::` to access an associated item: `Mod::Foo::Bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0423`. From 4beea1720af3f1bc2d89ecedec539cc4c788cc91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 20 Mar 2019 16:03:29 -0700 Subject: [PATCH 29/33] Deduplicate code for path suggestion --- src/librustc_resolve/error_reporting.rs | 103 +++++++----------- src/test/ui/resolve/issue-22692.stderr | 2 +- .../suggestions/assoc-const-as-field.stderr | 2 +- 3 files changed, 43 insertions(+), 64 deletions(-) diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index 0da10176d29..461d02e515d 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -5,7 +5,7 @@ use log::debug; use rustc::hir::def::{Def, CtorKind, Namespace::*}; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use rustc::session::config::nightly_options; -use syntax::ast::{ExprKind}; +use syntax::ast::{Expr, ExprKind}; use syntax::symbol::keywords; use syntax_pos::Span; @@ -250,6 +250,29 @@ impl<'a> Resolver<'a> { let ns = source.namespace(); let is_expected = &|def| source.is_expected(def); + let path_sep = |err: &mut DiagnosticBuilder<'_>, expr: &Expr| match expr.node { + ExprKind::Field(_, ident) => { + err.span_suggestion( + expr.span, + "use the path separator to refer to an item", + format!("{}::{}", path_str, ident), + Applicability::MaybeIncorrect, + ); + true + } + ExprKind::MethodCall(ref segment, ..) => { + let span = expr.span.with_hi(segment.ident.span.hi()); + err.span_suggestion( + span, + "use the path separator to refer to an item", + format!("{}::{}", path_str, segment.ident), + Applicability::MaybeIncorrect, + ); + true + } + _ => false, + }; + match (def, source) { (Def::Macro(..), _) => { err.span_suggestion( @@ -259,8 +282,7 @@ impl<'a> Resolver<'a> { Applicability::MaybeIncorrect, ); if path_str == "try" && span.rust_2015() { - err.note("if you want the `try` keyword, \ - you need to be in the 2018 edition"); + err.note("if you want the `try` keyword, you need to be in the 2018 edition"); } } (Def::TyAlias(..), PathSource::Trait(_)) => { @@ -269,25 +291,8 @@ impl<'a> Resolver<'a> { err.note("did you mean to use a trait alias?"); } } - (Def::Mod(..), PathSource::Expr(Some(parent))) => match parent.node { - ExprKind::Field(_, ident) => { - err.span_suggestion( - parent.span, - "use the path separator to refer to an item", - format!("{}::{}", path_str, ident), - Applicability::MaybeIncorrect, - ); - } - ExprKind::MethodCall(ref segment, ..) => { - let span = parent.span.with_hi(segment.ident.span.hi()); - err.span_suggestion( - span, - "use the path separator to refer to an item", - format!("{}::{}", path_str, segment.ident), - Applicability::MaybeIncorrect, - ); - } - _ => return false, + (Def::Mod(..), PathSource::Expr(Some(parent))) => if !path_sep(err, &parent) { + return false; }, (Def::Enum(..), PathSource::TupleStruct) | (Def::Enum(..), PathSource::Expr(..)) => { @@ -315,8 +320,10 @@ impl<'a> Resolver<'a> { = self.struct_constructors.get(&def_id).cloned() { let accessible_ctor = self.is_accessible(ctor_vis); if is_expected(ctor_def) && !accessible_ctor { - err.span_label(span, format!("constructor is not visible \ - here due to private fields")); + err.span_label( + span, + format!("constructor is not visible here due to private fields"), + ); } } else { // HACK(estebank): find a better way to figure out that this was a @@ -366,36 +373,12 @@ impl<'a> Resolver<'a> { } } match source { - PathSource::Expr(Some(parent)) => { - match parent.node { - ExprKind::MethodCall(ref path_assignment, _) => { - err.span_suggestion( - sm.start_point(parent.span) - .to(path_assignment.ident.span), - "use `::` to access an associated function", - format!("{}::{}", - path_str, - path_assignment.ident), - Applicability::MaybeIncorrect - ); - }, - ExprKind::Field(ref _expr, ident) => { - err.span_suggestion( - sm.start_point(parent.span).to(ident.span), - "use `::` to access an associated item", - format!("{}::{}", path_str, ident), - Applicability::MaybeIncorrect - ); - } - _ => { - err.span_label( - span, - format!("did you mean `{} {{ /* fields */ }}`?", - path_str), - ); - }, - } - }, + PathSource::Expr(Some(parent)) => if !path_sep(err, &parent) { + err.span_label( + span, + format!("did you mean `{} {{ /* fields */ }}`?", path_str), + ); + } PathSource::Expr(None) if followed_by_brace == true => { if let Some((sp, snippet)) = closing_brace { err.span_suggestion( @@ -407,16 +390,14 @@ impl<'a> Resolver<'a> { } else { err.span_label( span, - format!("did you mean `({} {{ /* fields */ }})`?", - path_str), + format!("did you mean `({} {{ /* fields */ }})`?", path_str), ); } }, _ => { err.span_label( span, - format!("did you mean `{} {{ /* fields */ }}`?", - path_str), + format!("did you mean `{} {{ /* fields */ }}`?", path_str), ); }, } @@ -425,13 +406,11 @@ impl<'a> Resolver<'a> { (Def::Union(..), _) | (Def::Variant(..), _) | (Def::Ctor(_, _, CtorKind::Fictive), _) if ns == ValueNS => { - err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", - path_str)); + err.span_label(span, format!("did you mean `{} {{ /* fields */ }}`?", path_str)); } (Def::SelfTy(..), _) if ns == ValueNS => { err.span_label(span, fallback_label); - err.note("can't use `Self` as a constructor, you must use the \ - implemented struct"); + err.note("can't use `Self` as a constructor, you must use the implemented struct"); } (Def::TyAlias(_), _) | (Def::AssociatedTy(..), _) if ns == ValueNS => { err.note("can't use a type alias as a constructor"); diff --git a/src/test/ui/resolve/issue-22692.stderr b/src/test/ui/resolve/issue-22692.stderr index 13752430e71..e076419f68d 100644 --- a/src/test/ui/resolve/issue-22692.stderr +++ b/src/test/ui/resolve/issue-22692.stderr @@ -4,7 +4,7 @@ error[E0423]: expected value, found struct `String` LL | let _ = String.new(); | ^^^^^^---- | | - | help: use `::` to access an associated function: `String::new` + | help: use the path separator to refer to an item: `String::new` error: aborting due to previous error diff --git a/src/test/ui/suggestions/assoc-const-as-field.stderr b/src/test/ui/suggestions/assoc-const-as-field.stderr index 3f23ae57c3d..5e746ecb2f2 100644 --- a/src/test/ui/suggestions/assoc-const-as-field.stderr +++ b/src/test/ui/suggestions/assoc-const-as-field.stderr @@ -4,7 +4,7 @@ error[E0423]: expected value, found struct `Mod::Foo` LL | foo(Mod::Foo.Bar); | ^^^^^^^^---- | | - | help: use `::` to access an associated item: `Mod::Foo::Bar` + | help: use the path separator to refer to an item: `Mod::Foo::Bar` error: aborting due to previous error From 6315221b39142a7ac2261c0f3afd93068fff2ac7 Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Mon, 25 Mar 2019 11:48:08 +0100 Subject: [PATCH 30/33] 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 4fad65f3ae2..3da92c0a05a 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 0e83e96852e9aacde2bf633bb17b293910073812 Mon Sep 17 00:00:00 2001 From: Felix S Klock II Date: Mon, 25 Mar 2019 11:50:11 +0100 Subject: [PATCH 31/33] 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 490cd5bb3fe..9b7b8368986 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 32/33] 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 ea52b0ea721..807b35e1af1 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 688d9c1aabb..796908b0df9 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 b171e1c7ac9..e679a7d2e8c 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 28c602a94ebe15b45cfda59a4681d6916901aa40 Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 25 Mar 2019 23:16:40 +0100 Subject: [PATCH 33/33] 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 defd4247f4e..c9a9375ec59 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 c3223f0cd63..90f62a4d132 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 94f76b03a64..b11bd9c2408 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,