Auto merge of #151325 - JonathanBrouwer:rollup-YoCcqTr, r=JonathanBrouwer

Rollup of 7 pull requests

Successful merges:

 - rust-lang/rust#150767 (Allow invoking all help options at once)
 - rust-lang/rust#150886 (Added mGCA related tests)
 - rust-lang/rust#151245 (Explicitly list crate level attrs)
 - rust-lang/rust#151268 (Fix ICE on inconsistent import resolution with macro-attributed extern crate)
 - rust-lang/rust#151275 (Normalize type_const items even with feature `generic_const_exprs`)
 - rust-lang/rust#151288 (Use `find_attr` instead of `attr::contains_name` in `lower_const_item_rhs`)
 - rust-lang/rust#151321 (Port #![no_main] to the attribute parser.)

r? @ghost
This commit is contained in:
bors 2026-01-18 18:08:26 +00:00
commit 0a3cd3b6b6
30 changed files with 440 additions and 95 deletions

View file

@ -2384,7 +2384,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
Some(ConstItemRhs::TypeConst(anon)) => {
hir::ConstItemRhs::TypeConst(self.lower_anon_const_to_const_arg_and_alloc(anon))
}
None if attr::contains_name(attrs, sym::type_const) => {
None if find_attr!(attrs, AttributeKind::TypeConst(_)) => {
let const_arg = ConstArg {
hir_id: self.next_id(),
kind: hir::ConstArgKind::Error(

View file

@ -136,6 +136,15 @@ impl<S: Stage> NoArgsAttributeParser<S> for NoStdParser {
const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoStd;
}
pub(crate) struct NoMainParser;
impl<S: Stage> NoArgsAttributeParser<S> for NoMainParser {
const PATH: &[Symbol] = &[sym::no_main];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoMain;
}
pub(crate) struct RustcCoherenceIsCoreParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcCoherenceIsCoreParser {

View file

@ -28,9 +28,9 @@ use crate::attributes::codegen_attrs::{
};
use crate::attributes::confusables::ConfusablesParser;
use crate::attributes::crate_level::{
CrateNameParser, MoveSizeLimitParser, NoCoreParser, NoStdParser, PatternComplexityLimitParser,
RecursionLimitParser, RustcCoherenceIsCoreParser, TypeLengthLimitParser,
WindowsSubsystemParser,
CrateNameParser, MoveSizeLimitParser, NoCoreParser, NoMainParser, NoStdParser,
PatternComplexityLimitParser, RecursionLimitParser, RustcCoherenceIsCoreParser,
TypeLengthLimitParser, WindowsSubsystemParser,
};
use crate::attributes::debugger::DebuggerViualizerParser;
use crate::attributes::deprecation::DeprecationParser;
@ -263,6 +263,7 @@ attribute_parsers!(
Single<WithoutArgs<NoCoreParser>>,
Single<WithoutArgs<NoImplicitPreludeParser>>,
Single<WithoutArgs<NoLinkParser>>,
Single<WithoutArgs<NoMainParser>>,
Single<WithoutArgs<NoMangleParser>>,
Single<WithoutArgs<NoStdParser>>,
Single<WithoutArgs<NonExhaustiveParser>>,

View file

@ -228,8 +228,10 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
let args = args::arg_expand_all(&default_early_dcx, at_args);
let Some(matches) = handle_options(&default_early_dcx, &args) else {
return;
let (matches, help_only) = match handle_options(&default_early_dcx, &args) {
HandledOptions::None => return,
HandledOptions::Normal(matches) => (matches, false),
HandledOptions::HelpOnly(matches) => (matches, true),
};
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))
return early_exit();
}
// We have now handled all help options, exit
if help_only {
return early_exit();
}
if print_crate_info(codegen_backend, sess, has_input) == Compilation::Stop {
return early_exit();
}
@ -1097,7 +1104,7 @@ pub fn describe_flag_categories(early_dcx: &EarlyDiagCtxt, matches: &Matches) ->
// Don't handle -W help here, because we might first load additional lints.
let debug_flags = matches.opt_strs("Z");
if debug_flags.iter().any(|x| *x == "help") {
describe_debug_flags();
describe_unstable_flags();
return true;
}
@ -1137,8 +1144,8 @@ fn get_backend_from_raw_matches(
get_codegen_backend(early_dcx, &sysroot, backend_name, &target)
}
fn describe_debug_flags() {
safe_println!("\nAvailable options:\n");
fn describe_unstable_flags() {
safe_println!("\nAvailable unstable options:\n");
print_flag_list("-Z", config::Z_OPTIONS);
}
@ -1162,6 +1169,16 @@ fn print_flag_list<T>(cmdline_opt: &str, flag_list: &[OptionDesc<T>]) {
}
}
pub enum HandledOptions {
/// Parsing failed, or we parsed a flag causing an early exit
None,
/// Successful parsing
Normal(getopts::Matches),
/// Parsing succeeded, but we received one or more 'help' flags
/// The compiler should proceed only until a possible `-W help` flag has been processed
HelpOnly(getopts::Matches),
}
/// Process command line options. Emits messages as appropriate. If compilation
/// should continue, returns a getopts::Matches object parsed from args,
/// otherwise returns `None`.
@ -1189,7 +1206,7 @@ fn print_flag_list<T>(cmdline_opt: &str, flag_list: &[OptionDesc<T>]) {
/// This does not need to be `pub` for rustc itself, but @chaosite needs it to
/// be public when using rustc as a library, see
/// <https://github.com/rust-lang/rust/commit/2b4c33817a5aaecabf4c6598d41e190080ec119e>
pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<getopts::Matches> {
pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> HandledOptions {
// Parse with *all* options defined in the compiler, we don't worry about
// option stability here we just want to parse as much as possible.
let mut options = getopts::Options::new();
@ -1235,26 +1252,69 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
// (unstable option being used on stable)
nightly_options::check_nightly_options(early_dcx, &matches, &config::rustc_optgroups());
if args.is_empty() || matches.opt_present("h") || matches.opt_present("help") {
// Only show unstable options in --help if we accept unstable options.
let unstable_enabled = nightly_options::is_unstable_enabled(&matches);
let nightly_build = nightly_options::match_is_nightly_build(&matches);
usage(matches.opt_present("verbose"), unstable_enabled, nightly_build);
return None;
// Handle the special case of -Wall.
let wall = matches.opt_strs("W");
if wall.iter().any(|x| *x == "all") {
print_wall_help();
return HandledOptions::None;
}
if describe_flag_categories(early_dcx, &matches) {
return None;
if handle_help(&matches, args) {
return HandledOptions::HelpOnly(matches);
}
if matches.opt_strs("C").iter().any(|x| x == "passes=list") {
get_backend_from_raw_matches(early_dcx, &matches).print_passes();
return HandledOptions::None;
}
if matches.opt_present("version") {
version!(early_dcx, "rustc", &matches);
return None;
return HandledOptions::None;
}
warn_on_confusing_output_filename_flag(early_dcx, &matches, args);
Some(matches)
HandledOptions::Normal(matches)
}
/// Handle help options in the order they are provided, ignoring other flags. Returns if any options were handled
/// Handled options:
/// - `-h`/`--help`/empty arguments
/// - `-Z help`
/// - `-C help`
/// NOTE: `-W help` is NOT handled here, as additional lints may be loaded.
pub fn handle_help(matches: &getopts::Matches, args: &[String]) -> bool {
let opt_pos = |opt| matches.opt_positions(opt).first().copied();
let opt_help_pos = |opt| {
matches
.opt_strs_pos(opt)
.iter()
.filter_map(|(pos, oval)| if oval == "help" { Some(*pos) } else { None })
.next()
};
let help_pos = if args.is_empty() { Some(0) } else { opt_pos("h").or_else(|| opt_pos("help")) };
let zhelp_pos = opt_help_pos("Z");
let chelp_pos = opt_help_pos("C");
let print_help = || {
// Only show unstable options in --help if we accept unstable options.
let unstable_enabled = nightly_options::is_unstable_enabled(&matches);
let nightly_build = nightly_options::match_is_nightly_build(&matches);
usage(matches.opt_present("verbose"), unstable_enabled, nightly_build);
};
let mut helps = [
(help_pos, &print_help as &dyn Fn()),
(zhelp_pos, &describe_unstable_flags),
(chelp_pos, &describe_codegen_flags),
];
helps.sort_by_key(|(pos, _)| pos.clone());
let mut printed_any = false;
for printer in helps.iter().filter_map(|(pos, func)| pos.is_some().then_some(func)) {
printer();
printed_any = true;
}
printed_any
}
/// Warn if `-o` is used without a space between the flag name and the value

View file

@ -852,6 +852,9 @@ pub enum AttributeKind {
/// Represents `#[no_link]`
NoLink,
/// Represents `#[no_main]`
NoMain,
/// Represents `#[no_mangle]`
NoMangle(Span),

View file

@ -79,6 +79,7 @@ impl AttributeKind {
NoCore(..) => No,
NoImplicitPrelude(..) => No,
NoLink => No,
NoMain => No,
NoMangle(..) => Yes, // Needed for rustdoc
NoStd(..) => No,
NonExhaustive(..) => Yes, // Needed for rustdoc

View file

@ -297,6 +297,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::PatternComplexityLimit { .. }
| AttributeKind::NoCore { .. }
| AttributeKind::NoStd { .. }
| AttributeKind::NoMain
| AttributeKind::ObjcClass { .. }
| AttributeKind::ObjcSelector { .. }
| AttributeKind::RustcCoherenceIsCore(..)
@ -389,13 +390,25 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::rustc_partition_reused
| sym::rustc_partition_codegened
| sym::rustc_expected_cgu_reuse
| sym::rustc_nounwind,
| sym::rustc_nounwind
// crate-level attrs, are checked below
| sym::feature
| sym::register_tool
| sym::rustc_no_implicit_bounds
| sym::test_runner
| sym::reexport_test_harness_main
| sym::no_main
| sym::no_builtins
| sym::crate_type
| sym::compiler_builtins
| sym::profiler_runtime
| sym::needs_panic_runtime
| sym::panic_runtime
| sym::rustc_preserve_ub_checks,
..
] => {}
[name, rest@..] => {
match BUILTIN_ATTRIBUTE_MAP.get(name) {
// checked below
Some(BuiltinAttribute { type_: AttributeType::CrateLevel, .. }) => {}
Some(_) => {
if rest.len() > 0 && AttributeParser::<Late>::is_parsed_attribute(slice::from_ref(name)) {
// Check if we tried to use a builtin attribute as an attribute namespace, like `#[must_use::skip]`.

View file

@ -1,4 +1,3 @@
use rustc_ast::attr;
use rustc_ast::entry::EntryPointType;
use rustc_errors::codes::*;
use rustc_hir::attrs::AttributeKind;
@ -7,7 +6,7 @@ use rustc_hir::{CRATE_HIR_ID, ItemId, Node, find_attr};
use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{CrateType, EntryFnType, sigpipe};
use rustc_span::{RemapPathScopeComponents, Span, sym};
use rustc_span::{RemapPathScopeComponents, Span};
use crate::errors::{ExternMain, MultipleRustcMain, NoMainErr};
@ -30,7 +29,7 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
}
// If the user wants no main function at all, then stop here.
if attr::contains_name(tcx.hir_attrs(CRATE_HIR_ID), sym::no_main) {
if find_attr!(tcx.hir_attrs(CRATE_HIR_ID), AttributeKind::NoMain) {
return None;
}

View file

@ -989,7 +989,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
PathResult::Module(module) => {
// Consistency checks, analogous to `finalize_macro_resolutions`.
if let Some(initial_module) = import.imported_module.get() {
if module != initial_module && no_ambiguity {
if module != initial_module && no_ambiguity && !self.issue_145575_hack_applied {
span_bug!(import.span, "inconsistent resolution for an import");
}
} else if self.privacy_errors.is_empty() {

View file

@ -2126,6 +2126,7 @@ options! {
#[rustc_lint_opt_deny_field_access("use `Session::must_emit_unwind_tables` instead of this field")]
force_unwind_tables: Option<bool> = (None, parse_opt_bool, [TRACKED],
"force use of unwind tables"),
help: bool = (false, parse_no_value, [UNTRACKED], "Print codegen options"),
incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
"enable incremental compilation"),
#[rustc_lint_opt_deny_field_access("documented to do nothing")]
@ -2398,6 +2399,7 @@ options! {
environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"),
has_thread_local: Option<bool> = (None, parse_opt_bool, [TRACKED],
"explicitly enable the `cfg(target_thread_local)` directive"),
help: bool = (false, parse_no_value, [UNTRACKED], "Print unstable compiler options"),
higher_ranked_assumptions: bool = (false, parse_bool, [TRACKED],
"allow deducing higher-ranked outlives assumptions from coroutines when proving auto traits"),
hint_mostly_unused: bool = (false, parse_bool, [TRACKED],

View file

@ -433,7 +433,12 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
#[instrument(skip(self), level = "debug")]
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
let tcx = self.selcx.tcx();
if tcx.features().generic_const_exprs() || !needs_normalization(self.selcx.infcx, &ct) {
if tcx.features().generic_const_exprs()
// Normalize type_const items even with feature `generic_const_exprs`.
&& !matches!(ct.kind(), ty::ConstKind::Unevaluated(uv) if tcx.is_type_const(uv.def))
|| !needs_normalization(self.selcx.infcx, &ct)
{
return ct;
}

View file

@ -1,4 +1,6 @@
//@ known-bug: #138089
//@ needs-rustc-debug-assertions
#![feature(generic_const_exprs)]
#![feature(min_generic_const_args)]
#![feature(inherent_associated_types)]

13
tests/crashes/138226-2.rs Normal file
View file

@ -0,0 +1,13 @@
//@ known-bug: #138226
//@ needs-rustc-debug-assertions
#![feature(min_generic_const_args)]
#![feature(inherent_associated_types)]
struct Bar<const N: usize>;
impl<const N: usize> Bar<N> {
#[type_const]
const LEN: usize = 4;
fn bar() {
let _ = [0; Self::LEN];
}
}

13
tests/crashes/138226.rs Normal file
View file

@ -0,0 +1,13 @@
//@ known-bug: #138226
//@ needs-rustc-debug-assertions
#![feature(min_generic_const_args)]
#![feature(inherent_associated_types)]
struct Foo<A, B>(A, B);
impl<A, B> Foo<A, B> {
#[type_const]
const LEN: usize = 4;
fn foo() {
let _ = [5; Self::LEN];
}
}

13
tests/crashes/149809.rs Normal file
View file

@ -0,0 +1,13 @@
//@ known-bug: #149809
#![feature(min_generic_const_args)]
#![feature(inherent_associated_types)]
struct Qux<'a> {
x: &'a (),
}
impl<'a> Qux<'a> {
#[type_const]
const LEN: usize = 4;
fn foo(_: [u8; Qux::LEN]) {}
}
fn main() {}

11
tests/crashes/150960.rs Normal file
View file

@ -0,0 +1,11 @@
//@ known-bug: #150960
#![feature(min_generic_const_args)]
struct Baz;
impl Baz {
#[type_const]
const LEN: usize = 4;
fn baz() {
let _ = [0; const { Self::LEN }];
}
}

View file

@ -18,4 +18,34 @@ fn main() {
// Check the diff between `rustc --help` and `rustc --help -v`.
let help_v_diff = similar::TextDiff::from_lines(&help, &help_v).unified_diff().to_string();
diff().expected_file("help-v.diff").actual_text("actual", &help_v_diff).run();
// Check that all help options can be invoked at once
let codegen_help = bare_rustc().arg("-Chelp").run().stdout_utf8();
let unstable_help = bare_rustc().arg("-Zhelp").run().stdout_utf8();
let lints_help = bare_rustc().arg("-Whelp").run().stdout_utf8();
let expected_all = format!("{help}{codegen_help}{unstable_help}{lints_help}");
let all_help = bare_rustc().args(["--help", "-Chelp", "-Zhelp", "-Whelp"]).run().stdout_utf8();
diff()
.expected_text(
"(rustc --help && rustc -Chelp && rustc -Zhelp && rustc -Whelp)",
&expected_all,
)
.actual_text("(rustc --help -Chelp -Zhelp -Whelp)", &all_help)
.run();
// Check that the ordering of help options is respected
// Note that this is except for `-Whelp`, which always comes last
let expected_ordered_help = format!("{unstable_help}{codegen_help}{help}{lints_help}");
let ordered_help =
bare_rustc().args(["-Whelp", "-Zhelp", "-Chelp", "--help"]).run().stdout_utf8();
diff()
.expected_text(
"(rustc -Whelp && rustc -Zhelp && rustc -Chelp && rustc --help)",
&expected_ordered_help,
)
.actual_text("(rustc -Whelp -Zhelp -Chelp --help)", &ordered_help)
.run();
// Test that `rustc --help` does not suppress invalid flag errors
let help = bare_rustc().arg("--help --invalid-flag").run_fail().stdout_utf8();
}

View file

@ -0,0 +1,27 @@
//! regression test for <https://github.com/rust-lang/rust/issues/141014>
//@ run-pass
#![expect(incomplete_features)]
#![feature(min_generic_const_args)]
#![allow(dead_code)]
trait Abc {}
trait A {
#[type_const]
const VALUE: usize;
}
impl<T: Abc> A for T {
#[type_const]
const VALUE: usize = 0;
}
trait S<const K: usize> {}
trait Handler<T: Abc>
where
(): S<{ <T as A>::VALUE }>,
{
}
fn main() {}

View file

@ -0,0 +1,11 @@
//@ needs-rustc-debug-assertions
#![feature(min_generic_const_args)]
#![feature(generic_const_exprs)]
#![expect(incomplete_features)]
#[type_const]
const A: u8 = A;
//~^ ERROR overflow normalizing the unevaluated constant `A`
fn main() {}

View file

@ -0,0 +1,11 @@
error[E0275]: overflow normalizing the unevaluated constant `A`
--> $DIR/cyclic-type-const-151251.rs:8:1
|
LL | const A: u8 = A;
| ^^^^^^^^^^^
|
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0275`.

View file

@ -0,0 +1,12 @@
//! regression test for <https://github.com/rust-lang/rust/issues/147415>
#![expect(incomplete_features)]
#![feature(min_generic_const_args)]
fn foo<T>() {
[0; size_of::<*mut T>()];
//~^ ERROR: tuple constructor with invalid base path
[0; const { size_of::<*mut T>() }];
//~^ ERROR: generic parameters may not be used in const operations
}
fn main() {}

View file

@ -0,0 +1,14 @@
error: tuple constructor with invalid base path
--> $DIR/size-of-generic-ptr-in-array-len.rs:6:9
|
LL | [0; size_of::<*mut T>()];
| ^^^^^^^^^^^^^^^^^^^
error: generic parameters may not be used in const operations
--> $DIR/size-of-generic-ptr-in-array-len.rs:8:32
|
LL | [0; const { size_of::<*mut T>() }];
| ^
error: aborting due to 2 previous errors

View file

@ -0,0 +1,19 @@
//@ needs-rustc-debug-assertions
#![feature(min_generic_const_args)]
#![expect(incomplete_features)]
trait Tr {
#[type_const]
const SIZE: usize;
}
struct T;
impl Tr for T {
#[type_const]
const SIZE: usize;
//~^ ERROR associated constant in `impl` without body
}
fn main() {}

View file

@ -0,0 +1,10 @@
error: associated constant in `impl` without body
--> $DIR/type-const-assoc-const-without-body.rs:15:5
|
LL | const SIZE: usize;
| ^^^^^^^^^^^^^^^^^-
| |
| help: provide a definition for the constant: `= <expr>;`
error: aborting due to 1 previous error

View file

@ -0,0 +1,12 @@
//@ needs-rustc-debug-assertions
#![feature(min_generic_const_args)]
#![expect(incomplete_features)]
impl S { //~ ERROR cannot find type `S` in this scope
#[type_const]
const SIZE: usize;
//~^ ERROR associated constant in `impl` without body
}
fn main() {}

View file

@ -0,0 +1,17 @@
error: associated constant in `impl` without body
--> $DIR/type-const-inherent-assoc-const-without-body.rs:8:5
|
LL | const SIZE: usize;
| ^^^^^^^^^^^^^^^^^-
| |
| help: provide a definition for the constant: `= <expr>;`
error[E0425]: cannot find type `S` in this scope
--> $DIR/type-const-inherent-assoc-const-without-body.rs:6:6
|
LL | impl S {
| ^ not found in this scope
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0425`.

View file

@ -884,26 +884,26 @@ mod feature {
#[no_main]
//~^ WARN crate-level attribute should be an inner attribute
//~| HELP add a `!`
mod no_main_1 {
//~^ NOTE: This attribute does not have an `!`, which means it is applied to this module
mod inner { #![no_main] }
//~^ WARN crate-level attribute should be in the root module
//~^ WARN the `#![no_main]` attribute can only be used at the crate root
#[no_main] fn f() { }
//~^ WARN crate-level attribute should be an inner attribute
//~| HELP add a `!`
//~| NOTE This attribute does not have an `!`, which means it is applied to this function
#[no_main] struct S;
//~^ WARN crate-level attribute should be an inner attribute
//~| HELP add a `!`
//~| NOTE This attribute does not have an `!`, which means it is applied to this struct
#[no_main] type T = S;
//~^ WARN crate-level attribute should be an inner attribute
//~| HELP add a `!`
//~| NOTE This attribute does not have an `!`, which means it is applied to this type alias
#[no_main] impl S { }
//~^ WARN crate-level attribute should be an inner attribute
//~| HELP add a `!`
//~| NOTE This attribute does not have an `!`, which means it is applied to this implementation
}
#[no_builtins]

View file

@ -240,17 +240,6 @@ help: add a `!`
LL | #![feature(x0600)]
| +
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:885:1
|
LL | #[no_main]
| ^^^^^^^^^^
|
help: add a `!`
|
LL | #![no_main]
| +
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:909:1
|
@ -476,56 +465,6 @@ help: add a `!`
LL | #![feature(x0600)] impl S { }
| +
warning: crate-level attribute should be in the root module
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:889:17
|
LL | mod inner { #![no_main] }
| ^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:892:5
|
LL | #[no_main] fn f() { }
| ^^^^^^^^^^
|
help: add a `!`
|
LL | #![no_main] fn f() { }
| +
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:896:5
|
LL | #[no_main] struct S;
| ^^^^^^^^^^
|
help: add a `!`
|
LL | #![no_main] struct S;
| +
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:900:5
|
LL | #[no_main] type T = S;
| ^^^^^^^^^^
|
help: add a `!`
|
LL | #![no_main] type T = S;
| +
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:904:5
|
LL | #[no_main] impl S { }
| ^^^^^^^^^^
|
help: add a `!`
|
LL | #![no_main] impl S { }
| +
warning: crate-level attribute should be in the root module
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:913:17
|
@ -1407,6 +1346,76 @@ note: This attribute does not have an `!`, which means it is applied to this imp
LL | #[crate_name = "0900"] impl S { }
| ^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:885:1
|
LL | #[no_main]
| ^^^^^^^^^^
|
note: This attribute does not have an `!`, which means it is applied to this module
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:887:1
|
LL | / mod no_main_1 {
LL | |
LL | | mod inner { #![no_main] }
... |
LL | | }
| |_^
warning: the `#![no_main]` attribute can only be used at the crate root
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:889:17
|
LL | mod inner { #![no_main] }
| ^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:892:5
|
LL | #[no_main] fn f() { }
| ^^^^^^^^^^
|
note: This attribute does not have an `!`, which means it is applied to this function
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:892:16
|
LL | #[no_main] fn f() { }
| ^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:896:5
|
LL | #[no_main] struct S;
| ^^^^^^^^^^
|
note: This attribute does not have an `!`, which means it is applied to this struct
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:896:16
|
LL | #[no_main] struct S;
| ^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:900:5
|
LL | #[no_main] type T = S;
| ^^^^^^^^^^
|
note: This attribute does not have an `!`, which means it is applied to this type alias
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:900:16
|
LL | #[no_main] type T = S;
| ^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_main]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:904:5
|
LL | #[no_main] impl S { }
| ^^^^^^^^^^
|
note: This attribute does not have an `!`, which means it is applied to this implementation block
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:904:16
|
LL | #[no_main] impl S { }
| ^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![recursion_limit]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:933:1
|

View file

@ -0,0 +1,14 @@
//@ edition: 2024
#[attr]
//~^ ERROR cannot find attribute `attr` in this scope
extern crate core as std;
//~^ ERROR macro-expanded `extern crate` items cannot shadow names passed with `--extern`
mod inner {
use std::str;
use crate::*;
}
fn main() {}

View file

@ -0,0 +1,14 @@
error: macro-expanded `extern crate` items cannot shadow names passed with `--extern`
--> $DIR/ice-inconsistent-resolution-151213.rs:5:1
|
LL | extern crate core as std;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: cannot find attribute `attr` in this scope
--> $DIR/ice-inconsistent-resolution-151213.rs:3:3
|
LL | #[attr]
| ^^^^
error: aborting due to 2 previous errors