Skip to content

Commit 7836ad4

Browse files
authored
Unrolled build for rust-lang#132901
Rollup merge of rust-lang#132901 - clubby789:enable-pass-check, r=jieyouxu Warn about invalid `mir-enable-passes` pass names Fixes rust-lang#132805
2 parents 6503543 + 8c64e9d commit 7836ad4

9 files changed

+227
-65
lines changed

compiler/rustc_mir_transform/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,5 @@ mir_transform_undefined_transmute = pointers cannot be transmuted to integers du
3434
.note = at compile-time, pointers do not have an integer value
3535
.note2 = avoiding this restriction via `union` or raw pointers leads to compile-time undefined behavior
3636
.help = for more information, see https://doc.rust-lang.org/std/mem/fn.transmute.html
37+
38+
mir_transform_unknown_pass_name = MIR pass `{$name}` is unknown and will be ignored

compiler/rustc_mir_transform/src/errors.rs

+6
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ pub(crate) struct UnalignedPackedRef {
3838
pub span: Span,
3939
}
4040

41+
#[derive(Diagnostic)]
42+
#[diag(mir_transform_unknown_pass_name)]
43+
pub(crate) struct UnknownPassName<'a> {
44+
pub(crate) name: &'a str,
45+
}
46+
4147
pub(crate) struct AssertLint<P> {
4248
pub span: Span,
4349
pub assert_kind: AssertKind<P>,

compiler/rustc_mir_transform/src/lib.rs

+142-61
Original file line numberDiff line numberDiff line change
@@ -40,77 +40,158 @@ use tracing::{debug, trace};
4040
#[macro_use]
4141
mod pass_manager;
4242

43+
use std::sync::LazyLock;
44+
4345
use pass_manager::{self as pm, Lint, MirLint, MirPass, WithMinOptLevel};
4446

45-
mod abort_unwinding_calls;
46-
mod add_call_guards;
47-
mod add_moves_for_packed_drops;
48-
mod add_retag;
49-
mod add_subtyping_projections;
50-
mod check_alignment;
51-
mod check_const_item_mutation;
52-
mod check_packed_ref;
53-
mod check_undefined_transmutes;
54-
// This pass is public to allow external drivers to perform MIR cleanup
55-
pub mod cleanup_post_borrowck;
56-
mod copy_prop;
57-
mod coroutine;
5847
mod cost_checker;
59-
mod coverage;
6048
mod cross_crate_inline;
61-
mod ctfe_limit;
62-
mod dataflow_const_prop;
63-
mod dead_store_elimination;
6449
mod deduce_param_attrs;
65-
mod deduplicate_blocks;
66-
mod deref_separator;
67-
mod dest_prop;
68-
pub mod dump_mir;
69-
mod early_otherwise_branch;
70-
mod elaborate_box_derefs;
71-
mod elaborate_drops;
7250
mod errors;
7351
mod ffi_unwind_calls;
74-
mod function_item_references;
75-
mod gvn;
76-
// Made public so that `mir_drops_elaborated_and_const_checked` can be overridden
77-
// by custom rustc drivers, running all the steps by themselves. See #114628.
78-
pub mod inline;
79-
mod instsimplify;
80-
mod jump_threading;
81-
mod known_panics_lint;
82-
mod large_enums;
8352
mod lint;
84-
mod lower_intrinsics;
85-
mod lower_slice_len;
86-
mod match_branches;
87-
mod mentioned_items;
88-
mod multiple_return_terminators;
89-
mod nrvo;
90-
mod post_drop_elaboration;
91-
mod prettify;
92-
mod promote_consts;
93-
mod ref_prop;
94-
mod remove_noop_landing_pads;
95-
mod remove_place_mention;
96-
mod remove_storage_markers;
97-
mod remove_uninit_drops;
98-
mod remove_unneeded_drops;
99-
mod remove_zsts;
100-
mod required_consts;
101-
mod reveal_all;
102-
mod sanity_check;
10353
mod shim;
10454
mod ssa;
105-
// This pass is public to allow external drivers to perform MIR cleanup
106-
pub mod simplify;
107-
mod simplify_branches;
108-
mod simplify_comparison_integral;
109-
mod single_use_consts;
110-
mod sroa;
111-
mod unreachable_enum_branching;
112-
mod unreachable_prop;
113-
mod validate;
55+
56+
/// We import passes via this macro so that we can have a static list of pass names
57+
/// (used to verify CLI arguments). It takes a list of modules, followed by the passes
58+
/// declared within them.
59+
/// ```ignore,macro-test
60+
/// declare_passes! {
61+
/// // Declare a single pass from the module `abort_unwinding_calls`
62+
/// mod abort_unwinding_calls : AbortUnwindingCalls;
63+
/// // When passes are grouped together as an enum, declare the two constituent passes
64+
/// mod add_call_guards : AddCallGuards {
65+
/// AllCallEdges,
66+
/// CriticalCallEdges
67+
/// };
68+
/// // Declares multiple pass groups, each containing their own constituent passes
69+
/// mod simplify : SimplifyCfg {
70+
/// Initial,
71+
/// /* omitted */
72+
/// }, SimplifyLocals {
73+
/// BeforeConstProp,
74+
/// /* omitted */
75+
/// };
76+
/// }
77+
/// ```
78+
macro_rules! declare_passes {
79+
(
80+
$(
81+
$vis:vis mod $mod_name:ident : $($pass_name:ident $( { $($ident:ident),* } )?),+ $(,)?;
82+
)*
83+
) => {
84+
$(
85+
$vis mod $mod_name;
86+
$(
87+
// Make sure the type name is correct
88+
#[allow(unused_imports)]
89+
use $mod_name::$pass_name as _;
90+
)+
91+
)*
92+
93+
static PASS_NAMES: LazyLock<FxIndexSet<&str>> = LazyLock::new(|| [
94+
// Fake marker pass
95+
"PreCodegen",
96+
$(
97+
$(
98+
stringify!($pass_name),
99+
$(
100+
$(
101+
$mod_name::$pass_name::$ident.name(),
102+
)*
103+
)?
104+
)+
105+
)*
106+
].into_iter().collect());
107+
};
108+
}
109+
110+
declare_passes! {
111+
mod abort_unwinding_calls : AbortUnwindingCalls;
112+
mod add_call_guards : AddCallGuards { AllCallEdges, CriticalCallEdges };
113+
mod add_moves_for_packed_drops : AddMovesForPackedDrops;
114+
mod add_retag : AddRetag;
115+
mod add_subtyping_projections : Subtyper;
116+
mod check_alignment : CheckAlignment;
117+
mod check_const_item_mutation : CheckConstItemMutation;
118+
mod check_packed_ref : CheckPackedRef;
119+
mod check_undefined_transmutes : CheckUndefinedTransmutes;
120+
// This pass is public to allow external drivers to perform MIR cleanup
121+
pub mod cleanup_post_borrowck : CleanupPostBorrowck;
122+
123+
mod copy_prop : CopyProp;
124+
mod coroutine : StateTransform;
125+
mod coverage : InstrumentCoverage;
126+
mod ctfe_limit : CtfeLimit;
127+
mod dataflow_const_prop : DataflowConstProp;
128+
mod dead_store_elimination : DeadStoreElimination {
129+
Initial,
130+
Final
131+
};
132+
mod deduplicate_blocks : DeduplicateBlocks;
133+
mod deref_separator : Derefer;
134+
mod dest_prop : DestinationPropagation;
135+
pub mod dump_mir : Marker;
136+
mod early_otherwise_branch : EarlyOtherwiseBranch;
137+
mod elaborate_box_derefs : ElaborateBoxDerefs;
138+
mod elaborate_drops : ElaborateDrops;
139+
mod function_item_references : FunctionItemReferences;
140+
mod gvn : GVN;
141+
// Made public so that `mir_drops_elaborated_and_const_checked` can be overridden
142+
// by custom rustc drivers, running all the steps by themselves. See #114628.
143+
pub mod inline : Inline;
144+
mod instsimplify : InstSimplify { BeforeInline, AfterSimplifyCfg };
145+
mod jump_threading : JumpThreading;
146+
mod known_panics_lint : KnownPanicsLint;
147+
mod large_enums : EnumSizeOpt;
148+
mod lower_intrinsics : LowerIntrinsics;
149+
mod lower_slice_len : LowerSliceLenCalls;
150+
mod match_branches : MatchBranchSimplification;
151+
mod mentioned_items : MentionedItems;
152+
mod multiple_return_terminators : MultipleReturnTerminators;
153+
mod nrvo : RenameReturnPlace;
154+
mod post_drop_elaboration : CheckLiveDrops;
155+
mod prettify : ReorderBasicBlocks, ReorderLocals;
156+
mod promote_consts : PromoteTemps;
157+
mod ref_prop : ReferencePropagation;
158+
mod remove_noop_landing_pads : RemoveNoopLandingPads;
159+
mod remove_place_mention : RemovePlaceMention;
160+
mod remove_storage_markers : RemoveStorageMarkers;
161+
mod remove_uninit_drops : RemoveUninitDrops;
162+
mod remove_unneeded_drops : RemoveUnneededDrops;
163+
mod remove_zsts : RemoveZsts;
164+
mod required_consts : RequiredConstsVisitor;
165+
mod reveal_all : RevealAll;
166+
mod sanity_check : SanityCheck;
167+
// This pass is public to allow external drivers to perform MIR cleanup
168+
pub mod simplify :
169+
SimplifyCfg {
170+
Initial,
171+
PromoteConsts,
172+
RemoveFalseEdges,
173+
PostAnalysis,
174+
PreOptimizations,
175+
Final,
176+
MakeShim,
177+
AfterUnreachableEnumBranching
178+
},
179+
SimplifyLocals {
180+
BeforeConstProp,
181+
AfterGVN,
182+
Final
183+
};
184+
mod simplify_branches : SimplifyConstCondition {
185+
AfterConstProp,
186+
Final
187+
};
188+
mod simplify_comparison_integral : SimplifyComparisonIntegral;
189+
mod single_use_consts : SingleUseConsts;
190+
mod sroa : ScalarReplacementOfAggregates;
191+
mod unreachable_enum_branching : UnreachableEnumBranching;
192+
mod unreachable_prop : UnreachablePropagation;
193+
mod validate : Validator;
194+
}
114195

115196
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
116197

compiler/rustc_mir_transform/src/pass_manager.rs

+30-4
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
use std::cell::RefCell;
22
use std::collections::hash_map::Entry;
33

4-
use rustc_data_structures::fx::FxHashMap;
4+
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
55
use rustc_middle::mir::{self, Body, MirPhase, RuntimePhase};
66
use rustc_middle::ty::TyCtxt;
77
use rustc_session::Session;
88
use tracing::trace;
99

1010
use crate::lint::lint_body;
11-
use crate::validate;
11+
use crate::{errors, validate};
1212

1313
thread_local! {
14-
static PASS_NAMES: RefCell<FxHashMap<&'static str, &'static str>> = {
14+
/// Maps MIR pass names to a snake case form to match profiling naming style
15+
static PASS_TO_PROFILER_NAMES: RefCell<FxHashMap<&'static str, &'static str>> = {
1516
RefCell::new(FxHashMap::default())
1617
};
1718
}
1819

1920
/// Converts a MIR pass name into a snake case form to match the profiling naming style.
2021
fn to_profiler_name(type_name: &'static str) -> &'static str {
21-
PASS_NAMES.with(|names| match names.borrow_mut().entry(type_name) {
22+
PASS_TO_PROFILER_NAMES.with(|names| match names.borrow_mut().entry(type_name) {
2223
Entry::Occupied(e) => *e.get(),
2324
Entry::Vacant(e) => {
2425
let snake_case: String = type_name
@@ -198,6 +199,31 @@ fn run_passes_inner<'tcx>(
198199
let overridden_passes = &tcx.sess.opts.unstable_opts.mir_enable_passes;
199200
trace!(?overridden_passes);
200201

202+
let named_passes: FxIndexSet<_> =
203+
overridden_passes.iter().map(|(name, _)| name.as_str()).collect();
204+
205+
for &name in named_passes.difference(&*crate::PASS_NAMES) {
206+
tcx.dcx().emit_warn(errors::UnknownPassName { name });
207+
}
208+
209+
// Verify that no passes are missing from the `declare_passes` invocation
210+
#[cfg(debug_assertions)]
211+
#[allow(rustc::diagnostic_outside_of_impl)]
212+
#[allow(rustc::untranslatable_diagnostic)]
213+
{
214+
let used_passes: FxIndexSet<_> = passes.iter().map(|p| p.name()).collect();
215+
216+
let undeclared = used_passes.difference(&*crate::PASS_NAMES).collect::<Vec<_>>();
217+
if let Some((name, rest)) = undeclared.split_first() {
218+
let mut err =
219+
tcx.dcx().struct_bug(format!("pass `{name}` is not declared in `PASS_NAMES`"));
220+
for name in rest {
221+
err.note(format!("pass `{name}` is also not declared in `PASS_NAMES`"));
222+
}
223+
err.emit();
224+
}
225+
}
226+
201227
let prof_arg = tcx.sess.prof.enabled().then(|| format!("{:?}", body.source.def_id()));
202228

203229
if !body.should_skip() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
warning: MIR pass `ThisPass` is unknown and will be ignored
2+
3+
warning: MIR pass `DoesNotExist` is unknown and will be ignored
4+
5+
warning: MIR pass `ThisPass` is unknown and will be ignored
6+
|
7+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
8+
9+
warning: MIR pass `DoesNotExist` is unknown and will be ignored
10+
|
11+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
12+
13+
warning: 4 warnings emitted
14+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
error: incorrect value `` for unstable option `mir-enable-passes` - a comma-separated list of strings, with elements beginning with + or - was expected
2+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
warning: MIR pass `ThisPassDoesNotExist` is unknown and will be ignored
2+
3+
warning: MIR pass `ThisPassDoesNotExist` is unknown and will be ignored
4+
|
5+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
6+
7+
warning: 2 warnings emitted
8+
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//@ revisions: empty unprefixed all_unknown all_known mixed
2+
3+
//@[empty] compile-flags: -Zmir-enable-passes=
4+
//@[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
5+
6+
//@[unprefixed] compile-flags: -Zmir-enable-passes=CheckAlignment
7+
//@[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
8+
9+
//@[all_unknown] check-pass
10+
//@[all_unknown] compile-flags: -Zmir-enable-passes=+ThisPass,-DoesNotExist
11+
//@[all_unknown] error-pattern: warning: MIR pass `ThisPass` is unknown and will be ignored
12+
//@[all_unknown] error-pattern: warning: MIR pass `DoesNotExist` is unknown and will be ignored
13+
14+
//@[all_known] check-pass
15+
//@[all_known] compile-flags: -Zmir-enable-passes=+CheckAlignment,+LowerIntrinsics
16+
17+
//@[mixed] check-pass
18+
//@[mixed] compile-flags: -Zmir-enable-passes=+ThisPassDoesNotExist,+CheckAlignment
19+
//@[mixed] error-pattern: warning: MIR pass `ThisPassDoesNotExist` is unknown and will be ignored
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
error: incorrect value `CheckAlignment` for unstable option `mir-enable-passes` - a comma-separated list of strings, with elements beginning with + or - was expected
2+

0 commit comments

Comments
 (0)