Rollup merge of #129738 - nnethercote:rustc_mir_transform-cleanups, r=cjgillot

`rustc_mir_transform` cleanups

A bunch of small improvements I made while looking closely at this code.

r? `@saethlin`
This commit is contained in:
Matthias Krüger 2024-09-02 04:19:28 +02:00 committed by GitHub
commit dce26656ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 103 additions and 205 deletions

View file

@ -86,7 +86,7 @@ fn add_move_for_packed_drop<'tcx>(
let source_info = terminator.source_info; let source_info = terminator.source_info;
let ty = place.ty(body, tcx).ty; let ty = place.ty(body, tcx).ty;
let temp = patch.new_temp(ty, terminator.source_info.span); let temp = patch.new_temp(ty, source_info.span);
let storage_dead_block = patch.new_block(BasicBlockData { let storage_dead_block = patch.new_block(BasicBlockData {
statements: vec![Statement { source_info, kind: StatementKind::StorageDead(temp) }], statements: vec![Statement { source_info, kind: StatementKind::StorageDead(temp) }],

View file

@ -37,24 +37,17 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> {
} }
fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) {
if context.is_borrow() { if context.is_borrow() && util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
if util::is_disaligned(self.tcx, self.body, self.param_env, *place) { let def_id = self.body.source.instance.def_id();
let def_id = self.body.source.instance.def_id(); if let Some(impl_def_id) = self.tcx.impl_of_method(def_id)
if let Some(impl_def_id) = self.tcx.impl_of_method(def_id) && self.tcx.is_builtin_derived(impl_def_id)
&& self.tcx.is_builtin_derived(impl_def_id) {
{ // If we ever reach here it means that the generated derive
// If we ever reach here it means that the generated derive // code is somehow doing an unaligned reference, which it
// code is somehow doing an unaligned reference, which it // shouldn't do.
// shouldn't do. span_bug!(self.source_info.span, "builtin derive created an unaligned reference");
span_bug!( } else {
self.source_info.span, self.tcx.dcx().emit_err(errors::UnalignedPackedRef { span: self.source_info.span });
"builtin derive created an unaligned reference"
);
} else {
self.tcx
.dcx()
.emit_err(errors::UnalignedPackedRef { span: self.source_info.span });
}
} }
} }
} }

View file

