Rollup merge of #129926 - nnethercote:mv-SanityCheck-and-MirPass, r=cjgillot
Move `SanityCheck` and `MirPass` They are currently in `rustc_middle`. This PR moves them to `rustc_mir_transform`, which makes more sense. r? ``@cjgillot``
This commit is contained in:
commit
4ed0f0d384
@ -3,8 +3,6 @@
|
||||
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::fmt::{self, Debug, Formatter};
|
||||
use std::ops::{Index, IndexMut};
|
||||
use std::{iter, mem};
|
||||
@ -26,7 +24,6 @@
|
||||
use rustc_index::{Idx, IndexSlice, IndexVec};
|
||||
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
@ -106,65 +103,6 @@ fn local_decls(&self) -> &LocalDecls<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static PASS_NAMES: RefCell<FxHashMap<&'static str, &'static str>> = {
|
||||
RefCell::new(FxHashMap::default())
|
||||
};
|
||||
}
|
||||
|
||||
/// Converts a MIR pass name into a snake case form to match the profiling naming style.
|
||||
fn to_profiler_name(type_name: &'static str) -> &'static str {
|
||||
PASS_NAMES.with(|names| match names.borrow_mut().entry(type_name) {
|
||||
Entry::Occupied(e) => *e.get(),
|
||||
Entry::Vacant(e) => {
|
||||
let snake_case: String = type_name
|
||||
.chars()
|
||||
.flat_map(|c| {
|
||||
if c.is_ascii_uppercase() {
|
||||
vec!['_', c.to_ascii_lowercase()]
|
||||
} else if c == '-' {
|
||||
vec!['_']
|
||||
} else {
|
||||
vec![c]
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let result = &*String::leak(format!("mir_pass{}", snake_case));
|
||||
e.insert(result);
|
||||
result
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// A streamlined trait that you can implement to create a pass; the
|
||||
/// pass will be named after the type, and it will consist of a main
|
||||
/// loop that goes over each available MIR and applies `run_pass`.
|
||||
pub trait MirPass<'tcx> {
|
||||
fn name(&self) -> &'static str {
|
||||
// FIXME Simplify the implementation once more `str` methods get const-stable.
|
||||
// See copypaste in `MirLint`
|
||||
const {
|
||||
let name = std::any::type_name::<Self>();
|
||||
crate::util::common::c_name(name)
|
||||
}
|
||||
}
|
||||
|
||||
fn profiler_name(&self) -> &'static str {
|
||||
to_profiler_name(self.name())
|
||||
}
|
||||
|
||||
/// Returns `true` if this pass is enabled with the current combination of compiler flags.
|
||||
fn is_enabled(&self, _sess: &Session) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>);
|
||||
|
||||
fn is_mir_dump_enabled(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl MirPhase {
|
||||
/// Gets the index of the current MirPhase within the set of all `MirPhase`s.
|
||||
///
|
||||
|
@ -20,19 +20,3 @@ pub fn to_readable_str(mut val: usize) -> String {
|
||||
|
||||
groups.join("_")
|
||||
}
|
||||
|
||||
// const wrapper for `if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }`
|
||||
pub const fn c_name(name: &'static str) -> &'static str {
|
||||
// FIXME Simplify the implementation once more `str` methods get const-stable.
|
||||
// and inline into call site
|
||||
let bytes = name.as_bytes();
|
||||
let mut i = bytes.len();
|
||||
while i > 0 && bytes[i - 1] != b':' {
|
||||
i = i - 1;
|
||||
}
|
||||
let (_, bytes) = bytes.split_at(i);
|
||||
match std::str::from_utf8(bytes) {
|
||||
Ok(name) => name,
|
||||
Err(_) => name,
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use rustc_ast::MetaItem;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_index::bit_set::BitSet;
|
||||
use rustc_middle::mir::{self, Body, Local, Location, MirPass};
|
||||
use rustc_middle::mir::{self, Body, Local, Location};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_span::symbol::{sym, Symbol};
|
||||
use rustc_span::Span;
|
||||
@ -18,8 +18,6 @@
|
||||
use crate::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex};
|
||||
use crate::{Analysis, JoinSemiLattice, ResultsCursor};
|
||||
|
||||
pub struct SanityCheck;
|
||||
|
||||
fn has_rustc_mir_with(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Option<MetaItem> {
|
||||
for attr in tcx.get_attrs(def_id, sym::rustc_mir) {
|
||||
let items = attr.meta_item_list();
|
||||
@ -33,9 +31,7 @@ fn has_rustc_mir_with(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Option<Me
|
||||
None
|
||||
}
|
||||
|
||||
// FIXME: This should be a `MirLint`, but it needs to be moved back to `rustc_mir_transform` first.
|
||||
impl<'tcx> MirPass<'tcx> for SanityCheck {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
pub fn sanity_check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
||||
let def_id = body.source.def_id();
|
||||
if !tcx.has_attr(def_id, sym::rustc_mir) {
|
||||
debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
|
||||
@ -80,7 +76,6 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
if has_rustc_mir_with(tcx, def_id, sym::stop_after_dataflow).is_some() {
|
||||
tcx.dcx().emit_fatal(StopAfterDataFlowEndedCompilation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This function scans `mir` for all calls to the intrinsic
|
||||
|
@ -22,7 +22,7 @@
|
||||
#[derive(PartialEq)]
|
||||
pub struct AbortUnwindingCalls;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls {
|
||||
impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let def_id = body.source.def_id();
|
||||
let kind = tcx.def_kind(def_id);
|
||||
|
@ -30,7 +30,7 @@ pub enum AddCallGuards {
|
||||
*
|
||||
*/
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for AddCallGuards {
|
||||
impl<'tcx> crate::MirPass<'tcx> for AddCallGuards {
|
||||
fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
self.add_call_guards(body);
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
/// blowup.
|
||||
pub struct AddMovesForPackedDrops;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for AddMovesForPackedDrops {
|
||||
impl<'tcx> crate::MirPass<'tcx> for AddMovesForPackedDrops {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
debug!("add_moves_for_packed_drops({:?} @ {:?})", body.source, body.span);
|
||||
add_moves_for_packed_drops(tcx, body);
|
||||
|
@ -48,7 +48,7 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for AddRetag {
|
||||
impl<'tcx> crate::MirPass<'tcx> for AddRetag {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.opts.unstable_opts.mir_emit_retag
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ pub fn subtype_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
checker.patcher.apply(body);
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for Subtyper {
|
||||
impl<'tcx> crate::MirPass<'tcx> for Subtyper {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
subtype_finder(tcx, body);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
pub struct CheckAlignment;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for CheckAlignment {
|
||||
impl<'tcx> crate::MirPass<'tcx> for CheckAlignment {
|
||||
fn is_enabled(&self, sess: &Session) -> bool {
|
||||
// FIXME(#112480) MSVC and rustc disagree on minimum stack alignment on x86 Windows
|
||||
if sess.target.llvm_target == "i686-pc-windows-msvc" {
|
||||
|
@ -6,11 +6,11 @@
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::Span;
|
||||
|
||||
use crate::{errors, MirLint};
|
||||
use crate::errors;
|
||||
|
||||
pub struct CheckConstItemMutation;
|
||||
|
||||
impl<'tcx> MirLint<'tcx> for CheckConstItemMutation {
|
||||
impl<'tcx> crate::MirLint<'tcx> for CheckConstItemMutation {
|
||||
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
||||
let mut checker = ConstMutationChecker { body, tcx, target_local: None };
|
||||
checker.visit_body(body);
|
||||
|
@ -3,11 +3,11 @@
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
|
||||
use crate::{errors, util, MirLint};
|
||||
use crate::{errors, util};
|
||||
|
||||
pub struct CheckPackedRef;
|
||||
|
||||
impl<'tcx> MirLint<'tcx> for CheckPackedRef {
|
||||
impl<'tcx> crate::MirLint<'tcx> for CheckPackedRef {
|
||||
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
||||
let param_env = tcx.param_env(body.source.def_id());
|
||||
let source_info = SourceInfo::outermost(body.span);
|
||||
|
@ -21,11 +21,9 @@
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
use crate::MirPass;
|
||||
|
||||
pub struct CleanupPostBorrowck;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck {
|
||||
impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck {
|
||||
fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
for basic_block in body.basic_blocks.as_mut() {
|
||||
for statement in basic_block.statements.iter_mut() {
|
||||
|
@ -19,7 +19,7 @@
|
||||
/// We want to replace all those locals by `_a`, either copied or moved.
|
||||
pub struct CopyProp;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for CopyProp {
|
||||
impl<'tcx> crate::MirPass<'tcx> for CopyProp {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() >= 1
|
||||
}
|
||||
|
@ -1535,7 +1535,7 @@ fn check_field_tys_sized<'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for StateTransform {
|
||||
impl<'tcx> crate::MirPass<'tcx> for StateTransform {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let Some(old_yield_ty) = body.yield_ty() else {
|
||||
// This only applies to coroutines
|
||||
|
@ -28,14 +28,13 @@
|
||||
use crate::coverage::counters::{CounterIncrementSite, CoverageCounters};
|
||||
use crate::coverage::graph::CoverageGraph;
|
||||
use crate::coverage::mappings::ExtractedMappings;
|
||||
use crate::MirPass;
|
||||
|
||||
/// Inserts `StatementKind::Coverage` statements that either instrument the binary with injected
|
||||
/// counters, via intrinsic `llvm.instrprof.increment`, and/or inject metadata used during codegen
|
||||
/// to construct the coverage map.
|
||||
pub struct InstrumentCoverage;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for InstrumentCoverage {
|
||||
impl<'tcx> crate::MirPass<'tcx> for InstrumentCoverage {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.instrument_coverage()
|
||||
}
|
||||
|
@ -8,11 +8,9 @@
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::MirPass;
|
||||
|
||||
pub struct CtfeLimit;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for CtfeLimit {
|
||||
impl<'tcx> crate::MirPass<'tcx> for CtfeLimit {
|
||||
#[instrument(skip(self, _tcx, body))]
|
||||
fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let doms = body.basic_blocks.dominators();
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
pub struct DataflowConstProp;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for DataflowConstProp {
|
||||
impl<'tcx> crate::MirPass<'tcx> for DataflowConstProp {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() >= 3
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ pub enum DeadStoreElimination {
|
||||
Final,
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for DeadStoreElimination {
|
||||
impl<'tcx> crate::MirPass<'tcx> for DeadStoreElimination {
|
||||
fn name(&self) -> &'static str {
|
||||
match self {
|
||||
DeadStoreElimination::Initial => "DeadStoreElimination-initial",
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
pub struct DeduplicateBlocks;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for DeduplicateBlocks {
|
||||
impl<'tcx> crate::MirPass<'tcx> for DeduplicateBlocks {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() >= 4
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
checker.patcher.apply(body);
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for Derefer {
|
||||
impl<'tcx> crate::MirPass<'tcx> for Derefer {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
deref_finder(tcx, body);
|
||||
}
|
||||
|
@ -146,11 +146,9 @@
|
||||
use rustc_mir_dataflow::Analysis;
|
||||
use tracing::{debug, trace};
|
||||
|
||||
use crate::MirPass;
|
||||
|
||||
pub struct DestinationPropagation;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for DestinationPropagation {
|
||||
impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
// For now, only run at MIR opt level 3. Two things need to be changed before this can be
|
||||
// turned on by default:
|
||||
|
@ -7,11 +7,9 @@
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::config::{OutFileName, OutputType};
|
||||
|
||||
use crate::MirPass;
|
||||
|
||||
pub struct Marker(pub &'static str);
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for Marker {
|
||||
impl<'tcx> crate::MirPass<'tcx> for Marker {
|
||||
fn name(&self) -> &'static str {
|
||||
self.0
|
||||
}
|
||||
|
@ -92,7 +92,7 @@
|
||||
/// ```
|
||||
pub struct EarlyOtherwiseBranch;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
|
||||
impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() >= 2
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ fn visit_place(
|
||||
|
||||
pub struct ElaborateBoxDerefs;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs {
|
||||
impl<'tcx> crate::MirPass<'tcx> for ElaborateBoxDerefs {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
if let Some(def_id) = tcx.lang_items().owned_box() {
|
||||
let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[FieldIdx::ZERO].did;
|
||||
|
@ -49,7 +49,7 @@
|
||||
/// ```
|
||||
pub struct ElaborateDrops;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for ElaborateDrops {
|
||||
impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops {
|
||||
#[instrument(level = "trace", skip(self, tcx, body))]
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
debug!("elaborate_drops({:?} @ {:?})", body.source, body.span);
|
||||
|
@ -9,11 +9,11 @@
|
||||
use rustc_span::Span;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use crate::{errors, MirLint};
|
||||
use crate::errors;
|
||||
|
||||
pub struct FunctionItemReferences;
|
||||
|
||||
impl<'tcx> MirLint<'tcx> for FunctionItemReferences {
|
||||
impl<'tcx> crate::MirLint<'tcx> for FunctionItemReferences {
|
||||
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
||||
let mut checker = FunctionItemRefChecker { tcx, body };
|
||||
checker.visit_body(body);
|
||||
|
@ -111,7 +111,7 @@
|
||||
|
||||
pub struct GVN;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for GVN {
|
||||
impl<'tcx> crate::MirPass<'tcx> for GVN {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() >= 2
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ struct CallSite<'tcx> {
|
||||
source_info: SourceInfo,
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for Inline {
|
||||
impl<'tcx> crate::MirPass<'tcx> for Inline {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
// FIXME(#127234): Coverage instrumentation currently doesn't handle inlined
|
||||
// MIR correctly when Modified Condition/Decision Coverage is enabled.
|
||||
|
@ -27,7 +27,7 @@ pub fn name(&self) -> &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for InstSimplify {
|
||||
impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
|
||||
fn name(&self) -> &'static str {
|
||||
self.name()
|
||||
}
|
||||
|
@ -61,7 +61,7 @@
|
||||
const MAX_COST: usize = 100;
|
||||
const MAX_PLACES: usize = 100;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for JumpThreading {
|
||||
impl<'tcx> crate::MirPass<'tcx> for JumpThreading {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() >= 2
|
||||
}
|
||||
|
@ -25,11 +25,10 @@
|
||||
use tracing::{debug, instrument, trace};
|
||||
|
||||
use crate::errors::{AssertLint, AssertLintKind};
|
||||
use crate::MirLint;
|
||||
|
||||
pub struct KnownPanicsLint;
|
||||
|
||||
impl<'tcx> MirLint<'tcx> for KnownPanicsLint {
|
||||
impl<'tcx> crate::MirLint<'tcx> for KnownPanicsLint {
|
||||
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
||||
if body.tainted_by_errors.is_some() {
|
||||
return;
|
||||
|
@ -27,7 +27,7 @@ pub struct EnumSizeOpt {
|
||||
pub(crate) discrepancy: u64,
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for EnumSizeOpt {
|
||||
impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt {
|
||||
fn is_enabled(&self, sess: &Session) -> bool {
|
||||
// There are some differences in behavior on wasm and ARM that are not properly
|
||||
// understood, so we conservatively treat this optimization as unsound:
|
||||
|
@ -26,13 +26,12 @@
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_middle::mir::{
|
||||
AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstOperand, ConstQualifs, LocalDecl,
|
||||
MirPass, MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo,
|
||||
MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo,
|
||||
Statement, StatementKind, TerminatorKind, START_BLOCK,
|
||||
};
|
||||
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::util::Providers;
|
||||
use rustc_middle::{bug, query, span_bug};
|
||||
use rustc_mir_dataflow::rustc_peek;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{sym, DUMMY_SP};
|
||||
use rustc_trait_selection::traits;
|
||||
@ -41,7 +40,7 @@
|
||||
#[macro_use]
|
||||
mod pass_manager;
|
||||
|
||||
use pass_manager::{self as pm, Lint, MirLint, WithMinOptLevel};
|
||||
use pass_manager::{self as pm, Lint, MirLint, MirPass, WithMinOptLevel};
|
||||
|
||||
mod abort_unwinding_calls;
|
||||
mod add_call_guards;
|
||||
@ -96,6 +95,7 @@
|
||||
mod remove_zsts;
|
||||
mod required_consts;
|
||||
mod reveal_all;
|
||||
mod sanity_check;
|
||||
mod shim;
|
||||
mod ssa;
|
||||
// This pass is public to allow external drivers to perform MIR cleanup
|
||||
@ -288,7 +288,7 @@ fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
|
||||
&Lint(function_item_references::FunctionItemReferences),
|
||||
// What we need to do constant evaluation.
|
||||
&simplify::SimplifyCfg::Initial,
|
||||
&rustc_peek::SanityCheck, // Just a lint
|
||||
&Lint(sanity_check::SanityCheck),
|
||||
],
|
||||
None,
|
||||
);
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
pub struct LowerIntrinsics;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
||||
impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let local_decls = &body.local_decls;
|
||||
for block in body.basic_blocks.as_mut() {
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
pub struct LowerSliceLenCalls;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for LowerSliceLenCalls {
|
||||
impl<'tcx> crate::MirPass<'tcx> for LowerSliceLenCalls {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() > 0
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
pub struct MatchBranchSimplification;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
|
||||
impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() >= 1
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use rustc_middle::mir::visit::Visitor;
|
||||
use rustc_middle::mir::{self, Location, MentionedItem, MirPass};
|
||||
use rustc_middle::mir::{self, Location, MentionedItem};
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_session::Session;
|
||||
@ -13,7 +13,7 @@ struct MentionedItemsVisitor<'a, 'tcx> {
|
||||
mentioned_items: &'a mut Vec<Spanned<MentionedItem<'tcx>>>,
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for MentionedItems {
|
||||
impl<'tcx> crate::MirPass<'tcx> for MentionedItems {
|
||||
fn is_enabled(&self, _sess: &Session) -> bool {
|
||||
// If this pass is skipped the collector assume that nothing got mentioned! We could
|
||||
// potentially skip it in opt-level 0 if we are sure that opt-level will never *remove* uses
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
pub struct MultipleReturnTerminators;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators {
|
||||
impl<'tcx> crate::MirPass<'tcx> for MultipleReturnTerminators {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() >= 4
|
||||
}
|
||||
|
@ -8,8 +8,6 @@
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use tracing::{debug, trace};
|
||||
|
||||
use crate::MirPass;
|
||||
|
||||
/// This pass looks for MIR that always copies the same local into the return place and eliminates
|
||||
/// the copy by renaming all uses of that local to `_0`.
|
||||
///
|
||||
@ -34,7 +32,7 @@
|
||||
/// [#71003]: https://github.com/rust-lang/rust/pull/71003
|
||||
pub struct RenameReturnPlace;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
|
||||
impl<'tcx> crate::MirPass<'tcx> for RenameReturnPlace {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
// unsound: #111005
|
||||
sess.mir_opt_level() > 0 && sess.opts.unstable_opts.unsound_mir_opts
|
||||
|
@ -1,19 +1,99 @@
|
||||
use std::cell::RefCell;
|
||||
use std::collections::hash_map::Entry;
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_middle::mir::{self, Body, MirPhase, RuntimePhase};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::Session;
|
||||
use tracing::trace;
|
||||
|
||||
use crate::lint::lint_body;
|
||||
use crate::{validate, MirPass};
|
||||
use crate::validate;
|
||||
|
||||
/// Just like `MirPass`, except it cannot mutate `Body`.
|
||||
pub trait MirLint<'tcx> {
|
||||
thread_local! {
|
||||
static PASS_NAMES: RefCell<FxHashMap<&'static str, &'static str>> = {
|
||||
RefCell::new(FxHashMap::default())
|
||||
};
|
||||
}
|
||||
|
||||
/// Converts a MIR pass name into a snake case form to match the profiling naming style.
|
||||
fn to_profiler_name(type_name: &'static str) -> &'static str {
|
||||
PASS_NAMES.with(|names| match names.borrow_mut().entry(type_name) {
|
||||
Entry::Occupied(e) => *e.get(),
|
||||
Entry::Vacant(e) => {
|
||||
let snake_case: String = type_name
|
||||
.chars()
|
||||
.flat_map(|c| {
|
||||
if c.is_ascii_uppercase() {
|
||||
vec!['_', c.to_ascii_lowercase()]
|
||||
} else if c == '-' {
|
||||
vec!['_']
|
||||
} else {
|
||||
vec![c]
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let result = &*String::leak(format!("mir_pass{}", snake_case));
|
||||
e.insert(result);
|
||||
result
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// const wrapper for `if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }`
|
||||
const fn c_name(name: &'static str) -> &'static str {
|
||||
// FIXME Simplify the implementation once more `str` methods get const-stable.
|
||||
// and inline into call site
|
||||
let bytes = name.as_bytes();
|
||||
let mut i = bytes.len();
|
||||
while i > 0 && bytes[i - 1] != b':' {
|
||||
i = i - 1;
|
||||
}
|
||||
let (_, bytes) = bytes.split_at(i);
|
||||
match std::str::from_utf8(bytes) {
|
||||
Ok(name) => name,
|
||||
Err(_) => name,
|
||||
}
|
||||
}
|
||||
|
||||
/// A streamlined trait that you can implement to create a pass; the
|
||||
/// pass will be named after the type, and it will consist of a main
|
||||
/// loop that goes over each available MIR and applies `run_pass`.
|
||||
pub(super) trait MirPass<'tcx> {
|
||||
fn name(&self) -> &'static str {
|
||||
// FIXME Simplify the implementation once more `str` methods get const-stable.
|
||||
// See copypaste in `MirLint`
|
||||
const {
|
||||
let name = std::any::type_name::<Self>();
|
||||
c_name(name)
|
||||
}
|
||||
}
|
||||
|
||||
fn profiler_name(&self) -> &'static str {
|
||||
to_profiler_name(self.name())
|
||||
}
|
||||
|
||||
/// Returns `true` if this pass is enabled with the current combination of compiler flags.
|
||||
fn is_enabled(&self, _sess: &Session) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>);
|
||||
|
||||
fn is_mir_dump_enabled(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Just like `MirPass`, except it cannot mutate `Body`, and MIR dumping is
|
||||
/// disabled (via the `Lint` adapter).
|
||||
pub(super) trait MirLint<'tcx> {
|
||||
fn name(&self) -> &'static str {
|
||||
// FIXME Simplify the implementation once more `str` methods get const-stable.
|
||||
// See copypaste in `MirPass`
|
||||
const {
|
||||
let name = std::any::type_name::<Self>();
|
||||
rustc_middle::util::common::c_name(name)
|
||||
c_name(name)
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,7 +106,7 @@ fn is_enabled(&self, _sess: &Session) -> bool {
|
||||
|
||||
/// An adapter for `MirLint`s that implements `MirPass`.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Lint<T>(pub T);
|
||||
pub(super) struct Lint<T>(pub T);
|
||||
|
||||
impl<'tcx, T> MirPass<'tcx> for Lint<T>
|
||||
where
|
||||
@ -49,7 +129,7 @@ fn is_mir_dump_enabled(&self) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct WithMinOptLevel<T>(pub u32, pub T);
|
||||
pub(super) struct WithMinOptLevel<T>(pub u32, pub T);
|
||||
|
||||
impl<'tcx, T> MirPass<'tcx> for WithMinOptLevel<T>
|
||||
where
|
||||
@ -70,7 +150,7 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
|
||||
/// Run the sequence of passes without validating the MIR after each pass. The MIR is still
|
||||
/// validated at the end.
|
||||
pub fn run_passes_no_validate<'tcx>(
|
||||
pub(super) fn run_passes_no_validate<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &mut Body<'tcx>,
|
||||
passes: &[&dyn MirPass<'tcx>],
|
||||
@ -80,7 +160,7 @@ pub fn run_passes_no_validate<'tcx>(
|
||||
}
|
||||
|
||||
/// The optional `phase_change` is applied after executing all the passes, if present
|
||||
pub fn run_passes<'tcx>(
|
||||
pub(super) fn run_passes<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &mut Body<'tcx>,
|
||||
passes: &[&dyn MirPass<'tcx>],
|
||||
@ -89,7 +169,7 @@ pub fn run_passes<'tcx>(
|
||||
run_passes_inner(tcx, body, passes, phase_change, true);
|
||||
}
|
||||
|
||||
pub fn should_run_pass<'tcx, P>(tcx: TyCtxt<'tcx>, pass: &P) -> bool
|
||||
pub(super) fn should_run_pass<'tcx, P>(tcx: TyCtxt<'tcx>, pass: &P) -> bool
|
||||
where
|
||||
P: MirPass<'tcx> + ?Sized,
|
||||
{
|
||||
@ -185,11 +265,11 @@ fn run_passes_inner<'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn validate_body<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, when: String) {
|
||||
pub(super) fn validate_body<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, when: String) {
|
||||
validate::Validator { when, mir_phase: body.phase }.run_pass(tcx, body);
|
||||
}
|
||||
|
||||
pub fn dump_mir_for_pass<'tcx>(
|
||||
pub(super) fn dump_mir_for_pass<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
pass_name: &str,
|
||||
@ -205,7 +285,7 @@ pub fn dump_mir_for_pass<'tcx>(
|
||||
);
|
||||
}
|
||||
|
||||
pub fn dump_mir_for_phase_change<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
||||
pub(super) fn dump_mir_for_phase_change<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
||||
assert_eq!(body.pass_count, 0);
|
||||
mir::dump_mir(tcx, true, body.phase.name(), &"after", body, |_, _| Ok(()))
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
/// `IndexVec`, unless that successor is a back-edge (such as from a loop).
|
||||
pub struct ReorderBasicBlocks;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for ReorderBasicBlocks {
|
||||
impl<'tcx> crate::MirPass<'tcx> for ReorderBasicBlocks {
|
||||
fn is_enabled(&self, _session: &Session) -> bool {
|
||||
false
|
||||
}
|
||||
@ -45,7 +45,7 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
/// (Does not reorder arguments nor the [`RETURN_PLACE`].)
|
||||
pub struct ReorderLocals;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for ReorderLocals {
|
||||
impl<'tcx> crate::MirPass<'tcx> for ReorderLocals {
|
||||
fn is_enabled(&self, _session: &Session) -> bool {
|
||||
false
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ pub struct PromoteTemps<'tcx> {
|
||||
pub promoted_fragments: Cell<IndexVec<Promoted, Body<'tcx>>>,
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> {
|
||||
impl<'tcx> crate::MirPass<'tcx> for PromoteTemps<'tcx> {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
// There's not really any point in promoting errorful MIR.
|
||||
//
|
||||
|
@ -72,7 +72,7 @@
|
||||
/// so we perform all the possible instantiations without removing the `_1 = &_2` statement.
|
||||
pub struct ReferencePropagation;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for ReferencePropagation {
|
||||
impl<'tcx> crate::MirPass<'tcx> for ReferencePropagation {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() >= 2
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
/// terrible code for these.
|
||||
pub struct RemoveNoopLandingPads;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for RemoveNoopLandingPads {
|
||||
impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.panic_strategy() != PanicStrategy::Abort
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
pub struct RemovePlaceMention;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for RemovePlaceMention {
|
||||
impl<'tcx> crate::MirPass<'tcx> for RemovePlaceMention {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
!sess.opts.unstable_opts.mir_keep_place_mention
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
pub struct RemoveStorageMarkers;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for RemoveStorageMarkers {
|
||||
impl<'tcx> crate::MirPass<'tcx> for RemoveStorageMarkers {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() > 0 && !sess.emit_lifetime_markers()
|
||||
}
|
||||
|
@ -6,8 +6,6 @@
|
||||
use rustc_mir_dataflow::{move_path_children_matching, Analysis, MaybeReachable};
|
||||
use rustc_target::abi::FieldIdx;
|
||||
|
||||
use crate::MirPass;
|
||||
|
||||
/// Removes `Drop` terminators whose target is known to be uninitialized at
|
||||
/// that point.
|
||||
///
|
||||
@ -18,7 +16,7 @@
|
||||
/// [#90770]: https://github.com/rust-lang/rust/issues/90770
|
||||
pub struct RemoveUninitDrops;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for RemoveUninitDrops {
|
||||
impl<'tcx> crate::MirPass<'tcx> for RemoveUninitDrops {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let param_env = tcx.param_env(body.source.def_id());
|
||||
let move_data =
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
pub struct RemoveUnneededDrops;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for RemoveUnneededDrops {
|
||||
impl<'tcx> crate::MirPass<'tcx> for RemoveUnneededDrops {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
trace!("Running RemoveUnneededDrops on {:?}", body.source);
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
pub struct RemoveZsts;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for RemoveZsts {
|
||||
impl<'tcx> crate::MirPass<'tcx> for RemoveZsts {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() > 0
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
pub struct RevealAll;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for RevealAll {
|
||||
impl<'tcx> crate::MirPass<'tcx> for RevealAll {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
|
||||
RevealAllVisitor { tcx, param_env }.visit_body_preserves_cfg(body);
|
||||
|
11
compiler/rustc_mir_transform/src/sanity_check.rs
Normal file
11
compiler/rustc_mir_transform/src/sanity_check.rs
Normal file
@ -0,0 +1,11 @@
|
||||
use rustc_middle::mir::Body;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_mir_dataflow::rustc_peek::sanity_check;
|
||||
|
||||
pub(super) struct SanityCheck;
|
||||
|
||||
impl<'tcx> crate::MirLint<'tcx> for SanityCheck {
|
||||
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
|
||||
sanity_check(tcx, body);
|
||||
}
|
||||
}
|
@ -74,7 +74,7 @@ pub(crate) fn simplify_cfg(body: &mut Body<'_>) {
|
||||
body.basic_blocks_mut().raw.shrink_to_fit();
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for SimplifyCfg {
|
||||
impl<'tcx> crate::MirPass<'tcx> for SimplifyCfg {
|
||||
fn name(&self) -> &'static str {
|
||||
self.name()
|
||||
}
|
||||
@ -366,7 +366,7 @@ pub enum SimplifyLocals {
|
||||
Final,
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for SimplifyLocals {
|
||||
impl<'tcx> crate::MirPass<'tcx> for SimplifyLocals {
|
||||
fn name(&self) -> &'static str {
|
||||
match &self {
|
||||
SimplifyLocals::BeforeConstProp => "SimplifyLocals-before-const-prop",
|
||||
|
@ -7,7 +7,7 @@ pub enum SimplifyConstCondition {
|
||||
Final,
|
||||
}
|
||||
/// A pass that replaces a branch with a goto when its condition is known.
|
||||
impl<'tcx> MirPass<'tcx> for SimplifyConstCondition {
|
||||
impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
|
||||
fn name(&self) -> &'static str {
|
||||
match self {
|
||||
SimplifyConstCondition::AfterConstProp => "SimplifyConstCondition-after-const-prop",
|
||||
|
@ -9,8 +9,6 @@
|
||||
use rustc_middle::ty::{Ty, TyCtxt};
|
||||
use tracing::trace;
|
||||
|
||||
use super::MirPass;
|
||||
|
||||
/// Pass to convert `if` conditions on integrals into switches on the integral.
|
||||
/// For an example, it turns something like
|
||||
///
|
||||
@ -27,7 +25,7 @@
|
||||
/// ```
|
||||
pub struct SimplifyComparisonIntegral;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral {
|
||||
impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() > 0
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
/// needed to do that too, including updating the debug info.
|
||||
pub struct SingleUseConsts;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for SingleUseConsts {
|
||||
impl<'tcx> crate::MirPass<'tcx> for SingleUseConsts {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() > 0
|
||||
}
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
pub struct ScalarReplacementOfAggregates;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for ScalarReplacementOfAggregates {
|
||||
impl<'tcx> crate::MirPass<'tcx> for ScalarReplacementOfAggregates {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() >= 2
|
||||
}
|
||||
|
@ -12,8 +12,6 @@
|
||||
use rustc_target::abi::{Abi, Variants};
|
||||
use tracing::trace;
|
||||
|
||||
use crate::MirPass;
|
||||
|
||||
pub struct UnreachableEnumBranching;
|
||||
|
||||
fn get_discriminant_local(terminator: &TerminatorKind<'_>) -> Option<Local> {
|
||||
@ -74,7 +72,7 @@ fn variant_discriminants<'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for UnreachableEnumBranching {
|
||||
impl<'tcx> crate::MirPass<'tcx> for UnreachableEnumBranching {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
sess.mir_opt_level() > 0
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
pub struct UnreachablePropagation;
|
||||
|
||||
impl MirPass<'_> for UnreachablePropagation {
|
||||
impl crate::MirPass<'_> for UnreachablePropagation {
|
||||
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
|
||||
// Enable only under -Zmir-opt-level=2 as this can make programs less debuggable.
|
||||
sess.mir_opt_level() >= 2
|
||||
|
@ -36,7 +36,7 @@ pub struct Validator {
|
||||
pub mir_phase: MirPhase,
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for Validator {
|
||||
impl<'tcx> crate::MirPass<'tcx> for Validator {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
// FIXME(JakobDegen): These bodies never instantiated in codegend anyway, so it's not
|
||||
// terribly important that they pass the validator. However, I think other passes might
|
||||
|
Loading…
Reference in New Issue
Block a user