Shrink LocalDecl
by 56 bytes.
By boxing `local_info`.
This commit is contained in:
parent
cda1627278
commit
27ae2f0d60
@ -696,7 +696,7 @@ pub struct LocalDecl<'tcx> {
|
||||
pub mutability: Mutability,
|
||||
|
||||
// FIXME(matthewjasper) Don't store in this in `Body`
|
||||
pub local_info: LocalInfo<'tcx>,
|
||||
pub local_info: Option<Box<LocalInfo<'tcx>>>,
|
||||
|
||||
/// `true` if this is an internal local.
|
||||
///
|
||||
@ -818,9 +818,11 @@ pub struct LocalDecl<'tcx> {
|
||||
|
||||
// `LocalDecl` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
static_assert_size!(LocalDecl<'_>, 128);
|
||||
static_assert_size!(LocalDecl<'_>, 72);
|
||||
|
||||
/// Extra information about a local that's used for diagnostics.
|
||||
/// Extra information about a some locals that's used for diagnostics. (Not
|
||||
/// used for non-StaticRef temporaries, the return place, or anonymous function
|
||||
/// parameters.)
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
||||
pub enum LocalInfo<'tcx> {
|
||||
/// A user-defined local variable or function parameter
|
||||
@ -831,8 +833,6 @@ pub enum LocalInfo<'tcx> {
|
||||
User(ClearCrossCrate<BindingForm<'tcx>>),
|
||||
/// A temporary created that references the static with the given `DefId`.
|
||||
StaticRef { def_id: DefId, is_thread_local: bool },
|
||||
/// Any other temporary, the return place, or an anonymous function parameter.
|
||||
Other,
|
||||
}
|
||||
|
||||
impl<'tcx> LocalDecl<'tcx> {
|
||||
@ -844,16 +844,16 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||
/// - or `match ... { C(x) => ... }`
|
||||
pub fn can_be_made_mutable(&self) -> bool {
|
||||
match self.local_info {
|
||||
LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
|
||||
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
|
||||
binding_mode: ty::BindingMode::BindByValue(_),
|
||||
opt_ty_info: _,
|
||||
opt_match_place: _,
|
||||
pat_span: _,
|
||||
}))) => true,
|
||||
})))) => true,
|
||||
|
||||
LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(
|
||||
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(
|
||||
ImplicitSelfKind::Imm,
|
||||
))) => true,
|
||||
)))) => true,
|
||||
|
||||
_ => false,
|
||||
}
|
||||
@ -864,14 +864,14 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||
/// mutable bindings, but the inverse does not necessarily hold).
|
||||
pub fn is_nonref_binding(&self) -> bool {
|
||||
match self.local_info {
|
||||
LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
|
||||
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
|
||||
binding_mode: ty::BindingMode::BindByValue(_),
|
||||
opt_ty_info: _,
|
||||
opt_match_place: _,
|
||||
pat_span: _,
|
||||
}))) => true,
|
||||
})))) => true,
|
||||
|
||||
LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(_))) => true,
|
||||
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(_)))) => true,
|
||||
|
||||
_ => false,
|
||||
}
|
||||
@ -882,7 +882,7 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||
#[inline]
|
||||
pub fn is_user_variable(&self) -> bool {
|
||||
match self.local_info {
|
||||
LocalInfo::User(_) => true,
|
||||
Some(box LocalInfo::User(_)) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -892,7 +892,7 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||
/// match arm.
|
||||
pub fn is_ref_for_guard(&self) -> bool {
|
||||
match self.local_info {
|
||||
LocalInfo::User(ClearCrossCrate::Set(BindingForm::RefForGuard)) => true,
|
||||
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::RefForGuard))) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -901,7 +901,7 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||
/// access that static
|
||||
pub fn is_ref_to_static(&self) -> bool {
|
||||
match self.local_info {
|
||||
LocalInfo::StaticRef { .. } => true,
|
||||
Some(box LocalInfo::StaticRef { .. }) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -910,7 +910,7 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||
/// access that static
|
||||
pub fn is_ref_to_thread_local(&self) -> bool {
|
||||
match self.local_info {
|
||||
LocalInfo::StaticRef { is_thread_local, .. } => is_thread_local,
|
||||
Some(box LocalInfo::StaticRef { is_thread_local, .. }) => is_thread_local,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@ -933,7 +933,7 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||
pub fn with_source_info(ty: Ty<'tcx>, source_info: SourceInfo) -> Self {
|
||||
LocalDecl {
|
||||
mutability: Mutability::Mut,
|
||||
local_info: LocalInfo::Other,
|
||||
local_info: None,
|
||||
internal: false,
|
||||
is_block_tail: None,
|
||||
ty,
|
||||
|
@ -1448,15 +1448,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
let (place_description, assigned_span) = match local_decl {
|
||||
Some(LocalDecl {
|
||||
local_info:
|
||||
LocalInfo::User(
|
||||
Some(box LocalInfo::User(
|
||||
ClearCrossCrate::Clear
|
||||
| ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
|
||||
opt_match_place: None,
|
||||
..
|
||||
})),
|
||||
)
|
||||
| LocalInfo::StaticRef { .. }
|
||||
| LocalInfo::Other,
|
||||
))
|
||||
| Some(box LocalInfo::StaticRef { .. })
|
||||
| None,
|
||||
..
|
||||
})
|
||||
| None => (self.describe_any_place(place.as_ref()), assigned_span),
|
||||
|
@ -202,7 +202,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
if self.body.local_decls[local].is_ref_to_static() =>
|
||||
{
|
||||
let local_info = &self.body.local_decls[local].local_info;
|
||||
if let LocalInfo::StaticRef { def_id, .. } = *local_info {
|
||||
if let Some(box LocalInfo::StaticRef { def_id, .. }) = *local_info {
|
||||
buf.push_str(&self.infcx.tcx.item_name(def_id).as_str());
|
||||
} else {
|
||||
unreachable!();
|
||||
|
@ -103,14 +103,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
//
|
||||
// opt_match_place is None for let [mut] x = ... statements,
|
||||
// whether or not the right-hand side is a place expression
|
||||
if let LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
||||
if let Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
||||
VarBindingForm {
|
||||
opt_match_place: Some((opt_match_place, match_span)),
|
||||
binding_mode: _,
|
||||
opt_ty_info: _,
|
||||
pat_span: _,
|
||||
},
|
||||
))) = local_decl.local_info
|
||||
)))) = local_decl.local_info
|
||||
{
|
||||
let stmt_source_info = self.body.source_info(location);
|
||||
self.append_binding_error(
|
||||
@ -482,10 +482,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
let mut suggestions: Vec<(Span, &str, String)> = Vec::new();
|
||||
for local in binds_to {
|
||||
let bind_to = &self.body.local_decls[*local];
|
||||
if let LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
|
||||
if let Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
|
||||
pat_span,
|
||||
..
|
||||
}))) = bind_to.local_info
|
||||
})))) = bind_to.local_info
|
||||
{
|
||||
if let Ok(pat_snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(pat_span)
|
||||
{
|
||||
|
@ -85,7 +85,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
} else {
|
||||
item_msg = format!("`{}`", access_place_desc.unwrap());
|
||||
let local_info = &self.body.local_decls[local].local_info;
|
||||
if let LocalInfo::StaticRef { def_id, .. } = *local_info {
|
||||
if let Some(box LocalInfo::StaticRef { def_id, .. }) = *local_info {
|
||||
let static_name = &self.infcx.tcx.item_name(def_id);
|
||||
reason = format!(", as `{}` is an immutable static item", static_name);
|
||||
} else {
|
||||
@ -216,9 +216,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
.local_decls
|
||||
.get(local)
|
||||
.map(|local_decl| {
|
||||
if let LocalInfo::User(ClearCrossCrate::Set(
|
||||
if let Some(box LocalInfo::User(ClearCrossCrate::Set(
|
||||
mir::BindingForm::ImplicitSelf(kind),
|
||||
)) = local_decl.local_info
|
||||
))) = local_decl.local_info
|
||||
{
|
||||
// Check if the user variable is a `&mut self` and we can therefore
|
||||
// suggest removing the `&mut`.
|
||||
@ -340,8 +340,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
|
||||
match self.local_names[local] {
|
||||
Some(name) if !local_decl.from_compiler_desugaring() => {
|
||||
let label = match local_decl.local_info {
|
||||
LocalInfo::User(ClearCrossCrate::Set(
|
||||
let label = match local_decl.local_info.as_ref().unwrap() {
|
||||
box LocalInfo::User(ClearCrossCrate::Set(
|
||||
mir::BindingForm::ImplicitSelf(_),
|
||||
)) => {
|
||||
let (span, suggestion) =
|
||||
@ -349,7 +349,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
Some((true, span, suggestion))
|
||||
}
|
||||
|
||||
LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var(
|
||||
box LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var(
|
||||
mir::VarBindingForm {
|
||||
binding_mode: ty::BindingMode::BindByValue(_),
|
||||
opt_ty_info,
|
||||
@ -381,14 +381,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
self.infcx.tcx,
|
||||
local_decl,
|
||||
opt_assignment_rhs_span,
|
||||
opt_ty_info,
|
||||
*opt_ty_info,
|
||||
);
|
||||
Some((true, span, suggestion))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var(
|
||||
box LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var(
|
||||
mir::VarBindingForm {
|
||||
binding_mode: ty::BindingMode::BindByReference(_),
|
||||
..
|
||||
@ -399,7 +399,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
.map(|replacement| (true, pattern_span, replacement))
|
||||
}
|
||||
|
||||
LocalInfo::User(ClearCrossCrate::Clear) => {
|
||||
box LocalInfo::User(ClearCrossCrate::Clear) => {
|
||||
bug!("saw cleared local state")
|
||||
}
|
||||
|
||||
|
@ -456,7 +456,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
||||
if proj_base.is_empty() {
|
||||
if let (local, []) = (place_local, proj_base) {
|
||||
let decl = &self.body.local_decls[local];
|
||||
if let LocalInfo::StaticRef { def_id, .. } = decl.local_info {
|
||||
if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info {
|
||||
let span = decl.source_info.span;
|
||||
self.check_static(def_id, span);
|
||||
return;
|
||||
|
@ -218,7 +218,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
|
||||
if let [] = proj_base {
|
||||
let decl = &self.body.local_decls[place.local];
|
||||
if decl.internal {
|
||||
if let LocalInfo::StaticRef { def_id, .. } = decl.local_info {
|
||||
if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info {
|
||||
if self.tcx.is_mutable_static(def_id) {
|
||||
self.require_unsafe(
|
||||
"use of mutable static",
|
||||
|
@ -61,7 +61,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
if let ExprKind::StaticRef { def_id, .. } = expr.kind {
|
||||
let is_thread_local = this.hir.tcx().is_thread_local_static(def_id);
|
||||
local_decl.internal = true;
|
||||
local_decl.local_info = LocalInfo::StaticRef { def_id, is_thread_local };
|
||||
local_decl.local_info = Some(box LocalInfo::StaticRef { def_id, is_thread_local });
|
||||
}
|
||||
this.local_decls.push(local_decl)
|
||||
};
|
||||
|
@ -470,9 +470,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
for binding in &candidate_ref.bindings {
|
||||
let local = self.var_local_id(binding.var_id, OutsideGuard);
|
||||
|
||||
if let LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
||||
if let Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
||||
VarBindingForm { opt_match_place: Some((ref mut match_place, _)), .. },
|
||||
))) = self.local_decls[local].local_info
|
||||
)))) = self.local_decls[local].local_info
|
||||
{
|
||||
*match_place = Some(initializer);
|
||||
} else {
|
||||
@ -1953,7 +1953,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
source_info,
|
||||
internal: false,
|
||||
is_block_tail: None,
|
||||
local_info: LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
|
||||
local_info: Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
|
||||
binding_mode,
|
||||
// hypothetically, `visit_bindings` could try to unzip
|
||||
// an outermost hir::Ty as we descend, matching up
|
||||
@ -1962,7 +1962,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
opt_ty_info: None,
|
||||
opt_match_place,
|
||||
pat_span,
|
||||
}))),
|
||||
})))),
|
||||
};
|
||||
let for_arm_body = self.local_decls.push(local);
|
||||
self.var_debug_info.push(VarDebugInfo {
|
||||
@ -1980,7 +1980,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
source_info,
|
||||
internal: false,
|
||||
is_block_tail: None,
|
||||
local_info: LocalInfo::User(ClearCrossCrate::Set(BindingForm::RefForGuard)),
|
||||
local_info: Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::RefForGuard))),
|
||||
});
|
||||
self.var_debug_info.push(VarDebugInfo {
|
||||
name,
|
||||
|
@ -909,17 +909,17 @@ 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) = self_binding {
|
||||
LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(*kind)))
|
||||
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(*kind))))
|
||||
} else {
|
||||
let binding_mode = ty::BindingMode::BindByValue(mutability);
|
||||
LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
||||
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
||||
VarBindingForm {
|
||||
binding_mode,
|
||||
opt_ty_info,
|
||||
opt_match_place: Some((Some(place), span)),
|
||||
pat_span: span,
|
||||
},
|
||||
)))
|
||||
))))
|
||||
};
|
||||
self.var_indices.insert(var, LocalsForNode::One(local));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user