@ -63,7 +63,9 @@ use rustc_index::bit_set::{BitMatrix, BitSet, GrowableBitSet};
use rustc_index::{Idx, IndexVec}; use rustc_index::{Idx, IndexVec};
use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::{self, CoroutineArgs, CoroutineArgsExt, InstanceKind, Ty, TyCtxt}; use rustc_middle::ty::{
self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, Ty, TyCtxt,
};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_mir_dataflow::impls::{ use rustc_mir_dataflow::impls::{
MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive, MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive,
@ -113,11 +115,18 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor<'tcx> {
} }
} }
struct DerefArgVisitor<'tcx> { struct SelfArgVisitor<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
new_base: Place<'tcx>,
} }
impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> { impl<'tcx> SelfArgVisitor<'tcx> {
fn new(tcx: TyCtxt<'tcx>, elem: ProjectionElem<Local, Ty<'tcx>>) -> Self {
Self { tcx, new_base: Place { local: SELF_ARG, projection: tcx.mk_place_elems(&[elem]) } }
}
}
impl<'tcx> MutVisitor<'tcx> for SelfArgVisitor<'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx self.tcx
} }
@ -128,53 +137,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> {
fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) { fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
if place.local == SELF_ARG { if place.local == SELF_ARG {
replace_base( replace_base(place, self.new_base, self.tcx);
place,
Place {
local: SELF_ARG,
projection: self.tcx().mk_place_elems(&[ProjectionElem::Deref]),
},
self.tcx,
);
} else {
self.visit_local(&mut place.local, context, location);
for elem in place.projection.iter() {
if let PlaceElem::Index(local) = elem {
assert_ne!(local, SELF_ARG);
}
}
}
}
}
struct PinArgVisitor<'tcx> {
ref_coroutine_ty: Ty<'tcx>,
tcx: TyCtxt<'tcx>,
}
impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}
fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) {
assert_ne!(*local, SELF_ARG);
}
fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
if place.local == SELF_ARG {
replace_base(
place,
Place {
local: SELF_ARG,
projection: self.tcx().mk_place_elems(&[ProjectionElem::Field(
FieldIdx::ZERO,
self.ref_coroutine_ty,
)]),
},
self.tcx,
);
} else { } else {
self.visit_local(&mut place.local, context, location); self.visit_local(&mut place.local, context, location);
@ -198,15 +161,6 @@ fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtx
const SELF_ARG: Local = Local::from_u32(1); const SELF_ARG: Local = Local::from_u32(1);
/// Coroutine has not been resumed yet.
const UNRESUMED: usize = CoroutineArgs::UNRESUMED;
/// Coroutine has returned / is completed.
const RETURNED: usize = CoroutineArgs::RETURNED;
/// Coroutine has panicked and is poisoned.
const POISONED: usize = CoroutineArgs::POISONED;
/// Number of reserved variants of coroutine state.
const RESERVED_VARIANTS: usize = CoroutineArgs::RESERVED_VARIANTS;
/// A `yield` point in the coroutine. /// A `yield` point in the coroutine.
struct SuspensionPoint<'tcx> { struct SuspensionPoint<'tcx> {
/// State discriminant used when suspending or resuming at this point. /// State discriminant used when suspending or resuming at this point.
@ -261,14 +215,10 @@ impl<'tcx> TransformVisitor<'tcx> {
// `gen` continues return `None` // `gen` continues return `None`
CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => { CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
let option_def_id = self.tcx.require_lang_item(LangItem::Option, None); let option_def_id = self.tcx.require_lang_item(LangItem::Option, None);
Rvalue::Aggregate( make_aggregate_adt(
Box::new(AggregateKind::Adt( option_def_id,
option_def_id, VariantIdx::ZERO,
VariantIdx::ZERO, self.tcx.mk_args(&[self.old_yield_ty.into()]),
self.tcx.mk_args(&[self.old_yield_ty.into()]),
None,
None,
)),
IndexVec::new(), IndexVec::new(),
) )
} }
@ -317,64 +267,28 @@ impl<'tcx> TransformVisitor<'tcx> {
is_return: bool, is_return: bool,
statements: &mut Vec<Statement<'tcx>>, statements: &mut Vec<Statement<'tcx>>,
) { ) {
const ZERO: VariantIdx = VariantIdx::ZERO;
const ONE: VariantIdx = VariantIdx::from_usize(1);
let rvalue = match self.coroutine_kind { let rvalue = match self.coroutine_kind {
CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => { CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => {
let poll_def_id = self.tcx.require_lang_item(LangItem::Poll, None); let poll_def_id = self.tcx.require_lang_item(LangItem::Poll, None);
let args = self.tcx.mk_args(&[self.old_ret_ty.into()]); let args = self.tcx.mk_args(&[self.old_ret_ty.into()]);
if is_return { let (variant_idx, operands) = if is_return {
// Poll::Ready(val) (ZERO, IndexVec::from_raw(vec![val])) // Poll::Ready(val)
Rvalue::Aggregate(
Box::new(AggregateKind::Adt(
poll_def_id,
VariantIdx::ZERO,
args,
None,
None,
)),
IndexVec::from_raw(vec![val]),
)
} else { } else {
// Poll::Pending (ONE, IndexVec::new()) // Poll::Pending
Rvalue::Aggregate( };
Box::new(AggregateKind::Adt( make_aggregate_adt(poll_def_id, variant_idx, args, operands)
poll_def_id,
VariantIdx::from_usize(1),
args,
None,
None,
)),
IndexVec::new(),
)
}
} }
CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => { CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
let option_def_id = self.tcx.require_lang_item(LangItem::Option, None); let option_def_id = self.tcx.require_lang_item(LangItem::Option, None);
let args = self.tcx.mk_args(&[self.old_yield_ty.into()]); let args = self.tcx.mk_args(&[self.old_yield_ty.into()]);
if is_return { let (variant_idx, operands) = if is_return {
// None (ZERO, IndexVec::new()) // None
Rvalue::Aggregate(
Box::new(AggregateKind::Adt(
option_def_id,
VariantIdx::ZERO,
args,
None,
None,
)),
IndexVec::new(),
)
} else { } else {
// Some(val) (ONE, IndexVec::from_raw(vec![val])) // Some(val)
Rvalue::Aggregate( };
Box::new(AggregateKind::Adt( make_aggregate_adt(option_def_id, variant_idx, args, operands)
option_def_id,
VariantIdx::from_usize(1),
args,
None,
None,
)),
IndexVec::from_raw(vec![val]),
)
}
} }
CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) => { CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) => {
if is_return { if is_return {
@ -400,31 +314,17 @@ impl<'tcx> TransformVisitor<'tcx> {
let coroutine_state_def_id = let coroutine_state_def_id =
self.tcx.require_lang_item(LangItem::CoroutineState, None); self.tcx.require_lang_item(LangItem::CoroutineState, None);
let args = self.tcx.mk_args(&[self.old_yield_ty.into(), self.old_ret_ty.into()]); let args = self.tcx.mk_args(&[self.old_yield_ty.into(), self.old_ret_ty.into()]);
if is_return { let variant_idx = if is_return {
// CoroutineState::Complete(val) ONE // CoroutineState::Complete(val)
Rvalue::Aggregate(
Box::new(AggregateKind::Adt(
coroutine_state_def_id,
VariantIdx::from_usize(1),
args,
None,
None,
)),
IndexVec::from_raw(vec![val]),
)
} else { } else {
// CoroutineState::Yielded(val) ZERO // CoroutineState::Yielded(val)
Rvalue::Aggregate( };
Box::new(AggregateKind::Adt( make_aggregate_adt(
coroutine_state_def_id, coroutine_state_def_id,
VariantIdx::ZERO, variant_idx,
args, args,
None, IndexVec::from_raw(vec![val]),
None, )
)),
IndexVec::from_raw(vec![val]),
)
}
} }
}; };
@ -517,7 +417,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
self.make_state(v, source_info, is_return, &mut data.statements); self.make_state(v, source_info, is_return, &mut data.statements);
let state = if let Some((resume, mut resume_arg)) = resume { let state = if let Some((resume, mut resume_arg)) = resume {
// Yield // Yield
let state = RESERVED_VARIANTS + self.suspension_points.len(); let state = CoroutineArgs::RESERVED_VARIANTS + self.suspension_points.len();
// The resume arg target location might itself be remapped if its base local is // The resume arg target location might itself be remapped if its base local is
// live across a yield. // live across a yield.
@ -550,7 +450,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
VariantIdx::new(state) VariantIdx::new(state)
} else { } else {
// Return // Return
VariantIdx::new(RETURNED) // state for returned VariantIdx::new(CoroutineArgs::RETURNED) // state for returned
}; };
data.statements.push(self.set_discr(state, source_info)); data.statements.push(self.set_discr(state, source_info));
data.terminator_mut().kind = TerminatorKind::Return; data.terminator_mut().kind = TerminatorKind::Return;
@ -560,6 +460,15 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
} }
} }
fn make_aggregate_adt<'tcx>(
def_id: DefId,
variant_idx: VariantIdx,
args: GenericArgsRef<'tcx>,
operands: IndexVec<FieldIdx, Operand<'tcx>>,
) -> Rvalue<'tcx> {
Rvalue::Aggregate(Box::new(AggregateKind::Adt(def_id, variant_idx, args, None, None)), operands)
}
fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let coroutine_ty = body.local_decls.raw[1].ty; let coroutine_ty = body.local_decls.raw[1].ty;
@ -569,7 +478,7 @@ fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Bo
body.local_decls.raw[1].ty = ref_coroutine_ty; body.local_decls.raw[1].ty = ref_coroutine_ty;
// Add a deref to accesses of the coroutine state // Add a deref to accesses of the coroutine state
DerefArgVisitor { tcx }.visit_body(body); SelfArgVisitor::new(tcx, ProjectionElem::Deref).visit_body(body);
} }
fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
@ -584,7 +493,8 @@ fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body
body.local_decls.raw[1].ty = pin_ref_coroutine_ty; body.local_decls.raw[1].ty = pin_ref_coroutine_ty;
// Add the Pin field access to accesses of the coroutine state // Add the Pin field access to accesses of the coroutine state
PinArgVisitor { ref_coroutine_ty, tcx }.visit_body(body); SelfArgVisitor::new(tcx, ProjectionElem::Field(FieldIdx::ZERO, ref_coroutine_ty))
.visit_body(body);
} }
/// Allocates a new local and replaces all references of `local` with it. Returns the new local. /// Allocates a new local and replaces all references of `local` with it. Returns the new local.
@ -651,8 +561,6 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let local = eliminate_get_context_call(&mut body[bb]); let local = eliminate_get_context_call(&mut body[bb]);
replace_resume_ty_local(tcx, body, local, context_mut_ref); replace_resume_ty_local(tcx, body, local, context_mut_ref);
} }
} else {
continue;
} }
} }
TerminatorKind::Yield { resume_arg, .. } => { TerminatorKind::Yield { resume_arg, .. } => {
@ -665,24 +573,23 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local { fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local {
let terminator = bb_data.terminator.take().unwrap(); let terminator = bb_data.terminator.take().unwrap();
if let TerminatorKind::Call { args, destination, target, .. } = terminator.kind { let TerminatorKind::Call { args, destination, target, .. } = terminator.kind else {
let [arg] = *Box::try_from(args).unwrap();
let local = arg.node.place().unwrap().local;
let arg = Rvalue::Use(arg.node);
let assign = Statement {
source_info: terminator.source_info,
kind: StatementKind::Assign(Box::new((destination, arg))),
};
bb_data.statements.push(assign);
bb_data.terminator = Some(Terminator {
source_info: terminator.source_info,
kind: TerminatorKind::Goto { target: target.unwrap() },
});
local
} else {
bug!(); bug!();
} };
let [arg] = *Box::try_from(args).unwrap();
let local = arg.node.place().unwrap().local;
let arg = Rvalue::Use(arg.node);
let assign = Statement {
source_info: terminator.source_info,
kind: StatementKind::Assign(Box::new((destination, arg))),
};
bb_data.statements.push(assign);
bb_data.terminator = Some(Terminator {
source_info: terminator.source_info,
kind: TerminatorKind::Goto { target: target.unwrap() },
});
local
} }
#[cfg_attr(not(debug_assertions), allow(unused))] #[cfg_attr(not(debug_assertions), allow(unused))]
@ -1085,10 +992,11 @@ fn compute_layout<'tcx>(
// Build the coroutine variant field list. // Build the coroutine variant field list.
// Create a map from local indices to coroutine struct indices. // Create a map from local indices to coroutine struct indices.
let mut variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, CoroutineSavedLocal>> = let mut variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, CoroutineSavedLocal>> =
iter::repeat(IndexVec::new()).take(RESERVED_VARIANTS).collect(); iter::repeat(IndexVec::new()).take(CoroutineArgs::RESERVED_VARIANTS).collect();
let mut remap = IndexVec::from_elem_n(None, saved_locals.domain_size()); let mut remap = IndexVec::from_elem_n(None, saved_locals.domain_size());
for (suspension_point_idx, live_locals) in live_locals_at_suspension_points.iter().enumerate() { for (suspension_point_idx, live_locals) in live_locals_at_suspension_points.iter().enumerate() {
let variant_index = VariantIdx::from(RESERVED_VARIANTS + suspension_point_idx); let variant_index =
VariantIdx::from(CoroutineArgs::RESERVED_VARIANTS + suspension_point_idx);
let mut fields = IndexVec::new(); let mut fields = IndexVec::new();
for (idx, saved_local) in live_locals.iter().enumerate() { for (idx, saved_local) in live_locals.iter().enumerate() {
fields.push(saved_local); fields.push(saved_local);
@ -1183,12 +1091,10 @@ fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
source_info, source_info,
kind: TerminatorKind::Drop { place, target, unwind, replace: _ }, kind: TerminatorKind::Drop { place, target, unwind, replace: _ },
} => { } => {
if let Some(local) = place.as_local() { if let Some(local) = place.as_local()
if local == SELF_ARG { && local == SELF_ARG
(target, unwind, source_info) {
} else { (target, unwind, source_info)
continue;
}
} else { } else {
continue; continue;
} }
@ -1237,7 +1143,7 @@ fn create_coroutine_drop_shim<'tcx>(
let mut cases = create_cases(&mut body, transform, Operation::Drop); let mut cases = create_cases(&mut body, transform, Operation::Drop);
cases.insert(0, (UNRESUMED, drop_clean)); cases.insert(0, (CoroutineArgs::UNRESUMED, drop_clean));
// The returned state and the poisoned state fall through to the default // The returned state and the poisoned state fall through to the default
// case which is just to return // case which is just to return
@ -1387,7 +1293,9 @@ fn create_coroutine_resume_function<'tcx>(
if can_unwind { if can_unwind {
let source_info = SourceInfo::outermost(body.span); let source_info = SourceInfo::outermost(body.span);
let poison_block = body.basic_blocks_mut().push(BasicBlockData { let poison_block = body.basic_blocks_mut().push(BasicBlockData {
statements: vec![transform.set_discr(VariantIdx::new(POISONED), source_info)], statements: vec![
transform.set_discr(VariantIdx::new(CoroutineArgs::POISONED), source_info),
],
terminator: Some(Terminator { source_info, kind: TerminatorKind::UnwindResume }), terminator: Some(Terminator { source_info, kind: TerminatorKind::UnwindResume }),
is_cleanup: true, is_cleanup: true,
}); });
@ -1419,13 +1327,16 @@ fn create_coroutine_resume_function<'tcx>(
use rustc_middle::mir::AssertKind::{ResumedAfterPanic, ResumedAfterReturn}; use rustc_middle::mir::AssertKind::{ResumedAfterPanic, ResumedAfterReturn};
// Jump to the entry point on the unresumed // Jump to the entry point on the unresumed
cases.insert(0, (UNRESUMED, START_BLOCK)); cases.insert(0, (CoroutineArgs::UNRESUMED, START_BLOCK));
// Panic when resumed on the returned or poisoned state // Panic when resumed on the returned or poisoned state
if can_unwind { if can_unwind {
cases.insert( cases.insert(
1, 1,
(POISONED, insert_panic_block(tcx, body, ResumedAfterPanic(transform.coroutine_kind))), (
CoroutineArgs::POISONED,
insert_panic_block(tcx, body, ResumedAfterPanic(transform.coroutine_kind)),
),
); );
} }
@ -1440,7 +1351,7 @@ fn create_coroutine_resume_function<'tcx>(
transform.insert_none_ret_block(body) transform.insert_none_ret_block(body)
} }
}; };
cases.insert(1, (RETURNED, block)); cases.insert(1, (CoroutineArgs::RETURNED, block));
} }
insert_switch(body, cases, &transform, TerminatorKind::Unreachable); insert_switch(body, cases, &transform, TerminatorKind::Unreachable);

View file

@ -3,13 +3,11 @@
#![feature(box_patterns)] #![feature(box_patterns)]
#![feature(const_type_name)] #![feature(const_type_name)]
#![feature(cow_is_borrowed)] #![feature(cow_is_borrowed)]
#![feature(decl_macro)]
#![feature(if_let_guard)] #![feature(if_let_guard)]
#![feature(impl_trait_in_assoc_type)] #![feature(impl_trait_in_assoc_type)]
#![feature(let_chains)] #![feature(let_chains)]
#![feature(map_try_insert)] #![feature(map_try_insert)]
#![feature(never_type)] #![feature(never_type)]
#![feature(option_get_or_insert_default)]
#![feature(round_char_boundary)] #![feature(round_char_boundary)]
#![feature(try_blocks)] #![feature(try_blocks)]
#![feature(yeet_expr)] #![feature(yeet_expr)]
@ -17,6 +15,7 @@
use hir::ConstContext; use hir::ConstContext;
use required_consts::RequiredConstsVisitor; use required_consts::RequiredConstsVisitor;
use rustc_const_eval::check_consts::{self, ConstCx};
use rustc_const_eval::util; use rustc_const_eval::util;
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::steal::Steal; use rustc_data_structures::steal::Steal;
@ -33,6 +32,7 @@ use rustc_middle::mir::{
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
use rustc_middle::util::Providers; use rustc_middle::util::Providers;
use rustc_middle::{bug, query, span_bug}; use rustc_middle::{bug, query, span_bug};
use rustc_mir_dataflow::rustc_peek;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use rustc_span::{sym, DUMMY_SP}; use rustc_span::{sym, DUMMY_SP};
use rustc_trait_selection::traits; use rustc_trait_selection::traits;
@ -108,9 +108,6 @@ mod unreachable_enum_branching;
mod unreachable_prop; mod unreachable_prop;
mod validate; mod validate;
use rustc_const_eval::check_consts::{self, ConstCx};
use rustc_mir_dataflow::rustc_peek;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" } rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
pub fn provide(providers: &mut Providers) { pub fn provide(providers: &mut Providers) {
@ -128,7 +125,7 @@ pub fn provide(providers: &mut Providers) {
mir_coroutine_witnesses: coroutine::mir_coroutine_witnesses, mir_coroutine_witnesses: coroutine::mir_coroutine_witnesses,
optimized_mir, optimized_mir,
is_mir_available, is_mir_available,
is_ctfe_mir_available: |tcx, did| is_mir_available(tcx, did), is_ctfe_mir_available: is_mir_available,
mir_callgraph_reachable: inline::cycle::mir_callgraph_reachable, mir_callgraph_reachable: inline::cycle::mir_callgraph_reachable,
mir_inliner_callees: inline::cycle::mir_inliner_callees, mir_inliner_callees: inline::cycle::mir_inliner_callees,
promoted_mir, promoted_mir,
@ -221,10 +218,8 @@ fn is_mir_available(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
/// Finds the full set of `DefId`s within the current crate that have /// Finds the full set of `DefId`s within the current crate that have
/// MIR associated with them. /// MIR associated with them.
fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> { fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
let mut set = FxIndexSet::default();
// All body-owners have MIR associated with them. // All body-owners have MIR associated with them.
set.extend(tcx.hir().body_owners()); let mut set: FxIndexSet<_> = tcx.hir().body_owners().collect();
// Additionally, tuple struct/variant constructors have MIR, but // Additionally, tuple struct/variant constructors have MIR, but
// they don't have a BodyId, so we need to build them separately. // they don't have a BodyId, so we need to build them separately.
@ -249,8 +244,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
// No need to const-check a non-const `fn`. // No need to const-check a non-const `fn`.
match const_kind { match const_kind {
Some(ConstContext::Const { .. } | ConstContext::Static(_)) Some(ConstContext::Const { .. } | ConstContext::Static(_) | ConstContext::ConstFn) => {}
| Some(ConstContext::ConstFn) => {}
None => span_bug!( None => span_bug!(
tcx.def_span(def), tcx.def_span(def),
"`mir_const_qualif` should only be called on const fns and const items" "`mir_const_qualif` should only be called on const fns and const items"