Hide implicit target features from diagnostics when possible
This commit is contained in:
parent
6b96a60611
commit
83276f5680
16 changed files with 89 additions and 43 deletions
|
@ -75,7 +75,7 @@ pub fn from_fn_attrs<'gcc, 'tcx>(
|
||||||
let function_features = codegen_fn_attrs
|
let function_features = codegen_fn_attrs
|
||||||
.target_features
|
.target_features
|
||||||
.iter()
|
.iter()
|
||||||
.map(|features| features.as_str())
|
.map(|features| features.name.as_str())
|
||||||
.collect::<Vec<&str>>();
|
.collect::<Vec<&str>>();
|
||||||
|
|
||||||
if let Some(features) = check_tied_features(
|
if let Some(features) = check_tied_features(
|
||||||
|
|
|
@ -496,7 +496,7 @@ pub fn from_fn_attrs<'ll, 'tcx>(
|
||||||
to_add.extend(tune_cpu_attr(cx));
|
to_add.extend(tune_cpu_attr(cx));
|
||||||
|
|
||||||
let function_features =
|
let function_features =
|
||||||
codegen_fn_attrs.target_features.iter().map(|f| f.as_str()).collect::<Vec<&str>>();
|
codegen_fn_attrs.target_features.iter().map(|f| f.name.as_str()).collect::<Vec<&str>>();
|
||||||
|
|
||||||
if let Some(f) = llvm_util::check_tied_features(
|
if let Some(f) = llvm_util::check_tied_features(
|
||||||
cx.tcx.sess,
|
cx.tcx.sess,
|
||||||
|
|
|
@ -6,6 +6,7 @@ use rustc_errors::Applicability;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
|
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
|
use rustc_middle::middle::codegen_fn_attrs::TargetFeature;
|
||||||
use rustc_middle::query::Providers;
|
use rustc_middle::query::Providers;
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
|
@ -18,7 +19,7 @@ pub fn from_target_feature(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
attr: &ast::Attribute,
|
attr: &ast::Attribute,
|
||||||
supported_target_features: &UnordMap<String, Option<Symbol>>,
|
supported_target_features: &UnordMap<String, Option<Symbol>>,
|
||||||
target_features: &mut Vec<Symbol>,
|
target_features: &mut Vec<TargetFeature>,
|
||||||
) {
|
) {
|
||||||
let Some(list) = attr.meta_item_list() else { return };
|
let Some(list) = attr.meta_item_list() else { return };
|
||||||
let bad_item = |span| {
|
let bad_item = |span| {
|
||||||
|
@ -99,14 +100,27 @@ pub fn from_target_feature(
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add both explicit and implied target features, using a set to deduplicate
|
// Add explicit features
|
||||||
let mut target_features_set = UnordSet::new();
|
target_features.extend(
|
||||||
|
added_target_features.iter().copied().map(|name| TargetFeature { name, implied: false }),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add implied features
|
||||||
|
let mut implied_target_features = UnordSet::new();
|
||||||
for feature in added_target_features.iter() {
|
for feature in added_target_features.iter() {
|
||||||
target_features_set
|
implied_target_features
|
||||||
.extend_unord(tcx.implied_target_features(*feature).clone().into_items());
|
.extend_unord(tcx.implied_target_features(*feature).clone().into_items());
|
||||||
}
|
}
|
||||||
target_features_set.extend(added_target_features);
|
for feature in added_target_features.iter() {
|
||||||
target_features.extend(target_features_set.into_sorted_stable_ord())
|
implied_target_features.remove(feature);
|
||||||
|
}
|
||||||
|
target_features.extend(
|
||||||
|
implied_target_features
|
||||||
|
.into_sorted_stable_ord()
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.map(|name| TargetFeature { name, implied: true }),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the set of target features used in a function for the purposes of
|
/// Computes the set of target features used in a function for the purposes of
|
||||||
|
@ -115,7 +129,7 @@ fn asm_target_features(tcx: TyCtxt<'_>, did: DefId) -> &FxIndexSet<Symbol> {
|
||||||
let mut target_features = tcx.sess.unstable_target_features.clone();
|
let mut target_features = tcx.sess.unstable_target_features.clone();
|
||||||
if tcx.def_kind(did).has_codegen_attrs() {
|
if tcx.def_kind(did).has_codegen_attrs() {
|
||||||
let attrs = tcx.codegen_fn_attrs(did);
|
let attrs = tcx.codegen_fn_attrs(did);
|
||||||
target_features.extend(&attrs.target_features);
|
target_features.extend(attrs.target_features.iter().map(|feature| feature.name));
|
||||||
match attrs.instruction_set {
|
match attrs.instruction_set {
|
||||||
None => {}
|
None => {}
|
||||||
Some(InstructionSetAttr::ArmA32) => {
|
Some(InstructionSetAttr::ArmA32) => {
|
||||||
|
|
|
@ -317,19 +317,26 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||||
&& attrs
|
&& attrs
|
||||||
.target_features
|
.target_features
|
||||||
.iter()
|
.iter()
|
||||||
.any(|feature| !self.tcx.sess.target_features.contains(feature))
|
.any(|feature| !self.tcx.sess.target_features.contains(&feature.name))
|
||||||
{
|
{
|
||||||
|
// Don't include implicit features in the error, unless only implicit features are
|
||||||
|
// missing. This should be rare, because it can only happen when an implicit feature
|
||||||
|
// is disabled, e.g. `+avx2,-avx`
|
||||||
|
let missing_explicit_features = attrs.target_features.iter().any(|feature| {
|
||||||
|
!feature.implied && !self.tcx.sess.target_features.contains(&feature.name)
|
||||||
|
});
|
||||||
throw_ub_custom!(
|
throw_ub_custom!(
|
||||||
fluent::const_eval_unavailable_target_features_for_fn,
|
fluent::const_eval_unavailable_target_features_for_fn,
|
||||||
unavailable_feats = attrs
|
unavailable_feats = attrs
|
||||||
.target_features
|
.target_features
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|&feature| !self.tcx.sess.target_features.contains(feature))
|
.filter(|&feature| !(missing_explicit_features && feature.implied)
|
||||||
|
&& !self.tcx.sess.target_features.contains(&feature.name))
|
||||||
.fold(String::new(), |mut s, feature| {
|
.fold(String::new(), |mut s, feature| {
|
||||||
if !s.is_empty() {
|
if !s.is_empty() {
|
||||||
s.push_str(", ");
|
s.push_str(", ");
|
||||||
}
|
}
|
||||||
s.push_str(feature.as_str());
|
s.push_str(feature.name.as_str());
|
||||||
s
|
s
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
|
@ -28,7 +28,7 @@ pub struct CodegenFnAttrs {
|
||||||
pub link_ordinal: Option<u16>,
|
pub link_ordinal: Option<u16>,
|
||||||
/// The `#[target_feature(enable = "...")]` attribute and the enabled
|
/// The `#[target_feature(enable = "...")]` attribute and the enabled
|
||||||
/// features (only enabled features are supported right now).
|
/// features (only enabled features are supported right now).
|
||||||
pub target_features: Vec<Symbol>,
|
pub target_features: Vec<TargetFeature>,
|
||||||
/// The `#[linkage = "..."]` attribute on Rust-defined items and the value we found.
|
/// The `#[linkage = "..."]` attribute on Rust-defined items and the value we found.
|
||||||
pub linkage: Option<Linkage>,
|
pub linkage: Option<Linkage>,
|
||||||
/// The `#[linkage = "..."]` attribute on foreign items and the value we found.
|
/// The `#[linkage = "..."]` attribute on foreign items and the value we found.
|
||||||
|
@ -51,6 +51,15 @@ pub struct CodegenFnAttrs {
|
||||||
pub patchable_function_entry: Option<PatchableFunctionEntry>,
|
pub patchable_function_entry: Option<PatchableFunctionEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||||
|
pub struct TargetFeature {
|
||||||
|
/// The name of the target feature (e.g. "avx")
|
||||||
|
pub name: Symbol,
|
||||||
|
/// The feature is implied by another feature, rather than explicitly added by the
|
||||||
|
/// `#[target_feature]` attribute
|
||||||
|
pub implied: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||||
pub struct PatchableFunctionEntry {
|
pub struct PatchableFunctionEntry {
|
||||||
/// Nops to prepend to the function
|
/// Nops to prepend to the function
|
||||||
|
|
|
@ -5,6 +5,7 @@ use std::ops::Bound;
|
||||||
use rustc_errors::DiagArgValue;
|
use rustc_errors::DiagArgValue;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability};
|
use rustc_hir::{self as hir, BindingMode, ByRef, HirId, Mutability};
|
||||||
|
use rustc_middle::middle::codegen_fn_attrs::TargetFeature;
|
||||||
use rustc_middle::mir::BorrowKind;
|
use rustc_middle::mir::BorrowKind;
|
||||||
use rustc_middle::span_bug;
|
use rustc_middle::span_bug;
|
||||||
use rustc_middle::thir::visit::Visitor;
|
use rustc_middle::thir::visit::Visitor;
|
||||||
|
@ -31,7 +32,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
|
||||||
safety_context: SafetyContext,
|
safety_context: SafetyContext,
|
||||||
/// The `#[target_feature]` attributes of the body. Used for checking
|
/// The `#[target_feature]` attributes of the body. Used for checking
|
||||||
/// calls to functions with `#[target_feature]` (RFC 2396).
|
/// calls to functions with `#[target_feature]` (RFC 2396).
|
||||||
body_target_features: &'tcx [Symbol],
|
body_target_features: &'tcx [TargetFeature],
|
||||||
/// When inside the LHS of an assignment to a field, this is the type
|
/// When inside the LHS of an assignment to a field, this is the type
|
||||||
/// of the LHS and the span of the assignment expression.
|
/// of the LHS and the span of the assignment expression.
|
||||||
assignment_info: Option<Ty<'tcx>>,
|
assignment_info: Option<Ty<'tcx>>,
|
||||||
|
@ -442,14 +443,29 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
||||||
// is_like_wasm check in hir_analysis/src/collect.rs
|
// is_like_wasm check in hir_analysis/src/collect.rs
|
||||||
let callee_features = &self.tcx.codegen_fn_attrs(func_did).target_features;
|
let callee_features = &self.tcx.codegen_fn_attrs(func_did).target_features;
|
||||||
if !self.tcx.sess.target.options.is_like_wasm
|
if !self.tcx.sess.target.options.is_like_wasm
|
||||||
&& !callee_features
|
&& !callee_features.iter().all(|feature| {
|
||||||
.iter()
|
self.body_target_features.iter().any(|f| f.name == feature.name)
|
||||||
.all(|feature| self.body_target_features.contains(feature))
|
})
|
||||||
{
|
{
|
||||||
|
// Don't include implicit features in the error, unless only implicit
|
||||||
|
// features are missing.
|
||||||
|
let missing_explicit_features = callee_features.iter().any(|feature| {
|
||||||
|
!feature.implied
|
||||||
|
&& !self.body_target_features.iter().any(|body_feature| {
|
||||||
|
!feature.implied && body_feature.name == feature.name
|
||||||
|
})
|
||||||
|
});
|
||||||
let missing: Vec<_> = callee_features
|
let missing: Vec<_> = callee_features
|
||||||
.iter()
|
.iter()
|
||||||
.copied()
|
.copied()
|
||||||
.filter(|feature| !self.body_target_features.contains(feature))
|
.filter(|feature| {
|
||||||
|
!(missing_explicit_features && feature.implied)
|
||||||
|
&& !self
|
||||||
|
.body_target_features
|
||||||
|
.iter()
|
||||||
|
.any(|body_feature| body_feature.name == feature.name)
|
||||||
|
})
|
||||||
|
.map(|feature| feature.name)
|
||||||
.collect();
|
.collect();
|
||||||
let build_enabled = self
|
let build_enabled = self
|
||||||
.tcx
|
.tcx
|
||||||
|
|
|
@ -479,7 +479,9 @@ impl<'tcx> Inliner<'tcx> {
|
||||||
return Err("incompatible instruction set");
|
return Err("incompatible instruction set");
|
||||||
}
|
}
|
||||||
|
|
||||||
if callee_attrs.target_features != self.codegen_fn_attrs.target_features {
|
let callee_feature_names = callee_attrs.target_features.iter().map(|f| f.name);
|
||||||
|
let this_feature_names = self.codegen_fn_attrs.target_features.iter().map(|f| f.name);
|
||||||
|
if callee_feature_names.ne(this_feature_names) {
|
||||||
// In general it is not correct to inline a callee with target features that are a
|
// In general it is not correct to inline a callee with target features that are a
|
||||||
// subset of the caller. This is because the callee might contain calls, and the ABI of
|
// subset of the caller. This is because the callee might contain calls, and the ABI of
|
||||||
// those calls depends on the target features of the surrounding function. By moving a
|
// those calls depends on the target features of the surrounding function. By moving a
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: calling a function that requires unavailable target features: avx, sse3, sse4.1, sse4.2, ssse3
|
error: Undefined Behavior: calling a function that requires unavailable target features: avx
|
||||||
--> $DIR/simd_feature_flag_difference.rs:LL:CC
|
--> $DIR/simd_feature_flag_difference.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | unsafe { foo(0.0, x) }
|
LL | unsafe { foo(0.0, x) }
|
||||||
| ^^^^^^^^^^^ calling a function that requires unavailable target features: avx, sse3, sse4.1, sse4.2, ssse3
|
| ^^^^^^^^^^^ calling a function that requires unavailable target features: avx
|
||||||
|
|
|
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
assert!(!is_x86_feature_detected!("ssse3"));
|
assert!(!is_x86_feature_detected!("ssse3"));
|
||||||
unsafe {
|
unsafe {
|
||||||
ssse3_fn(); //~ ERROR: calling a function that requires unavailable target features: sse3, ssse3
|
ssse3_fn(); //~ ERROR: calling a function that requires unavailable target features: ssse3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: calling a function that requires unavailable target features: sse3, ssse3
|
error: Undefined Behavior: calling a function that requires unavailable target features: ssse3
|
||||||
--> $DIR/target_feature.rs:LL:CC
|
--> $DIR/target_feature.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | ssse3_fn();
|
LL | ssse3_fn();
|
||||||
| ^^^^^^^^^^ calling a function that requires unavailable target features: sse3, ssse3
|
| ^^^^^^^^^^ calling a function that requires unavailable target features: ssse3
|
||||||
|
|
|
|
||||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
//@ignore-target-s390x
|
//@ignore-target-s390x
|
||||||
//@ignore-target-thumbv7em
|
//@ignore-target-thumbv7em
|
||||||
//@ignore-target-wasm32
|
//@ignore-target-wasm32
|
||||||
//@compile-flags: -C target-feature=+aes,+vaes,+avx512f,+sse4.2
|
//@compile-flags: -C target-feature=+aes,+vaes,+avx512f
|
||||||
|
|
||||||
#![feature(avx512_target_feature, stdarch_x86_avx512)]
|
#![feature(avx512_target_feature, stdarch_x86_avx512)]
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
//@ignore-target-s390x
|
//@ignore-target-s390x
|
||||||
//@ignore-target-thumbv7em
|
//@ignore-target-thumbv7em
|
||||||
//@ignore-target-wasm32
|
//@ignore-target-wasm32
|
||||||
//@compile-flags: -C target-feature=+avx,+sse4.2
|
//@compile-flags: -C target-feature=+avx
|
||||||
|
|
||||||
#[cfg(target_arch = "x86")]
|
#[cfg(target_arch = "x86")]
|
||||||
use std::arch::x86::*;
|
use std::arch::x86::*;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
//@ignore-target-s390x
|
//@ignore-target-s390x
|
||||||
//@ignore-target-thumbv7em
|
//@ignore-target-thumbv7em
|
||||||
//@ignore-target-wasm32
|
//@ignore-target-wasm32
|
||||||
//@compile-flags: -C target-feature=+avx2,+sse4.2
|
//@compile-flags: -C target-feature=+avx2
|
||||||
|
|
||||||
#[cfg(target_arch = "x86")]
|
#[cfg(target_arch = "x86")]
|
||||||
use std::arch::x86::*;
|
use std::arch::x86::*;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
//@ignore-target-s390x
|
//@ignore-target-s390x
|
||||||
//@ignore-target-thumbv7em
|
//@ignore-target-thumbv7em
|
||||||
//@ignore-target-wasm32
|
//@ignore-target-wasm32
|
||||||
//@compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bitalg,+avx512vpopcntdq,+sse4.2
|
//@compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bitalg,+avx512vpopcntdq
|
||||||
|
|
||||||
#![feature(avx512_target_feature)]
|
#![feature(avx512_target_feature)]
|
||||||
#![feature(stdarch_x86_avx512)]
|
#![feature(stdarch_x86_avx512)]
|
||||||
|
|
|
@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/const_fn_target_feature.rs:11:24
|
--> $DIR/const_fn_target_feature.rs:11:24
|
||||||
|
|
|
|
||||||
LL | const B: () = unsafe { avx2_fn() };
|
LL | const B: () = unsafe { avx2_fn() };
|
||||||
| ^^^^^^^^^ calling a function that requires unavailable target features: avx, avx2, sse4.1, sse4.2
|
| ^^^^^^^^^ calling a function that requires unavailable target features: avx2
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and req
|
||||||
LL | sse2();
|
LL | sse2();
|
||||||
| ^^^^^^ call to function with `#[target_feature]`
|
| ^^^^^^ call to function with `#[target_feature]`
|
||||||
|
|
|
|
||||||
= help: in order for the call to be safe, the context requires the following additional target features: sse and sse2
|
= help: in order for the call to be safe, the context requires the following additional target feature: sse2
|
||||||
= note: the sse and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
|
= note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
|
||||||
|
|
||||||
error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
|
error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||||
--> $DIR/safe-calls.rs:29:5
|
--> $DIR/safe-calls.rs:29:5
|
||||||
|
@ -13,8 +13,7 @@ error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and
|
||||||
LL | avx_bmi2();
|
LL | avx_bmi2();
|
||||||
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
||||||
|
|
|
|
||||||
= help: in order for the call to be safe, the context requires the following additional target features: avx, sse, sse2, sse3, sse4.1, sse4.2, ssse3, and bmi2
|
= help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
|
||||||
= note: the sse and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
|
|
||||||
|
|
||||||
error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
|
error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||||
--> $DIR/safe-calls.rs:31:5
|
--> $DIR/safe-calls.rs:31:5
|
||||||
|
@ -22,8 +21,7 @@ error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsa
|
||||||
LL | Quux.avx_bmi2();
|
LL | Quux.avx_bmi2();
|
||||||
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
|
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
|
||||||
|
|
|
|
||||||
= help: in order for the call to be safe, the context requires the following additional target features: avx, sse, sse2, sse3, sse4.1, sse4.2, ssse3, and bmi2
|
= help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
|
||||||
= note: the sse and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
|
|
||||||
|
|
||||||
error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
|
error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||||
--> $DIR/safe-calls.rs:38:5
|
--> $DIR/safe-calls.rs:38:5
|
||||||
|
@ -31,7 +29,7 @@ error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and
|
||||||
LL | avx_bmi2();
|
LL | avx_bmi2();
|
||||||
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
| ^^^^^^^^^^ call to function with `#[target_feature]`
|
||||||
|
|
|
|
||||||
= help: in order for the call to be safe, the context requires the following additional target features: avx, sse3, sse4.1, sse4.2, ssse3, and bmi2
|
= help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
|
||||||
|
|
||||||
error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
|
error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||||
--> $DIR/safe-calls.rs:40:5
|
--> $DIR/safe-calls.rs:40:5
|
||||||
|
@ -39,7 +37,7 @@ error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsa
|
||||||
LL | Quux.avx_bmi2();
|
LL | Quux.avx_bmi2();
|
||||||
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
|
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
|
||||||
|
|
|
|
||||||
= help: in order for the call to be safe, the context requires the following additional target features: avx, sse3, sse4.1, sse4.2, ssse3, and bmi2
|
= help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2
|
||||||
|
|
||||||
error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
|
error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||||
--> $DIR/safe-calls.rs:47:5
|
--> $DIR/safe-calls.rs:47:5
|
||||||
|
@ -63,8 +61,8 @@ error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and req
|
||||||
LL | const _: () = sse2();
|
LL | const _: () = sse2();
|
||||||
| ^^^^^^ call to function with `#[target_feature]`
|
| ^^^^^^ call to function with `#[target_feature]`
|
||||||
|
|
|
|
||||||
= help: in order for the call to be safe, the context requires the following additional target features: sse and sse2
|
= help: in order for the call to be safe, the context requires the following additional target feature: sse2
|
||||||
= note: the sse and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
|
= note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
|
||||||
|
|
||||||
error[E0133]: call to function `sse2_and_fxsr` with `#[target_feature]` is unsafe and requires unsafe function or block
|
error[E0133]: call to function `sse2_and_fxsr` with `#[target_feature]` is unsafe and requires unsafe function or block
|
||||||
--> $DIR/safe-calls.rs:64:15
|
--> $DIR/safe-calls.rs:64:15
|
||||||
|
@ -72,8 +70,8 @@ error[E0133]: call to function `sse2_and_fxsr` with `#[target_feature]` is unsaf
|
||||||
LL | const _: () = sse2_and_fxsr();
|
LL | const _: () = sse2_and_fxsr();
|
||||||
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
|
| ^^^^^^^^^^^^^^^ call to function with `#[target_feature]`
|
||||||
|
|
|
|
||||||
= help: in order for the call to be safe, the context requires the following additional target features: sse, sse2, and fxsr
|
= help: in order for the call to be safe, the context requires the following additional target features: sse2 and fxsr
|
||||||
= note: the fxsr, sse, and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
|
= note: the fxsr and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
|
||||||
|
|
||||||
error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe block
|
error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe block
|
||||||
--> $DIR/safe-calls.rs:69:5
|
--> $DIR/safe-calls.rs:69:5
|
||||||
|
@ -82,8 +80,8 @@ LL | sse2();
|
||||||
| ^^^^^^ call to function with `#[target_feature]`
|
| ^^^^^^ call to function with `#[target_feature]`
|
||||||
|
|
|
|
||||||
= note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
|
= note: for more information, see issue #71668 <https://github.com/rust-lang/rust/issues/71668>
|
||||||
= help: in order for the call to be safe, the context requires the following additional target features: sse and sse2
|
= help: in order for the call to be safe, the context requires the following additional target feature: sse2
|
||||||
= note: the sse and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]`
|
= note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]`
|
||||||
note: an unsafe function restricts its caller, but its body is safe by default
|
note: an unsafe function restricts its caller, but its body is safe by default
|
||||||
--> $DIR/safe-calls.rs:68:1
|
--> $DIR/safe-calls.rs:68:1
|
||||||
|
|
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue