Rollup merge of #146389 - jdonszelmann:no-std, r=oli-obk

Convert `no_std` and `no_core` to the new attribute infrastructure

r? ```@oli-obk```

Also added a test for these, since we didn't have any and I was kind of surprised new diagnostics didn't break anything hehe
This commit is contained in:
Jana Dönszelmann 2025-09-13 02:40:44 +02:00 committed by GitHub
commit 147e97ae68
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 241 additions and 91 deletions

View file

@ -176,3 +176,27 @@ impl<S: Stage> SingleAttributeParser<S> for PatternComplexityLimitParser {
})
}
}
pub(crate) struct NoCoreParser;
impl<S: Stage> NoArgsAttributeParser<S> for NoCoreParser {
const PATH: &[Symbol] = &[sym::no_core];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
// because it's a crate-level attribute, we already warn about it.
// Putting target limitations here would give duplicate warnings
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoCore;
const TYPE: AttributeType = AttributeType::CrateLevel;
}
pub(crate) struct NoStdParser;
impl<S: Stage> NoArgsAttributeParser<S> for NoStdParser {
const PATH: &[Symbol] = &[sym::no_std];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
// because it's a crate-level attribute, we already warn about it.
// Putting target limitations here would give duplicate warnings
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoStd;
const TYPE: AttributeType = AttributeType::CrateLevel;
}

View file

