convert rustc_main to the new attribute parsing infrastructure

This commit is contained in:
Jana Dönszelmann
2025-10-14 16:25:39 +02:00
parent 956f47c32f
commit 047c37cf23
12 changed files with 74 additions and 97 deletions

View File

@@ -1,7 +1,5 @@
use rustc_span::{Symbol, sym};
use crate::attr::{self, AttributeExt};
#[derive(Debug)]
pub enum EntryPointType {
/// This function is not an entrypoint.
@@ -30,11 +28,11 @@ pub enum EntryPointType {
}
pub fn entry_point_type(
attrs: &[impl AttributeExt],
has_rustc_main: bool,
at_root: bool,
name: Option<Symbol>,
) -> EntryPointType {
if attr::contains_name(attrs, sym::rustc_main) {
if has_rustc_main {
EntryPointType::RustcMainAttr
} else if let Some(name) = name
&& name == sym::main

View File

@@ -1,9 +1,18 @@
use super::prelude::*;
use super::util::parse_single_integer;
pub(crate) struct RustcLayoutScalarValidRangeStart;
pub(crate) struct RustcMainParser;
impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeStart {
impl<S: Stage> NoArgsAttributeParser<S> for RustcMainParser {
const PATH: &'static [Symbol] = &[sym::rustc_main];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcMain;
}
pub(crate) struct RustcLayoutScalarValidRangeStartParser;
impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeStartParser {
const PATH: &'static [Symbol] = &[sym::rustc_layout_scalar_valid_range_start];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
@@ -16,9 +25,9 @@ impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeStart {
}
}
pub(crate) struct RustcLayoutScalarValidRangeEnd;
pub(crate) struct RustcLayoutScalarValidRangeEndParser;
impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeEnd {
impl<S: Stage> SingleAttributeParser<S> for RustcLayoutScalarValidRangeEndParser {
const PATH: &'static [Symbol] = &[sym::rustc_layout_scalar_valid_range_end];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;

View File

@@ -53,7 +53,7 @@ use crate::attributes::proc_macro_attrs::{
use crate::attributes::prototype::CustomMirParser;
use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
use crate::attributes::rustc_internal::{
RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart,
RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, RustcMainParser,
RustcObjectLifetimeDefaultParser, RustcSimdMonomorphizeLaneLimitParser,
};
use crate::attributes::semantics::MayDangleParser;
@@ -197,8 +197,8 @@ attribute_parsers!(
Single<RecursionLimitParser>,
Single<RustcBuiltinMacroParser>,
Single<RustcForceInlineParser>,
Single<RustcLayoutScalarValidRangeEnd>,
Single<RustcLayoutScalarValidRangeStart>,
Single<RustcLayoutScalarValidRangeEndParser>,
Single<RustcLayoutScalarValidRangeStartParser>,
Single<RustcObjectLifetimeDefaultParser>,
Single<RustcSimdMonomorphizeLaneLimitParser>,
Single<SanitizeParser>,
@@ -238,6 +238,7 @@ attribute_parsers!(
Single<WithoutArgs<ProcMacroParser>>,
Single<WithoutArgs<PubTransparentParser>>,
Single<WithoutArgs<RustcCoherenceIsCoreParser>>,
Single<WithoutArgs<RustcMainParser>>,
Single<WithoutArgs<SpecializationTraitParser>>,
Single<WithoutArgs<StdInternalSymbolParser>>,
Single<WithoutArgs<TrackCallerParser>>,

View File

@@ -3,6 +3,7 @@
use std::mem;
use rustc_ast as ast;
use rustc_ast::attr::contains_name;
use rustc_ast::entry::EntryPointType;
use rustc_ast::mut_visit::*;
use rustc_ast::visit::Visitor;
@@ -172,9 +173,11 @@ impl<'a> Visitor<'a> for InnerItemLinter<'_> {
fn entry_point_type(item: &ast::Item, at_root: bool) -> EntryPointType {
match &item.kind {
ast::ItemKind::Fn(fn_) => {
rustc_ast::entry::entry_point_type(&item.attrs, at_root, Some(fn_.ident.name))
}
ast::ItemKind::Fn(fn_) => rustc_ast::entry::entry_point_type(
contains_name(&item.attrs, sym::rustc_main),
at_root,
Some(fn_.ident.name),
),
_ => EntryPointType::None,
}
}

View File

@@ -670,6 +670,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_layout_scalar_valid_range_start]`.
RustcLayoutScalarValidRangeStart(Box<u128>, Span),
/// Represents `#[rustc_main]`.
RustcMain,
/// Represents `#[rustc_object_lifetime_default]`.
RustcObjectLifetimeDefault,

View File

@@ -88,6 +88,7 @@ impl AttributeKind {
RustcCoherenceIsCore(..) => No,
RustcLayoutScalarValidRangeEnd(..) => Yes,
RustcLayoutScalarValidRangeStart(..) => Yes,
RustcMain => No,
RustcObjectLifetimeDefault => No,
RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate
Sanitize { .. } => No,

View File

@@ -34,9 +34,6 @@ passes_attr_crate_level =
.suggestion = to apply to the crate, use an inner attribute
.note = read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
passes_attr_only_in_functions =
`{$attr}` attribute can only be used on functions
passes_autodiff_attr =
`#[autodiff]` should be applied to a function
.label = not a function

View File

@@ -283,6 +283,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::ObjcSelector { .. }
| AttributeKind::RustcCoherenceIsCore(..)
| AttributeKind::DebuggerVisualizer(..)
| AttributeKind::RustcMain,
) => { /* do nothing */ }
Attribute::Unparsed(attr_item) => {
style = Some(attr_item.style);
@@ -2395,14 +2396,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
// Check for builtin attributes at the crate level
// which were unsuccessfully resolved due to cannot determine
// resolution for the attribute macro error.
const ATTRS_TO_CHECK: &[Symbol] = &[
sym::rustc_main,
sym::derive,
sym::test,
sym::test_case,
sym::global_allocator,
sym::bench,
];
const ATTRS_TO_CHECK: &[Symbol] =
&[sym::derive, sym::test, sym::test_case, sym::global_allocator, sym::bench];
for attr in attrs {
// FIXME(jdonszelmann): all attrs should be combined here cleaning this up some day.

View File

@@ -1,16 +1,16 @@
use rustc_ast::attr;
use rustc_ast::entry::EntryPointType;
use rustc_errors::codes::*;
use rustc_hir::def::DefKind;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId};
use rustc_hir::{CRATE_HIR_ID, ItemId, Node};
use rustc_hir::{CRATE_HIR_ID, ItemId, Node, find_attr};
use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::RemapFileNameExt;
use rustc_session::config::{CrateType, EntryFnType, RemapPathScopeComponents, sigpipe};
use rustc_span::{Span, Symbol, sym};
use rustc_span::{Span, sym};
use crate::errors::{AttrOnlyInFunctions, ExternMain, MultipleRustcMain, NoMainErr};
use crate::errors::{ExternMain, MultipleRustcMain, NoMainErr};
struct EntryContext<'tcx> {
tcx: TyCtxt<'tcx>,
@@ -44,26 +44,12 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
configure_main(tcx, &ctxt)
}
fn attr_span_by_symbol(ctxt: &EntryContext<'_>, id: ItemId, sym: Symbol) -> Option<Span> {
let attrs = ctxt.tcx.hir_attrs(id.hir_id());
attr::find_by_name(attrs, sym).map(|attr| attr.span())
}
fn check_and_search_item(id: ItemId, ctxt: &mut EntryContext<'_>) {
if !matches!(ctxt.tcx.def_kind(id.owner_id), DefKind::Fn) {
for attr in [sym::rustc_main] {
if let Some(span) = attr_span_by_symbol(ctxt, id, attr) {
ctxt.tcx.dcx().emit_err(AttrOnlyInFunctions { span, attr });
}
}
return;
}
let at_root = ctxt.tcx.opt_local_parent(id.owner_id.def_id) == Some(CRATE_DEF_ID);
let attrs = ctxt.tcx.hir_attrs(id.hir_id());
let entry_point_type = rustc_ast::entry::entry_point_type(
attrs,
find_attr!(attrs, AttributeKind::RustcMain),
at_root,
ctxt.tcx.opt_item_name(id.owner_id.to_def_id()),
);

View File

@@ -843,14 +843,6 @@ pub(crate) struct FeaturePreviouslyDeclared<'a> {
pub prev_declared: &'a str,
}
#[derive(Diagnostic)]
#[diag(passes_attr_only_in_functions)]
pub(crate) struct AttrOnlyInFunctions {
#[primary_span]
pub span: Span,
pub attr: Symbol,
}
#[derive(Diagnostic)]
#[diag(passes_multiple_rustc_main, code = E0137)]
pub(crate) struct MultipleRustcMain {

View File

@@ -10,7 +10,7 @@
#![macro_export]
//~^ ERROR: `#[macro_export]` attribute cannot be used on crates
#![rustc_main]
//~^ ERROR: `rustc_main` attribute cannot be used at crate level
//~^ ERROR: `#[rustc_main]` attribute cannot be used on crates
//~| ERROR: use of an internal attribute [E0658]
//~| NOTE: the `#[rustc_main]` attribute is an internal implementation detail that will never be stable
//~| NOTE: the `#[rustc_main]` attribute is used internally to specify test entry point function
@@ -31,7 +31,6 @@
//~^ ERROR attribute cannot be used on
mod inline {
//~^ NOTE the inner attribute doesn't annotate this module
//~| NOTE the inner attribute doesn't annotate this module
mod inner { #![inline] }
//~^ ERROR attribute cannot be used on

View File

@@ -16,6 +16,14 @@ LL | #![macro_export]
|
= help: `#[macro_export]` can only be applied to macro defs
error: `#[rustc_main]` attribute cannot be used on crates
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1
|
LL | #![rustc_main]
| ^^^^^^^^^^^^^^
|
= help: `#[rustc_main]` can only be applied to functions
error: `#[path]` attribute cannot be used on crates
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:19:1
|
@@ -57,7 +65,7 @@ LL | #[inline]
= help: `#[inline]` can only be applied to functions
error: `#[inline]` attribute cannot be used on modules
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:36:17
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:35:17
|
LL | mod inner { #![inline] }
| ^^^^^^^^^^
@@ -65,7 +73,7 @@ LL | mod inner { #![inline] }
= help: `#[inline]` can only be applied to functions
error: `#[inline]` attribute cannot be used on structs
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:45:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:44:5
|
LL | #[inline] struct S;
| ^^^^^^^^^
@@ -73,7 +81,7 @@ LL | #[inline] struct S;
= help: `#[inline]` can only be applied to functions
error: `#[inline]` attribute cannot be used on type aliases
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:48:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:47:5
|
LL | #[inline] type T = S;
| ^^^^^^^^^
@@ -81,7 +89,7 @@ LL | #[inline] type T = S;
= help: `#[inline]` can only be applied to functions
error: `#[inline]` attribute cannot be used on inherent impl blocks
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:51:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:50:5
|
LL | #[inline] impl S { }
| ^^^^^^^^^
@@ -89,7 +97,7 @@ LL | #[inline] impl S { }
= help: `#[inline]` can only be applied to functions
error: `#[export_name]` attribute cannot be used on modules
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:81:1
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:80:1
|
LL | #[export_name = "2200"]
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -97,7 +105,7 @@ LL | #[export_name = "2200"]
= help: `#[export_name]` can be applied to functions and statics
error: `#[export_name]` attribute cannot be used on modules
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:84:17
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:83:17
|
LL | mod inner { #![export_name="2200"] }
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -105,7 +113,7 @@ LL | mod inner { #![export_name="2200"] }
= help: `#[export_name]` can be applied to functions and statics
error: `#[export_name]` attribute cannot be used on structs
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:89:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:88:5
|
LL | #[export_name = "2200"] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -113,7 +121,7 @@ LL | #[export_name = "2200"] struct S;
= help: `#[export_name]` can be applied to functions and statics
error: `#[export_name]` attribute cannot be used on type aliases
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:92:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:91:5
|
LL | #[export_name = "2200"] type T = S;
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -121,7 +129,7 @@ LL | #[export_name = "2200"] type T = S;
= help: `#[export_name]` can be applied to functions and statics
error: `#[export_name]` attribute cannot be used on inherent impl blocks
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:95:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:94:5
|
LL | #[export_name = "2200"] impl S { }
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -129,7 +137,7 @@ LL | #[export_name = "2200"] impl S { }
= help: `#[export_name]` can be applied to functions and statics
error: `#[export_name]` attribute cannot be used on required trait methods
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:99:9
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:98:9
|
LL | #[export_name = "2200"] fn foo();
| ^^^^^^^^^^^^^^^^^^^^^^^
@@ -137,7 +145,7 @@ LL | #[export_name = "2200"] fn foo();
= help: `#[export_name]` can be applied to functions, inherent methods, provided trait methods, statics, and trait methods in impl blocks
error: attribute should be applied to an `extern crate` item
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:55:1
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:54:1
|
LL | #[no_link]
| ^^^^^^^^^^
@@ -151,7 +159,7 @@ LL | | }
| |_- not an `extern crate` item
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:106:8
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:105:8
|
LL | #[repr(C)]
| ^
@@ -164,7 +172,7 @@ LL | | }
| |_- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:130:8
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:129:8
|
LL | #[repr(Rust)]
| ^^^^
@@ -182,21 +190,6 @@ error: attribute should be applied to an `extern crate` item
LL | #![no_link]
| ^^^^^^^^^^^ not an `extern crate` item
error: `rustc_main` attribute cannot be used at crate level
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1
|
LL | #![rustc_main]
| ^^^^^^^^^^^^^^
...
LL | mod inline {
| ------ the inner attribute doesn't annotate this module
|
help: perhaps you meant to use an outer attribute
|
LL - #![rustc_main]
LL + #[rustc_main]
|
error: `repr` attribute cannot be used at crate level
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:17:1
|
@@ -213,85 +206,85 @@ LL + #[repr()]
|
error: attribute should be applied to an `extern crate` item
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:60:17
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:59:17
|
LL | mod inner { #![no_link] }
| ------------^^^^^^^^^^^-- not an `extern crate` item
error: attribute should be applied to an `extern crate` item
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:64:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:63:5
|
LL | #[no_link] fn f() { }
| ^^^^^^^^^^ ---------- not an `extern crate` item
error: attribute should be applied to an `extern crate` item
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:68:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:67:5
|
LL | #[no_link] struct S;
| ^^^^^^^^^^ --------- not an `extern crate` item
error: attribute should be applied to an `extern crate` item
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:72:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:71:5
|
LL | #[no_link]type T = S;
| ^^^^^^^^^^----------- not an `extern crate` item
error: attribute should be applied to an `extern crate` item
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:76:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:75:5
|
LL | #[no_link] impl S { }
| ^^^^^^^^^^ ---------- not an `extern crate` item
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:110:25
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:109:25
|
LL | mod inner { #![repr(C)] }
| --------------------^---- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:114:12
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:113:12
|
LL | #[repr(C)] fn f() { }
| ^ ---------- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:120:12
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:119:12
|
LL | #[repr(C)] type T = S;
| ^ ----------- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:124:12
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:123:12
|
LL | #[repr(C)] impl S { }
| ^ ---------- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:134:25
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:133:25
|
LL | mod inner { #![repr(Rust)] }
| --------------------^^^^---- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:138:12
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:137:12
|
LL | #[repr(Rust)] fn f() { }
| ^^^^ ---------- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:144:12
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:143:12
|
LL | #[repr(Rust)] type T = S;
| ^^^^ ----------- not a struct, enum, or union
error[E0517]: attribute should be applied to a struct, enum, or union
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:148:12
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:147:12
|
LL | #[repr(Rust)] impl S { }
| ^^^^ ---------- not a struct, enum, or union
error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]`
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:39:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:38:5
|
LL | #[inline = "2100"] fn f() { }
| ^^^^^^^^^^^^^^^^^^
@@ -306,7 +299,7 @@ Some errors have detailed explanations: E0517, E0658.
For more information about an error, try `rustc --explain E0517`.
Future incompatibility report: Future breakage diagnostic:
error: valid forms for the attribute are `#[inline(always)]`, `#[inline(never)]`, and `#[inline]`
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:39:5
--> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:38:5
|
LL | #[inline = "2100"] fn f() { }
| ^^^^^^^^^^^^^^^^^^