mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Rollup merge of #132901 - clubby789:enable-pass-check, r=jieyouxu
Warn about invalid `mir-enable-passes` pass names Fixes #132805
This commit is contained in:
commit
8628fd553d
@ -34,3 +34,5 @@ mir_transform_undefined_transmute = pointers cannot be transmuted to integers du
|
||||
.note = at compile-time, pointers do not have an integer value
|
||||
.note2 = avoiding this restriction via `union` or raw pointers leads to compile-time undefined behavior
|
||||
.help = for more information, see https://doc.rust-lang.org/std/mem/fn.transmute.html
|
||||
|
||||
mir_transform_unknown_pass_name = MIR pass `{$name}` is unknown and will be ignored
|
||||
|
@ -38,6 +38,12 @@ pub(crate) struct UnalignedPackedRef {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_transform_unknown_pass_name)]
|
||||
pub(crate) struct UnknownPassName<'a> {
|
||||
pub(crate) name: &'a str,
|
||||
}
|
||||
|
||||
pub(crate) struct AssertLint<P> {
|
||||
pub span: Span,
|
||||
pub assert_kind: AssertKind<P>,
|
||||
|
@ -40,77 +40,158 @@ use tracing::{debug, trace};
|
||||
#[macro_use]
|
||||
mod pass_manager;
|
||||
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use pass_manager::{self as pm, Lint, MirLint, MirPass, WithMinOptLevel};
|
||||
|
||||
mod abort_unwinding_calls;
|
||||
mod add_call_guards;
|
||||
mod add_moves_for_packed_drops;
|
||||
mod add_retag;
|
||||
mod add_subtyping_projections;
|
||||
mod check_alignment;
|
||||
mod check_const_item_mutation;
|
||||
mod check_packed_ref;
|
||||
mod check_undefined_transmutes;
|
||||
// This pass is public to allow external drivers to perform MIR cleanup
|
||||
pub mod cleanup_post_borrowck;
|
||||
mod copy_prop;
|
||||
mod coroutine;
|
||||
mod cost_checker;
|
||||
mod coverage;
|
||||
mod cross_crate_inline;
|
||||
mod ctfe_limit;
|
||||
mod dataflow_const_prop;
|
||||
mod dead_store_elimination;
|
||||
mod deduce_param_attrs;
|
||||
mod deduplicate_blocks;
|
||||
mod deref_separator;
|
||||
mod dest_prop;
|
||||
pub mod dump_mir;
|
||||
mod early_otherwise_branch;
|
||||
mod elaborate_box_derefs;
|
||||
mod elaborate_drops;
|
||||
mod errors;
|
||||
mod ffi_unwind_calls;
|
||||
mod function_item_references;
|
||||
mod gvn;
|
||||
// Made public so that `mir_drops_elaborated_and_const_checked` can be overridden
|
||||
// by custom rustc drivers, running all the steps by themselves. See #114628.
|
||||
pub mod inline;
|
||||
mod instsimplify;
|
||||
mod jump_threading;
|
||||
mod known_panics_lint;
|
||||
mod large_enums;
|
||||
mod lint;
|
||||
mod lower_intrinsics;
|
||||
mod lower_slice_len;
|
||||
mod match_branches;
|
||||
mod mentioned_items;
|
||||
mod multiple_return_terminators;
|
||||
mod nrvo;
|
||||
mod post_drop_elaboration;
|
||||
mod prettify;
|
||||
mod promote_consts;
|
||||
mod ref_prop;
|
||||
mod remove_noop_landing_pads;
|
||||
mod remove_place_mention;
|
||||
mod remove_storage_markers;
|
||||
mod remove_uninit_drops;
|
||||
mod remove_unneeded_drops;
|
||||
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
|
||||
pub mod simplify;
|
||||
mod simplify_branches;
|
||||
mod simplify_comparison_integral;
|
||||
mod single_use_consts;
|
||||
mod sroa;
|
||||
mod unreachable_enum_branching;
|
||||
mod unreachable_prop;
|
||||
mod validate;
|
||||
|
||||
/// We import passes via this macro so that we can have a static list of pass names
|
||||
/// (used to verify CLI arguments). It takes a list of modules, followed by the passes
|
||||
/// declared within them.
|
||||
/// ```ignore,macro-test
|
||||
/// declare_passes! {
|
||||
/// // Declare a single pass from the module `abort_unwinding_calls`
|
||||
/// mod abort_unwinding_calls : AbortUnwindingCalls;
|
||||
/// // When passes are grouped together as an enum, declare the two constituent passes
|
||||
/// mod add_call_guards : AddCallGuards {
|
||||
/// AllCallEdges,
|
||||
/// CriticalCallEdges
|
||||
/// };
|
||||
/// // Declares multiple pass groups, each containing their own constituent passes
|
||||
/// mod simplify : SimplifyCfg {
|
||||
/// Initial,
|
||||
/// /* omitted */
|
||||
/// }, SimplifyLocals {
|
||||
/// BeforeConstProp,
|
||||
/// /* omitted */
|
||||
/// };
|
||||
/// }
|
||||
/// ```
|
||||
macro_rules! declare_passes {
|
||||
(
|
||||
$(
|
||||
$vis:vis mod $mod_name:ident : $($pass_name:ident $( { $($ident:ident),* } )?),+ $(,)?;
|
||||
)*
|
||||
) => {
|
||||
$(
|
||||
$vis mod $mod_name;
|
||||
$(
|
||||
// Make sure the type name is correct
|
||||
#[allow(unused_imports)]
|
||||
use $mod_name::$pass_name as _;
|
||||
)+
|
||||
)*
|
||||
|
||||
static PASS_NAMES: LazyLock<FxIndexSet<&str>> = LazyLock::new(|| [
|
||||
// Fake marker pass
|
||||
"PreCodegen",
|
||||
$(
|
||||
$(
|
||||
stringify!($pass_name),
|
||||
$(
|
||||
$(
|
||||
$mod_name::$pass_name::$ident.name(),
|
||||
)*
|
||||
)?
|
||||
)+
|
||||
)*
|
||||
].into_iter().collect());
|
||||
};
|
||||
}
|
||||
|
||||
declare_passes! {
|
||||
mod abort_unwinding_calls : AbortUnwindingCalls;
|
||||
mod add_call_guards : AddCallGuards { AllCallEdges, CriticalCallEdges };
|
||||
mod add_moves_for_packed_drops : AddMovesForPackedDrops;
|
||||
mod add_retag : AddRetag;
|
||||
mod add_subtyping_projections : Subtyper;
|
||||
mod check_alignment : CheckAlignment;
|
||||
mod check_const_item_mutation : CheckConstItemMutation;
|
||||
mod check_packed_ref : CheckPackedRef;
|
||||
mod check_undefined_transmutes : CheckUndefinedTransmutes;
|
||||
// This pass is public to allow external drivers to perform MIR cleanup
|
||||
pub mod cleanup_post_borrowck : CleanupPostBorrowck;
|
||||
|
||||
mod copy_prop : CopyProp;
|
||||
mod coroutine : StateTransform;
|
||||
mod coverage : InstrumentCoverage;
|
||||
mod ctfe_limit : CtfeLimit;
|
||||
mod dataflow_const_prop : DataflowConstProp;
|
||||
mod dead_store_elimination : DeadStoreElimination {
|
||||
Initial,
|
||||
Final
|
||||
};
|
||||
mod deduplicate_blocks : DeduplicateBlocks;
|
||||
mod deref_separator : Derefer;
|
||||
mod dest_prop : DestinationPropagation;
|
||||
pub mod dump_mir : Marker;
|
||||
mod early_otherwise_branch : EarlyOtherwiseBranch;
|
||||
mod elaborate_box_derefs : ElaborateBoxDerefs;
|
||||
mod elaborate_drops : ElaborateDrops;
|
||||
mod function_item_references : FunctionItemReferences;
|
||||
mod gvn : GVN;
|
||||
// Made public so that `mir_drops_elaborated_and_const_checked` can be overridden
|
||||
// by custom rustc drivers, running all the steps by themselves. See #114628.
|
||||
pub mod inline : Inline;
|
||||
mod instsimplify : InstSimplify { BeforeInline, AfterSimplifyCfg };
|
||||
mod jump_threading : JumpThreading;
|
||||
mod known_panics_lint : KnownPanicsLint;
|
||||
mod large_enums : EnumSizeOpt;
|
||||
mod lower_intrinsics : LowerIntrinsics;
|
||||
mod lower_slice_len : LowerSliceLenCalls;
|
||||
mod match_branches : MatchBranchSimplification;
|
||||
mod mentioned_items : MentionedItems;
|
||||
mod multiple_return_terminators : MultipleReturnTerminators;
|
||||
mod nrvo : RenameReturnPlace;
|
||||
mod post_drop_elaboration : CheckLiveDrops;
|
||||
mod prettify : ReorderBasicBlocks, ReorderLocals;
|
||||
mod promote_consts : PromoteTemps;
|
||||
mod ref_prop : ReferencePropagation;
|
||||
mod remove_noop_landing_pads : RemoveNoopLandingPads;
|
||||
mod remove_place_mention : RemovePlaceMention;
|
||||
mod remove_storage_markers : RemoveStorageMarkers;
|
||||
mod remove_uninit_drops : RemoveUninitDrops;
|
||||
mod remove_unneeded_drops : RemoveUnneededDrops;
|
||||
mod remove_zsts : RemoveZsts;
|
||||
mod required_consts : RequiredConstsVisitor;
|
||||
mod reveal_all : RevealAll;
|
||||
mod sanity_check : SanityCheck;
|
||||
// This pass is public to allow external drivers to perform MIR cleanup
|
||||
pub mod simplify :
|
||||
SimplifyCfg {
|
||||
Initial,
|
||||
PromoteConsts,
|
||||
RemoveFalseEdges,
|
||||
PostAnalysis,
|
||||
PreOptimizations,
|
||||
Final,
|
||||
MakeShim,
|
||||
AfterUnreachableEnumBranching
|
||||
},
|
||||
SimplifyLocals {
|
||||
BeforeConstProp,
|
||||
AfterGVN,
|
||||
Final
|
||||
};
|
||||
mod simplify_branches : SimplifyConstCondition {
|
||||
AfterConstProp,
|
||||
Final
|
||||
};
|
||||
mod simplify_comparison_integral : SimplifyComparisonIntegral;
|
||||
mod single_use_consts : SingleUseConsts;
|
||||
mod sroa : ScalarReplacementOfAggregates;
|
||||
mod unreachable_enum_branching : UnreachableEnumBranching;
|
||||
mod unreachable_prop : UnreachablePropagation;
|
||||
mod validate : Validator;
|
||||
}
|
||||
|
||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||
|
||||
|
@ -1,24 +1,25 @@
|
||||
use std::cell::RefCell;
|
||||
use std::collections::hash_map::Entry;
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
|
||||
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;
|
||||
use crate::{errors, validate};
|
||||
|
||||
thread_local! {
|
||||
static PASS_NAMES: RefCell<FxHashMap<&'static str, &'static str>> = {
|
||||
/// Maps MIR pass names to a snake case form to match profiling naming style
|
||||
static PASS_TO_PROFILER_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) {
|
||||
PASS_TO_PROFILER_NAMES.with(|names| match names.borrow_mut().entry(type_name) {
|
||||
Entry::Occupied(e) => *e.get(),
|
||||
Entry::Vacant(e) => {
|
||||
let snake_case: String = type_name
|
||||
@ -198,6 +199,31 @@ fn run_passes_inner<'tcx>(
|
||||
let overridden_passes = &tcx.sess.opts.unstable_opts.mir_enable_passes;
|
||||
trace!(?overridden_passes);
|
||||
|
||||
let named_passes: FxIndexSet<_> =
|
||||
overridden_passes.iter().map(|(name, _)| name.as_str()).collect();
|
||||
|
||||
for &name in named_passes.difference(&*crate::PASS_NAMES) {
|
||||
tcx.dcx().emit_warn(errors::UnknownPassName { name });
|
||||
}
|
||||
|
||||
// Verify that no passes are missing from the `declare_passes` invocation
|
||||
#[cfg(debug_assertions)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
{
|
||||
let used_passes: FxIndexSet<_> = passes.iter().map(|p| p.name()).collect();
|
||||
|
||||
let undeclared = used_passes.difference(&*crate::PASS_NAMES).collect::<Vec<_>>();
|
||||
if let Some((name, rest)) = undeclared.split_first() {
|
||||
let mut err =
|
||||
tcx.dcx().struct_bug(format!("pass `{name}` is not declared in `PASS_NAMES`"));
|
||||
for name in rest {
|
||||
err.note(format!("pass `{name}` is also not declared in `PASS_NAMES`"));
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
|
||||
let prof_arg = tcx.sess.prof.enabled().then(|| format!("{:?}", body.source.def_id()));
|
||||
|
||||
if !body.should_skip() {
|
||||
|
14
tests/ui/mir/enable_passes_validation.all_unknown.stderr
Normal file
14
tests/ui/mir/enable_passes_validation.all_unknown.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
warning: MIR pass `ThisPass` is unknown and will be ignored
|
||||
|
||||
warning: MIR pass `DoesNotExist` is unknown and will be ignored
|
||||
|
||||
warning: MIR pass `ThisPass` is unknown and will be ignored
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
warning: MIR pass `DoesNotExist` is unknown and will be ignored
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
warning: 4 warnings emitted
|
||||
|
2
tests/ui/mir/enable_passes_validation.empty.stderr
Normal file
2
tests/ui/mir/enable_passes_validation.empty.stderr
Normal file
@ -0,0 +1,2 @@
|
||||
error: incorrect value `` for unstable option `mir-enable-passes` - a comma-separated list of strings, with elements beginning with + or - was expected
|
||||
|
8
tests/ui/mir/enable_passes_validation.mixed.stderr
Normal file
8
tests/ui/mir/enable_passes_validation.mixed.stderr
Normal file
@ -0,0 +1,8 @@
|
||||
warning: MIR pass `ThisPassDoesNotExist` is unknown and will be ignored
|
||||
|
||||
warning: MIR pass `ThisPassDoesNotExist` is unknown and will be ignored
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
warning: 2 warnings emitted
|
||||
|
21
tests/ui/mir/enable_passes_validation.rs
Normal file
21
tests/ui/mir/enable_passes_validation.rs
Normal file
@ -0,0 +1,21 @@
|
||||
//@ revisions: empty unprefixed all_unknown all_known mixed
|
||||
|
||||
//@[empty] compile-flags: -Zmir-enable-passes=
|
||||
//@[empty] error-pattern error: incorrect value `` for unstable option `mir-enable-passes` - a comma-separated list of strings, with elements beginning with + or - was expected
|
||||
|
||||
//@[unprefixed] compile-flags: -Zmir-enable-passes=CheckAlignment
|
||||
//@[unprefixed] error-pattern error: incorrect value `CheckAlignment` for unstable option `mir-enable-passes` - a comma-separated list of strings, with elements beginning with + or - was expected
|
||||
|
||||
//@[all_unknown] check-pass
|
||||
//@[all_unknown] compile-flags: -Zmir-enable-passes=+ThisPass,-DoesNotExist
|
||||
//@[all_unknown] error-pattern: warning: MIR pass `ThisPass` is unknown and will be ignored
|
||||
//@[all_unknown] error-pattern: warning: MIR pass `DoesNotExist` is unknown and will be ignored
|
||||
|
||||
//@[all_known] check-pass
|
||||
//@[all_known] compile-flags: -Zmir-enable-passes=+CheckAlignment,+LowerIntrinsics
|
||||
|
||||
//@[mixed] check-pass
|
||||
//@[mixed] compile-flags: -Zmir-enable-passes=+ThisPassDoesNotExist,+CheckAlignment
|
||||
//@[mixed] error-pattern: warning: MIR pass `ThisPassDoesNotExist` is unknown and will be ignored
|
||||
|
||||
fn main() {}
|
2
tests/ui/mir/enable_passes_validation.unprefixed.stderr
Normal file
2
tests/ui/mir/enable_passes_validation.unprefixed.stderr
Normal file
@ -0,0 +1,2 @@
|
||||
error: incorrect value `CheckAlignment` for unstable option `mir-enable-passes` - a comma-separated list of strings, with elements beginning with + or - was expected
|
||||
|
Loading…
Reference in New Issue
Block a user