Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/crate_level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
6 changes: 4 additions & 2 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -222,8 +222,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>>,
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),

Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir/src/attrs/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
10 changes: 2 additions & 8 deletions src/tools/clippy/clippy_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
25 changes: 25 additions & 0 deletions tests/ui/attributes/malformed-no-std.rs
Original file line number Diff line number Diff line change
@@ -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() {}
86 changes: 86 additions & 0 deletions tests/ui/attributes/malformed-no-std.stderr
Original file line number Diff line number Diff line change
@@ -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`.
12 changes: 6 additions & 6 deletions tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading
Loading