Rollup merge of #156242 - Jamesbarford:feat/remove-alwaysinline+target-feature, r=RalfJung,saethlin

Remove unsound `target_feature_inline_always` feature

## Summary
- Remove `target_feature_inline_always`
- Update stdarch generators to only use `#[inline]` & regenerate stdarch.

## Why?
Succinctly; the feature relies on LLVMs `AlwaysInlinerPass()` running before LLVMs heuristic based inliner pass. Which is not a basis for sound code.

This has been discussed in [the tracking issue](https://github.com/rust-lang/rust/issues/145574).

If the ordering of the passes were to change, of which they have in the past, it is very possible we could inline functions across callsites with mismatching target features leading to unsound code. Checks proposed in; https://github.com/rust-lang/rust/pull/155426 would only take into account caller -> callee which is not enough to guard against possibly of generating unsound code if the pass ordering were to change.

There doesn't seem to be a way, presently, this this mechanism to provide soundness guarantees nor does it seem like `AlwaysInlinerPass()` is a desired feature of LLVM, which this feature relies on.

r? @RalfJung
This commit is contained in:
Jonathan Brouwer
2026-05-21 12:21:45 +02:00
committed by GitHub
19 changed files with 49 additions and 448 deletions
+17 -23
View File
@@ -41,20 +41,13 @@ pub(crate) fn remove_string_attr_from_llfn(llfn: &Value, name: &str) {
}
/// Get LLVM attribute for the provided inline heuristic.
pub(crate) fn inline_attr<'ll, 'tcx>(
#[inline]
fn inline_attr<'ll>(
cx: &SimpleCx<'ll>,
tcx: TyCtxt<'tcx>,
instance: ty::Instance<'tcx>,
sess: &Session,
inline: InlineAttr,
) -> Option<&'ll Attribute> {
// `optnone` requires `noinline`
let codegen_fn_attrs = tcx.codegen_fn_attrs(instance.def_id());
let inline = match (codegen_fn_attrs.inline, &codegen_fn_attrs.optimize) {
(_, OptimizeAttr::DoNotOptimize) => InlineAttr::Never,
(InlineAttr::None, _) if instance.def.requires_inline(tcx) => InlineAttr::Hint,
(inline, _) => inline,
};
if !tcx.sess.opts.unstable_opts.inline_llvm {
if !sess.opts.unstable_opts.inline_llvm {
// disable LLVM inlining
return Some(AttributeKind::NoInline.create_attr(cx.llcx));
}
@@ -64,7 +57,7 @@ pub(crate) fn inline_attr<'ll, 'tcx>(
Some(AttributeKind::AlwaysInline.create_attr(cx.llcx))
}
InlineAttr::Never => {
if tcx.sess.target.arch != Arch::AmdGpu {
if sess.target.arch != Arch::AmdGpu {
Some(AttributeKind::NoInline.create_attr(cx.llcx))
} else {
None
@@ -418,6 +411,17 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
OptimizeAttr::Speed => {}
}
if let Some(instance) = instance {
// `optnone` requires `noinline`
let inline = match (codegen_fn_attrs.inline, &codegen_fn_attrs.optimize) {
(_, OptimizeAttr::DoNotOptimize) => InlineAttr::Never,
(InlineAttr::None, _) if instance.def.requires_inline(tcx) => InlineAttr::Hint,
(inline, _) => inline,
};
to_add.extend(inline_attr(cx, sess, inline));
}
if sess.must_emit_unwind_tables() {
to_add.push(uwtable_attr(cx.llcx, sess.opts.unstable_opts.use_sync_unwind));
}
@@ -568,16 +572,6 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
let function_features =
codegen_fn_attrs.target_features.iter().map(|f| f.name.as_str()).collect::<Vec<&str>>();
// Apply function attributes as per usual if there are no user defined
// target features otherwise this will get applied at the callsite.
if function_features.is_empty() {
if let Some(instance) = instance
&& let Some(inline_attr) = inline_attr(cx, tcx, instance)
{
to_add.push(inline_attr);
}
}
let function_features = function_features
.iter()
// Convert to LLVMFeatures and filter out unavailable ones
+1 -27
View File
@@ -15,7 +15,7 @@
use rustc_codegen_ssa::traits::*;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature, TargetFeatureKind};
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
TyAndLayout,
@@ -1419,32 +1419,6 @@ fn call(
)
};
if let Some(callee_instance) = callee_instance {
// Attributes on the function definition being called
let callee_attrs = self.cx.tcx.codegen_fn_attrs(callee_instance.def_id());
if let Some(caller_attrs) = caller_attrs
// If there is an inline attribute and a target feature that matches
// we will add the attribute to the callsite otherwise we'll omit
// this and not add the attribute to prevent soundness issues.
&& let Some(inlining_rule) = attributes::inline_attr(&self.cx, self.cx.tcx, callee_instance)
&& self.cx.tcx.is_target_feature_call_safe(
&callee_attrs.target_features,
&caller_attrs.target_features.iter().cloned().chain(
self.cx.tcx.sess.target_features.iter().map(|feat| TargetFeature {
name: *feat,
kind: TargetFeatureKind::Implied,
})
).collect::<Vec<_>>(),
)
{
attributes::apply_to_callsite(
call,
llvm::AttributePlace::Function,
&[inlining_rule],
);
}
}
if let Some(fn_abi) = fn_abi {
fn_abi.apply_attrs_callsite(self, call);
}
@@ -419,16 +419,16 @@ fn check_result(
// llvm/llvm-project#70563).
if !codegen_fn_attrs.target_features.is_empty()
&& matches!(codegen_fn_attrs.inline, InlineAttr::Always)
&& !tcx.features().target_feature_inline_always()
&& let Some(span) = interesting_spans.inline
{
feature_err(
tcx.sess,
sym::target_feature_inline_always,
span,
"cannot use `#[inline(always)]` with `#[target_feature]`",
)
.emit();
let mut diag = tcx
.dcx()
.struct_span_err(span, "cannot use `#[inline(always)]` with `#[target_feature]`");
diag.note(
"See this issue for full discussion: \
https://github.com/rust-lang/rust/issues/145574",
);
diag.emit();
}
// warn that inline has no effect when no_sanitize is present
+3
View File
@@ -282,6 +282,9 @@ macro_rules! declare_features {
/// Allows string patterns to dereference values to match them.
(removed, string_deref_patterns, "1.94.0", Some(87121), Some("superseded by `deref_patterns`"), 150530),
(removed, struct_inherit, "1.0.0", None, None),
/// Allows the use of target_feature when a function is marked inline(always).
(removed, target_feature_inline_always, "CURRENT_RUSTC_VERSION", Some(145574),
Some("removed because of unfixable soundness issues")),
(removed, test_removed_feature, "1.0.0", None, None),
/// Allows using items which are missing stability attributes
(removed, unmarked_api, "1.0.0", None, None),
-2
View File
@@ -727,8 +727,6 @@ pub fn internal(&self, feature: Symbol) -> bool {
(unstable, super_let, "1.88.0", Some(139076)),
/// Allows subtrait items to shadow supertrait items.
(unstable, supertrait_item_shadowing, "1.86.0", Some(89151)),
/// Allows the use of target_feature when a function is marked inline(always).
(unstable, target_feature_inline_always, "1.91.0", Some(145574)),
/// Allows using `#[thread_local]` on `static` items.
(unstable, thread_local, "1.0.0", Some(29594)),
/// Allows defining `trait X = A + B;` alias items.
+4
View File
@@ -644,6 +644,10 @@ macro_rules! add_lint_group {
);
store.register_removed("wasm_c_abi", "the wasm C ABI has been fixed");
store.register_removed("soft_unstable", "the general soft-unstable mechanism has been removed");
store.register_removed(
"inline_always_mismatching_target_features",
"replaced by a hard error for `#[inline(always)]` with `#[target_feature]`",
);
}
fn register_internals(store: &mut LintStore) {
-56
View File
@@ -56,7 +56,6 @@
ILL_FORMED_ATTRIBUTE_INPUT,
INCOMPLETE_INCLUDE,
INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
INLINE_ALWAYS_MISMATCHING_TARGET_FEATURES,
INLINE_NO_SANITIZE,
INVALID_DOC_ATTRIBUTES,
INVALID_MACRO_EXPORT_ARGUMENTS,
@@ -5492,61 +5491,6 @@
"detects tail calls of functions marked with `#[track_caller]`",
@feature_gate = explicit_tail_calls;
}
declare_lint! {
/// The `inline_always_mismatching_target_features` lint will trigger when a
/// function with the `#[inline(always)]` and `#[target_feature(enable = "...")]`
/// attributes is called and cannot be inlined due to missing target features in the caller.
///
/// ### Example
///
/// ```rust,ignore (fails on x86_64)
/// #[inline(always)]
/// #[target_feature(enable = "fp16")]
/// unsafe fn callee() {
/// // operations using fp16 types
/// }
///
/// // Caller does not enable the required target feature
/// fn caller() {
/// unsafe { callee(); }
/// }
///
/// fn main() {
/// caller();
/// }
/// ```
///
/// This will produce:
///
/// ```text
/// warning: call to `#[inline(always)]`-annotated `callee` requires the same target features. Function will not have `alwaysinline` attribute applied
/// --> $DIR/builtin.rs:5192:14
/// |
/// 10 | unsafe { callee(); }
/// | ^^^^^^^^
/// |
/// note: `fp16` target feature enabled in `callee` here but missing from `caller`
/// --> $DIR/builtin.rs:5185:1
/// |
/// 3 | #[target_feature(enable = "fp16")]
/// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/// 4 | unsafe fn callee() {
/// | ------------------
/// = note: `#[warn(inline_always_mismatching_target_features)]` on by default
/// warning: 1 warning emitted
/// ```
///
/// ### Explanation
///
/// Inlining a function with a target feature attribute into a caller that
/// lacks the corresponding target feature can lead to unsound behavior.
/// LLVM may select the wrong instructions or registers, or reorder
/// operations, potentially resulting in runtime errors.
pub INLINE_ALWAYS_MISMATCHING_TARGET_FEATURES,
Warn,
r#"detects when a function annotated with `#[inline(always)]` and `#[target_feature(enable = "..")]` is inlined into a caller without the required target feature"#,
}
declare_lint! {
/// The `repr_c_enums_larger_than_int` lint detects `repr(C)` enums with discriminant
/// values that do not fit into a C `int` or `unsigned int`.
@@ -1,88 +0,0 @@
use rustc_hir::attrs::InlineAttr;
use rustc_middle::middle::codegen_fn_attrs::{TargetFeature, TargetFeatureKind};
use rustc_middle::mir::{Body, TerminatorKind};
use rustc_middle::ty::{self, TyCtxt};
use crate::pass_manager::MirLint;
pub(super) struct CheckInlineAlwaysTargetFeature;
impl<'tcx> MirLint<'tcx> for CheckInlineAlwaysTargetFeature {
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
check_inline_always_target_features(tcx, body)
}
}
/// `#[target_feature]`-annotated functions can be marked `#[inline]` and will only be inlined if
/// the target features match (as well as all of the other inlining heuristics). `#[inline(always)]`
/// will always inline regardless of matching target features, which can result in errors from LLVM.
/// However, it is desirable to be able to always annotate certain functions (e.g. SIMD intrinsics)
/// as `#[inline(always)]` but check the target features match in Rust to avoid the LLVM errors.
///
/// We check the caller and callee target features to ensure that this can
/// be done or emit a lint.
#[inline]
fn check_inline_always_target_features<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
let caller_def_id = body.source.def_id().expect_local();
if !tcx.def_kind(caller_def_id).has_codegen_attrs() {
return;
}
let caller_codegen_fn_attrs = tcx.codegen_fn_attrs(caller_def_id);
for bb in body.basic_blocks.iter() {
let terminator = bb.terminator();
match &terminator.kind {
TerminatorKind::Call { func, .. } | TerminatorKind::TailCall { func, .. } => {
let fn_ty = func.ty(body, tcx);
let ty::FnDef(callee_def_id, _) = *fn_ty.kind() else {
continue;
};
if !tcx.def_kind(callee_def_id).has_codegen_attrs() {
continue;
}
let callee_codegen_fn_attrs = tcx.codegen_fn_attrs(callee_def_id);
if callee_codegen_fn_attrs.inline != InlineAttr::Always
|| callee_codegen_fn_attrs.target_features.is_empty()
{
continue;
}
// Scan the users defined target features and ensure they
// match the caller.
if tcx.is_target_feature_call_safe(
&callee_codegen_fn_attrs.target_features,
&caller_codegen_fn_attrs
.target_features
.iter()
.cloned()
.chain(tcx.sess.target_features.iter().map(|feat| TargetFeature {
name: *feat,
kind: TargetFeatureKind::Implied,
}))
.collect::<Vec<_>>(),
) {
continue;
}
let callee_only: Vec<_> = callee_codegen_fn_attrs
.target_features
.iter()
.filter(|it| !caller_codegen_fn_attrs.target_features.contains(it))
.filter(|it| !matches!(it.kind, TargetFeatureKind::Implied))
.map(|it| it.name.as_str())
.collect();
crate::errors::emit_inline_always_target_feature_diagnostic(
tcx,
terminator.source_info.span,
callee_def_id,
caller_def_id.into(),
&callee_only,
);
}
_ => (),
}
}
}
@@ -5,52 +5,11 @@
};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_middle::mir::AssertKind;
use rustc_middle::query::QueryKey;
use rustc_middle::ty::TyCtxt;
use rustc_session::lint::{self, Lint};
use rustc_span::def_id::DefId;
use rustc_span::{Ident, Span, Symbol};
/// Emit diagnostic for calls to `#[inline(always)]`-annotated functions with a
/// `#[target_feature]` attribute where the caller enables a different set of target features.
pub(crate) fn emit_inline_always_target_feature_diagnostic<'a, 'tcx>(
tcx: TyCtxt<'tcx>,
call_span: Span,
callee_def_id: DefId,
caller_def_id: DefId,
callee_only: &[&'a str],
) {
tcx.emit_node_span_lint(
lint::builtin::INLINE_ALWAYS_MISMATCHING_TARGET_FEATURES,
tcx.local_def_id_to_hir_id(caller_def_id.as_local().unwrap()),
call_span,
rustc_errors::DiagDecorator(|lint| {
let callee = tcx.def_path_str(callee_def_id);
let caller = tcx.def_path_str(caller_def_id);
lint.primary_message(format!(
"call to `#[inline(always)]`-annotated `{callee}` \
requires the same target features to be inlined"
));
lint.note("function will not be inlined");
lint.note(format!(
"the following target features are on `{callee}` but missing from `{caller}`: {}",
callee_only.join(", ")
));
lint.span_note(callee_def_id.default_span(tcx), format!("`{callee}` is defined here"));
let feats = callee_only.join(",");
lint.span_suggestion(
tcx.def_span(caller_def_id).shrink_to_lo(),
format!("add `#[target_feature]` attribute to `{caller}`"),
format!("#[target_feature(enable = \"{feats}\")]\n"),
lint::Applicability::MaybeIncorrect,
);
}),
);
}
#[derive(Diagnostic)]
#[diag("function cannot return without recursing")]
#[help("a `loop` may express intention better if this is on purpose")]
-4
View File
@@ -122,7 +122,6 @@ macro_rules! pass_names {
mod add_subtyping_projections : Subtyper;
mod check_inline : CheckForceInline;
mod check_call_recursion : CheckCallRecursion, CheckDropRecursion;
mod check_inline_always_target_features: CheckInlineAlwaysTargetFeature;
mod check_alignment : CheckAlignment;
mod check_enums : CheckEnums;
mod check_const_item_mutation : CheckConstItemMutation;
@@ -403,9 +402,6 @@ fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
// MIR-level lints.
&Lint(check_inline::CheckForceInline),
&Lint(check_call_recursion::CheckCallRecursion),
// Check callee's target features match callers target features when
// using `#[inline(always)]`
&Lint(check_inline_always_target_features::CheckInlineAlwaysTargetFeature),
&Lint(check_packed_ref::CheckPackedRef),
&Lint(check_const_item_mutation::CheckConstItemMutation),
&Lint(function_item_references::FunctionItemReferences),
-1
View File
@@ -166,7 +166,6 @@
#![feature(staged_api)]
#![feature(stmt_expr_attributes)]
#![feature(strict_provenance_lints)]
#![feature(target_feature_inline_always)]
#![feature(trait_alias)]
#![feature(transparent_unions)]
#![feature(try_blocks)]
-1
View File
@@ -306,7 +306,6 @@
#![feature(staged_api)]
#![feature(stmt_expr_attributes)]
#![feature(strict_provenance_lints)]
#![feature(target_feature_inline_always)]
#![feature(thread_local)]
#![feature(try_blocks)]
#![feature(try_trait_v2)]
@@ -1,41 +0,0 @@
//@ add-minicore
//@ compile-flags: --target aarch64-unknown-linux-gnu -Zinline-mir=no -C no-prepopulate-passes
//@ needs-llvm-components: aarch64
#![crate_type = "lib"]
#![feature(no_core, lang_items, target_feature_inline_always)]
#![no_core]
extern crate minicore;
use minicore::*;
#[inline(always)]
#[target_feature(enable = "neon")]
#[no_mangle]
pub fn single_target_feature() -> i32 {
42
}
#[inline(always)]
#[target_feature(enable = "neon,i8mm")]
#[no_mangle]
// CHECK: define{{( noundef)?}} i32 @multiple_target_features() unnamed_addr #1 {
pub fn multiple_target_features() -> i32 {
// CHECK: %_0 = call{{( noundef)?}} i32 @single_target_feature() #3
single_target_feature()
}
#[no_mangle]
// CHECK: define{{( noundef)?}} i32 @inherits_from_global() unnamed_addr #2 {
pub fn inherits_from_global() -> i32 {
unsafe {
// CHECK: %_0 = call{{( noundef)?}} i32 @single_target_feature() #3
single_target_feature()
}
}
// Attribute #3 requires the alwaysinline attribute, the alwaysinline attribute is not emitted on a
// function definition when target features are present, rather it will be moved onto the function
// call, if the features match up.
//
// CHECK: attributes #3 = { alwaysinline nounwind }
@@ -1,9 +0,0 @@
//@ only-aarch64
#[inline(always)]
//~^ ERROR cannot use `#[inline(always)]` with `#[target_feature]`
#[target_feature(enable="fp16")]
fn test() {
}
fn main() { }
@@ -1,13 +0,0 @@
error[E0658]: cannot use `#[inline(always)]` with `#[target_feature]`
--> $DIR/feature-gate-target-feature-inline-always.rs:2:1
|
LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #145574 <https://github.com/rust-lang/rust/issues/145574> for more information
= help: add `#![feature(target_feature_inline_always)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0658`.
@@ -1,60 +0,0 @@
warning: call to `#[inline(always)]`-annotated `target_feature_identity` requires the same target features to be inlined
--> $DIR/inline-always.rs:20:5
|
LL | target_feature_identity();
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: function will not be inlined
= note: the following target features are on `target_feature_identity` but missing from `call_no_target_features`: neon, fp16
note: `target_feature_identity` is defined here
--> $DIR/inline-always.rs:17:1
|
LL | pub unsafe fn target_feature_identity() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `#[warn(inline_always_mismatching_target_features)]` on by default
help: add `#[target_feature]` attribute to `call_no_target_features`
|
LL + #[target_feature(enable = "neon,fp16")]
LL | unsafe fn call_no_target_features() {
|
warning: call to `#[inline(always)]`-annotated `multiple_target_features` requires the same target features to be inlined
--> $DIR/inline-always.rs:23:5
|
LL | multiple_target_features();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: function will not be inlined
= note: the following target features are on `multiple_target_features` but missing from `call_no_target_features`: fp16, sve, rdm
note: `multiple_target_features` is defined here
--> $DIR/inline-always.rs:53:1
|
LL | fn multiple_target_features() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: add `#[target_feature]` attribute to `call_no_target_features`
|
LL + #[target_feature(enable = "fp16,sve,rdm")]
LL | unsafe fn call_no_target_features() {
|
warning: call to `#[inline(always)]`-annotated `multiple_target_features` requires the same target features to be inlined
--> $DIR/inline-always.rs:29:5
|
LL | multiple_target_features();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: function will not be inlined
= note: the following target features are on `multiple_target_features` but missing from `call_to_first_set`: rdm
note: `multiple_target_features` is defined here
--> $DIR/inline-always.rs:53:1
|
LL | fn multiple_target_features() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: add `#[target_feature]` attribute to `call_to_first_set`
|
LL + #[target_feature(enable = "rdm")]
LL | unsafe fn call_to_first_set() {
|
warning: 3 warnings emitted
-55
View File
@@ -1,55 +0,0 @@
//@ add-minicore
//@ build-pass
//@ compile-flags: --crate-type=lib
//@ revisions: aarch64
//@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
//@[aarch64] needs-llvm-components: aarch64
//@ ignore-backends: gcc
#![feature(no_core, target_feature_inline_always)]
#![no_core]
extern crate minicore;
use minicore::*;
#[inline(always)]
#[target_feature(enable = "neon,fp16")]
pub unsafe fn target_feature_identity() {}
unsafe fn call_no_target_features() {
target_feature_identity();
//~^ WARNING call to `#[inline(always)]`-annotated `target_feature_identity` requires the same target features to be inlined [inline_always_mismatching_target_features]
global_feature_enabled();
multiple_target_features();
//~^ WARNING call to `#[inline(always)]`-annotated `multiple_target_features` requires the same target features to be inlined [inline_always_mismatching_target_features]
}
#[target_feature(enable = "fp16,sve")]
unsafe fn call_to_first_set() {
multiple_target_features();
//~^ WARNING call to `#[inline(always)]`-annotated `multiple_target_features` requires the same target features to be inlined [inline_always_mismatching_target_features]
}
/* You can't have "fhm" without "fp16" */
#[target_feature(enable = "fhm")]
unsafe fn mismatching_features() {
target_feature_identity()
}
#[target_feature(enable = "fp16")]
unsafe fn matching_target_features() {
target_feature_identity()
}
#[inline(always)]
#[target_feature(enable = "neon")]
unsafe fn global_feature_enabled() {
}
#[inline(always)]
#[target_feature(enable = "fp16,sve")]
#[target_feature(enable="rdm")]
fn multiple_target_features() {
}
+1 -2
View File
@@ -67,8 +67,7 @@ trait Baz {}
#[inline(always)]
//~^ ERROR: cannot use `#[inline(always)]`
//~| NOTE: see issue #145574 <https://github.com/rust-lang/rust/issues/145574> for more information
//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
//~| NOTE: See this issue for full discussion: https://github.com/rust-lang/rust/issues/145574
#[target_feature(enable = "sse2")]
unsafe fn test() {}
@@ -121,7 +121,7 @@ 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:75:1
--> $DIR/invalid-attribute.rs:74:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -129,7 +129,7 @@ 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:79:1
--> $DIR/invalid-attribute.rs:78:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -137,7 +137,7 @@ 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:85:1
--> $DIR/invalid-attribute.rs:84:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -145,7 +145,7 @@ 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:106:5
--> $DIR/invalid-attribute.rs:105:5
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -153,22 +153,20 @@ 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:112:5
--> $DIR/invalid-attribute.rs:111: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]`
error: cannot use `#[inline(always)]` with `#[target_feature]`
--> $DIR/invalid-attribute.rs:68:1
|
LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #145574 <https://github.com/rust-lang/rust/issues/145574> for more information
= help: add `#![feature(target_feature_inline_always)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
= note: See this issue for full discussion: https://github.com/rust-lang/rust/issues/145574
error: the feature named `foo` is not valid for this target
--> $DIR/invalid-attribute.rs:26:18
@@ -179,7 +177,7 @@ LL | #[target_feature(enable = "foo")]
= help: valid names are: `fma`, `xop`, `adx`, `aes`, and `avx` and 75 more
error[E0046]: not all trait items implemented, missing: `foo`
--> $DIR/invalid-attribute.rs:81:1
--> $DIR/invalid-attribute.rs:80:1
|
LL | impl Quux for u8 {}
| ^^^^^^^^^^^^^^^^ missing `foo` in implementation
@@ -188,7 +186,7 @@ LL | fn foo();
| --------- `foo` from trait
error: `#[target_feature(..)]` cannot be applied to safe trait method
--> $DIR/invalid-attribute.rs:95:5
--> $DIR/invalid-attribute.rs:94:5
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method
@@ -197,13 +195,13 @@ LL | fn foo() {}
| -------- not an `unsafe` function
error[E0053]: method `foo` has an incompatible type for trait
--> $DIR/invalid-attribute.rs:98:5
--> $DIR/invalid-attribute.rs:97:5
|
LL | fn foo() {}
| ^^^^^^^^ expected safe fn, found unsafe fn
|
note: type in trait
--> $DIR/invalid-attribute.rs:90:5
--> $DIR/invalid-attribute.rs:89:5
|
LL | fn foo();
| ^^^^^^^^^
@@ -211,7 +209,7 @@ LL | fn foo();
found signature `#[target_features] fn()`
error: the feature named `+sse2` is not valid for this target
--> $DIR/invalid-attribute.rs:117:18
--> $DIR/invalid-attribute.rs:116:18
|
LL | #[target_feature(enable = "+sse2")]
| ^^^^^^^^^^^^^^^^ `+sse2` is not valid for this target
@@ -223,7 +221,7 @@ LL + #[target_feature(enable = "sse2")]
|
error: the feature named `sse5` is not valid for this target
--> $DIR/invalid-attribute.rs:122:18
--> $DIR/invalid-attribute.rs:121:18
|
LL | #[target_feature(enable = "sse5")]
| ^^^^^^^^^^^^^^^ `sse5` is not valid for this target
@@ -231,7 +229,7 @@ LL | #[target_feature(enable = "sse5")]
= help: valid names are: `sse`, `sse2`, `sse3`, `sse4a`, and `ssse3` and 75 more
error: the feature named `avx512` is not valid for this target
--> $DIR/invalid-attribute.rs:127:18
--> $DIR/invalid-attribute.rs:126:18
|
LL | #[target_feature(enable = "avx512")]
| ^^^^^^^^^^^^^^^^^ `avx512` is not valid for this target
@@ -240,5 +238,5 @@ LL | #[target_feature(enable = "avx512")]
error: aborting due to 26 previous errors
Some errors have detailed explanations: E0046, E0053, E0539, E0658.
Some errors have detailed explanations: E0046, E0053, E0539.
For more information about an error, try `rustc --explain E0046`.