Skip to content

Commit 0a3cd3b

Browse files
committed
Auto merge of #151325 - JonathanBrouwer:rollup-YoCcqTr, r=JonathanBrouwer
Rollup of 7 pull requests Successful merges: - #150767 (Allow invoking all help options at once) - #150886 (Added mGCA related tests) - #151245 (Explicitly list crate level attrs) - #151268 (Fix ICE on inconsistent import resolution with macro-attributed extern crate) - #151275 (Normalize type_const items even with feature `generic_const_exprs`) - #151288 (Use `find_attr` instead of `attr::contains_name` in `lower_const_item_rhs`) - #151321 (Port #![no_main] to the attribute parser.) r? @ghost
2 parents 2b112ef + 3c2c533 commit 0a3cd3b

30 files changed

Lines changed: 440 additions & 95 deletions

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2384,7 +2384,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23842384
Some(ConstItemRhs::TypeConst(anon)) => {
23852385
hir::ConstItemRhs::TypeConst(self.lower_anon_const_to_const_arg_and_alloc(anon))
23862386
}
2387-
None if attr::contains_name(attrs, sym::type_const) => {
2387+
None if find_attr!(attrs, AttributeKind::TypeConst(_)) => {
23882388
let const_arg = ConstArg {
23892389
hir_id: self.next_id(),
23902390
kind: hir::ConstArgKind::Error(

compiler/rustc_attr_parsing/src/attributes/crate_level.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,15 @@ impl<S: Stage> NoArgsAttributeParser<S> for NoStdParser {
136136
const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoStd;
137137
}
138138

139+
pub(crate) struct NoMainParser;
140+
141+
impl<S: Stage> NoArgsAttributeParser<S> for NoMainParser {
142+
const PATH: &[Symbol] = &[sym::no_main];
143+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
144+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
145+
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoMain;
146+
}
147+
139148
pub(crate) struct RustcCoherenceIsCoreParser;
140149

141150
impl<S: Stage> NoArgsAttributeParser<S> for RustcCoherenceIsCoreParser {

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ use crate::attributes::codegen_attrs::{
2828
};
2929
use crate::attributes::confusables::ConfusablesParser;
3030
use crate::attributes::crate_level::{
31-
CrateNameParser, MoveSizeLimitParser, NoCoreParser, NoStdParser, PatternComplexityLimitParser,
32-
RecursionLimitParser, RustcCoherenceIsCoreParser, TypeLengthLimitParser,
33-
WindowsSubsystemParser,
31+
CrateNameParser, MoveSizeLimitParser, NoCoreParser, NoMainParser, NoStdParser,
32+
PatternComplexityLimitParser, RecursionLimitParser, RustcCoherenceIsCoreParser,
33+
TypeLengthLimitParser, WindowsSubsystemParser,
3434
};
3535
use crate::attributes::debugger::DebuggerViualizerParser;
3636
use crate::attributes::deprecation::DeprecationParser;
@@ -263,6 +263,7 @@ attribute_parsers!(
263263
Single<WithoutArgs<NoCoreParser>>,
264264
Single<WithoutArgs<NoImplicitPreludeParser>>,
265265
Single<WithoutArgs<NoLinkParser>>,
266+
Single<WithoutArgs<NoMainParser>>,
266267
Single<WithoutArgs<NoMangleParser>>,
267268
Single<WithoutArgs<NoStdParser>>,
268269
Single<WithoutArgs<NonExhaustiveParser>>,

compiler/rustc_driver_impl/src/lib.rs

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,10 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
228228

229229
let args = args::arg_expand_all(&default_early_dcx, at_args);
230230

231-
let Some(matches) = handle_options(&default_early_dcx, &args) else {
232-
return;
231+
let (matches, help_only) = match handle_options(&default_early_dcx, &args) {
232+
HandledOptions::None => return,
233+
HandledOptions::Normal(matches) => (matches, false),
234+
HandledOptions::HelpOnly(matches) => (matches, true),
233235
};
234236

235237
let sopts = config::build_session_options(&mut default_early_dcx, &matches);
@@ -291,6 +293,11 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
291293
return early_exit();
292294
}
293295

296+
// We have now handled all help options, exit
297+
if help_only {
298+
return early_exit();
299+
}
300+
294301
if print_crate_info(codegen_backend, sess, has_input) == Compilation::Stop {
295302
return early_exit();
296303
}
@@ -1097,7 +1104,7 @@ pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) ->
10971104
// Don't handle -W help here, because we might first load additional lints.
10981105
let debug_flags = matches.opt_strs("Z");
10991106
if debug_flags.iter().any(|x| *x == "help") {
1100-
describe_debug_flags();
1107+
describe_unstable_flags();
11011108
return true;
11021109
}
11031110

@@ -1137,8 +1144,8 @@ fn get_backend_from_raw_matches(
11371144
get_codegen_backend(early_dcx, &sysroot, backend_name, &target)
11381145
}
11391146

1140-
fn describe_debug_flags() {
1141-
safe_println!("\nAvailable options:\n");
1147+
fn describe_unstable_flags() {
1148+
safe_println!("\nAvailable unstable options:\n");
11421149
print_flag_list("-Z", config::Z_OPTIONS);
11431150
}
11441151

@@ -1162,6 +1169,16 @@ fn print_flag_list<T>(cmdline_opt: &str, flag_list: &[OptionDesc<T>]) {
11621169
}
11631170
}
11641171

1172+
pub enum HandledOptions {
1173+
/// Parsing failed, or we parsed a flag causing an early exit
1174+
None,
1175+
/// Successful parsing
1176+
Normal(getopts::Matches),
1177+
/// Parsing succeeded, but we received one or more 'help' flags
1178+
/// The compiler should proceed only until a possible `-W help` flag has been processed
1179+
HelpOnly(getopts::Matches),
1180+
}
1181+
11651182
/// Process command line options. Emits messages as appropriate. If compilation
11661183
/// should continue, returns a getopts::Matches object parsed from args,
11671184
/// otherwise returns `None`.
@@ -1189,7 +1206,7 @@ fn print_flag_list<T>(cmdline_opt: &str, flag_list: &[OptionDesc<T>]) {
11891206
/// This does not need to be `pub` for rustc itself, but @chaosite needs it to
11901207
/// be public when using rustc as a library, see
11911208
/// <https://github.com/rust-lang/rust/commit/2b4c33817a5aaecabf4c6598d41e190080ec119e>
1192-
pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<getopts::Matches> {
1209+
pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> HandledOptions {
11931210
// Parse with *all* options defined in the compiler, we don't worry about
11941211
// option stability here we just want to parse as much as possible.
11951212
let mut options = getopts::Options::new();
@@ -1235,26 +1252,69 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
12351252
// (unstable option being used on stable)
12361253
nightly_options::check_nightly_options(early_dcx, &matches, &config::rustc_optgroups());
12371254

1238-
if args.is_empty() || matches.opt_present("h") || matches.opt_present("help") {
1239-
// Only show unstable options in --help if we accept unstable options.
1240-
let unstable_enabled = nightly_options::is_unstable_enabled(&matches);
1241-
let nightly_build = nightly_options::match_is_nightly_build(&matches);
1242-
usage(matches.opt_present("verbose"), unstable_enabled, nightly_build);
1243-
return None;
1255+
// Handle the special case of -Wall.
1256+
let wall = matches.opt_strs("W");
1257+
if wall.iter().any(|x| *x == "all") {
1258+
print_wall_help();
1259+
return HandledOptions::None;
12441260
}
12451261

1246-
if describe_flag_categories(early_dcx, &matches) {
1247-
return None;
1262+
if handle_help(&matches, args) {
1263+
return HandledOptions::HelpOnly(matches);
1264+
}
1265+
1266+
if matches.opt_strs("C").iter().any(|x| x == "passes=list") {
1267+
get_backend_from_raw_matches(early_dcx, &matches).print_passes();
1268+
return HandledOptions::None;
12481269
}
12491270

12501271
if matches.opt_present("version") {
12511272
version!(early_dcx, "rustc", &matches);
1252-
return None;
1273+
return HandledOptions::None;
12531274
}
12541275

12551276
warn_on_confusing_output_filename_flag(early_dcx, &matches, args);
12561277

1257-
Some(matches)
1278+
HandledOptions::Normal(matches)
1279+
}
1280+
1281+
/// Handle help options in the order they are provided, ignoring other flags. Returns if any options were handled
1282+
/// Handled options:
1283+
/// - `-h`/`--help`/empty arguments
1284+
/// - `-Z help`
1285+
/// - `-C help`
1286+
/// NOTE: `-W help` is NOT handled here, as additional lints may be loaded.
1287+
pub fn handle_help(matches: &getopts::Matches, args: &[String]) -> bool {
1288+
let opt_pos = |opt| matches.opt_positions(opt).first().copied();
1289+
let opt_help_pos = |opt| {
1290+
matches
1291+
.opt_strs_pos(opt)
1292+
.iter()
1293+
.filter_map(|(pos, oval)| if oval == "help" { Some(*pos) } else { None })
1294+
.next()
1295+
};
1296+
let help_pos = if args.is_empty() { Some(0) } else { opt_pos("h").or_else(|| opt_pos("help")) };
1297+
let zhelp_pos = opt_help_pos("Z");
1298+
let chelp_pos = opt_help_pos("C");
1299+
let print_help = || {
1300+
// Only show unstable options in --help if we accept unstable options.
1301+
let unstable_enabled = nightly_options::is_unstable_enabled(&matches);
1302+
let nightly_build = nightly_options::match_is_nightly_build(&matches);
1303+
usage(matches.opt_present("verbose"), unstable_enabled, nightly_build);
1304+
};
1305+
1306+
let mut helps = [
1307+
(help_pos, &print_help as &dyn Fn()),
1308+
(zhelp_pos, &describe_unstable_flags),
1309+
(chelp_pos, &describe_codegen_flags),
1310+
];
1311+
helps.sort_by_key(|(pos, _)| pos.clone());
1312+
let mut printed_any = false;
1313+
for printer in helps.iter().filter_map(|(pos, func)| pos.is_some().then_some(func)) {
1314+
printer();
1315+
printed_any = true;
1316+
}
1317+
printed_any
12581318
}
12591319

12601320
/// Warn if `-o` is used without a space between the flag name and the value

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,9 @@ pub enum AttributeKind {
852852
/// Represents `#[no_link]`
853853
NoLink,
854854

855+
/// Represents `#[no_main]`
856+
NoMain,
857+
855858
/// Represents `#[no_mangle]`
856859
NoMangle(Span),
857860

compiler/rustc_hir/src/attrs/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ impl AttributeKind {
7979
NoCore(..) => No,
8080
NoImplicitPrelude(..) => No,
8181
NoLink => No,
82+
NoMain => No,
8283
NoMangle(..) => Yes, // Needed for rustdoc
8384
NoStd(..) => No,
8485
NonExhaustive(..) => Yes, // Needed for rustdoc

compiler/rustc_passes/src/check_attr.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
297297
| AttributeKind::PatternComplexityLimit { .. }
298298
| AttributeKind::NoCore { .. }
299299
| AttributeKind::NoStd { .. }
300+
| AttributeKind::NoMain
300301
| AttributeKind::ObjcClass { .. }
301302
| AttributeKind::ObjcSelector { .. }
302303
| AttributeKind::RustcCoherenceIsCore(..)
@@ -389,13 +390,25 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
389390
| sym::rustc_partition_reused
390391
| sym::rustc_partition_codegened
391392
| sym::rustc_expected_cgu_reuse
392-
| sym::rustc_nounwind,
393+
| sym::rustc_nounwind
394+
// crate-level attrs, are checked below
395+
| sym::feature
396+
| sym::register_tool
397+
| sym::rustc_no_implicit_bounds
398+
| sym::test_runner
399+
| sym::reexport_test_harness_main
400+
| sym::no_main
401+
| sym::no_builtins
402+
| sym::crate_type
403+
| sym::compiler_builtins
404+
| sym::profiler_runtime
405+
| sym::needs_panic_runtime
406+
| sym::panic_runtime
407+
| sym::rustc_preserve_ub_checks,
393408
..
394409
] => {}
395410
[name, rest@..] => {
396411
match BUILTIN_ATTRIBUTE_MAP.get(name) {
397-
// checked below
398-
Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {}
399412
Some(_) => {
400413
if rest.len() > 0 && AttributeParser::<Late>::is_parsed_attribute(slice::from_ref(name)) {
401414
// Check if we tried to use a builtin attribute as an attribute namespace, like `#[must_use::skip]`.

compiler/rustc_passes/src/entry.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use rustc_ast::attr;
21
use rustc_ast::entry::EntryPointType;
32
use rustc_errors::codes::*;
43
use rustc_hir::attrs::AttributeKind;
@@ -7,7 +6,7 @@ use rustc_hir::{CRATE_HIR_ID, ItemId, Node, find_attr};
76
use rustc_middle::query::Providers;
87
use rustc_middle::ty::TyCtxt;
98
use rustc_session::config::{CrateType, EntryFnType, sigpipe};
10-
use rustc_span::{RemapPathScopeComponents, Span, sym};
9+
use rustc_span::{RemapPathScopeComponents, Span};
1110

1211
use crate::errors::{ExternMain, MultipleRustcMain, NoMainErr};
1312

@@ -30,7 +29,7 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
3029
}
3130

3231
// If the user wants no main function at all, then stop here.
33-
if attr::contains_name(tcx.hir_attrs(CRATE_HIR_ID), sym::no_main) {
32+
if find_attr!(tcx.hir_attrs(CRATE_HIR_ID), AttributeKind::NoMain) {
3433
return None;
3534
}
3635

compiler/rustc_resolve/src/imports.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
989989
PathResult::Module(module) => {
990990
// Consistency checks, analogous to `finalize_macro_resolutions`.
991991
if let Some(initial_module) = import.imported_module.get() {
992-
if module != initial_module && no_ambiguity {
992+
if module != initial_module && no_ambiguity && !self.issue_145575_hack_applied {
993993
span_bug!(import.span, "inconsistent resolution for an import");
994994
}
995995
} else if self.privacy_errors.is_empty() {

compiler/rustc_session/src/options.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2126,6 +2126,7 @@ options! {
21262126
#[rustc_lint_opt_deny_field_access("use `Session::must_emit_unwind_tables` instead of this field")]
21272127
force_unwind_tables: Option<bool> = (None, parse_opt_bool, [TRACKED],
21282128
"force use of unwind tables"),
2129+
help: bool = (false, parse_no_value, [UNTRACKED], "Print codegen options"),
21292130
incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
21302131
"enable incremental compilation"),
21312132
#[rustc_lint_opt_deny_field_access("documented to do nothing")]
@@ -2398,6 +2399,7 @@ options! {
23982399
environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"),
23992400
has_thread_local: Option<bool> = (None, parse_opt_bool, [TRACKED],
24002401
"explicitly enable the `cfg(target_thread_local)` directive"),
2402+
help: bool = (false, parse_no_value, [UNTRACKED], "Print unstable compiler options"),
24012403
higher_ranked_assumptions: bool = (false, parse_bool, [TRACKED],
24022404
"allow deducing higher-ranked outlives assumptions from coroutines when proving auto traits"),
24032405
hint_mostly_unused: bool = (false, parse_bool, [TRACKED],

0 commit comments

Comments
 (0)