@ -25,8 +25,8 @@ use crate::attributes::codegen_attrs::{
};
use crate::attributes::confusables::ConfusablesParser;
use crate::attributes::crate_level::{
CrateNameParser, MoveSizeLimitParser, PatternComplexityLimitParser, RecursionLimitParser,
TypeLengthLimitParser,
CrateNameParser, MoveSizeLimitParser, NoCoreParser, NoStdParser, PatternComplexityLimitParser,
RecursionLimitParser, TypeLengthLimitParser,
};
use crate::attributes::deprecation::DeprecationParser;
use crate::attributes::dummy::DummyParser;
@ -223,8 +223,10 @@ attribute_parsers!(
Single<WithoutArgs<MacroEscapeParser>>,
Single<WithoutArgs<MarkerParser>>,
Single<WithoutArgs<MayDangleParser>>,
Single<WithoutArgs<NoCoreParser>>,
Single<WithoutArgs<NoImplicitPreludeParser>>,
Single<WithoutArgs<NoMangleParser>>,
Single<WithoutArgs<NoStdParser>>,
Single<WithoutArgs<NonExhaustiveParser>>,
Single<WithoutArgs<ParenSugarParser>>,
Single<WithoutArgs<PassByValueParser>>,

View file

@ -579,12 +579,18 @@ pub enum AttributeKind {
/// Represents `#[naked]`
Naked(Span),
/// Represents `#[no_core]`
NoCore(Span),
/// Represents `#[no_implicit_prelude]`
NoImplicitPrelude(Span),
/// Represents `#[no_mangle]`
NoMangle(Span),
/// Represents `#[no_std]`
NoStd(Span),
/// Represents `#[non_exhaustive]`
NonExhaustive(Span),

View file

@ -64,8 +64,10 @@ impl AttributeKind {
MoveSizeLimit { .. } => No,
MustUse { .. } => Yes,
Naked(..) => No,
NoCore(..) => No,
NoImplicitPrelude(..) => No,
NoMangle(..) => Yes, // Needed for rustdoc
NoMangle(..) => Yes, // Needed for rustdoc
NoStd(..) => No,
NonExhaustive(..) => Yes, // Needed for rustdoc
Optimize(..) => No,
ParenSugar(..) => No,

View file

@ -274,6 +274,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::MoveSizeLimit { .. }
| AttributeKind::TypeLengthLimit { .. }
| AttributeKind::PatternComplexityLimit { .. }
| AttributeKind::NoCore { .. }
| AttributeKind::NoStd { .. }
) => { /* do nothing */ }
Attribute::Unparsed(attr_item) => {
style = Some(attr_item.style);

View file

@ -2133,17 +2133,11 @@ pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> {
}
pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool {
cx.tcx
.hir_attrs(hir::CRATE_HIR_ID)
.iter()
.any(|attr| attr.has_name(sym::no_std))
find_attr!(cx.tcx.hir_attrs(hir::CRATE_HIR_ID), AttributeKind::NoStd(..))
}
pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool {
cx.tcx
.hir_attrs(hir::CRATE_HIR_ID)
.iter()
.any(|attr| attr.has_name(sym::no_core))
find_attr!(cx.tcx.hir_attrs(hir::CRATE_HIR_ID), AttributeKind::NoCore(..))
}
/// Check if parent of a hir node is a trait implementation block.

View file

@ -0,0 +1,25 @@
#![feature(no_core)]
// these all still apply no_std and then later error
#![no_std = "foo"]
//~^ ERROR malformed `no_std` attribute input
#![no_std("bar")]
//~^ ERROR malformed `no_std` attribute input
#![no_std(foo = "bar")]
//~^ ERROR malformed `no_std` attribute input
#![no_core = "foo"]
//~^ ERROR malformed `no_core` attribute input
#![no_core("bar")]
//~^ ERROR malformed `no_core` attribute input
#![no_core(foo = "bar")]
//~^ ERROR malformed `no_core` attribute input
#[deny(unused_attributes)]
#[no_std]
//~^ ERROR crate-level attribute should be an inner attribute: add an exclamation mark:
#[no_core]
//~^ ERROR crate-level attribute should be an inner attribute: add an exclamation mark:
// to fix compilation
extern crate core;
extern crate std;
fn main() {}

View file

@ -0,0 +1,86 @@
error[E0565]: malformed `no_std` attribute input
--> $DIR/malformed-no-std.rs:3:1
|
LL | #![no_std = "foo"]
| ^^^^^^^^^^-------^
| | |
| | didn't expect any arguments here
| help: must be of the form: `#![no_std]`
error[E0565]: malformed `no_std` attribute input
--> $DIR/malformed-no-std.rs:5:1
|
LL | #![no_std("bar")]
| ^^^^^^^^^-------^
| | |
| | didn't expect any arguments here
| help: must be of the form: `#![no_std]`
error[E0565]: malformed `no_std` attribute input
--> $DIR/malformed-no-std.rs:7:1
|
LL | #![no_std(foo = "bar")]
| ^^^^^^^^^-------------^
| | |
| | didn't expect any arguments here
| help: must be of the form: `#![no_std]`
error[E0565]: malformed `no_core` attribute input
--> $DIR/malformed-no-std.rs:9:1
|
LL | #![no_core = "foo"]
| ^^^^^^^^^^^-------^
| | |
| | didn't expect any arguments here
| help: must be of the form: `#![no_core]`
error[E0565]: malformed `no_core` attribute input
--> $DIR/malformed-no-std.rs:11:1
|
LL | #![no_core("bar")]
| ^^^^^^^^^^-------^
| | |
| | didn't expect any arguments here
| help: must be of the form: `#![no_core]`
error[E0565]: malformed `no_core` attribute input
--> $DIR/malformed-no-std.rs:13:1
|
LL | #![no_core(foo = "bar")]
| ^^^^^^^^^^-------------^
| | |
| | didn't expect any arguments here
| help: must be of the form: `#![no_core]`
error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
--> $DIR/malformed-no-std.rs:17:1
|
LL | #[no_std]
| ^^^^^^^^^
|
note: This attribute does not have an `!`, which means it is applied to this extern crate
--> $DIR/malformed-no-std.rs:22:1
|
LL | extern crate core;
| ^^^^^^^^^^^^^^^^^^
note: the lint level is defined here
--> $DIR/malformed-no-std.rs:16:8
|
LL | #[deny(unused_attributes)]
| ^^^^^^^^^^^^^^^^^
error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_core]`
--> $DIR/malformed-no-std.rs:19:1
|
LL | #[no_core]
| ^^^^^^^^^^
|
note: This attribute does not have an `!`, which means it is applied to this extern crate
--> $DIR/malformed-no-std.rs:22:1
|
LL | extern crate core;
| ^^^^^^^^^^^^^^^^^^
error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0565`.

View file

@ -539,26 +539,26 @@ mod macro_escape {
#[no_std]
//~^ WARN crate-level attribute should be an inner attribute
//~| HELP add a `!`
mod no_std {
//~^ NOTE This attribute does not have an `!`, which means it is applied to this module
mod inner { #![no_std] }
//~^ WARN crate-level attribute should be in the root module
//~^ WARN the `#![no_std]` attribute can only be used at the crate root
#[no_std] 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_std] 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_std] 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_std] 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 block
}
// At time of authorship, #[proc_macro_derive = "2500"] signals error

View file

@ -209,17 +209,6 @@ help: add a `!`
LL | #![reexport_test_harness_main = "2900"]
| +
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:1
|
LL | #[no_std]
| ^^^^^^^^^
|
help: add a `!`
|
LL | #![no_std]
| +
warning: attribute should be applied to an `extern` block with non-Rust ABI
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:695:1
|
@ -387,56 +376,6 @@ help: add a `!`
LL | #![reexport_test_harness_main = "2900"] impl S { }
| +
warning: crate-level attribute should be in the root module
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:17
|
LL | mod inner { #![no_std] }
| ^^^^^^^^^^
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:547:5
|
LL | #[no_std] fn f() { }
| ^^^^^^^^^
|
help: add a `!`
|
LL | #![no_std] fn f() { }
| +
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:551:5
|
LL | #[no_std] struct S;
| ^^^^^^^^^
|
help: add a `!`
|
LL | #![no_std] struct S;
| +
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:555:5
|
LL | #[no_std] type T = S;
| ^^^^^^^^^
|
help: add a `!`
|
LL | #![no_std] type T = S;
| +
warning: crate-level attribute should be an inner attribute
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:559:5
|
LL | #[no_std] impl S { }
| ^^^^^^^^^
|
help: add a `!`
|
LL | #![no_std] impl S { }
| +
warning: attribute should be applied to an `extern` block with non-Rust ABI
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:701:17
|
@ -1095,6 +1034,76 @@ LL | #[macro_escape] impl S { }
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= help: `#[macro_escape]` can be applied to modules, extern crates, and crates
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:1
|
LL | #[no_std]
| ^^^^^^^^^
|
note: This attribute does not have an `!`, which means it is applied to this module
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:542:1
|
LL | / mod no_std {
LL | |
LL | | mod inner { #![no_std] }
... |
LL | | }
| |_^
warning: the `#![no_std]` attribute can only be used at the crate root
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:17
|
LL | mod inner { #![no_std] }
| ^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:547:5
|
LL | #[no_std] 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:547:15
|
LL | #[no_std] fn f() { }
| ^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:551:5
|
LL | #[no_std] 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:551:15
|
LL | #[no_std] struct S;
| ^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:555:5
|
LL | #[no_std] 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:555:15
|
LL | #[no_std] type T = S;
| ^^^^^^^^^^^
warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:559:5
|
LL | #[no_std] 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:559:15
|
LL | #[no_std] impl S { }
| ^^^^^^^^^^
warning: `#[cold]` attribute cannot be used on modules
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:581:1
|

View file

@ -28,18 +28,6 @@ note: attribute also specified here
LL | #[no_link]
| ^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr-duplicate.rs:27:1
|
LL | #![no_std]
| ^^^^^^^^^^ help: remove this attribute
|
note: attribute also specified here
--> $DIR/unused-attr-duplicate.rs:26:1
|
LL | #![no_std]
| ^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr-duplicate.rs:31:1
|
@ -304,6 +292,18 @@ LL | #![type_length_limit = "1048576"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
error: unused attribute
--> $DIR/unused-attr-duplicate.rs:27:1
|
LL | #![no_std]
| ^^^^^^^^^^ help: remove this attribute
|
note: attribute also specified here
--> $DIR/unused-attr-duplicate.rs:26:1
|
LL | #![no_std]
| ^^^^^^^^^^
error: unused attribute
--> $DIR/unused-attr-duplicate.rs:29:1
|

View file

@ -55,7 +55,7 @@ use self::prelude::*;
*/
#[doc = "inner doc attribute"]
#[allow(dead_code, unused_variables)]
#[no_std]
#[attr = NoStd]
mod attributes {
/// outer single-line doc comment