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
17 changes: 15 additions & 2 deletions compiler/rustc_codegen_ssa/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1248,8 +1248,21 @@ pub(crate) struct FeatureNotValid<'a> {
#[primary_span]
#[label("`{$feature}` is not valid for this target")]
pub span: Span,
#[help("consider removing the leading `+` in the feature name")]
pub plus_hint: bool,
#[subdiagnostic]
pub plus_hint: Option<RemovePlusFromFeatureName<'a>>,
}

#[derive(Subdiagnostic)]
#[suggestion(
"consider removing the leading `+` in the feature name",
code = "enable = \"{stripped}\"",
applicability = "maybe-incorrect",
style = "verbose"
)]
pub struct RemovePlusFromFeatureName<'a> {
#[primary_span]
pub span: Span,
pub stripped: &'a str,
}

#[derive(Diagnostic)]
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_codegen_ssa/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_target::spec::Arch;
use rustc_target::target_features::{RUSTC_SPECIFIC_FEATURES, Stability};
use smallvec::SmallVec;

use crate::errors::FeatureNotValid;
use crate::errors::{FeatureNotValid, RemovePlusFromFeatureName};
use crate::{errors, target_features};

/// Compute the enabled target features from the `#[target_feature]` function attribute.
Expand All @@ -34,7 +34,8 @@ pub(crate) fn from_target_feature_attr(
let Some(stability) = rust_target_features.get(feature_str) else {
let plus_hint = feature_str
.strip_prefix('+')
.is_some_and(|stripped| rust_target_features.contains_key(stripped));
.filter(|stripped| rust_target_features.contains_key(*stripped))
.map(|stripped| RemovePlusFromFeatureName { span: feature_span, stripped });
tcx.dcx().emit_err(FeatureNotValid {
feature: feature_str,
span: feature_span,
Expand Down
2 changes: 2 additions & 0 deletions tests/auxiliary/minicore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ impl_marker_trait!(
]
);

impl Sync for () {}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

() does not work with the macro right above. So this will have to do.


#[lang = "drop_in_place"]
fn drop_in_place<T>(_: *mut T) {}

Expand Down
17 changes: 14 additions & 3 deletions tests/ui/target-feature/invalid-attribute.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
//@ only-x86_64
//@ add-minicore
//@ compile-flags: --target=x86_64-unknown-linux-gnu
//@ needs-llvm-components: x86

#![warn(unused_attributes)]
#![feature(no_core)]
#![no_core]

use minicore::*;

#[target_feature(enable = "sse2")]
//~^ ERROR attribute cannot be used on
extern crate alloc;
extern crate minicore;

#[target_feature(enable = "sse2")]
//~^ ERROR attribute cannot be used on
use alloc::alloc::alloc;
use minicore::mem::transmute;

#[target_feature(enable = "sse2")]
//~^ ERROR attribute cannot be used on
Expand Down Expand Up @@ -112,3 +118,8 @@ fn main() {
//~^ ERROR `+sse2` is not valid for this target
//~| NOTE `+sse2` is not valid for this target
unsafe fn hey() {}

#[target_feature(enable = "+sse5")]
//~^ ERROR `+sse5` is not valid for this target
//~| NOTE `+sse5` is not valid for this target
unsafe fn typo() {}
Comment thread
JonathanBrouwer marked this conversation as resolved.
64 changes: 37 additions & 27 deletions tests/ui/target-feature/invalid-attribute.stderr
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
error: `#[target_feature]` attribute cannot be used on extern crates
--> $DIR/invalid-attribute.rs:5:1
--> $DIR/invalid-attribute.rs:11:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[target_feature]` can only be applied to functions

error: `#[target_feature]` attribute cannot be used on use statements
--> $DIR/invalid-attribute.rs:9:1
--> $DIR/invalid-attribute.rs:15:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[target_feature]` can only be applied to functions

error: `#[target_feature]` attribute cannot be used on foreign modules
--> $DIR/invalid-attribute.rs:13:1
--> $DIR/invalid-attribute.rs:19:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[target_feature]` can only be applied to functions

error[E0539]: malformed `target_feature` attribute input
--> $DIR/invalid-attribute.rs:17:1
--> $DIR/invalid-attribute.rs:23:1
|
LL | #[target_feature = "+sse2"]
| ^^^^^^^^^^^^^^^^^---------^
Expand All @@ -32,7 +32,7 @@ LL | #[target_feature = "+sse2"]
| help: must be of the form: `#[target_feature(enable = "feat1, feat2")]`

error[E0539]: malformed `target_feature` attribute input
--> $DIR/invalid-attribute.rs:23:1
--> $DIR/invalid-attribute.rs:29:1
|
LL | #[target_feature(bar)]
| ^^^^^^^^^^^^^^^^^---^^
Expand All @@ -41,7 +41,7 @@ LL | #[target_feature(bar)]
| help: must be of the form: `#[target_feature(enable = "feat1, feat2")]`

error[E0539]: malformed `target_feature` attribute input
--> $DIR/invalid-attribute.rs:26:1
--> $DIR/invalid-attribute.rs:32:1
|
LL | #[target_feature(disable = "baz")]
| ^^^^^^^^^^^^^^^^^-------^^^^^^^^^^
Expand All @@ -50,103 +50,103 @@ LL | #[target_feature(disable = "baz")]
| help: must be of the form: `#[target_feature(enable = "feat1, feat2")]`

error: `#[target_feature]` attribute cannot be used on modules
--> $DIR/invalid-attribute.rs:31:1
--> $DIR/invalid-attribute.rs:37:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[target_feature]` can only be applied to functions

error: `#[target_feature]` attribute cannot be used on constants
--> $DIR/invalid-attribute.rs:35:1
--> $DIR/invalid-attribute.rs:41:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[target_feature]` can only be applied to functions

error: `#[target_feature]` attribute cannot be used on structs
--> $DIR/invalid-attribute.rs:39:1
--> $DIR/invalid-attribute.rs:45:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[target_feature]` can only be applied to functions

error: `#[target_feature]` attribute cannot be used on enums
--> $DIR/invalid-attribute.rs:43:1
--> $DIR/invalid-attribute.rs:49:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[target_feature]` can only be applied to functions

error: `#[target_feature]` attribute cannot be used on unions
--> $DIR/invalid-attribute.rs:47:1
--> $DIR/invalid-attribute.rs:53:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[target_feature]` can only be applied to functions

error: `#[target_feature]` attribute cannot be used on type aliases
--> $DIR/invalid-attribute.rs:54:1
--> $DIR/invalid-attribute.rs:60:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[target_feature]` can only be applied to functions

error: `#[target_feature]` attribute cannot be used on traits
--> $DIR/invalid-attribute.rs:58:1
--> $DIR/invalid-attribute.rs:64:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[target_feature]` can only be applied to functions

error: `#[target_feature]` attribute cannot be used on statics
--> $DIR/invalid-attribute.rs:69:1
--> $DIR/invalid-attribute.rs:75:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[target_feature]` can only be applied to functions

error: `#[target_feature]` attribute cannot be used on trait impl blocks
--> $DIR/invalid-attribute.rs:73:1
--> $DIR/invalid-attribute.rs:79:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[target_feature]` can only be applied to functions

error: `#[target_feature]` attribute cannot be used on inherent impl blocks
--> $DIR/invalid-attribute.rs:79:1
--> $DIR/invalid-attribute.rs:85:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[target_feature]` can only be applied to functions

error: `#[target_feature]` attribute cannot be used on expressions
--> $DIR/invalid-attribute.rs:100:5
--> $DIR/invalid-attribute.rs:106:5
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[target_feature]` can only be applied to functions

error: `#[target_feature]` attribute cannot be used on closures
--> $DIR/invalid-attribute.rs:106:5
--> $DIR/invalid-attribute.rs:112:5
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: `#[target_feature]` can be applied to functions and methods

error[E0658]: cannot use `#[inline(always)]` with `#[target_feature]`
--> $DIR/invalid-attribute.rs:62:1
--> $DIR/invalid-attribute.rs:68:1
|
LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^
Expand All @@ -156,13 +156,13 @@ LL | #[inline(always)]
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: the feature named `foo` is not valid for this target
--> $DIR/invalid-attribute.rs:20:18
--> $DIR/invalid-attribute.rs:26:18
|
LL | #[target_feature(enable = "foo")]
| ^^^^^^^^^^^^^^ `foo` is not valid for this target

error[E0046]: not all trait items implemented, missing: `foo`
--> $DIR/invalid-attribute.rs:75:1
--> $DIR/invalid-attribute.rs:81:1
|
LL | impl Quux for u8 {}
| ^^^^^^^^^^^^^^^^ missing `foo` in implementation
Expand All @@ -171,7 +171,7 @@ LL | fn foo();
| --------- `foo` from trait

error: `#[target_feature(..)]` cannot be applied to safe trait method
--> $DIR/invalid-attribute.rs:89:5
--> $DIR/invalid-attribute.rs:95:5
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method
Expand All @@ -180,28 +180,38 @@ LL | fn foo() {}
| -------- not an `unsafe` function

error[E0053]: method `foo` has an incompatible type for trait
--> $DIR/invalid-attribute.rs:92:5
--> $DIR/invalid-attribute.rs:98:5
|
LL | fn foo() {}
| ^^^^^^^^ expected safe fn, found unsafe fn
|
note: type in trait
--> $DIR/invalid-attribute.rs:84:5
--> $DIR/invalid-attribute.rs:90:5
|
LL | fn foo();
| ^^^^^^^^^
= note: expected signature `fn()`
found signature `#[target_features] fn()`

error: the feature named `+sse2` is not valid for this target
--> $DIR/invalid-attribute.rs:111:18
--> $DIR/invalid-attribute.rs:117:18
|
LL | #[target_feature(enable = "+sse2")]
| ^^^^^^^^^^^^^^^^ `+sse2` is not valid for this target
|
= help: consider removing the leading `+` in the feature name
help: consider removing the leading `+` in the feature name
|
LL - #[target_feature(enable = "+sse2")]
LL + #[target_feature(enable = "sse2")]
|

error: the feature named `+sse5` is not valid for this target
--> $DIR/invalid-attribute.rs:122:18
|
LL | #[target_feature(enable = "+sse5")]
| ^^^^^^^^^^^^^^^^ `+sse5` is not valid for this target

error: aborting due to 24 previous errors
error: aborting due to 25 previous errors

Some errors have detailed explanations: E0046, E0053, E0539, E0658.
For more information about an error, try `rustc --explain E0046`.
Loading