Skip to content

Commit e5e14d3

Browse files
committed
When closure with no arguments was expected, suggest wrapping
1 parent 0f4b498 commit e5e14d3

8 files changed

+53
-7
lines changed

src/libcore/ops/function.rs

+15
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@
6666
#[lang = "fn"]
6767
#[stable(feature = "rust1", since = "1.0.0")]
6868
#[rustc_paren_sugar]
69+
#[rustc_on_unimplemented(
70+
on(Args="()", note="wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"),
71+
message="expected a `{Fn}<{Args}>` closure, found `{Self}`",
72+
label="expected an `Fn<{Args}>` closure, found `{Self}`",
73+
)]
6974
#[fundamental] // so that regex can rely that `&str: !FnMut`
7075
pub trait Fn<Args> : FnMut<Args> {
7176
/// Performs the call operation.
@@ -139,6 +144,11 @@ pub trait Fn<Args> : FnMut<Args> {
139144
#[lang = "fn_mut"]
140145
#[stable(feature = "rust1", since = "1.0.0")]
141146
#[rustc_paren_sugar]
147+
#[rustc_on_unimplemented(
148+
on(Args="()", note="wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"),
149+
message="expected a `{FnMut}<{Args}>` closure, found `{Self}`",
150+
label="expected an `FnMut<{Args}>` closure, found `{Self}`",
151+
)]
142152
#[fundamental] // so that regex can rely that `&str: !FnMut`
143153
pub trait FnMut<Args> : FnOnce<Args> {
144154
/// Performs the call operation.
@@ -212,6 +222,11 @@ pub trait FnMut<Args> : FnOnce<Args> {
212222
#[lang = "fn_once"]
213223
#[stable(feature = "rust1", since = "1.0.0")]
214224
#[rustc_paren_sugar]
225+
#[rustc_on_unimplemented(
226+
on(Args="()", note="wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}"),
227+
message="expected a `{FnOnce}<{Args}>` closure, found `{Self}`",
228+
label="expected an `FnOnce<{Args}>` closure, found `{Self}`",
229+
)]
215230
#[fundamental] // so that regex can rely that `&str: !FnMut`
216231
pub trait FnOnce<Args> {
217232
/// The returned type after the call operator is used.

src/test/ui/closure-expected.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
let x = Some(1);
13+
let y = x.or_else(4);
14+
//~^ ERROR expected a `std::ops::FnOnce<()>` closure, found `{integer}`
15+
}

src/test/ui/closure-expected.stderr

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0277]: expected a `std::ops::FnOnce<()>` closure, found `{integer}`
2+
--> $DIR/closure-expected.rs:13:15
3+
|
4+
LL | let y = x.or_else(4);
5+
| ^^^^^^^ expected an `FnOnce<()>` closure, found `{integer}`
6+
|
7+
= help: the trait `std::ops::FnOnce<()>` is not implemented for `{integer}`
8+
= note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0277`.

src/test/ui/extern/extern-wrong-value-type.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ fn main() {
1717
// extern functions are extern "C" fn
1818
let _x: extern "C" fn() = f; // OK
1919
is_fn(f);
20-
//~^ ERROR `extern "C" fn() {f}: std::ops::Fn<()>` is not satisfied
20+
//~^ ERROR expected a `std::ops::Fn<()>` closure, found `extern "C" fn() {f}`
2121
}

src/test/ui/fn/fn-trait-formatting.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ fn main() {
2727
//~| found type `std::boxed::Box<dyn std::ops::FnMut() -> isize>`
2828

2929
needs_fn(1);
30-
//~^ ERROR : std::ops::Fn<(isize,)>`
30+
//~^ ERROR expected a `std::ops::Fn<(isize,)>` closure, found `{integer}`
3131
}

src/test/ui/issues/issue-22034.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ fn main() {
1616
let ptr: *mut () = 0 as *mut _;
1717
let _: &mut Fn() = unsafe {
1818
&mut *(ptr as *mut Fn())
19-
//~^ ERROR `(): std::ops::Fn<()>` is not satisfied
19+
//~^ ERROR expected a `std::ops::Fn<()>` closure, found `()`
2020
};
2121
}

src/test/ui/issues/issue-22034.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
error[E0277]: the trait bound `(): std::ops::Fn<()>` is not satisfied
1+
error[E0277]: expected a `std::ops::Fn<()>` closure, found `()`
22
--> $DIR/issue-22034.rs:18:16
33
|
44
LL | &mut *(ptr as *mut Fn())
5-
| ^^^ the trait `std::ops::Fn<()>` is not implemented for `()`
5+
| ^^^ expected an `Fn<()>` closure, found `()`
66
|
7+
= help: the trait `std::ops::Fn<()>` is not implemented for `()`
8+
= note: wrap the `()` in a closure with no arguments: `|| { /* code */ }
79
= note: required for the cast to the object type `dyn std::ops::Fn()`
810

911
error: aborting due to previous error

src/test/ui/issues/issue-23966.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
error[E0277]: the trait bound `(): std::ops::FnMut<(_, char)>` is not satisfied
1+
error[E0277]: expected a `std::ops::FnMut<(_, char)>` closure, found `()`
22
--> $DIR/issue-23966.rs:12:16
33
|
44
LL | "".chars().fold(|_, _| (), ());
5-
| ^^^^ the trait `std::ops::FnMut<(_, char)>` is not implemented for `()`
5+
| ^^^^ expected an `FnMut<(_, char)>` closure, found `()`
6+
|
7+
= help: the trait `std::ops::FnMut<(_, char)>` is not implemented for `()`
68

79
error: aborting due to previous error
810

0 commit comments

Comments
 (0)