Skip to content

Commit 6bdc877

Browse files
committed
Add a suggestion to cast target_feature fn items to fn pointers.
See #134090 (comment) for the motivation behind this suggestion.
1 parent 203e6c1 commit 6bdc877

File tree

3 files changed

+47
-13
lines changed

3 files changed

+47
-13
lines changed

Diff for: compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+3
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
462462
err.note(
463463
"`#[target_feature]` functions do not implement the `Fn` traits",
464464
);
465+
err.note(
466+
"try casting the function to a `fn` pointer or wrapping it in a closure",
467+
);
465468
}
466469

467470
self.try_to_add_help_message(

Diff for: tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
#[target_feature(enable = "avx")]
66
fn foo() {}
77

8+
#[target_feature(enable = "avx")]
9+
fn bar(arg: i32) {}
10+
811
#[target_feature(enable = "avx")]
912
unsafe fn foo_unsafe() {}
1013

@@ -20,10 +23,15 @@ fn call_once(f: impl FnOnce()) {
2023
f()
2124
}
2225

26+
fn call_once_i32(f: impl FnOnce(i32)) {
27+
f(0)
28+
}
29+
2330
fn main() {
2431
call(foo); //~ ERROR expected a `Fn()` closure, found `#[target_features] fn() {foo}`
2532
call_mut(foo); //~ ERROR expected a `FnMut()` closure, found `#[target_features] fn() {foo}`
2633
call_once(foo); //~ ERROR expected a `FnOnce()` closure, found `#[target_features] fn() {foo}`
34+
call_once_i32(bar); //~ ERROR expected a `FnOnce(i32)` closure, found `#[target_features] fn(i32) {bar}`
2735

2836
call(foo_unsafe);
2937
//~^ ERROR expected a `Fn()` closure, found `unsafe fn() {foo_unsafe}`

Diff for: tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr

+36-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0277]: expected a `Fn()` closure, found `#[target_features] fn() {foo}`
2-
--> $DIR/fn-traits.rs:24:10
2+
--> $DIR/fn-traits.rs:31:10
33
|
44
LL | call(foo);
55
| ---- ^^^ expected an `Fn()` closure, found `#[target_features] fn() {foo}`
@@ -9,14 +9,15 @@ LL | call(foo);
99
= help: the trait `Fn()` is not implemented for fn item `#[target_features] fn() {foo}`
1010
= note: wrap the `#[target_features] fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
1111
= note: `#[target_feature]` functions do not implement the `Fn` traits
12+
= note: try casting the function to a `fn` pointer or wrapping it in a closure
1213
note: required by a bound in `call`
13-
--> $DIR/fn-traits.rs:11:17
14+
--> $DIR/fn-traits.rs:14:17
1415
|
1516
LL | fn call(f: impl Fn()) {
1617
| ^^^^ required by this bound in `call`
1718

1819
error[E0277]: expected a `FnMut()` closure, found `#[target_features] fn() {foo}`
19-
--> $DIR/fn-traits.rs:25:14
20+
--> $DIR/fn-traits.rs:32:14
2021
|
2122
LL | call_mut(foo);
2223
| -------- ^^^ expected an `FnMut()` closure, found `#[target_features] fn() {foo}`
@@ -26,14 +27,15 @@ LL | call_mut(foo);
2627
= help: the trait `FnMut()` is not implemented for fn item `#[target_features] fn() {foo}`
2728
= note: wrap the `#[target_features] fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
2829
= note: `#[target_feature]` functions do not implement the `Fn` traits
30+
= note: try casting the function to a `fn` pointer or wrapping it in a closure
2931
note: required by a bound in `call_mut`
30-
--> $DIR/fn-traits.rs:15:25
32+
--> $DIR/fn-traits.rs:18:25
3133
|
3234
LL | fn call_mut(mut f: impl FnMut()) {
3335
| ^^^^^^^ required by this bound in `call_mut`
3436

3537
error[E0277]: expected a `FnOnce()` closure, found `#[target_features] fn() {foo}`
36-
--> $DIR/fn-traits.rs:26:15
38+
--> $DIR/fn-traits.rs:33:15
3739
|
3840
LL | call_once(foo);
3941
| --------- ^^^ expected an `FnOnce()` closure, found `#[target_features] fn() {foo}`
@@ -43,14 +45,32 @@ LL | call_once(foo);
4345
= help: the trait `FnOnce()` is not implemented for fn item `#[target_features] fn() {foo}`
4446
= note: wrap the `#[target_features] fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
4547
= note: `#[target_feature]` functions do not implement the `Fn` traits
48+
= note: try casting the function to a `fn` pointer or wrapping it in a closure
4649
note: required by a bound in `call_once`
47-
--> $DIR/fn-traits.rs:19:22
50+
--> $DIR/fn-traits.rs:22:22
4851
|
4952
LL | fn call_once(f: impl FnOnce()) {
5053
| ^^^^^^^^ required by this bound in `call_once`
5154

55+
error[E0277]: expected a `FnOnce(i32)` closure, found `#[target_features] fn(i32) {bar}`
56+
--> $DIR/fn-traits.rs:34:19
57+
|
58+
LL | call_once_i32(bar);
59+
| ------------- ^^^ expected an `FnOnce(i32)` closure, found `#[target_features] fn(i32) {bar}`
60+
| |
61+
| required by a bound introduced by this call
62+
|
63+
= help: the trait `FnOnce(i32)` is not implemented for fn item `#[target_features] fn(i32) {bar}`
64+
= note: `#[target_feature]` functions do not implement the `Fn` traits
65+
= note: try casting the function to a `fn` pointer or wrapping it in a closure
66+
note: required by a bound in `call_once_i32`
67+
--> $DIR/fn-traits.rs:26:26
68+
|
69+
LL | fn call_once_i32(f: impl FnOnce(i32)) {
70+
| ^^^^^^^^^^^ required by this bound in `call_once_i32`
71+
5272
error[E0277]: expected a `Fn()` closure, found `unsafe fn() {foo_unsafe}`
53-
--> $DIR/fn-traits.rs:28:10
73+
--> $DIR/fn-traits.rs:36:10
5474
|
5575
LL | call(foo_unsafe);
5676
| ---- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
@@ -61,14 +81,15 @@ LL | call(foo_unsafe);
6181
= note: unsafe function cannot be called generically without an unsafe block
6282
= note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
6383
= note: `#[target_feature]` functions do not implement the `Fn` traits
84+
= note: try casting the function to a `fn` pointer or wrapping it in a closure
6485
note: required by a bound in `call`
65-
--> $DIR/fn-traits.rs:11:17
86+
--> $DIR/fn-traits.rs:14:17
6687
|
6788
LL | fn call(f: impl Fn()) {
6889
| ^^^^ required by this bound in `call`
6990

7091
error[E0277]: expected a `FnMut()` closure, found `unsafe fn() {foo_unsafe}`
71-
--> $DIR/fn-traits.rs:30:14
92+
--> $DIR/fn-traits.rs:38:14
7293
|
7394
LL | call_mut(foo_unsafe);
7495
| -------- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
@@ -79,14 +100,15 @@ LL | call_mut(foo_unsafe);
79100
= note: unsafe function cannot be called generically without an unsafe block
80101
= note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
81102
= note: `#[target_feature]` functions do not implement the `Fn` traits
103+
= note: try casting the function to a `fn` pointer or wrapping it in a closure
82104
note: required by a bound in `call_mut`
83-
--> $DIR/fn-traits.rs:15:25
105+
--> $DIR/fn-traits.rs:18:25
84106
|
85107
LL | fn call_mut(mut f: impl FnMut()) {
86108
| ^^^^^^^ required by this bound in `call_mut`
87109

88110
error[E0277]: expected a `FnOnce()` closure, found `unsafe fn() {foo_unsafe}`
89-
--> $DIR/fn-traits.rs:32:15
111+
--> $DIR/fn-traits.rs:40:15
90112
|
91113
LL | call_once(foo_unsafe);
92114
| --------- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
@@ -97,12 +119,13 @@ LL | call_once(foo_unsafe);
97119
= note: unsafe function cannot be called generically without an unsafe block
98120
= note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
99121
= note: `#[target_feature]` functions do not implement the `Fn` traits
122+
= note: try casting the function to a `fn` pointer or wrapping it in a closure
100123
note: required by a bound in `call_once`
101-
--> $DIR/fn-traits.rs:19:22
124+
--> $DIR/fn-traits.rs:22:22
102125
|
103126
LL | fn call_once(f: impl FnOnce()) {
104127
| ^^^^^^^^ required by this bound in `call_once`
105128

106-
error: aborting due to 6 previous errors
129+
error: aborting due to 7 previous errors
107130

108131
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)