diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs index 5604fbd25edcd..ab99186777f92 100644 --- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs +++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs @@ -136,6 +136,15 @@ impl NoArgsAttributeParser for NoStdParser { const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoStd; } +pub(crate) struct NoMainParser; + +impl NoArgsAttributeParser for NoMainParser { + const PATH: &[Symbol] = &[sym::no_main]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::NoMain; +} + pub(crate) struct RustcCoherenceIsCoreParser; impl NoArgsAttributeParser for RustcCoherenceIsCoreParser { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 449894f7834bc..c5b98139074ec 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -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>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 7b7fae9fdcca8..119bf554b2ae3 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -852,6 +852,9 @@ pub enum AttributeKind { /// Represents `#[no_link]` NoLink, + /// Represents `#[no_main]` + NoMain, + /// Represents `#[no_mangle]` NoMangle(Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index dff8a57277714..7ba268c16271a 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -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 diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4b71d4755cb6c..50e80cabdb070 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -297,6 +297,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::PatternComplexityLimit { .. } | AttributeKind::NoCore { .. } | AttributeKind::NoStd { .. } + | AttributeKind::NoMain | AttributeKind::ObjcClass { .. } | AttributeKind::ObjcSelector { .. } | AttributeKind::RustcCoherenceIsCore(..) diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index c02a01c1b8235..bd737518ed479 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -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; } diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs index 6716e78a7197a..3e3235e658f68 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs @@ -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] diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr index 8ed39a0079ba5..d89aec222be8e 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr @@ -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 |