diff --git a/src/libcore/ops/function.rs b/src/libcore/ops/function.rs index d10fcb86b2411..3ebd10a920919 100644 --- a/src/libcore/ops/function.rs +++ b/src/libcore/ops/function.rs @@ -66,6 +66,11 @@ #[lang = "fn"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_paren_sugar] +#[rustc_on_unimplemented( + on(Args="()", note="wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"), + message="expected a `{Fn}<{Args}>` closure, found `{Self}`", + label="expected an `Fn<{Args}>` closure, found `{Self}`", +)] #[fundamental] // so that regex can rely that `&str: !FnMut` pub trait Fn : FnMut { /// Performs the call operation. @@ -139,6 +144,11 @@ pub trait Fn : FnMut { #[lang = "fn_mut"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_paren_sugar] +#[rustc_on_unimplemented( + on(Args="()", note="wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"), + message="expected a `{FnMut}<{Args}>` closure, found `{Self}`", + label="expected an `FnMut<{Args}>` closure, found `{Self}`", +)] #[fundamental] // so that regex can rely that `&str: !FnMut` pub trait FnMut : FnOnce { /// Performs the call operation. @@ -212,6 +222,11 @@ pub trait FnMut : FnOnce { #[lang = "fn_once"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_paren_sugar] +#[rustc_on_unimplemented( + on(Args="()", note="wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"), + message="expected a `{FnOnce}<{Args}>` closure, found `{Self}`", + label="expected an `FnOnce<{Args}>` closure, found `{Self}`", +)] #[fundamental] // so that regex can rely that `&str: !FnMut` pub trait FnOnce { /// The returned type after the call operator is used. diff --git a/src/test/ui/closure-expected.rs b/src/test/ui/closure-expected.rs new file mode 100644 index 0000000000000..ff52948ca8559 --- /dev/null +++ b/src/test/ui/closure-expected.rs @@ -0,0 +1,15 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let x = Some(1); + let y = x.or_else(4); + //~^ ERROR expected a `std::ops::FnOnce<()>` closure, found `{integer}` +} diff --git a/src/test/ui/closure-expected.stderr b/src/test/ui/closure-expected.stderr new file mode 100644 index 0000000000000..0da506b5b8139 --- /dev/null +++ b/src/test/ui/closure-expected.stderr @@ -0,0 +1,12 @@ +error[E0277]: expected a `std::ops::FnOnce<()>` closure, found `{integer}` + --> $DIR/closure-expected.rs:13:15 + | +LL | let y = x.or_else(4); + | ^^^^^^^ expected an `FnOnce<()>` closure, found `{integer}` + | + = help: the trait `std::ops::FnOnce<()>` is not implemented for `{integer}` + = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ } + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/extern/extern-wrong-value-type.rs b/src/test/ui/extern/extern-wrong-value-type.rs index 66b06c505e476..ea313385c1018 100644 --- a/src/test/ui/extern/extern-wrong-value-type.rs +++ b/src/test/ui/extern/extern-wrong-value-type.rs @@ -17,5 +17,5 @@ fn main() { // extern functions are extern "C" fn let _x: extern "C" fn() = f; // OK is_fn(f); - //~^ ERROR `extern "C" fn() {f}: std::ops::Fn<()>` is not satisfied + //~^ ERROR expected a `std::ops::Fn<()>` closure, found `extern "C" fn() {f}` } diff --git a/src/test/ui/extern/extern-wrong-value-type.stderr b/src/test/ui/extern/extern-wrong-value-type.stderr index 35e0d68e46aa8..0d8185839ccb4 100644 --- a/src/test/ui/extern/extern-wrong-value-type.stderr +++ b/src/test/ui/extern/extern-wrong-value-type.stderr @@ -1,9 +1,11 @@ -error[E0277]: the trait bound `extern "C" fn() {f}: std::ops::Fn<()>` is not satisfied +error[E0277]: expected a `std::ops::Fn<()>` closure, found `extern "C" fn() {f}` --> $DIR/extern-wrong-value-type.rs:19:5 | LL | is_fn(f); - | ^^^^^ the trait `std::ops::Fn<()>` is not implemented for `extern "C" fn() {f}` + | ^^^^^ expected an `Fn<()>` closure, found `extern "C" fn() {f}` | + = help: the trait `std::ops::Fn<()>` is not implemented for `extern "C" fn() {f}` + = note: wrap the `extern "C" fn() {f}` in a closure with no arguments: `|| { /* code */ } note: required by `is_fn` --> $DIR/extern-wrong-value-type.rs:14:1 | diff --git a/src/test/ui/fn/fn-trait-formatting.rs b/src/test/ui/fn/fn-trait-formatting.rs index 56d64d77ee258..ac7b0a6098462 100644 --- a/src/test/ui/fn/fn-trait-formatting.rs +++ b/src/test/ui/fn/fn-trait-formatting.rs @@ -27,5 +27,5 @@ fn main() { //~| found type `std::boxed::Box isize>` needs_fn(1); - //~^ ERROR : std::ops::Fn<(isize,)>` + //~^ ERROR expected a `std::ops::Fn<(isize,)>` closure, found `{integer}` } diff --git a/src/test/ui/fn/fn-trait-formatting.stderr b/src/test/ui/fn/fn-trait-formatting.stderr index 5bf1ed76d5f46..198b343cdd3e7 100644 --- a/src/test/ui/fn/fn-trait-formatting.stderr +++ b/src/test/ui/fn/fn-trait-formatting.stderr @@ -25,15 +25,13 @@ LL | let _: () = (box || -> isize { unimplemented!() }) as Box is = note: expected type `()` found type `std::boxed::Box isize>` -error[E0277]: the trait bound `{integer}: std::ops::Fn<(isize,)>` is not satisfied +error[E0277]: expected a `std::ops::Fn<(isize,)>` closure, found `{integer}` --> $DIR/fn-trait-formatting.rs:29:5 | LL | needs_fn(1); - | ^^^^^^^^ the trait `std::ops::Fn<(isize,)>` is not implemented for `{integer}` + | ^^^^^^^^ expected an `Fn<(isize,)>` closure, found `{integer}` | - = help: the following implementations were found: - <&'a F as std::ops::Fn> - > + = help: the trait `std::ops::Fn<(isize,)>` is not implemented for `{integer}` note: required by `needs_fn` --> $DIR/fn-trait-formatting.rs:13:1 | diff --git a/src/test/ui/issues/issue-22034.rs b/src/test/ui/issues/issue-22034.rs index 5271ea7991784..2708de2c13a8f 100644 --- a/src/test/ui/issues/issue-22034.rs +++ b/src/test/ui/issues/issue-22034.rs @@ -16,6 +16,6 @@ fn main() { let ptr: *mut () = 0 as *mut _; let _: &mut Fn() = unsafe { &mut *(ptr as *mut Fn()) - //~^ ERROR `(): std::ops::Fn<()>` is not satisfied + //~^ ERROR expected a `std::ops::Fn<()>` closure, found `()` }; } diff --git a/src/test/ui/issues/issue-22034.stderr b/src/test/ui/issues/issue-22034.stderr index bac62a1301aad..da376fedbb98a 100644 --- a/src/test/ui/issues/issue-22034.stderr +++ b/src/test/ui/issues/issue-22034.stderr @@ -1,9 +1,11 @@ -error[E0277]: the trait bound `(): std::ops::Fn<()>` is not satisfied +error[E0277]: expected a `std::ops::Fn<()>` closure, found `()` --> $DIR/issue-22034.rs:18:16 | LL | &mut *(ptr as *mut Fn()) - | ^^^ the trait `std::ops::Fn<()>` is not implemented for `()` + | ^^^ expected an `Fn<()>` closure, found `()` | + = help: the trait `std::ops::Fn<()>` is not implemented for `()` + = note: wrap the `()` in a closure with no arguments: `|| { /* code */ } = note: required for the cast to the object type `dyn std::ops::Fn()` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23966.stderr b/src/test/ui/issues/issue-23966.stderr index 07d2cfbf55f10..0418933180c00 100644 --- a/src/test/ui/issues/issue-23966.stderr +++ b/src/test/ui/issues/issue-23966.stderr @@ -1,8 +1,10 @@ -error[E0277]: the trait bound `(): std::ops::FnMut<(_, char)>` is not satisfied +error[E0277]: expected a `std::ops::FnMut<(_, char)>` closure, found `()` --> $DIR/issue-23966.rs:12:16 | LL | "".chars().fold(|_, _| (), ()); - | ^^^^ the trait `std::ops::FnMut<(_, char)>` is not implemented for `()` + | ^^^^ expected an `FnMut<(_, char)>` closure, found `()` + | + = help: the trait `std::ops::FnMut<(_, char)>` is not implemented for `()` error: aborting due to previous error diff --git a/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr index 95aa3f15b7648..e5e66efcaa2ce 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr @@ -1,9 +1,10 @@ -error[E0277]: the trait bound `S: std::ops::Fn<(isize,)>` is not satisfied +error[E0277]: expected a `std::ops::Fn<(isize,)>` closure, found `S` --> $DIR/unboxed-closures-fnmut-as-fn.rs:38:13 | LL | let x = call_it(&S, 22); - | ^^^^^^^ the trait `std::ops::Fn<(isize,)>` is not implemented for `S` + | ^^^^^^^ expected an `Fn<(isize,)>` closure, found `S` | + = help: the trait `std::ops::Fn<(isize,)>` is not implemented for `S` note: required by `call_it` --> $DIR/unboxed-closures-fnmut-as-fn.rs:33:1 | diff --git a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr index 16b2b11ad7b42..7c76c10443af9 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr @@ -1,33 +1,36 @@ -error[E0277]: the trait bound `for<'r> for<'s> unsafe fn(&'s isize) -> isize {square}: std::ops::Fn<(&'r isize,)>` is not satisfied +error[E0277]: expected a `std::ops::Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` --> $DIR/unboxed-closures-unsafe-extern-fn.rs:22:13 | LL | let x = call_it(&square, 22); - | ^^^^^^^ the trait `for<'r> std::ops::Fn<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}` + | ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` | + = help: the trait `for<'r> std::ops::Fn<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}` note: required by `call_it` --> $DIR/unboxed-closures-unsafe-extern-fn.rs:17:1 | LL | fn call_itisize>(_: &F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `for<'r> for<'s> unsafe fn(&'s isize) -> isize {square}: std::ops::FnMut<(&'r isize,)>` is not satisfied +error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` --> $DIR/unboxed-closures-unsafe-extern-fn.rs:27:13 | LL | let y = call_it_mut(&mut square, 22); - | ^^^^^^^^^^^ the trait `for<'r> std::ops::FnMut<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}` + | ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` | + = help: the trait `for<'r> std::ops::FnMut<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}` note: required by `call_it_mut` --> $DIR/unboxed-closures-unsafe-extern-fn.rs:18:1 | LL | fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `for<'r> for<'s> unsafe fn(&'s isize) -> isize {square}: std::ops::FnOnce<(&'r isize,)>` is not satisfied +error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` --> $DIR/unboxed-closures-unsafe-extern-fn.rs:32:13 | LL | let z = call_it_once(square, 22); - | ^^^^^^^^^^^^ the trait `for<'r> std::ops::FnOnce<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}` + | ^^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}` | + = help: the trait `for<'r> std::ops::FnOnce<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}` note: required by `call_it_once` --> $DIR/unboxed-closures-unsafe-extern-fn.rs:19:1 | diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr index 6e5e1b928a2c0..18ade48de6640 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr @@ -1,33 +1,36 @@ -error[E0277]: the trait bound `for<'r> for<'s> extern "C" fn(&'s isize) -> isize {square}: std::ops::Fn<(&'r isize,)>` is not satisfied +error[E0277]: expected a `std::ops::Fn<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` --> $DIR/unboxed-closures-wrong-abi.rs:22:13 | LL | let x = call_it(&square, 22); - | ^^^^^^^ the trait `for<'r> std::ops::Fn<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}` + | ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` | + = help: the trait `for<'r> std::ops::Fn<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}` note: required by `call_it` --> $DIR/unboxed-closures-wrong-abi.rs:17:1 | LL | fn call_itisize>(_: &F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `for<'r> for<'s> extern "C" fn(&'s isize) -> isize {square}: std::ops::FnMut<(&'r isize,)>` is not satisfied +error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` --> $DIR/unboxed-closures-wrong-abi.rs:27:13 | LL | let y = call_it_mut(&mut square, 22); - | ^^^^^^^^^^^ the trait `for<'r> std::ops::FnMut<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}` + | ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` | + = help: the trait `for<'r> std::ops::FnMut<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}` note: required by `call_it_mut` --> $DIR/unboxed-closures-wrong-abi.rs:18:1 | LL | fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `for<'r> for<'s> extern "C" fn(&'s isize) -> isize {square}: std::ops::FnOnce<(&'r isize,)>` is not satisfied +error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` --> $DIR/unboxed-closures-wrong-abi.rs:32:13 | LL | let z = call_it_once(square, 22); - | ^^^^^^^^^^^^ the trait `for<'r> std::ops::FnOnce<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}` + | ^^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}` | + = help: the trait `for<'r> std::ops::FnOnce<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}` note: required by `call_it_once` --> $DIR/unboxed-closures-wrong-abi.rs:19:1 | diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr index 5c2e73f57160d..f27b73017a28f 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr @@ -1,33 +1,36 @@ -error[E0277]: the trait bound `for<'r> unsafe fn(isize) -> isize {square}: std::ops::Fn<(&'r isize,)>` is not satisfied +error[E0277]: expected a `std::ops::Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:23:13 | LL | let x = call_it(&square, 22); - | ^^^^^^^ the trait `for<'r> std::ops::Fn<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}` + | ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` | + = help: the trait `for<'r> std::ops::Fn<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}` note: required by `call_it` --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:18:1 | LL | fn call_itisize>(_: &F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `for<'r> unsafe fn(isize) -> isize {square}: std::ops::FnMut<(&'r isize,)>` is not satisfied +error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:28:13 | LL | let y = call_it_mut(&mut square, 22); - | ^^^^^^^^^^^ the trait `for<'r> std::ops::FnMut<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}` + | ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` | + = help: the trait `for<'r> std::ops::FnMut<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}` note: required by `call_it_mut` --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:19:1 | LL | fn call_it_mutisize>(_: &mut F, _: isize) -> isize { 0 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `for<'r> unsafe fn(isize) -> isize {square}: std::ops::FnOnce<(&'r isize,)>` is not satisfied +error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:33:13 | LL | let z = call_it_once(square, 22); - | ^^^^^^^^^^^^ the trait `for<'r> std::ops::FnOnce<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}` + | ^^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}` | + = help: the trait `for<'r> std::ops::FnOnce<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}` note: required by `call_it_once` --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:20:1 |