Skip to content

Commit 1e555ba

Browse files
authored
Rollup merge of #95663 - notriddle:notriddle/unsafe-fn-closure, r=compiler-errors
diagnostics: give a special note for unsafe fn / Fn/FnOnce/FnMut Fixes #90073
2 parents cbf54fa + 6d18fbb commit 1e555ba

File tree

6 files changed

+44
-10
lines changed

6 files changed

+44
-10
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs

+9
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
208208
flags.push((sym::_Self, Some("&[]".to_owned())));
209209
}
210210

211+
if self_ty.is_fn() {
212+
let fn_sig = self_ty.fn_sig(self.tcx);
213+
let shortname = match fn_sig.unsafety() {
214+
hir::Unsafety::Normal => "fn",
215+
hir::Unsafety::Unsafe => "unsafe fn",
216+
};
217+
flags.push((sym::_Self, Some(shortname.to_owned())));
218+
}
219+
211220
if let ty::Array(aty, len) = self_ty.kind() {
212221
flags.push((sym::_Self, Some("[]".to_owned())));
213222
flags.push((sym::_Self, Some(format!("[{}]", aty))));

library/core/src/ops/function.rs

+18
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@
6060
Args = "()",
6161
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
6262
),
63+
on(
64+
_Self = "unsafe fn",
65+
note = "unsafe function cannot be called generically without an unsafe block",
66+
// SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
67+
label = "call the function in a closure: `|| unsafe {{ /* code */ }}`"
68+
),
6369
message = "expected a `{Fn}<{Args}>` closure, found `{Self}`",
6470
label = "expected an `Fn<{Args}>` closure, found `{Self}`"
6571
)]
@@ -141,6 +147,12 @@ pub trait Fn<Args>: FnMut<Args> {
141147
Args = "()",
142148
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
143149
),
150+
on(
151+
_Self = "unsafe fn",
152+
note = "unsafe function cannot be called generically without an unsafe block",
153+
// SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
154+
label = "call the function in a closure: `|| unsafe {{ /* code */ }}`"
155+
),
144156
message = "expected a `{FnMut}<{Args}>` closure, found `{Self}`",
145157
label = "expected an `FnMut<{Args}>` closure, found `{Self}`"
146158
)]
@@ -214,6 +226,12 @@ pub trait FnMut<Args>: FnOnce<Args> {
214226
Args = "()",
215227
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
216228
),
229+
on(
230+
_Self = "unsafe fn",
231+
note = "unsafe function cannot be called generically without an unsafe block",
232+
// SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
233+
label = "call the function in a closure: `|| unsafe {{ /* code */ }}`"
234+
),
217235
message = "expected a `{FnOnce}<{Args}>` closure, found `{Self}`",
218236
label = "expected an `FnOnce<{Args}>` closure, found `{Self}`"
219237
)]

src/test/ui/closures/coerce-unsafe-to-closure.stderr

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ error[E0277]: expected a `FnOnce<(&str,)>` closure, found `unsafe extern "rust-i
22
--> $DIR/coerce-unsafe-to-closure.rs:2:44
33
|
44
LL | let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
5-
| --- ^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(&str,)>` closure, found `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
5+
| --- ^^^^^^^^^^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
66
| |
77
| required by a bound introduced by this call
88
|
99
= help: the trait `FnOnce<(&str,)>` is not implemented for `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
10+
= note: unsafe function cannot be called generically without an unsafe block
1011
note: required by a bound in `Option::<T>::map`
1112
--> $SRC_DIR/core/src/option.rs:LL:COL
1213
|

