ICE when checking LocalInfo on runtime MIR.
This commit is contained in:
parent
50d0959a2f
commit
526a2c7521
@ -242,8 +242,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||||||
let full_debug_info = bx.sess().opts.debuginfo == DebugInfo::Full;
|
let full_debug_info = bx.sess().opts.debuginfo == DebugInfo::Full;
|
||||||
|
|
||||||
// FIXME(eddyb) maybe name the return place as `_0` or `return`?
|
// FIXME(eddyb) maybe name the return place as `_0` or `return`?
|
||||||
if local == mir::RETURN_PLACE && !self.mir.local_decls[mir::RETURN_PLACE].is_user_variable()
|
if local == mir::RETURN_PLACE {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -919,15 +919,15 @@ impl<'tcx> LocalDecl<'tcx> {
|
|||||||
/// - or `match ... { C(x) => ... }`
|
/// - or `match ... { C(x) => ... }`
|
||||||
pub fn can_be_made_mutable(&self) -> bool {
|
pub fn can_be_made_mutable(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
self.local_info,
|
self.local_info(),
|
||||||
ClearCrossCrate::Set(box LocalInfo::User(
|
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),
|
||||||
))
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -936,15 +936,15 @@ impl<'tcx> LocalDecl<'tcx> {
|
|||||||
/// mutable bindings, but the inverse does not necessarily hold).
|
/// mutable bindings, but the inverse does not necessarily hold).
|
||||||
pub fn is_nonref_binding(&self) -> bool {
|
pub fn is_nonref_binding(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
self.local_info,
|
self.local_info(),
|
||||||
ClearCrossCrate::Set(box LocalInfo::User(
|
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(_),
|
||||||
))
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -952,40 +952,35 @@ 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, ClearCrossCrate::Set(box LocalInfo::User(_)))
|
matches!(self.local_info(), 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`
|
||||||
/// expression that is used to access said variable for the guard of the
|
/// expression that is used to access said variable for the guard of the
|
||||||
/// match arm.
|
/// match arm.
|
||||||
pub fn is_ref_for_guard(&self) -> bool {
|
pub fn is_ref_for_guard(&self) -> bool {
|
||||||
matches!(
|
matches!(self.local_info(), LocalInfo::User(BindingForm::RefForGuard))
|
||||||
self.local_info,
|
|
||||||
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, ClearCrossCrate::Set(box LocalInfo::StaticRef { .. }))
|
matches!(self.local_info(), 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() {
|
||||||
ClearCrossCrate::Set(box LocalInfo::StaticRef { is_thread_local, .. }) => {
|
LocalInfo::StaticRef { is_thread_local, .. } => *is_thread_local,
|
||||||
is_thread_local
|
|
||||||
}
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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() {
|
||||||
ClearCrossCrate::Set(box LocalInfo::DerefTemp) => return true,
|
LocalInfo::DerefTemp => return true,
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -29,9 +29,9 @@ use rustc_hir::intravisit::{self, Visitor};
|
|||||||
use rustc_index::vec::IndexVec;
|
use rustc_index::vec::IndexVec;
|
||||||
use rustc_middle::mir::visit::Visitor as _;
|
use rustc_middle::mir::visit::Visitor as _;
|
||||||
use rustc_middle::mir::{
|
use rustc_middle::mir::{
|
||||||
traversal, AnalysisPhase, Body, ConstQualifs, Constant, LocalDecl, MirPass, MirPhase, Operand,
|
traversal, AnalysisPhase, Body, ClearCrossCrate, ConstQualifs, Constant, LocalDecl, MirPass,
|
||||||
Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo, Statement, StatementKind,
|
MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo,
|
||||||
TerminatorKind,
|
Statement, StatementKind, TerminatorKind,
|
||||||
};
|
};
|
||||||
use rustc_middle::ty::query::Providers;
|
use rustc_middle::ty::query::Providers;
|
||||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
|
||||||
@ -532,6 +532,12 @@ fn run_runtime_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||||||
&[&lower_intrinsics::LowerIntrinsics, &simplify::SimplifyCfg::new("elaborate-drops")];
|
&[&lower_intrinsics::LowerIntrinsics, &simplify::SimplifyCfg::new("elaborate-drops")];
|
||||||
|
|
||||||
pm::run_passes(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::PostCleanup)));
|
pm::run_passes(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::PostCleanup)));
|
||||||
|
|
||||||
|
// Clear this by anticipation. Optimizations and runtime MIR have no reason to look
|
||||||
|
// into this information, which is meant for borrowck diagnostics.
|
||||||
|
for decl in &mut body.local_decls {
|
||||||
|
decl.local_info = ClearCrossCrate::Clear;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||||
|
@ -13,8 +13,8 @@ pub fn sum(x: u32, y: u32) -> u32 {
|
|||||||
|
|
||||||
// NO-LABEL: define{{.*}}i32 @sum(i32 noundef %x, i32 noundef %y)
|
// NO-LABEL: define{{.*}}i32 @sum(i32 noundef %x, i32 noundef %y)
|
||||||
// NO-NEXT: start:
|
// NO-NEXT: start:
|
||||||
// NO-NEXT: %z = add i32 %y, %x
|
// NO-NEXT: %0 = add i32 %y, %x
|
||||||
// NO-NEXT: ret i32 %z
|
// NO-NEXT: ret i32 %0
|
||||||
let z = x + y;
|
let z = x + y;
|
||||||
z
|
z
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ pub fn test(a: u32, b: u32) -> u32 {
|
|||||||
// CHECK: %c = add i32 %a, %b
|
// CHECK: %c = add i32 %a, %b
|
||||||
let d = c;
|
let d = c;
|
||||||
let e = d * a;
|
let e = d * a;
|
||||||
// CHECK-NEXT: %e = mul i32 %c, %a
|
// CHECK-NEXT: %0 = mul i32 %c, %a
|
||||||
e
|
e
|
||||||
// CHECK-NEXT: ret i32 %e
|
// CHECK-NEXT: ret i32 %0
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user