Auto merge of #108944 - cjgillot:clear-local-info, r=oli-obk
Wrap the whole LocalInfo in ClearCrossCrate. MIR contains a lot of information about locals. The primary purpose of this information is the quality of borrowck diagnostics. This PR aims to drop this information after MIR analyses are finished, ie. starting from post-cleanup runtime MIR.
This commit is contained in:
commit
511364e787
30 changed files with 188 additions and 214 deletions
|
@ -20,7 +20,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
expr: &Expr<'tcx>,
|
||||
) -> BlockAnd<Operand<'tcx>> {
|
||||
let local_scope = self.local_scope();
|
||||
self.as_operand(block, Some(local_scope), expr, None, NeedsTemporary::Maybe)
|
||||
self.as_operand(block, Some(local_scope), expr, LocalInfo::Boring, NeedsTemporary::Maybe)
|
||||
}
|
||||
|
||||
/// Returns an operand suitable for use until the end of the current scope expression and
|
||||
|
@ -102,7 +102,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
mut block: BasicBlock,
|
||||
scope: Option<region::Scope>,
|
||||
expr: &Expr<'tcx>,
|
||||
local_info: Option<Box<LocalInfo<'tcx>>>,
|
||||
local_info: LocalInfo<'tcx>,
|
||||
needs_temporary: NeedsTemporary,
|
||||
) -> BlockAnd<Operand<'tcx>> {
|
||||
let this = self;
|
||||
|
@ -124,8 +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));
|
||||
if this.local_decls[operand].local_info.is_none() {
|
||||
this.local_decls[operand].local_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)))
|
||||
}
|
||||
|
@ -178,6 +182,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
this.as_operand(block, scope, expr, None, NeedsTemporary::Maybe)
|
||||
this.as_operand(block, scope, expr, LocalInfo::Boring, NeedsTemporary::Maybe)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
block,
|
||||
scope,
|
||||
&this.thir[value],
|
||||
None,
|
||||
LocalInfo::Boring,
|
||||
NeedsTemporary::No
|
||||
)
|
||||
);
|
||||
|
@ -74,18 +74,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
ExprKind::Binary { op, lhs, rhs } => {
|
||||
let lhs = unpack!(
|
||||
block =
|
||||
this.as_operand(block, scope, &this.thir[lhs], None, NeedsTemporary::Maybe)
|
||||
this.as_operand(block, scope, &this.thir[lhs], LocalInfo::Boring, NeedsTemporary::Maybe)
|
||||
);
|
||||
let rhs = unpack!(
|
||||
block =
|
||||
this.as_operand(block, scope, &this.thir[rhs], None, NeedsTemporary::No)
|
||||
this.as_operand(block, scope, &this.thir[rhs], LocalInfo::Boring, NeedsTemporary::No)
|
||||
);
|
||||
this.build_binary_op(block, op, expr_span, expr.ty, lhs, rhs)
|
||||
}
|
||||
ExprKind::Unary { op, arg } => {
|
||||
let arg = unpack!(
|
||||
block =
|
||||
this.as_operand(block, scope, &this.thir[arg], None, NeedsTemporary::No)
|
||||
this.as_operand(block, scope, &this.thir[arg], LocalInfo::Boring, NeedsTemporary::No)
|
||||
);
|
||||
// Check for -MIN on signed integers
|
||||
if this.check_overflow && op == UnOp::Neg && expr.ty.is_signed() {
|
||||
|
@ -260,7 +260,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
} else {
|
||||
let ty = source.ty;
|
||||
let source = unpack!(
|
||||
block = this.as_operand(block, scope, source, None, NeedsTemporary::No)
|
||||
block = this.as_operand(block, scope, source, LocalInfo::Boring, NeedsTemporary::No)
|
||||
);
|
||||
(source, ty)
|
||||
};
|
||||
|
@ -273,7 +273,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
ExprKind::Pointer { cast, source } => {
|
||||
let source = unpack!(
|
||||
block =
|
||||
this.as_operand(block, scope, &this.thir[source], None, NeedsTemporary::No)
|
||||
this.as_operand(block, scope, &this.thir[source], LocalInfo::Boring, NeedsTemporary::No)
|
||||
);
|
||||
block.and(Rvalue::Cast(CastKind::Pointer(cast), source, expr.ty))
|
||||
}
|
||||
|
@ -315,7 +315,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
block,
|
||||
scope,
|
||||
&this.thir[f],
|
||||
None,
|
||||
LocalInfo::Boring,
|
||||
NeedsTemporary::Maybe
|
||||
)
|
||||
)
|
||||
|
@ -336,7 +336,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
block,
|
||||
scope,
|
||||
&this.thir[f],
|
||||
None,
|
||||
LocalInfo::Boring,
|
||||
NeedsTemporary::Maybe
|
||||
)
|
||||
)
|
||||
|
@ -424,7 +424,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
block,
|
||||
scope,
|
||||
upvar,
|
||||
None,
|
||||
LocalInfo::Boring,
|
||||
NeedsTemporary::Maybe
|
||||
)
|
||||
)
|
||||
|
@ -503,7 +503,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
Some(Category::Rvalue(RvalueFunc::AsRvalue) | Category::Constant)
|
||||
));
|
||||
let operand =
|
||||
unpack!(block = this.as_operand(block, scope, expr, None, NeedsTemporary::No));
|
||||
unpack!(block = this.as_operand(block, scope, expr, LocalInfo::Boring, NeedsTemporary::No));
|
||||
block.and(Rvalue::Use(operand))
|
||||
}
|
||||
}
|
||||
|
@ -663,7 +663,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
} else {
|
||||
// For a non-const, we may need to generate an appropriate `Drop`
|
||||
let value_operand =
|
||||
unpack!(block = this.as_operand(block, scope, value, None, NeedsTemporary::No));
|
||||
unpack!(block = this.as_operand(block, scope, value, LocalInfo::Boring, NeedsTemporary::No));
|
||||
if let Operand::Move(to_drop) = value_operand {
|
||||
let success = this.cfg.start_new_block();
|
||||
this.cfg.terminate(
|
||||
|
|
|
@ -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 =
|
||||
Some(Box::new(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 =
|
||||
Some(Box::new(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 = Some(Box::new(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);
|
||||
|
|
|
@ -328,7 +328,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let fields_map: FxHashMap<_, _> = fields
|
||||
.into_iter()
|
||||
.map(|f| {
|
||||
let local_info = Box::new(LocalInfo::AggregateTemp);
|
||||
(
|
||||
f.name,
|
||||
unpack!(
|
||||
|
@ -336,7 +335,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
block,
|
||||
Some(scope),
|
||||
&this.thir[f.expr],
|
||||
Some(local_info),
|
||||
LocalInfo::AggregateTemp,
|
||||
NeedsTemporary::Maybe,
|
||||
)
|
||||
),
|
||||
|
@ -526,7 +525,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
block,
|
||||
Some(scope),
|
||||
&this.thir[value],
|
||||
None,
|
||||
LocalInfo::Boring,
|
||||
NeedsTemporary::No
|
||||
)
|
||||
);
|
||||
|
|
|
@ -607,9 +607,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// };
|
||||
// ```
|
||||
if let Some(place) = initializer.try_to_place(self) {
|
||||
let Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
||||
let LocalInfo::User(BindingForm::Var(
|
||||
VarBindingForm { opt_match_place: Some((ref mut match_place, _)), .. },
|
||||
)))) = self.local_decls[local].local_info else {
|
||||
)) = **self.local_decls[local].local_info.as_mut().assert_crate_local() else {
|
||||
bug!("Let binding to non-user variable.")
|
||||
};
|
||||
*match_place = Some(place);
|
||||
|
@ -1754,7 +1754,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let fake_borrow_ty = tcx.mk_imm_ref(tcx.lifetimes.re_erased, fake_borrow_deref_ty);
|
||||
let mut fake_borrow_temp = LocalDecl::new(fake_borrow_ty, temp_span);
|
||||
fake_borrow_temp.internal = self.local_decls[matched_place.local].internal;
|
||||
fake_borrow_temp.local_info = Some(Box::new(LocalInfo::FakeBorrow));
|
||||
fake_borrow_temp.local_info = ClearCrossCrate::Set(Box::new(LocalInfo::FakeBorrow));
|
||||
let fake_borrow_temp = self.local_decls.push(fake_borrow_temp);
|
||||
|
||||
(matched_place, fake_borrow_temp)
|
||||
|
@ -2224,8 +2224,7 @@ 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: Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
||||
local_info: ClearCrossCrate::Set(Box::new(LocalInfo::User(BindingForm::Var(
|
||||
VarBindingForm {
|
||||
binding_mode,
|
||||
// hypothetically, `visit_primary_bindings` could try to unzip
|
||||
|
@ -2236,7 +2235,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
opt_match_place,
|
||||
pat_span,
|
||||
},
|
||||
))))),
|
||||
)))),
|
||||
};
|
||||
let for_arm_body = self.local_decls.push(local);
|
||||
self.var_debug_info.push(VarDebugInfo {
|
||||
|
@ -2253,10 +2252,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
user_ty: None,
|
||||
source_info,
|
||||
internal: false,
|
||||
is_block_tail: None,
|
||||
local_info: Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(
|
||||
BindingForm::RefForGuard,
|
||||
)))),
|
||||
local_info: ClearCrossCrate::Set(Box::new(LocalInfo::User(BindingForm::RefForGuard))),
|
||||
});
|
||||
self.var_debug_info.push(VarDebugInfo {
|
||||
name,
|
||||
|
|
|
@ -876,20 +876,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
} => {
|
||||
self.local_decls[local].mutability = mutability;
|
||||
self.local_decls[local].source_info.scope = self.source_scope;
|
||||
self.local_decls[local].local_info = if let Some(kind) = param.self_kind {
|
||||
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(
|
||||
**self.local_decls[local].local_info.as_mut().assert_crate_local() = if let Some(kind) = param.self_kind {
|
||||
LocalInfo::User(
|
||||
BindingForm::ImplicitSelf(kind),
|
||||
))))
|
||||
)
|
||||
} else {
|
||||
let binding_mode = ty::BindingMode::BindByValue(mutability);
|
||||
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
||||
LocalInfo::User(BindingForm::Var(
|
||||
VarBindingForm {
|
||||
binding_mode,
|
||||
opt_ty_info: param.ty_span,
|
||||
opt_match_place: Some((None, span)),
|
||||
pat_span: span,
|
||||
},
|
||||
)))))
|
||||
))
|
||||
};
|
||||
self.var_indices.insert(var, LocalsForNode::One(local));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue