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
2 changes: 1 addition & 1 deletion compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4769,7 +4769,7 @@ pub enum RestrictionKind<'hir> {
/// explicitly to allow unsafe operations.
#[derive(Copy, Clone, Debug, StableHash, PartialEq, Eq)]
pub enum HeaderSafety {
/// A safe function annotated with `#[target_features]`.
/// A safe function annotated with `#[target_feature(..)]`.
/// The type system treats this function as an unsafe function,
/// but safety checking will check this enum to treat it as safe
/// and allowing calling other safe target feature functions with
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_middle/src/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ impl<'tcx> TypeError<'tcx> {
}
TypeError::IntrinsicCast => "cannot coerce intrinsics to function pointers".into(),
TypeError::TargetFeatureCast(_) => {
"cannot coerce functions with `#[target_feature]` to safe function pointers".into()
"cannot coerce functions with `#[target_feature(..)]` to safe function pointers"
.into()
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
let mut sig =
self.tcx().fn_sig(def_id).instantiate(self.tcx(), args).skip_norm_wip();
if self.tcx().codegen_fn_attrs(def_id).safe_target_features {
write!(self, "#[target_features] ")?;
write!(self, "#[target_feature(..)] ")?;
sig = sig.map_bound(|mut sig| {
sig.fn_sig_kind = sig.fn_sig_kind.set_safety(hir::Safety::Safe);
sig
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1219,7 +1219,7 @@ impl Target {
/// These features are checked against the target features reported by LLVM based on
/// `-Ctarget-cpu` and `-Ctarget-features`. Constraint violations result in a warning.
///
/// We also check features enabled via `#[target_features]` (and here, constraint violations
/// We also check features enabled via `#[target_feature(..)]` (and here, constraint violations
/// emit a hard error), including features enabled indirectly via implications -- but if LLVM
/// considers more features to be implied than we do, that could bypass this check!
pub fn abi_required_features(&self) -> FeatureConstraints {
Expand Down
36 changes: 18 additions & 18 deletions compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -773,17 +773,17 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
let (lt1, sig1) = get_lifetimes(sig1);
let (lt2, sig2) = get_lifetimes(sig2);

// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// #[target_feature(..)] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
let mut values =
(DiagStyledString::normal("".to_string()), DiagStyledString::normal("".to_string()));

// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^^^^^^^^^^^^^^
// #[target_feature(..)] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^^^^^^^^^^^^^^^^^
let fn_item_prefix_and_safety = |fn_def, sig: ty::FnSig<'_>| match fn_def {
None => ("", sig.safety().prefix_str()),
Some((did, _)) => {
if self.tcx.codegen_fn_attrs(did).safe_target_features {
("#[target_features] ", "")
("#[target_feature(..)] ", "")
} else {
("", sig.safety().prefix_str())
}
Expand All @@ -794,33 +794,33 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
values.0.push(prefix1, prefix1 != prefix2);
values.1.push(prefix2, prefix1 != prefix2);

// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^^^^
// #[target_feature(..)] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^^^^
let lifetime_diff = lt1 != lt2;
values.0.push(lt1, lifetime_diff);
values.1.push(lt2, lifetime_diff);

// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^^
// #[target_feature(..)] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^^
values.0.push(safety1, safety1 != safety2);
values.1.push(safety2, safety1 != safety2);

// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^^^^^^
// #[target_feature(..)] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^^^^^^
if sig1.abi() != ExternAbi::Rust {
values.0.push(format!("extern {} ", sig1.abi()), sig1.abi() != sig2.abi());
}
if sig2.abi() != ExternAbi::Rust {
values.1.push(format!("extern {} ", sig2.abi()), sig1.abi() != sig2.abi());
}

// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^
// #[target_feature(..)] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^
values.0.push_normal("fn(");
values.1.push_normal("fn(");

// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^
// #[target_feature(..)] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^
let len1 = sig1.inputs().len();
let len2 = sig2.inputs().len();
let splatted_arg_index1 = sig1.splatted().map(usize::from);
Expand Down Expand Up @@ -868,13 +868,13 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
values.1.push("...", !sig1.c_variadic());
}

// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^
// #[target_feature(..)] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^
values.0.push_normal(")");
values.1.push_normal(")");

// #[target_features] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^^^^
// #[target_feature(..)] for<'a> unsafe extern "C" fn(&'a T) -> &'a T
// ^^^^^^^^
let output1 = sig1.output();
let output2 = sig2.output();
let (x1, x2) = self.cmp(output1, output2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -621,9 +621,9 @@ impl<T> Trait<T> for X {
TypeError::TargetFeatureCast(def_id) => {
let target_spans = find_attr!(tcx, def_id, TargetFeature{attr_span: span, was_forced: false, ..} => *span);
diag.note(
"functions with `#[target_feature]` can only be coerced to `unsafe` function pointers"
"functions with `#[target_feature(..)]` can only be coerced to `unsafe` function pointers"
);
diag.span_labels(target_spans, "`#[target_feature]` added here");
diag.span_labels(target_spans, "`#[target_feature(..)]` added here");
}
_ => {}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
};
if is_fn_trait && is_target_feature_fn {
err.note(
"`#[target_feature]` functions do not implement the `Fn` traits",
"`#[target_feature(..)]` functions do not implement the `Fn` traits",
);
err.note(
"try casting the function to a `fn` pointer or wrapping it in a closure",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
error[E0277]: the trait bound `#[target_features] fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}: AsyncFn()` is not satisfied
error[E0277]: the trait bound `#[target_feature(..)] fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}: AsyncFn()` is not satisfied
--> $DIR/fn-exception-target-features.rs:15:10
|
LL | test(target_feature);
| ---- ^^^^^^^^^^^^^^ unsatisfied trait bound
| |
| required by a bound introduced by this call
|
= help: the trait `AsyncFn()` is not implemented for fn item `#[target_features] fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}`
= help: the trait `AsyncFn()` is not implemented for fn item `#[target_feature(..)] fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> {target_feature}`
note: required by a bound in `test`
--> $DIR/fn-exception-target-features.rs:12:17
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ note: type in trait
LL | fn foo(&self);
| ^^^^^^^^^^^^^^
= note: expected signature `fn(&Bar2)`
found signature `#[target_features] fn(&Bar2)`
found signature `#[target_feature(..)] fn(&Bar2)`

error: aborting due to 3 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ note: type in trait
LL | fn foo(&self);
| ^^^^^^^^^^^^^^
= note: expected signature `fn(&Bar2)`
found signature `#[target_features] fn(&Bar2)`
found signature `#[target_feature(..)] fn(&Bar2)`

error: aborting due to 2 previous errors; 1 warning emitted

Expand Down
16 changes: 8 additions & 8 deletions tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@ error[E0308]: mismatched types
--> $DIR/fn-ptr.rs:12:21
|
LL | #[target_feature(enable = "avx")]
| --------------------------------- `#[target_feature]` added here
| --------------------------------- `#[target_feature(..)]` added here
...
LL | let foo: fn() = foo_avx;
| ---- ^^^^^^^ cannot coerce functions with `#[target_feature]` to safe function pointers
| ---- ^^^^^^^ cannot coerce functions with `#[target_feature(..)]` to safe function pointers
| |
| expected due to this
|
= note: expected fn pointer `fn()`
found fn item `#[target_features] fn() {foo_avx}`
= note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
found fn item `#[target_feature(..)] fn() {foo_avx}`
= note: functions with `#[target_feature(..)]` can only be coerced to `unsafe` function pointers

error[E0308]: mismatched types
--> $DIR/fn-ptr.rs:21:21
|
LL | #[target_feature(enable = "sse2")]
| ---------------------------------- `#[target_feature]` added here
| ---------------------------------- `#[target_feature(..)]` added here
...
LL | let foo: fn() = foo;
| ---- ^^^ cannot coerce functions with `#[target_feature]` to safe function pointers
| ---- ^^^ cannot coerce functions with `#[target_feature(..)]` to safe function pointers
| |
| expected due to this
|
= note: expected fn pointer `fn()`
found fn item `#[target_features] fn() {foo}`
= note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers
found fn item `#[target_feature(..)] fn() {foo}`
= note: functions with `#[target_feature(..)]` can only be coerced to `unsafe` function pointers

error: aborting due to 2 previous errors

Expand Down
8 changes: 4 additions & 4 deletions tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ fn call_once_i32(f: impl FnOnce(i32)) {
}

fn main() {
call(foo); //~ ERROR expected an `Fn()` closure, found `#[target_features] fn() {foo}`
call_mut(foo); //~ ERROR expected an `FnMut()` closure, found `#[target_features] fn() {foo}`
call_once(foo); //~ ERROR expected an `FnOnce()` closure, found `#[target_features] fn() {foo}`
call_once_i32(bar); //~ ERROR expected an `FnOnce(i32)` closure, found `#[target_features] fn(i32) {bar}`
call(foo); //~ ERROR expected an `Fn()` closure, found `#[target_feature(..)] fn() {foo}`
call_mut(foo); //~ ERROR expected an `FnMut()` closure, found `#[target_feature(..)] fn() {foo}`
call_once(foo); //~ ERROR expected an `FnOnce()` closure, found `#[target_feature(..)] fn() {foo}`
call_once_i32(bar); //~ ERROR expected an `FnOnce(i32)` closure, found `#[target_feature(..)] fn(i32) {bar}`

call(foo_unsafe);
//~^ ERROR expected an `Fn()` closure, found `unsafe fn() {foo_unsafe}`
Expand Down
44 changes: 22 additions & 22 deletions tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr
Original file line number Diff line number Diff line change
@@ -1,67 +1,67 @@
error[E0277]: expected an `Fn()` closure, found `#[target_features] fn() {foo}`
error[E0277]: expected an `Fn()` closure, found `#[target_feature(..)] fn() {foo}`
--> $DIR/fn-traits.rs:29:10
|
LL | call(foo);
| ---- ^^^ expected an `Fn()` closure, found `#[target_features] fn() {foo}`
| ---- ^^^ expected an `Fn()` closure, found `#[target_feature(..)] fn() {foo}`
| |
| required by a bound introduced by this call
|
= help: the trait `Fn()` is not implemented for fn item `#[target_features] fn() {foo}`
= note: wrap the `#[target_features] fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
= note: `#[target_feature]` functions do not implement the `Fn` traits
= help: the trait `Fn()` is not implemented for fn item `#[target_feature(..)] fn() {foo}`
= note: wrap the `#[target_feature(..)] fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
= note: `#[target_feature(..)]` functions do not implement the `Fn` traits
= note: try casting the function to a `fn` pointer or wrapping it in a closure
note: required by a bound in `call`
--> $DIR/fn-traits.rs:12:17
|
LL | fn call(f: impl Fn()) {
| ^^^^ required by this bound in `call`

error[E0277]: expected an `FnMut()` closure, found `#[target_features] fn() {foo}`
error[E0277]: expected an `FnMut()` closure, found `#[target_feature(..)] fn() {foo}`
--> $DIR/fn-traits.rs:30:14
|
LL | call_mut(foo);
| -------- ^^^ expected an `FnMut()` closure, found `#[target_features] fn() {foo}`
| -------- ^^^ expected an `FnMut()` closure, found `#[target_feature(..)] fn() {foo}`
| |
| required by a bound introduced by this call
|
= help: the trait `FnMut()` is not implemented for fn item `#[target_features] fn() {foo}`
= note: wrap the `#[target_features] fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
= note: `#[target_feature]` functions do not implement the `Fn` traits
= help: the trait `FnMut()` is not implemented for fn item `#[target_feature(..)] fn() {foo}`
= note: wrap the `#[target_feature(..)] fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
= note: `#[target_feature(..)]` functions do not implement the `Fn` traits
= note: try casting the function to a `fn` pointer or wrapping it in a closure
note: required by a bound in `call_mut`
--> $DIR/fn-traits.rs:16:25
|
LL | fn call_mut(mut f: impl FnMut()) {
| ^^^^^^^ required by this bound in `call_mut`

error[E0277]: expected an `FnOnce()` closure, found `#[target_features] fn() {foo}`
error[E0277]: expected an `FnOnce()` closure, found `#[target_feature(..)] fn() {foo}`
--> $DIR/fn-traits.rs:31:15
|
LL | call_once(foo);
| --------- ^^^ expected an `FnOnce()` closure, found `#[target_features] fn() {foo}`
| --------- ^^^ expected an `FnOnce()` closure, found `#[target_feature(..)] fn() {foo}`
| |
| required by a bound introduced by this call
|
= help: the trait `FnOnce()` is not implemented for fn item `#[target_features] fn() {foo}`
= note: wrap the `#[target_features] fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
= note: `#[target_feature]` functions do not implement the `Fn` traits
= help: the trait `FnOnce()` is not implemented for fn item `#[target_feature(..)] fn() {foo}`
= note: wrap the `#[target_feature(..)] fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
= note: `#[target_feature(..)]` functions do not implement the `Fn` traits
= note: try casting the function to a `fn` pointer or wrapping it in a closure
note: required by a bound in `call_once`
--> $DIR/fn-traits.rs:20:22
|
LL | fn call_once(f: impl FnOnce()) {
| ^^^^^^^^ required by this bound in `call_once`

error[E0277]: expected an `FnOnce(i32)` closure, found `#[target_features] fn(i32) {bar}`
error[E0277]: expected an `FnOnce(i32)` closure, found `#[target_feature(..)] fn(i32) {bar}`
--> $DIR/fn-traits.rs:32:19
|
LL | call_once_i32(bar);
| ------------- ^^^ expected an `FnOnce(i32)` closure, found `#[target_features] fn(i32) {bar}`
| ------------- ^^^ expected an `FnOnce(i32)` closure, found `#[target_feature(..)] fn(i32) {bar}`
| |
| required by a bound introduced by this call
|
= help: the trait `FnOnce(i32)` is not implemented for fn item `#[target_features] fn(i32) {bar}`
= note: `#[target_feature]` functions do not implement the `Fn` traits
= help: the trait `FnOnce(i32)` is not implemented for fn item `#[target_feature(..)] fn(i32) {bar}`
= note: `#[target_feature(..)]` functions do not implement the `Fn` traits
= note: try casting the function to a `fn` pointer or wrapping it in a closure
note: required by a bound in `call_once_i32`
--> $DIR/fn-traits.rs:24:26
Expand All @@ -80,7 +80,7 @@ LL | call(foo_unsafe);
= help: the trait `Fn()` is not implemented for fn item `unsafe fn() {foo_unsafe}`
= note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
= note: unsafe function cannot be called generically without an unsafe block
= note: `#[target_feature]` functions do not implement the `Fn` traits
= note: `#[target_feature(..)]` functions do not implement the `Fn` traits
= note: try casting the function to a `fn` pointer or wrapping it in a closure
note: required by a bound in `call`
--> $DIR/fn-traits.rs:12:17
Expand All @@ -99,7 +99,7 @@ LL | call_mut(foo_unsafe);
= help: the trait `FnMut()` is not implemented for fn item `unsafe fn() {foo_unsafe}`
= note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
= note: unsafe function cannot be called generically without an unsafe block
= note: `#[target_feature]` functions do not implement the `Fn` traits
= note: `#[target_feature(..)]` functions do not implement the `Fn` traits
= note: try casting the function to a `fn` pointer or wrapping it in a closure
note: required by a bound in `call_mut`
--> $DIR/fn-traits.rs:16:25
Expand All @@ -118,7 +118,7 @@ LL | call_once(foo_unsafe);
= help: the trait `FnOnce()` is not implemented for fn item `unsafe fn() {foo_unsafe}`
= note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
= note: unsafe function cannot be called generically without an unsafe block
= note: `#[target_feature]` functions do not implement the `Fn` traits
= note: `#[target_feature(..)]` functions do not implement the `Fn` traits
= note: try casting the function to a `fn` pointer or wrapping it in a closure
note: required by a bound in `call_once`
--> $DIR/fn-traits.rs:20:22
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/rfcs/rfc-2396-target_feature-11/trait-impl.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ note: type in trait
LL | fn foo(&self);
| ^^^^^^^^^^^^^^
= note: expected signature `fn(&Bar)`
found signature `#[target_features] fn(&Bar)`
found signature `#[target_feature(..)] fn(&Bar)`

error: `#[target_feature(..)]` cannot be applied to safe trait method
--> $DIR/trait-impl.rs:21:5
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/target-feature/invalid-attribute.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ note: type in trait
LL | fn foo();
| ^^^^^^^^^
= note: expected signature `fn()`
found signature `#[target_features] fn()`
found signature `#[target_feature(..)] fn()`

error: the feature named `+sse2` is not valid for this target
--> $DIR/invalid-attribute.rs:117:18
Expand Down
Loading