Rollup merge of #151321 - no_main-attr, r=JonathanBrouwer

Port #![no_main] to the attribute parser.

Tracking issue: https://github.com/rust-lang/rust/issues/131229

r? @JonathanBrouwer
This commit is contained in:
Jonathan Brouwer 2026-01-18 18:26:06 +01:00 committed by GitHub
commit 3c2c533d2e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 96 additions and 73 deletions

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

@ -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(..)

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

@ -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
|