src/test/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ error[E0277]: expected a `Fn<()>` closure, found `unsafe fn() {foo_unsafe}`
5353
--> $DIR/fn-traits.rs:28:10
5454
|
5555
LL | call(foo_unsafe);
56-
| ---- ^^^^^^^^^^ expected an `Fn<()>` closure, found `unsafe fn() {foo_unsafe}`
56+
| ---- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
5757
| |
5858
| required by a bound introduced by this call
5959
|
@@ -70,7 +70,7 @@ error[E0277]: expected a `FnMut<()>` closure, found `unsafe fn() {foo_unsafe}`
7070
--> $DIR/fn-traits.rs:30:14
7171
|
7272
LL | call_mut(foo_unsafe);
73-
| -------- ^^^^^^^^^^ expected an `FnMut<()>` closure, found `unsafe fn() {foo_unsafe}`
73+
| -------- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
7474
| |
7575
| required by a bound introduced by this call
7676
|
@@ -87,7 +87,7 @@ error[E0277]: expected a `FnOnce<()>` closure, found `unsafe fn() {foo_unsafe}`
8787
--> $DIR/fn-traits.rs:32:15
8888
|
8989
LL | call_once(foo_unsafe);
90-
| --------- ^^^^^^^^^^ expected an `FnOnce<()>` closure, found `unsafe fn() {foo_unsafe}`
90+
| --------- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
9191
| |
9292
| required by a bound introduced by this call
9393
|

src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr

+6-3
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ error[E0277]: expected a `Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r i
22
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:20:21
33
|
44
LL | let x = call_it(&square, 22);
5-
| ------- ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
5+
| ------- ^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
66
| |
77
| required by a bound introduced by this call
88
|
99
= help: the trait `for<'r> Fn<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
10+
= note: unsafe function cannot be called generically without an unsafe block
1011
note: required by a bound in `call_it`
1112
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:9:15
1213
|
@@ -17,11 +18,12 @@ error[E0277]: expected a `FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'
1718
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:25:25
1819
|
1920
LL | let y = call_it_mut(&mut square, 22);
20-
| ----------- ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
21+
| ----------- ^^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
2122
| |
2223
| required by a bound introduced by this call
2324
|
2425
= help: the trait `for<'r> FnMut<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
26+
= note: unsafe function cannot be called generically without an unsafe block
2527
note: required by a bound in `call_it_mut`
2628
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:19
2729
|
@@ -32,11 +34,12 @@ error[E0277]: expected a `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&
3234
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:30:26
3335
|
3436
LL | let z = call_it_once(square, 22);
35-
| ------------ ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
37+
| ------------ ^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
3638
| |
3739
| required by a bound introduced by this call
3840
|
3941
= help: the trait `for<'r> FnOnce<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
42+
= note: unsafe function cannot be called generically without an unsafe block
4043
note: required by a bound in `call_it_once`
4144
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:15:20
4245
|

src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr

+6-3
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ error[E0277]: expected a `Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isi
22
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:21:21
33
|
44
LL | let x = call_it(&square, 22);
5-
| ------- ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
5+
| ------- ^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
66
| |
77
| required by a bound introduced by this call
88
|
99
= help: the trait `for<'r> Fn<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
10+
= note: unsafe function cannot be called generically without an unsafe block
1011
note: required by a bound in `call_it`
1112
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:10:15
1213
|
@@ -17,11 +18,12 @@ error[E0277]: expected a `FnMut<(&isize,)>` closure, found `unsafe fn(isize) ->
1718
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:26:25
1819
|
1920
LL | let y = call_it_mut(&mut square, 22);
20-
| ----------- ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
21+
| ----------- ^^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
2122
| |
2223
| required by a bound introduced by this call
2324
|
2425
= help: the trait `for<'r> FnMut<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
26+
= note: unsafe function cannot be called generically without an unsafe block
2527
note: required by a bound in `call_it_mut`
2628
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:19
2729
|
@@ -32,11 +34,12 @@ error[E0277]: expected a `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) ->
3234
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:31:26
3335
|
3436
LL | let z = call_it_once(square, 22);
35-
| ------------ ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
37+
| ------------ ^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
3638
| |
3739
| required by a bound introduced by this call
3840
|
3941
= help: the trait `for<'r> FnOnce<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
42+
= note: unsafe function cannot be called generically without an unsafe block
4043
note: required by a bound in `call_it_once`
4144
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:16:20
4245
|

0 commit comments

Comments
 (0)