diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 19855075ced8..62b3f3ecfc32 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -6,8 +6,8 @@ use rustc_hir::intravisit::Visitor; use rustc_index::vec::IndexVec; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_middle::mir::{ - Body, CastKind, ConstraintCategory, FakeReadCause, Local, Location, Operand, Place, Rvalue, - Statement, StatementKind, TerminatorKind, + Body, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location, Operand, Place, + Rvalue, Statement, StatementKind, TerminatorKind, }; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::{self, RegionVid, TyCtxt}; @@ -220,7 +220,7 @@ impl<'tcx> BorrowExplanation<'tcx> { ); err.span_label(body.source_info(drop_loc).span, message); - if let Some(info) = &local_decl.is_block_tail { + if let LocalInfo::BlockTailTemp(info) = local_decl.local_info() { if info.tail_result_is_ignored { // #85581: If the first mutable borrow's scope contains // the second borrow, this suggestion isn't helpful. diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index b9725029276e..5fbc0347a4cb 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -785,13 +785,6 @@ pub struct LocalDecl<'tcx> { /// generator. pub internal: bool, - /// If this local is a temporary and `is_block_tail` is `Some`, - /// then it is a temporary created for evaluation of some - /// subexpression of some block's tail expression (with no - /// intervening statement context). - // FIXME(matthewjasper) Don't store in this in `Body` - pub is_block_tail: Option, - /// The type of this local. pub ty: Ty<'tcx>, @@ -905,6 +898,10 @@ pub enum LocalInfo<'tcx> { /// A temporary created during the creation of an aggregate /// (e.g. a temporary for `foo` in `MyStruct { my_field: foo }`) AggregateTemp, + /// A temporary created for evaluation of some subexpression of some block's tail expression + /// (with no intervening statement context). + // FIXME(matthewjasper) Don't store in this in `Body` + BlockTailTemp(BlockTailInfo), /// A temporary created during the pass `Derefer` to avoid it's retagging DerefTemp, /// A temporary created for borrow checking. @@ -1018,7 +1015,6 @@ impl<'tcx> LocalDecl<'tcx> { mutability: Mutability::Mut, local_info: ClearCrossCrate::Set(Box::new(LocalInfo::Boring)), internal: false, - is_block_tail: None, ty, user_ty: None, source_info, @@ -1038,14 +1034,6 @@ impl<'tcx> LocalDecl<'tcx> { self.mutability = Mutability::Not; self } - - /// Converts `self` into same `LocalDecl` except tagged as internal temporary. - #[inline] - pub fn block_tail(mut self, info: BlockTailInfo) -> Self { - assert!(self.is_block_tail.is_none()); - self.is_block_tail = Some(info); - self - } } #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] @@ -3106,7 +3094,7 @@ mod size_asserts { use rustc_data_structures::static_assert_size; // tidy-alphabetical-start static_assert_size!(BasicBlockData<'_>, 144); - static_assert_size!(LocalDecl<'_>, 56); + static_assert_size!(LocalDecl<'_>, 40); static_assert_size!(Statement<'_>, 32); static_assert_size!(StatementKind<'_>, 16); static_assert_size!(Terminator<'_>, 112); diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index cbeacf21c19f..cffdd7ff37f2 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -804,7 +804,6 @@ macro_rules! make_mir_visitor { source_info, internal: _, local_info: _, - is_block_tail: _, } = local_decl; self.visit_ty($(& $mutability)? *ty, TyContext::LocalDecl { diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs index 4249a47621c6..6941da331fc5 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs @@ -124,9 +124,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } Category::Constant | Category::Place | Category::Rvalue(..) => { let operand = unpack!(block = this.as_temp(block, scope, expr, Mutability::Mut)); - let decl_info = this.local_decls[operand].local_info.as_mut().assert_crate_local(); - if let LocalInfo::Boring = **decl_info { - **decl_info = local_info; + // Overwrite temp local info if we have something more interesting to record. + if !matches!(local_info, LocalInfo::Boring) { + let decl_info = this.local_decls[operand].local_info.as_mut().assert_crate_local(); + if let LocalInfo::Boring | LocalInfo::BlockTailTemp(_) = **decl_info { + **decl_info = local_info; + } } block.and(Operand::Move(Place::from(operand))) } diff --git a/compiler/rustc_mir_build/src/build/expr/as_temp.rs b/compiler/rustc_mir_build/src/build/expr/as_temp.rs index f978a920f43a..c8910c272b1b 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_temp.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_temp.rs @@ -49,29 +49,28 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } debug!("creating temp {:?} with block_context: {:?}", local_decl, this.block_context); - // Find out whether this temp is being created within the - // tail expression of a block whose result is ignored. - if let Some(tail_info) = this.block_context.currently_in_block_tail() { - local_decl = local_decl.block_tail(tail_info); - } - match expr.kind { + let local_info = match expr.kind { ExprKind::StaticRef { def_id, .. } => { assert!(!this.tcx.is_thread_local_static(def_id)); local_decl.internal = true; - **local_decl.local_info.as_mut().assert_crate_local() = - LocalInfo::StaticRef { def_id, is_thread_local: false }; + LocalInfo::StaticRef { def_id, is_thread_local: false } } ExprKind::ThreadLocalRef(def_id) => { assert!(this.tcx.is_thread_local_static(def_id)); local_decl.internal = true; - **local_decl.local_info.as_mut().assert_crate_local() = - LocalInfo::StaticRef { def_id, is_thread_local: true }; + LocalInfo::StaticRef { def_id, is_thread_local: true } } ExprKind::NamedConst { def_id, .. } | ExprKind::ConstParam { def_id, .. } => { - **local_decl.local_info.as_mut().assert_crate_local() = LocalInfo::ConstRef { def_id }; + LocalInfo::ConstRef { def_id } } - _ => {} - } + // Find out whether this temp is being created within the + // tail expression of a block whose result is ignored. + _ if let Some(tail_info) = this.block_context.currently_in_block_tail() => { + LocalInfo::BlockTailTemp(tail_info) + } + _ => LocalInfo::Boring, + }; + **local_decl.local_info.as_mut().assert_crate_local() = local_info; this.local_decls.push(local_decl) }; let temp_place = Place::from(temp); diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 43d4a72390f3..22785dfd2ce0 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -2224,7 +2224,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { user_ty: if user_ty.is_empty() { None } else { Some(Box::new(user_ty)) }, source_info, internal: false, - is_block_tail: None, local_info: ClearCrossCrate::Set(Box::new(LocalInfo::User(BindingForm::Var( VarBindingForm { binding_mode, @@ -2253,7 +2252,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { user_ty: None, source_info, internal: false, - is_block_tail: None, local_info: ClearCrossCrate::Set(Box::new(LocalInfo::User(BindingForm::RefForGuard))), }); self.var_debug_info.push(VarDebugInfo {