Add an experimental unsafe(force_target_feature) attribute.
This uses the feature gate for https://github.com/rust-lang/rust/issues/143352, but is described in https://github.com/rust-lang/rfcs/pull/3820 which is strongly tied to the experiment.
This commit is contained in:
@@ -193,7 +193,7 @@ fn process_builtin_attrs(
|
||||
}
|
||||
}
|
||||
AttributeKind::Optimize(optimize, _) => codegen_fn_attrs.optimize = *optimize,
|
||||
AttributeKind::TargetFeature(features, attr_span) => {
|
||||
AttributeKind::TargetFeature { features, attr_span, was_forced } => {
|
||||
let Some(sig) = tcx.hir_node_by_def_id(did).fn_sig() else {
|
||||
tcx.dcx().span_delayed_bug(*attr_span, "target_feature applied to non-fn");
|
||||
continue;
|
||||
@@ -201,7 +201,7 @@ fn process_builtin_attrs(
|
||||
let safe_target_features =
|
||||
matches!(sig.header.safety, hir::HeaderSafety::SafeTargetFeatures);
|
||||
codegen_fn_attrs.safe_target_features = safe_target_features;
|
||||
if safe_target_features {
|
||||
if safe_target_features && !was_forced {
|
||||
if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc {
|
||||
// The `#[target_feature]` attribute is allowed on
|
||||
// WebAssembly targets on all functions. Prior to stabilizing
|
||||
@@ -232,6 +232,7 @@ fn process_builtin_attrs(
|
||||
tcx,
|
||||
did,
|
||||
features,
|
||||
*was_forced,
|
||||
rust_target_features,
|
||||
&mut codegen_fn_attrs.target_features,
|
||||
);
|
||||
@@ -462,7 +463,7 @@ fn check_result(
|
||||
.collect(),
|
||||
) {
|
||||
let span =
|
||||
find_attr!(tcx.get_all_attrs(did), AttributeKind::TargetFeature(_, span) => *span)
|
||||
find_attr!(tcx.get_all_attrs(did), AttributeKind::TargetFeature{attr_span: span, ..} => *span)
|
||||
.unwrap_or_else(|| tcx.def_span(did));
|
||||
|
||||
tcx.dcx()
|
||||
|
||||
@@ -3,7 +3,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet};
|
||||
use rustc_hir::attrs::InstructionSetAttr;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
|
||||
use rustc_middle::middle::codegen_fn_attrs::TargetFeature;
|
||||
use rustc_middle::middle::codegen_fn_attrs::{TargetFeature, TargetFeatureKind};
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_session::Session;
|
||||
@@ -22,6 +22,7 @@ pub(crate) fn from_target_feature_attr(
|
||||
tcx: TyCtxt<'_>,
|
||||
did: LocalDefId,
|
||||
features: &[(Symbol, Span)],
|
||||
was_forced: bool,
|
||||
rust_target_features: &UnordMap<String, target_features::Stability>,
|
||||
target_features: &mut Vec<TargetFeature>,
|
||||
) {
|
||||
@@ -88,7 +89,14 @@ pub(crate) fn from_target_feature_attr(
|
||||
}
|
||||
}
|
||||
}
|
||||
target_features.push(TargetFeature { name, implied: name != feature })
|
||||
let kind = if name != feature {
|
||||
TargetFeatureKind::Implied
|
||||
} else if was_forced {
|
||||
TargetFeatureKind::Forced
|
||||
} else {
|
||||
TargetFeatureKind::Enabled
|
||||
};
|
||||
target_features.push(TargetFeature { name, kind })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user