Wrap the whole LocalInfo in ClearCrossCrate.
This commit is contained in:
parent
2e7034ebf7
commit
bcb161def7
19 changed files with 134 additions and 142 deletions
|
@ -2482,15 +2482,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
let (place_description, assigned_span) = match local_decl {
|
let (place_description, assigned_span) = match local_decl {
|
||||||
Some(LocalDecl {
|
Some(LocalDecl {
|
||||||
local_info:
|
local_info:
|
||||||
Some(box LocalInfo::User(
|
ClearCrossCrate::Set(
|
||||||
ClearCrossCrate::Clear
|
box LocalInfo::User(BindingForm::Var(VarBindingForm {
|
||||||
| ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
|
|
||||||
opt_match_place: None,
|
opt_match_place: None,
|
||||||
..
|
..
|
||||||
})),
|
}))
|
||||||
))
|
| box LocalInfo::StaticRef { .. }
|
||||||
| Some(box LocalInfo::StaticRef { .. })
|
| box LocalInfo::Boring,
|
||||||
| None,
|
),
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
| None => (self.describe_any_place(place.as_ref()), assigned_span),
|
| None => (self.describe_any_place(place.as_ref()), assigned_span),
|
||||||
|
|
|
@ -196,10 +196,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
if self.body.local_decls[local].is_ref_for_guard() {
|
if self.body.local_decls[local].is_ref_for_guard() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some(box LocalInfo::StaticRef { def_id, .. }) =
|
if let LocalInfo::StaticRef { def_id, .. } =
|
||||||
&self.body.local_decls[local].local_info
|
*self.body.local_decls[local].local_info()
|
||||||
{
|
{
|
||||||
buf.push_str(self.infcx.tcx.item_name(*def_id).as_str());
|
buf.push_str(self.infcx.tcx.item_name(def_id).as_str());
|
||||||
ok = Ok(());
|
ok = Ok(());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,14 +102,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
//
|
//
|
||||||
// opt_match_place is None for let [mut] x = ... statements,
|
// opt_match_place is None for let [mut] x = ... statements,
|
||||||
// whether or not the right-hand side is a place expression
|
// whether or not the right-hand side is a place expression
|
||||||
if let Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
if let LocalInfo::User(BindingForm::Var(VarBindingForm {
|
||||||
VarBindingForm {
|
opt_match_place: Some((opt_match_place, match_span)),
|
||||||
opt_match_place: Some((opt_match_place, match_span)),
|
binding_mode: _,
|
||||||
binding_mode: _,
|
opt_ty_info: _,
|
||||||
opt_ty_info: _,
|
pat_span: _,
|
||||||
pat_span: _,
|
})) = *local_decl.local_info()
|
||||||
},
|
|
||||||
)))) = local_decl.local_info
|
|
||||||
{
|
{
|
||||||
let stmt_source_info = self.body.source_info(location);
|
let stmt_source_info = self.body.source_info(location);
|
||||||
self.append_binding_error(
|
self.append_binding_error(
|
||||||
|
@ -478,9 +476,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
let mut suggestions: Vec<(Span, String, String)> = Vec::new();
|
let mut suggestions: Vec<(Span, String, String)> = Vec::new();
|
||||||
for local in binds_to {
|
for local in binds_to {
|
||||||
let bind_to = &self.body.local_decls[*local];
|
let bind_to = &self.body.local_decls[*local];
|
||||||
if let Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
if let LocalInfo::User(BindingForm::Var(VarBindingForm { pat_span, .. })) =
|
||||||
VarBindingForm { pat_span, .. },
|
*bind_to.local_info()
|
||||||
)))) = bind_to.local_info
|
|
||||||
{
|
{
|
||||||
let Ok(pat_snippet) =
|
let Ok(pat_snippet) =
|
||||||
self.infcx.tcx.sess.source_map().span_to_snippet(pat_span) else { continue; };
|
self.infcx.tcx.sess.source_map().span_to_snippet(pat_span) else { continue; };
|
||||||
|
|
|
@ -7,7 +7,7 @@ use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem};
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_middle::{
|
use rustc_middle::{
|
||||||
hir::place::PlaceBase,
|
hir::place::PlaceBase,
|
||||||
mir::{self, BindingForm, ClearCrossCrate, Local, LocalDecl, LocalInfo, LocalKind, Location},
|
mir::{self, BindingForm, Local, LocalDecl, LocalInfo, LocalKind, Location},
|
||||||
};
|
};
|
||||||
use rustc_span::source_map::DesugaringKind;
|
use rustc_span::source_map::DesugaringKind;
|
||||||
use rustc_span::symbol::{kw, Symbol};
|
use rustc_span::symbol::{kw, Symbol};
|
||||||
|
@ -105,8 +105,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
reason = String::new();
|
reason = String::new();
|
||||||
} else {
|
} else {
|
||||||
item_msg = access_place_desc;
|
item_msg = access_place_desc;
|
||||||
let local_info = &self.body.local_decls[local].local_info;
|
let local_info = self.body.local_decls[local].local_info();
|
||||||
if let Some(box LocalInfo::StaticRef { def_id, .. }) = *local_info {
|
if let LocalInfo::StaticRef { def_id, .. } = *local_info {
|
||||||
let static_name = &self.infcx.tcx.item_name(def_id);
|
let static_name = &self.infcx.tcx.item_name(def_id);
|
||||||
reason = format!(", as `{static_name}` is an immutable static item");
|
reason = format!(", as `{static_name}` is an immutable static item");
|
||||||
} else {
|
} else {
|
||||||
|
@ -305,15 +305,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
..
|
..
|
||||||
}) = &self.body[location.block].statements.get(location.statement_index)
|
}) = &self.body[location.block].statements.get(location.statement_index)
|
||||||
{
|
{
|
||||||
match decl.local_info {
|
match *decl.local_info() {
|
||||||
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
LocalInfo::User(BindingForm::Var(mir::VarBindingForm {
|
||||||
mir::VarBindingForm {
|
binding_mode: ty::BindingMode::BindByValue(Mutability::Not),
|
||||||
binding_mode: ty::BindingMode::BindByValue(Mutability::Not),
|
opt_ty_info: Some(sp),
|
||||||
opt_ty_info: Some(sp),
|
opt_match_place: _,
|
||||||
opt_match_place: _,
|
pat_span: _,
|
||||||
pat_span: _,
|
})) => {
|
||||||
},
|
|
||||||
)))) => {
|
|
||||||
if suggest {
|
if suggest {
|
||||||
err.span_note(sp, "the binding is already a mutable borrow");
|
err.span_note(sp, "the binding is already a mutable borrow");
|
||||||
}
|
}
|
||||||
|
@ -346,10 +344,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
} else if decl.mutability.is_not() {
|
} else if decl.mutability.is_not() {
|
||||||
if matches!(
|
if matches!(
|
||||||
decl.local_info,
|
decl.local_info(),
|
||||||
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(
|
LocalInfo::User(BindingForm::ImplicitSelf(hir::ImplicitSelfKind::MutRef))
|
||||||
hir::ImplicitSelfKind::MutRef
|
|
||||||
),)))
|
|
||||||
) {
|
) {
|
||||||
err.note(
|
err.note(
|
||||||
"as `Self` may be unsized, this call attempts to take `&mut &mut self`",
|
"as `Self` may be unsized, this call attempts to take `&mut &mut self`",
|
||||||
|
@ -482,22 +478,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
match self.local_names[local] {
|
match self.local_names[local] {
|
||||||
Some(name) if !local_decl.from_compiler_desugaring() => {
|
Some(name) if !local_decl.from_compiler_desugaring() => {
|
||||||
let label = match local_decl.local_info.as_deref().unwrap() {
|
let label = match *local_decl.local_info() {
|
||||||
LocalInfo::User(ClearCrossCrate::Set(
|
LocalInfo::User(mir::BindingForm::ImplicitSelf(_)) => {
|
||||||
mir::BindingForm::ImplicitSelf(_),
|
|
||||||
)) => {
|
|
||||||
let (span, suggestion) =
|
let (span, suggestion) =
|
||||||
suggest_ampmut_self(self.infcx.tcx, local_decl);
|
suggest_ampmut_self(self.infcx.tcx, local_decl);
|
||||||
Some((true, span, suggestion))
|
Some((true, span, suggestion))
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var(
|
LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
|
||||||
mir::VarBindingForm {
|
binding_mode: ty::BindingMode::BindByValue(_),
|
||||||
binding_mode: ty::BindingMode::BindByValue(_),
|
opt_ty_info,
|
||||||
opt_ty_info,
|
..
|
||||||
..
|
})) => {
|
||||||
},
|
|
||||||
))) => {
|
|
||||||
// check if the RHS is from desugaring
|
// check if the RHS is from desugaring
|
||||||
let opt_assignment_rhs_span =
|
let opt_assignment_rhs_span =
|
||||||
self.body.find_assignments(local).first().map(|&location| {
|
self.body.find_assignments(local).first().map(|&location| {
|
||||||
|
@ -534,16 +526,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
self.infcx.tcx,
|
self.infcx.tcx,
|
||||||
local_decl,
|
local_decl,
|
||||||
opt_assignment_rhs_span,
|
opt_assignment_rhs_span,
|
||||||
*opt_ty_info,
|
opt_ty_info,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
match local_decl.local_info.as_deref() {
|
match local_decl.local_info() {
|
||||||
Some(LocalInfo::User(ClearCrossCrate::Set(
|
LocalInfo::User(mir::BindingForm::Var(
|
||||||
mir::BindingForm::Var(mir::VarBindingForm {
|
mir::VarBindingForm {
|
||||||
opt_ty_info: None,
|
opt_ty_info: None, ..
|
||||||
..
|
},
|
||||||
}),
|
)) => {
|
||||||
))) => {
|
|
||||||
let (span, sugg) = suggest_ampmut_self(
|
let (span, sugg) = suggest_ampmut_self(
|
||||||
self.infcx.tcx,
|
self.infcx.tcx,
|
||||||
local_decl,
|
local_decl,
|
||||||
|
@ -555,7 +546,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
self.infcx.tcx,
|
self.infcx.tcx,
|
||||||
local_decl,
|
local_decl,
|
||||||
opt_assignment_rhs_span,
|
opt_assignment_rhs_span,
|
||||||
*opt_ty_info,
|
opt_ty_info,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -564,21 +555,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var(
|
LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
|
||||||
mir::VarBindingForm {
|
binding_mode: ty::BindingMode::BindByReference(_),
|
||||||
binding_mode: ty::BindingMode::BindByReference(_),
|
..
|
||||||
..
|
})) => {
|
||||||
},
|
|
||||||
))) => {
|
|
||||||
let pattern_span = local_decl.source_info.span;
|
let pattern_span = local_decl.source_info.span;
|
||||||
suggest_ref_mut(self.infcx.tcx, pattern_span)
|
suggest_ref_mut(self.infcx.tcx, pattern_span)
|
||||||
.map(|replacement| (true, pattern_span, replacement))
|
.map(|replacement| (true, pattern_span, replacement))
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalInfo::User(ClearCrossCrate::Clear) => {
|
|
||||||
bug!("saw cleared local state")
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1151,20 +1136,19 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool {
|
pub fn mut_borrow_of_mutable_ref(local_decl: &LocalDecl<'_>, local_name: Option<Symbol>) -> bool {
|
||||||
debug!("local_info: {:?}, ty.kind(): {:?}", local_decl.local_info, local_decl.ty.kind());
|
debug!("local_info: {:?}, ty.kind(): {:?}", local_decl.local_info, local_decl.ty.kind());
|
||||||
|
|
||||||
match local_decl.local_info.as_deref() {
|
match *local_decl.local_info() {
|
||||||
// Check if mutably borrowing a mutable reference.
|
// Check if mutably borrowing a mutable reference.
|
||||||
Some(LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::Var(
|
LocalInfo::User(mir::BindingForm::Var(mir::VarBindingForm {
|
||||||
mir::VarBindingForm {
|
binding_mode: ty::BindingMode::BindByValue(Mutability::Not),
|
||||||
binding_mode: ty::BindingMode::BindByValue(Mutability::Not), ..
|
..
|
||||||
},
|
})) => matches!(local_decl.ty.kind(), ty::Ref(_, _, hir::Mutability::Mut)),
|
||||||
)))) => matches!(local_decl.ty.kind(), ty::Ref(_, _, hir::Mutability::Mut)),
|
LocalInfo::User(mir::BindingForm::ImplicitSelf(kind)) => {
|
||||||
Some(LocalInfo::User(ClearCrossCrate::Set(mir::BindingForm::ImplicitSelf(kind)))) => {
|
|
||||||
// Check if the user variable is a `&mut self` and we can therefore
|
// Check if the user variable is a `&mut self` and we can therefore
|
||||||
// suggest removing the `&mut`.
|
// suggest removing the `&mut`.
|
||||||
//
|
//
|
||||||
// Deliberately fall into this case for all implicit self types,
|
// Deliberately fall into this case for all implicit self types,
|
||||||
// so that we don't fall in to the next case with them.
|
// so that we don't fall in to the next case with them.
|
||||||
*kind == hir::ImplicitSelfKind::MutRef
|
kind == hir::ImplicitSelfKind::MutRef
|
||||||
}
|
}
|
||||||
_ if Some(kw::SelfLower) == local_name => {
|
_ if Some(kw::SelfLower) == local_name => {
|
||||||
// Otherwise, check if the name is the `self` keyword - in which case
|
// Otherwise, check if the name is the `self` keyword - in which case
|
||||||
|
|
|
@ -1180,10 +1180,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(l)
|
Some(l)
|
||||||
if matches!(
|
if matches!(body.local_decls[l].local_info(), LocalInfo::AggregateTemp) =>
|
||||||
body.local_decls[l].local_info,
|
|
||||||
Some(box LocalInfo::AggregateTemp)
|
|
||||||
) =>
|
|
||||||
{
|
{
|
||||||
ConstraintCategory::Usage
|
ConstraintCategory::Usage
|
||||||
}
|
}
|
||||||
|
|
|
@ -643,7 +643,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
if base_ty.is_unsafe_ptr() {
|
if base_ty.is_unsafe_ptr() {
|
||||||
if proj_base.is_empty() {
|
if proj_base.is_empty() {
|
||||||
let decl = &self.body.local_decls[place_local];
|
let decl = &self.body.local_decls[place_local];
|
||||||
if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info {
|
if let LocalInfo::StaticRef { def_id, .. } = *decl.local_info() {
|
||||||
let span = decl.source_info.span;
|
let span = decl.source_info.span;
|
||||||
self.check_static(def_id, span);
|
self.check_static(def_id, span);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -572,6 +572,13 @@ impl<T> ClearCrossCrate<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_mut(&mut self) -> ClearCrossCrate<&mut T> {
|
||||||
|
match self {
|
||||||
|
ClearCrossCrate::Clear => ClearCrossCrate::Clear,
|
||||||
|
ClearCrossCrate::Set(v) => ClearCrossCrate::Set(v),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn assert_crate_local(self) -> T {
|
pub fn assert_crate_local(self) -> T {
|
||||||
match self {
|
match self {
|
||||||
ClearCrossCrate::Clear => bug!("unwrapping cross-crate data"),
|
ClearCrossCrate::Clear => bug!("unwrapping cross-crate data"),
|
||||||
|
@ -760,7 +767,7 @@ pub struct LocalDecl<'tcx> {
|
||||||
pub mutability: Mutability,
|
pub mutability: Mutability,
|
||||||
|
|
||||||
// FIXME(matthewjasper) Don't store in this in `Body`
|
// FIXME(matthewjasper) Don't store in this in `Body`
|
||||||
pub local_info: Option<Box<LocalInfo<'tcx>>>,
|
pub local_info: ClearCrossCrate<Box<LocalInfo<'tcx>>>,
|
||||||
|
|
||||||
/// `true` if this is an internal local.
|
/// `true` if this is an internal local.
|
||||||
///
|
///
|
||||||
|
@ -890,7 +897,7 @@ pub enum LocalInfo<'tcx> {
|
||||||
/// The `BindingForm` is solely used for local diagnostics when generating
|
/// The `BindingForm` is solely used for local diagnostics when generating
|
||||||
/// warnings/errors when compiling the current crate, and therefore it need
|
/// warnings/errors when compiling the current crate, and therefore it need
|
||||||
/// not be visible across crates.
|
/// not be visible across crates.
|
||||||
User(ClearCrossCrate<BindingForm<'tcx>>),
|
User(BindingForm<'tcx>),
|
||||||
/// A temporary created that references the static with the given `DefId`.
|
/// A temporary created that references the static with the given `DefId`.
|
||||||
StaticRef { def_id: DefId, is_thread_local: bool },
|
StaticRef { def_id: DefId, is_thread_local: bool },
|
||||||
/// A temporary created that references the const with the given `DefId`
|
/// A temporary created that references the const with the given `DefId`
|
||||||
|
@ -902,9 +909,15 @@ pub enum LocalInfo<'tcx> {
|
||||||
DerefTemp,
|
DerefTemp,
|
||||||
/// A temporary created for borrow checking.
|
/// A temporary created for borrow checking.
|
||||||
FakeBorrow,
|
FakeBorrow,
|
||||||
|
/// A local without anything interesting about it.
|
||||||
|
Boring,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> LocalDecl<'tcx> {
|
impl<'tcx> LocalDecl<'tcx> {
|
||||||
|
pub fn local_info(&self) -> &LocalInfo<'tcx> {
|
||||||
|
&**self.local_info.as_ref().assert_crate_local()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` only if local is a binding that can itself be
|
/// Returns `true` only if local is a binding that can itself be
|
||||||
/// made mutable via the addition of the `mut` keyword, namely
|
/// made mutable via the addition of the `mut` keyword, namely
|
||||||
/// something like the occurrences of `x` in:
|
/// something like the occurrences of `x` in:
|
||||||
|
@ -914,14 +927,14 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||||
pub fn can_be_made_mutable(&self) -> bool {
|
pub fn can_be_made_mutable(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
self.local_info,
|
self.local_info,
|
||||||
Some(box LocalInfo::User(ClearCrossCrate::Set(
|
ClearCrossCrate::Set(box LocalInfo::User(
|
||||||
BindingForm::Var(VarBindingForm {
|
BindingForm::Var(VarBindingForm {
|
||||||
binding_mode: ty::BindingMode::BindByValue(_),
|
binding_mode: ty::BindingMode::BindByValue(_),
|
||||||
opt_ty_info: _,
|
opt_ty_info: _,
|
||||||
opt_match_place: _,
|
opt_match_place: _,
|
||||||
pat_span: _,
|
pat_span: _,
|
||||||
}) | BindingForm::ImplicitSelf(ImplicitSelfKind::Imm),
|
}) | BindingForm::ImplicitSelf(ImplicitSelfKind::Imm),
|
||||||
)))
|
))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -931,14 +944,14 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||||
pub fn is_nonref_binding(&self) -> bool {
|
pub fn is_nonref_binding(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
self.local_info,
|
self.local_info,
|
||||||
Some(box LocalInfo::User(ClearCrossCrate::Set(
|
ClearCrossCrate::Set(box LocalInfo::User(
|
||||||
BindingForm::Var(VarBindingForm {
|
BindingForm::Var(VarBindingForm {
|
||||||
binding_mode: ty::BindingMode::BindByValue(_),
|
binding_mode: ty::BindingMode::BindByValue(_),
|
||||||
opt_ty_info: _,
|
opt_ty_info: _,
|
||||||
opt_match_place: _,
|
opt_match_place: _,
|
||||||
pat_span: _,
|
pat_span: _,
|
||||||
}) | BindingForm::ImplicitSelf(_),
|
}) | BindingForm::ImplicitSelf(_),
|
||||||
)))
|
))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -946,7 +959,7 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||||
/// parameter declared by the user.
|
/// parameter declared by the user.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_user_variable(&self) -> bool {
|
pub fn is_user_variable(&self) -> bool {
|
||||||
matches!(self.local_info, Some(box LocalInfo::User(_)))
|
matches!(self.local_info, ClearCrossCrate::Set(box LocalInfo::User(_)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if this is a reference to a variable bound in a `match`
|
/// Returns `true` if this is a reference to a variable bound in a `match`
|
||||||
|
@ -955,21 +968,23 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||||
pub fn is_ref_for_guard(&self) -> bool {
|
pub fn is_ref_for_guard(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
self.local_info,
|
self.local_info,
|
||||||
Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::RefForGuard)))
|
ClearCrossCrate::Set(box LocalInfo::User(BindingForm::RefForGuard))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `Some` if this is a reference to a static item that is used to
|
/// Returns `Some` if this is a reference to a static item that is used to
|
||||||
/// access that static.
|
/// access that static.
|
||||||
pub fn is_ref_to_static(&self) -> bool {
|
pub fn is_ref_to_static(&self) -> bool {
|
||||||
matches!(self.local_info, Some(box LocalInfo::StaticRef { .. }))
|
matches!(self.local_info, ClearCrossCrate::Set(box LocalInfo::StaticRef { .. }))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `Some` if this is a reference to a thread-local static item that is used to
|
/// Returns `Some` if this is a reference to a thread-local static item that is used to
|
||||||
/// access that static.
|
/// access that static.
|
||||||
pub fn is_ref_to_thread_local(&self) -> bool {
|
pub fn is_ref_to_thread_local(&self) -> bool {
|
||||||
match self.local_info {
|
match self.local_info {
|
||||||
Some(box LocalInfo::StaticRef { is_thread_local, .. }) => is_thread_local,
|
ClearCrossCrate::Set(box LocalInfo::StaticRef { is_thread_local, .. }) => {
|
||||||
|
is_thread_local
|
||||||
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -977,7 +992,7 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||||
/// Returns `true` if this is a DerefTemp
|
/// Returns `true` if this is a DerefTemp
|
||||||
pub fn is_deref_temp(&self) -> bool {
|
pub fn is_deref_temp(&self) -> bool {
|
||||||
match self.local_info {
|
match self.local_info {
|
||||||
Some(box LocalInfo::DerefTemp) => return true,
|
ClearCrossCrate::Set(box LocalInfo::DerefTemp) => return true,
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -1001,7 +1016,7 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||||
pub fn with_source_info(ty: Ty<'tcx>, source_info: SourceInfo) -> Self {
|
pub fn with_source_info(ty: Ty<'tcx>, source_info: SourceInfo) -> Self {
|
||||||
LocalDecl {
|
LocalDecl {
|
||||||
mutability: Mutability::Mut,
|
mutability: Mutability::Mut,
|
||||||
local_info: None,
|
local_info: ClearCrossCrate::Set(Box::new(LocalInfo::Boring)),
|
||||||
internal: false,
|
internal: false,
|
||||||
is_block_tail: None,
|
is_block_tail: None,
|
||||||
ty,
|
ty,
|
||||||
|
|
|
@ -72,12 +72,12 @@ impl<'tcx> MirPatch<'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
local_info: Option<Box<LocalInfo<'tcx>>>,
|
local_info: LocalInfo<'tcx>,
|
||||||
) -> Local {
|
) -> Local {
|
||||||
let index = self.next_local;
|
let index = self.next_local;
|
||||||
self.next_local += 1;
|
self.next_local += 1;
|
||||||
let mut new_decl = LocalDecl::new(ty, span).internal();
|
let mut new_decl = LocalDecl::new(ty, span).internal();
|
||||||
new_decl.local_info = local_info;
|
**new_decl.local_info.as_mut().assert_crate_local() = local_info;
|
||||||
self.new_locals.push(new_decl);
|
self.new_locals.push(new_decl);
|
||||||
Local::new(index as usize)
|
Local::new(index as usize)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
expr: &Expr<'tcx>,
|
expr: &Expr<'tcx>,
|
||||||
) -> BlockAnd<Operand<'tcx>> {
|
) -> BlockAnd<Operand<'tcx>> {
|
||||||
let local_scope = self.local_scope();
|
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
|
/// 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,
|
mut block: BasicBlock,
|
||||||
scope: Option<region::Scope>,
|
scope: Option<region::Scope>,
|
||||||
expr: &Expr<'tcx>,
|
expr: &Expr<'tcx>,
|
||||||
local_info: Option<Box<LocalInfo<'tcx>>>,
|
local_info: LocalInfo<'tcx>,
|
||||||
needs_temporary: NeedsTemporary,
|
needs_temporary: NeedsTemporary,
|
||||||
) -> BlockAnd<Operand<'tcx>> {
|
) -> BlockAnd<Operand<'tcx>> {
|
||||||
let this = self;
|
let this = self;
|
||||||
|
@ -124,8 +124,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
Category::Constant | Category::Place | Category::Rvalue(..) => {
|
Category::Constant | Category::Place | Category::Rvalue(..) => {
|
||||||
let operand = unpack!(block = this.as_temp(block, scope, expr, Mutability::Mut));
|
let operand = unpack!(block = this.as_temp(block, scope, expr, Mutability::Mut));
|
||||||
if this.local_decls[operand].local_info.is_none() {
|
let decl_info = this.local_decls[operand].local_info.as_mut().assert_crate_local();
|
||||||
this.local_decls[operand].local_info = local_info;
|
if let LocalInfo::Boring = **decl_info {
|
||||||
|
**decl_info = local_info;
|
||||||
}
|
}
|
||||||
block.and(Operand::Move(Place::from(operand)))
|
block.and(Operand::Move(Place::from(operand)))
|
||||||
}
|
}
|
||||||
|
@ -178,6 +179,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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
block,
|
block,
|
||||||
scope,
|
scope,
|
||||||
&this.thir[value],
|
&this.thir[value],
|
||||||
None,
|
LocalInfo::Boring,
|
||||||
NeedsTemporary::No
|
NeedsTemporary::No
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -73,18 +73,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
ExprKind::Binary { op, lhs, rhs } => {
|
ExprKind::Binary { op, lhs, rhs } => {
|
||||||
let lhs = unpack!(
|
let lhs = unpack!(
|
||||||
block =
|
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!(
|
let rhs = unpack!(
|
||||||
block =
|
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)
|
this.build_binary_op(block, op, expr_span, expr.ty, lhs, rhs)
|
||||||
}
|
}
|
||||||
ExprKind::Unary { op, arg } => {
|
ExprKind::Unary { op, arg } => {
|
||||||
let arg = unpack!(
|
let arg = unpack!(
|
||||||
block =
|
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
|
// Check for -MIN on signed integers
|
||||||
if this.check_overflow && op == UnOp::Neg && expr.ty.is_signed() {
|
if this.check_overflow && op == UnOp::Neg && expr.ty.is_signed() {
|
||||||
|
@ -259,7 +259,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
let ty = source.ty;
|
let ty = source.ty;
|
||||||
let source = unpack!(
|
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)
|
(source, ty)
|
||||||
};
|
};
|
||||||
|
@ -272,7 +272,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
ExprKind::Pointer { cast, source } => {
|
ExprKind::Pointer { cast, source } => {
|
||||||
let source = unpack!(
|
let source = unpack!(
|
||||||
block =
|
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))
|
block.and(Rvalue::Cast(CastKind::Pointer(cast), source, expr.ty))
|
||||||
}
|
}
|
||||||
|
@ -314,7 +314,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
block,
|
block,
|
||||||
scope,
|
scope,
|
||||||
&this.thir[f],
|
&this.thir[f],
|
||||||
None,
|
LocalInfo::Boring,
|
||||||
NeedsTemporary::Maybe
|
NeedsTemporary::Maybe
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -335,7 +335,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
block,
|
block,
|
||||||
scope,
|
scope,
|
||||||
&this.thir[f],
|
&this.thir[f],
|
||||||
None,
|
LocalInfo::Boring,
|
||||||
NeedsTemporary::Maybe
|
NeedsTemporary::Maybe
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -423,7 +423,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
block,
|
block,
|
||||||
scope,
|
scope,
|
||||||
upvar,
|
upvar,
|
||||||
None,
|
LocalInfo::Boring,
|
||||||
NeedsTemporary::Maybe
|
NeedsTemporary::Maybe
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -502,7 +502,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
Some(Category::Rvalue(RvalueFunc::AsRvalue) | Category::Constant)
|
Some(Category::Rvalue(RvalueFunc::AsRvalue) | Category::Constant)
|
||||||
));
|
));
|
||||||
let operand =
|
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))
|
block.and(Rvalue::Use(operand))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -622,7 +622,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
} else {
|
} else {
|
||||||
// For a non-const, we may need to generate an appropriate `Drop`
|
// For a non-const, we may need to generate an appropriate `Drop`
|
||||||
let value_operand =
|
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 {
|
if let Operand::Move(to_drop) = value_operand {
|
||||||
let success = this.cfg.start_new_block();
|
let success = this.cfg.start_new_block();
|
||||||
this.cfg.terminate(
|
this.cfg.terminate(
|
||||||
|
|
|
@ -58,17 +58,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
ExprKind::StaticRef { def_id, .. } => {
|
ExprKind::StaticRef { def_id, .. } => {
|
||||||
assert!(!this.tcx.is_thread_local_static(def_id));
|
assert!(!this.tcx.is_thread_local_static(def_id));
|
||||||
local_decl.internal = true;
|
local_decl.internal = true;
|
||||||
local_decl.local_info =
|
**local_decl.local_info.as_mut().assert_crate_local() =
|
||||||
Some(Box::new(LocalInfo::StaticRef { def_id, is_thread_local: false }));
|
LocalInfo::StaticRef { def_id, is_thread_local: false };
|
||||||
}
|
}
|
||||||
ExprKind::ThreadLocalRef(def_id) => {
|
ExprKind::ThreadLocalRef(def_id) => {
|
||||||
assert!(this.tcx.is_thread_local_static(def_id));
|
assert!(this.tcx.is_thread_local_static(def_id));
|
||||||
local_decl.internal = true;
|
local_decl.internal = true;
|
||||||
local_decl.local_info =
|
**local_decl.local_info.as_mut().assert_crate_local() =
|
||||||
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, .. } => {
|
ExprKind::NamedConst { def_id, .. } | ExprKind::ConstParam { def_id, .. } => {
|
||||||
local_decl.local_info = Some(Box::new(LocalInfo::ConstRef { def_id }));
|
**local_decl.local_info.as_mut().assert_crate_local() = LocalInfo::ConstRef { def_id };
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -328,7 +328,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
let fields_map: FxHashMap<_, _> = fields
|
let fields_map: FxHashMap<_, _> = fields
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|f| {
|
.map(|f| {
|
||||||
let local_info = Box::new(LocalInfo::AggregateTemp);
|
|
||||||
(
|
(
|
||||||
f.name,
|
f.name,
|
||||||
unpack!(
|
unpack!(
|
||||||
|
@ -336,7 +335,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
block,
|
block,
|
||||||
Some(scope),
|
Some(scope),
|
||||||
&this.thir[f.expr],
|
&this.thir[f.expr],
|
||||||
Some(local_info),
|
LocalInfo::AggregateTemp,
|
||||||
NeedsTemporary::Maybe,
|
NeedsTemporary::Maybe,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
@ -526,7 +525,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
block,
|
block,
|
||||||
Some(scope),
|
Some(scope),
|
||||||
&this.thir[value],
|
&this.thir[value],
|
||||||
None,
|
LocalInfo::Boring,
|
||||||
NeedsTemporary::No
|
NeedsTemporary::No
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -607,9 +607,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
// };
|
// };
|
||||||
// ```
|
// ```
|
||||||
if let Some(place) = initializer.try_to_place(self) {
|
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, _)), .. },
|
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.")
|
bug!("Let binding to non-user variable.")
|
||||||
};
|
};
|
||||||
*match_place = Some(place);
|
*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 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);
|
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.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);
|
let fake_borrow_temp = self.local_decls.push(fake_borrow_temp);
|
||||||
|
|
||||||
(matched_place, fake_borrow_temp)
|
(matched_place, fake_borrow_temp)
|
||||||
|
@ -2225,7 +2225,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
source_info,
|
source_info,
|
||||||
internal: false,
|
internal: false,
|
||||||
is_block_tail: None,
|
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 {
|
VarBindingForm {
|
||||||
binding_mode,
|
binding_mode,
|
||||||
// hypothetically, `visit_primary_bindings` could try to unzip
|
// hypothetically, `visit_primary_bindings` could try to unzip
|
||||||
|
@ -2236,7 +2236,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
opt_match_place,
|
opt_match_place,
|
||||||
pat_span,
|
pat_span,
|
||||||
},
|
},
|
||||||
))))),
|
)))),
|
||||||
};
|
};
|
||||||
let for_arm_body = self.local_decls.push(local);
|
let for_arm_body = self.local_decls.push(local);
|
||||||
self.var_debug_info.push(VarDebugInfo {
|
self.var_debug_info.push(VarDebugInfo {
|
||||||
|
@ -2254,9 +2254,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
source_info,
|
source_info,
|
||||||
internal: false,
|
internal: false,
|
||||||
is_block_tail: None,
|
is_block_tail: None,
|
||||||
local_info: Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(
|
local_info: ClearCrossCrate::Set(Box::new(LocalInfo::User(BindingForm::RefForGuard))),
|
||||||
BindingForm::RefForGuard,
|
|
||||||
)))),
|
|
||||||
});
|
});
|
||||||
self.var_debug_info.push(VarDebugInfo {
|
self.var_debug_info.push(VarDebugInfo {
|
||||||
name,
|
name,
|
||||||
|
|
|
@ -876,20 +876,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
} => {
|
} => {
|
||||||
self.local_decls[local].mutability = mutability;
|
self.local_decls[local].mutability = mutability;
|
||||||
self.local_decls[local].source_info.scope = self.source_scope;
|
self.local_decls[local].source_info.scope = self.source_scope;
|
||||||
self.local_decls[local].local_info = if let Some(kind) = param.self_kind {
|
**self.local_decls[local].local_info.as_mut().assert_crate_local() = if let Some(kind) = param.self_kind {
|
||||||
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(
|
LocalInfo::User(
|
||||||
BindingForm::ImplicitSelf(kind),
|
BindingForm::ImplicitSelf(kind),
|
||||||
))))
|
)
|
||||||
} else {
|
} else {
|
||||||
let binding_mode = ty::BindingMode::BindByValue(mutability);
|
let binding_mode = ty::BindingMode::BindByValue(mutability);
|
||||||
Some(Box::new(LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
|
LocalInfo::User(BindingForm::Var(
|
||||||
VarBindingForm {
|
VarBindingForm {
|
||||||
binding_mode,
|
binding_mode,
|
||||||
opt_ty_info: param.ty_span,
|
opt_ty_info: param.ty_span,
|
||||||
opt_match_place: Some((None, span)),
|
opt_match_place: Some((None, span)),
|
||||||
pat_span: span,
|
pat_span: span,
|
||||||
},
|
},
|
||||||
)))))
|
))
|
||||||
};
|
};
|
||||||
self.var_indices.insert(var, LocalsForNode::One(local));
|
self.var_indices.insert(var, LocalsForNode::One(local));
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ struct ConstMutationChecker<'a, 'tcx> {
|
||||||
|
|
||||||
impl<'tcx> ConstMutationChecker<'_, 'tcx> {
|
impl<'tcx> ConstMutationChecker<'_, 'tcx> {
|
||||||
fn is_const_item(&self, local: Local) -> Option<DefId> {
|
fn is_const_item(&self, local: Local) -> Option<DefId> {
|
||||||
if let Some(box LocalInfo::ConstRef { def_id }) = self.body.local_decls[local].local_info {
|
if let LocalInfo::ConstRef { def_id } = *self.body.local_decls[local].local_info() {
|
||||||
Some(def_id)
|
Some(def_id)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -182,7 +182,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
|
||||||
// If the projection root is an artificial local that we introduced when
|
// If the projection root is an artificial local that we introduced when
|
||||||
// desugaring `static`, give a more specific error message
|
// desugaring `static`, give a more specific error message
|
||||||
// (avoid the general "raw pointer" clause below, that would only be confusing).
|
// (avoid the general "raw pointer" clause below, that would only be confusing).
|
||||||
if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info {
|
if let LocalInfo::StaticRef { def_id, .. } = *decl.local_info() {
|
||||||
if self.tcx.is_mutable_static(def_id) {
|
if self.tcx.is_mutable_static(def_id) {
|
||||||
self.require_unsafe(
|
self.require_unsafe(
|
||||||
UnsafetyViolationKind::General,
|
UnsafetyViolationKind::General,
|
||||||
|
|
|
@ -40,7 +40,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefChecker<'tcx> {
|
||||||
let temp = self.patcher.new_internal_with_info(
|
let temp = self.patcher.new_internal_with_info(
|
||||||
ty,
|
ty,
|
||||||
self.local_decls[p_ref.local].source_info.span,
|
self.local_decls[p_ref.local].source_info.span,
|
||||||
Some(Box::new(LocalInfo::DerefTemp)),
|
LocalInfo::DerefTemp,
|
||||||
);
|
);
|
||||||
|
|
||||||
// We are adding current p_ref's projections to our
|
// We are adding current p_ref's projections to our
|
||||||
|
|
|
@ -924,13 +924,19 @@ fn compute_layout<'tcx>(
|
||||||
debug!(?decl);
|
debug!(?decl);
|
||||||
|
|
||||||
let ignore_for_traits = if tcx.sess.opts.unstable_opts.drop_tracking_mir {
|
let ignore_for_traits = if tcx.sess.opts.unstable_opts.drop_tracking_mir {
|
||||||
|
// Do not `assert_crate_local` here, as post-borrowck cleanup may have already cleared
|
||||||
|
// the information. This is alright, since `ignore_for_traits` is only relevant when
|
||||||
|
// this code runs on pre-cleanup MIR, and `ignore_for_traits = false` is the safer
|
||||||
|
// default.
|
||||||
match decl.local_info {
|
match decl.local_info {
|
||||||
// Do not include raw pointers created from accessing `static` items, as those could
|
// Do not include raw pointers created from accessing `static` items, as those could
|
||||||
// well be re-created by another access to the same static.
|
// well be re-created by another access to the same static.
|
||||||
Some(box LocalInfo::StaticRef { is_thread_local, .. }) => !is_thread_local,
|
ClearCrossCrate::Set(box LocalInfo::StaticRef { is_thread_local, .. }) => {
|
||||||
|
!is_thread_local
|
||||||
|
}
|
||||||
// Fake borrows are only read by fake reads, so do not have any reality in
|
// Fake borrows are only read by fake reads, so do not have any reality in
|
||||||
// post-analysis MIR.
|
// post-analysis MIR.
|
||||||
Some(box LocalInfo::FakeBorrow) => true,
|
ClearCrossCrate::Set(box LocalInfo::FakeBorrow) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
let mut _7: !; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
|
let mut _7: !; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
|
||||||
let mut _8: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
|
let mut _8: std::result::Result<std::convert::Infallible, i32>; // in scope 0 at $DIR/separate_const_switch.rs:+1:9: +1:10
|
||||||
let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
|
let _9: i32; // in scope 0 at $DIR/separate_const_switch.rs:+1:8: +1:10
|
||||||
let mut _16: i32; // in scope 0 at $SRC_DIR/core/src/result.rs:LL:COL
|
|
||||||
scope 1 {
|
scope 1 {
|
||||||
debug residual => _6; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10
|
debug residual => _6; // in scope 1 at $DIR/separate_const_switch.rs:+1:9: +1:10
|
||||||
scope 2 {
|
scope 2 {
|
||||||
|
@ -23,7 +22,7 @@
|
||||||
scope 9 {
|
scope 9 {
|
||||||
debug e => _14; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
|
debug e => _14; // in scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
|
||||||
scope 10 (inlined <i32 as From<i32>>::from) { // at $SRC_DIR/core/src/result.rs:LL:COL
|
scope 10 (inlined <i32 as From<i32>>::from) { // at $SRC_DIR/core/src/result.rs:LL:COL
|
||||||
debug t => _16; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
debug t => _14; // in scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,10 +89,7 @@
|
||||||
StorageLive(_14); // scope 2 at $DIR/separate_const_switch.rs:+1:8: +1:10
|
StorageLive(_14); // scope 2 at $DIR/separate_const_switch.rs:+1:8: +1:10
|
||||||
_14 = move ((_8 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
|
_14 = move ((_8 as Err).0: i32); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL
|
||||||
StorageLive(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
|
StorageLive(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
|
||||||
StorageLive(_16); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
|
_15 = move _14; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
||||||
_16 = move _14; // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
|
|
||||||
_15 = move _16; // scope 10 at $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
|
||||||
StorageDead(_16); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
|
|
||||||
_0 = Result::<i32, i32>::Err(move _15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
|
_0 = Result::<i32, i32>::Err(move _15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
|
||||||
StorageDead(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
|
StorageDead(_15); // scope 9 at $SRC_DIR/core/src/result.rs:LL:COL
|
||||||
StorageDead(_14); // scope 2 at $DIR/separate_const_switch.rs:+1:8: +1:10
|
StorageDead(_14); // scope 2 at $DIR/separate_const_switch.rs:+1:8: +1:10
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue