Skip to content

Commit

Permalink
Rollup merge of #95663 - notriddle:notriddle/unsafe-fn-closure, r=com…
Browse files Browse the repository at this point in the history
…piler-errors

diagnostics: give a special note for unsafe fn / Fn/FnOnce/FnMut

Fixes #90073
  • Loading branch information
Dylan-DPC authored Apr 5, 2022
2 parents cbf54fa + 6d18fbb commit 1e555ba
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
flags.push((sym::_Self, Some("&[]".to_owned())));
}

if self_ty.is_fn() {
let fn_sig = self_ty.fn_sig(self.tcx);
let shortname = match fn_sig.unsafety() {
hir::Unsafety::Normal => "fn",
hir::Unsafety::Unsafe => "unsafe fn",
};
flags.push((sym::_Self, Some(shortname.to_owned())));
}

if let ty::Array(aty, len) = self_ty.kind() {
flags.push((sym::_Self, Some("[]".to_owned())));
flags.push((sym::_Self, Some(format!("[{}]", aty))));
Expand Down
18 changes: 18 additions & 0 deletions library/core/src/ops/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@
Args = "()",
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
),
on(
_Self = "unsafe fn",
note = "unsafe function cannot be called generically without an unsafe block",
// SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
label = "call the function in a closure: `|| unsafe {{ /* code */ }}`"
),
message = "expected a `{Fn}<{Args}>` closure, found `{Self}`",
label = "expected an `Fn<{Args}>` closure, found `{Self}`"
)]
Expand Down Expand Up @@ -141,6 +147,12 @@ pub trait Fn<Args>: FnMut<Args> {
Args = "()",
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
),
on(
_Self = "unsafe fn",
note = "unsafe function cannot be called generically without an unsafe block",
// SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
label = "call the function in a closure: `|| unsafe {{ /* code */ }}`"
),
message = "expected a `{FnMut}<{Args}>` closure, found `{Self}`",
label = "expected an `FnMut<{Args}>` closure, found `{Self}`"
)]
Expand Down Expand Up @@ -214,6 +226,12 @@ pub trait FnMut<Args>: FnOnce<Args> {
Args = "()",
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
),
on(
_Self = "unsafe fn",
note = "unsafe function cannot be called generically without an unsafe block",
// SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
label = "call the function in a closure: `|| unsafe {{ /* code */ }}`"
),
message = "expected a `{FnOnce}<{Args}>` closure, found `{Self}`",
label = "expected an `FnOnce<{Args}>` closure, found `{Self}`"
)]
Expand Down
3 changes: 2 additions & 1 deletion src/test/ui/closures/coerce-unsafe-to-closure.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ error[E0277]: expected a `FnOnce<(&str,)>` closure, found `unsafe extern "rust-i
--> $DIR/coerce-unsafe-to-closure.rs:2:44
|
LL | let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
| --- ^^^^^^^^^^^^^^^^^^^ expected an `FnOnce<(&str,)>` closure, found `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
| --- ^^^^^^^^^^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
| |
| required by a bound introduced by this call
|
= help: the trait `FnOnce<(&str,)>` is not implemented for `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
= note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `Option::<T>::map`
--> $SRC_DIR/core/src/option.rs:LL:COL
|
Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ error[E0277]: expected a `Fn<()>` closure, found `unsafe fn() {foo_unsafe}`
--> $DIR/fn-traits.rs:28:10
|
LL | call(foo_unsafe);
| ---- ^^^^^^^^^^ expected an `Fn<()>` closure, found `unsafe fn() {foo_unsafe}`
| ---- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
| |
| required by a bound introduced by this call
|
Expand All @@ -70,7 +70,7 @@ error[E0277]: expected a `FnMut<()>` closure, found `unsafe fn() {foo_unsafe}`
--> $DIR/fn-traits.rs:30:14
|
LL | call_mut(foo_unsafe);
| -------- ^^^^^^^^^^ expected an `FnMut<()>` closure, found `unsafe fn() {foo_unsafe}`
| -------- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
| |
| required by a bound introduced by this call
|
Expand All @@ -87,7 +87,7 @@ error[E0277]: expected a `FnOnce<()>` closure, found `unsafe fn() {foo_unsafe}`
--> $DIR/fn-traits.rs:32:15
|
LL | call_once(foo_unsafe);
| --------- ^^^^^^^^^^ expected an `FnOnce<()>` closure, found `unsafe fn() {foo_unsafe}`
| --------- ^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
| |
| required by a bound introduced by this call
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ error[E0277]: expected a `Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r i
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:20:21
|
LL | let x = call_it(&square, 22);
| ------- ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
| ------- ^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
| |
| required by a bound introduced by this call
|
= help: the trait `for<'r> Fn<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
= note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `call_it`
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:9:15
|
Expand All @@ -17,11 +18,12 @@ error[E0277]: expected a `FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:25:25
|
LL | let y = call_it_mut(&mut square, 22);
| ----------- ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
| ----------- ^^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
| |
| required by a bound introduced by this call
|
= help: the trait `for<'r> FnMut<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
= note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `call_it_mut`
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:19
|
Expand All @@ -32,11 +34,12 @@ error[E0277]: expected a `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:30:26
|
LL | let z = call_it_once(square, 22);
| ------------ ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
| ------------ ^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
| |
| required by a bound introduced by this call
|
= help: the trait `for<'r> FnOnce<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
= note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `call_it_once`
--> $DIR/unboxed-closures-unsafe-extern-fn.rs:15:20
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ error[E0277]: expected a `Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isi
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:21:21
|
LL | let x = call_it(&square, 22);
| ------- ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
| ------- ^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
| |
| required by a bound introduced by this call
|
= help: the trait `for<'r> Fn<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
= note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `call_it`
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:10:15
|
Expand All @@ -17,11 +18,12 @@ error[E0277]: expected a `FnMut<(&isize,)>` closure, found `unsafe fn(isize) ->
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:26:25
|
LL | let y = call_it_mut(&mut square, 22);
| ----------- ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
| ----------- ^^^^^^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
| |
| required by a bound introduced by this call
|
= help: the trait `for<'r> FnMut<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
= note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `call_it_mut`
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:19
|
Expand All @@ -32,11 +34,12 @@ error[E0277]: expected a `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) ->
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:31:26
|
LL | let z = call_it_once(square, 22);
| ------------ ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
| ------------ ^^^^^^ call the function in a closure: `|| unsafe { /* code */ }`
| |
| required by a bound introduced by this call
|
= help: the trait `for<'r> FnOnce<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
= note: unsafe function cannot be called generically without an unsafe block
note: required by a bound in `call_it_once`
--> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:16:20
|
Expand Down

0 comments on commit 1e555ba

Please sign in to comment.