Skip to content

Commit

Permalink
Pretty print Fn traits in rustc_on_unimplemented
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Oct 5, 2023
1 parent 4910642 commit 32abbdc
Show file tree
Hide file tree
Showing 55 changed files with 151 additions and 136 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ symbols! {
ToOwned,
ToString,
TokenStream,
Trait,
Try,
TryCaptureGeneric,
TryCapturePrintable,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ static ALLOWED_FORMAT_SYMBOLS: &[Symbol] = &[
sym::float,
sym::_Self,
sym::crate_local,
sym::Trait,
];

impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
Expand Down Expand Up @@ -180,6 +181,19 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
flags.push((sym::cause, Some("MainFunctionType".to_string())));
}

if let Some(kind) = self.tcx.fn_trait_kind_from_def_id(trait_ref.def_id)
&& let ty::Tuple(args) = trait_ref.args.type_at(1).kind()
{
let args = args
.iter()
.map(|ty| ty.to_string())
.collect::<Vec<_>>()
.join(", ");
flags.push((sym::Trait, Some(format!("{}({args})", kind.as_str()))));
} else {
flags.push((sym::Trait, Some(trait_ref.print_only_trait_path().to_string())));
}

// Add all types without trimmed paths.
ty::print::with_no_trimmed_paths!({
let generics = self.tcx.generics_of(def_id);
Expand Down
24 changes: 12 additions & 12 deletions library/core/src/ops/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ use crate::marker::Tuple;
#[lang = "fn"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[rustc_on_unimplemented(
#[cfg_attr(not(bootstrap), rustc_on_unimplemented(
on(
Args = "()",
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
Expand All @@ -67,9 +67,9 @@ use crate::marker::Tuple;
// 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}`"
)]
message = "expected a `{Trait}` closure, found `{Self}`",
label = "expected an `{Trait}` closure, found `{Self}`"
))]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
// FIXME(effects) #[const_trait]
Expand Down Expand Up @@ -143,7 +143,7 @@ pub trait Fn<Args: Tuple>: FnMut<Args> {
#[lang = "fn_mut"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[rustc_on_unimplemented(
#[cfg_attr(not(bootstrap), rustc_on_unimplemented(
on(
Args = "()",
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
Expand All @@ -154,9 +154,9 @@ pub trait Fn<Args: Tuple>: FnMut<Args> {
// 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}`"
)]
message = "expected a `{Trait}` closure, found `{Self}`",
label = "expected an `{Trait}` closure, found `{Self}`"
))]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
// FIXME(effects) #[const_trait]
Expand Down Expand Up @@ -222,7 +222,7 @@ pub trait FnMut<Args: Tuple>: FnOnce<Args> {
#[lang = "fn_once"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_paren_sugar]
#[rustc_on_unimplemented(
#[cfg_attr(not(bootstrap), rustc_on_unimplemented(
on(
Args = "()",
note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
Expand All @@ -233,9 +233,9 @@ pub trait FnMut<Args: Tuple>: FnOnce<Args> {
// 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}`"
)]
message = "expected a `{Trait}` closure, found `{Self}`",
label = "expected an `{Trait}` closure, found `{Self}`"
))]
#[fundamental] // so that regex can rely that `&str: !FnMut`
#[must_use = "closures are lazy and do nothing unless called"]
// FIXME(effects) #[const_trait]
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/closures/closure-expected.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
fn main() {
let x = Some(1);
let y = x.or_else(4);
//~^ ERROR expected a `FnOnce<()>` closure, found `{integer}`
//~^ ERROR expected a `FnOnce()` closure, found `{integer}`
}
4 changes: 2 additions & 2 deletions tests/ui/closures/closure-expected.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: expected a `FnOnce<()>` closure, found `{integer}`
error[E0277]: expected a `FnOnce()` closure, found `{integer}`
--> $DIR/closure-expected.rs:3:23
|
LL | let y = x.or_else(4);
| ------- ^ expected an `FnOnce<()>` closure, found `{integer}`
| ------- ^ expected an `FnOnce()` closure, found `{integer}`
| |
| required by a bound introduced by this call
|
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/closures/coerce-unsafe-to-closure.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0277]: expected a `FnOnce<(&str,)>` closure, found `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
error[E0277]: expected a `FnOnce(&str)` closure, found `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_, _>}`
--> $DIR/coerce-unsafe-to-closure.rs:2:44
|
LL | let x: Option<&[u8]> = Some("foo").map(std::mem::transmute);
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/extern/extern-wrong-value-type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ fn main() {
// extern functions are extern "C" fn
let _x: extern "C" fn() = f; // OK
is_fn(f);
//~^ ERROR expected a `Fn<()>` closure, found `extern "C" fn() {f}`
//~^ ERROR expected a `Fn()` closure, found `extern "C" fn() {f}`
}
4 changes: 2 additions & 2 deletions tests/ui/extern/extern-wrong-value-type.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: expected a `Fn<()>` closure, found `extern "C" fn() {f}`
error[E0277]: expected a `Fn()` closure, found `extern "C" fn() {f}`
--> $DIR/extern-wrong-value-type.rs:9:11
|
LL | is_fn(f);
| ----- ^ expected an `Fn<()>` closure, found `extern "C" fn() {f}`
| ----- ^ expected an `Fn()` closure, found `extern "C" fn() {f}`
| |
| required by a bound introduced by this call
|
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/fn/fn-trait-formatting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ fn main() {
//~| found struct `Box<dyn FnMut() -> isize>`

needs_fn(1);
//~^ ERROR expected a `Fn<(isize,)>` closure, found `{integer}`
//~^ ERROR expected a `Fn(isize)` closure, found `{integer}`
}
4 changes: 2 additions & 2 deletions tests/ui/fn/fn-trait-formatting.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ LL | let _: () = Box::new(|| -> isize { unimplemented!() }) as Box<dyn FnMut
= note: expected unit type `()`
found struct `Box<dyn FnMut() -> isize>`

error[E0277]: expected a `Fn<(isize,)>` closure, found `{integer}`
error[E0277]: expected a `Fn(isize)` closure, found `{integer}`
--> $DIR/fn-trait-formatting.rs:19:14
|
LL | needs_fn(1);
| -------- ^ expected an `Fn<(isize,)>` closure, found `{integer}`
| -------- ^ expected an `Fn(isize)` closure, found `{integer}`
| |
| required by a bound introduced by this call
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ trait Fun {

impl<T> Fun for T {
type F<'a> = Self;
//~^ ERROR expected a `Fn<()>` closure, found `T`
//~^ ERROR expected a `Fn()` closure, found `T`
}

fn main() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: expected a `Fn<()>` closure, found `T`
error[E0277]: expected a `Fn()` closure, found `T`
--> $DIR/issue-68642-broken-llvm-ir.rs:12:18
|
LL | type F<'a> = Self;
| ^^^^ expected an `Fn<()>` closure, found `T`
| ^^^^ expected an `Fn()` closure, found `T`
|
= note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `Fun::F`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ trait Fun {

impl<T> Fun for T {
type F<'a> = Self;
//~^ ERROR expected a `Fn<()>` closure, found `T`
//~^ ERROR expected a `Fn()` closure, found `T`
}

pub fn main() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: expected a `Fn<()>` closure, found `T`
error[E0277]: expected a `Fn()` closure, found `T`
--> $DIR/issue-68643-broken-mir.rs:12:18
|
LL | type F<'a> = Self;
| ^^^^ expected an `Fn<()>` closure, found `T`
| ^^^^ expected an `Fn()` closure, found `T`
|
= note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `Fun::F`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ trait Fun {

impl<T> Fun for T {
type F<'a> = Self;
//~^ ERROR expected a `Fn<()>` closure, found `T`
//~^ ERROR expected a `Fn()` closure, found `T`
}

fn main() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: expected a `Fn<()>` closure, found `T`
error[E0277]: expected a `Fn()` closure, found `T`
--> $DIR/issue-68644-codegen-selection.rs:12:18
|
LL | type F<'a> = Self;
| ^^^^ expected an `Fn<()>` closure, found `T`
| ^^^^ expected an `Fn()` closure, found `T`
|
= note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `Fun::F`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ trait Fun {

impl<T> Fun for T {
type F<'a> = Self;
//~^ ERROR expected a `Fn<()>` closure, found `T`
//~^ ERROR expected a `Fn()` closure, found `T`
}

fn main() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: expected a `Fn<()>` closure, found `T`
error[E0277]: expected a `Fn()` closure, found `T`
--> $DIR/issue-68645-codegen-fulfillment.rs:12:18
|
LL | type F<'a> = Self;
| ^^^^ expected an `Fn<()>` closure, found `T`
| ^^^^ expected an `Fn()` closure, found `T`
|
= note: wrap the `T` in a closure with no arguments: `|| { /* code */ }`
note: required by a bound in `Fun::F`
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/higher-ranked/trait-bounds/fn-ptr.classic.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: expected a `Fn<(&'w (),)>` closure, found `fn(&'w ())`
error[E0277]: expected a `Fn(&'w ())` closure, found `fn(&'w ())`
--> $DIR/fn-ptr.rs:12:5
|
LL | ice();
| ^^^ expected an `Fn<(&'w (),)>` closure, found `fn(&'w ())`
| ^^^ expected an `Fn(&'w ())` closure, found `fn(&'w ())`
|
= help: the trait `for<'w> Fn<(&'w (),)>` is not implemented for `fn(&'w ())`
note: required by a bound in `ice`
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/higher-ranked/trait-bounds/fn-ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ where

fn main() {
ice();
//[classic]~^ ERROR expected a `Fn<(&'w (),)>` closure, found `fn(&'w ())`
//[classic]~^ ERROR expected a `Fn(&'w ())` closure, found `fn(&'w ())`
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: expected a `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F`
error[E0277]: expected a `Fn(<_ as ATC<'a>>::Type)` closure, found `F`
--> $DIR/issue-62529-3.rs:25:14
|
LL | call(f, ());
| ---- ^ expected an `Fn<(<_ as ATC<'a>>::Type,)>` closure, found `F`
| ---- ^ expected an `Fn(<_ as ATC<'a>>::Type)` closure, found `F`
| |
| required by a bound introduced by this call
|
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/implied-bounds/issue-100690.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ impl<'a, T: 'a> Handle<'a, T, UIView<'a, T>, Result<(), io::Error>> for TUIHandl
F: FnOnce(&mut UIView<'a, T>) -> Result<(), io::Error> + Send + 'static,
{
real_dispatch(f)
//~^ ERROR expected a `FnOnce<(&mut UIView<'_, T>,)>` closure, found `F`
//~| NOTE expected an `FnOnce<(&mut UIView<'_, T>,)>` closure, found `F`
//~^ ERROR expected a `FnOnce(&mut UIView<'_, T>)` closure, found `F`
//~| NOTE expected an `FnOnce(&mut UIView<'_, T>)` closure, found `F`
//~| NOTE expected a closure with arguments
//~| NOTE required by a bound introduced by this call
}
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/implied-bounds/issue-100690.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: expected a `FnOnce<(&mut UIView<'_, T>,)>` closure, found `F`
error[E0277]: expected a `FnOnce(&mut UIView<'_, T>)` closure, found `F`
--> $DIR/issue-100690.rs:37:23
|
LL | real_dispatch(f)
| ------------- ^ expected an `FnOnce<(&mut UIView<'_, T>,)>` closure, found `F`
| ------------- ^ expected an `FnOnce(&mut UIView<'_, T>)` closure, found `F`
| |
| required by a bound introduced by this call
|
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/intrinsics/const-eval-select-bad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ const fn not_fn_items() {
//~^ ERROR this argument must be a function item
//~| ERROR this argument must be a function item
const_eval_select((), 42, 0xDEADBEEF);
//~^ ERROR expected a `FnOnce<()>` closure
//~| ERROR expected a `FnOnce<()>` closure
//~^ ERROR expected a `FnOnce()` closure
//~| ERROR expected a `FnOnce()` closure
//~| ERROR this argument must be a function item
//~| ERROR this argument must be a function item
}
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/intrinsics/const-eval-select-bad.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ LL | const_eval_select((), 42, 0xDEADBEEF);
= note: expected a function item, found {integer}
= help: consult the documentation on `const_eval_select` for more information

error[E0277]: expected a `FnOnce<()>` closure, found `{integer}`
error[E0277]: expected a `FnOnce()` closure, found `{integer}`
--> $DIR/const-eval-select-bad.rs:10:27
|
LL | const_eval_select((), 42, 0xDEADBEEF);
| ----------------- ^^ expected an `FnOnce<()>` closure, found `{integer}`
| ----------------- ^^ expected an `FnOnce()` closure, found `{integer}`
| |
| required by a bound introduced by this call
|
Expand All @@ -47,11 +47,11 @@ LL | const_eval_select((), 42, 0xDEADBEEF);
= note: expected a function item, found {integer}
= help: consult the documentation on `const_eval_select` for more information

error[E0277]: expected a `FnOnce<()>` closure, found `{integer}`
error[E0277]: expected a `FnOnce()` closure, found `{integer}`
--> $DIR/const-eval-select-bad.rs:10:31
|
LL | const_eval_select((), 42, 0xDEADBEEF);
| ----------------- ^^^^^^^^^^ expected an `FnOnce<()>` closure, found `{integer}`
| ----------------- ^^^^^^^^^^ expected an `FnOnce()` closure, found `{integer}`
| |
| required by a bound introduced by this call
|
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/issues/issue-22034.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ fn main() {
let ptr: *mut () = core::ptr::null_mut();
let _: &mut dyn Fn() = unsafe {
&mut *(ptr as *mut dyn Fn())
//~^ ERROR expected a `Fn<()>` closure, found `()`
//~^ ERROR expected a `Fn()` closure, found `()`
};
}
4 changes: 2 additions & 2 deletions tests/ui/issues/issue-22034.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: expected a `Fn<()>` closure, found `()`
error[E0277]: expected a `Fn()` closure, found `()`
--> $DIR/issue-22034.rs:8:16
|
LL | &mut *(ptr as *mut dyn Fn())
| ^^^ expected an `Fn<()>` closure, found `()`
| ^^^ expected an `Fn()` closure, found `()`
|
= help: the trait `Fn<()>` is not implemented for `()`
= note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/issues/issue-23966.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: expected a `FnMut<(_, char)>` closure, found `()`
error[E0277]: expected a `FnMut(_, char)` closure, found `()`
--> $DIR/issue-23966.rs:2:32
|
LL | "".chars().fold(|_, _| (), ());
| ---- ^^ expected an `FnMut<(_, char)>` closure, found `()`
| ---- ^^ expected an `FnMut(_, char)` closure, found `()`
| |
| required by a bound introduced by this call
|
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/issues/issue-59494.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ fn main() {
let g = |(a, _)| a;
let t7 = |env| |a| |b| t7p(f, g)(((env, a), b));
let t8 = t8n(t7, t7p(f, g));
//~^ ERROR: expected a `Fn<(_,)>` closure, found `impl Fn(((_, _), _))` [E0277]
//~^ ERROR: expected a `Fn(_)` closure, found `impl Fn(((_, _), _))` [E0277]
}
4 changes: 2 additions & 2 deletions tests/ui/issues/issue-59494.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0277]: expected a `Fn<(_,)>` closure, found `impl Fn(((_, _), _))`
error[E0277]: expected a `Fn(_)` closure, found `impl Fn(((_, _), _))`
--> $DIR/issue-59494.rs:21:22
|
LL | let t8 = t8n(t7, t7p(f, g));
| --- ^^^^^^^^^ expected an `Fn<(_,)>` closure, found `impl Fn(((_, _), _))`
| --- ^^^^^^^^^ expected an `Fn(_)` closure, found `impl Fn(((_, _), _))`
| |
| required by a bound introduced by this call
|
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/mismatched_types/suggest-option-asderef-unfixable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ fn main() {
let _ = produces_string().and_then(takes_str_but_too_many_refs);
//~^ ERROR type mismatch in function arguments
let _ = produces_string().and_then(takes_str_but_wrong_abi);
//~^ ERROR expected a `FnOnce<(String,)>` closure, found `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}`
//~^ ERROR expected a `FnOnce(String)` closure, found `for<'a> extern "C" fn(&'a str) -> Option<()> {takes_str_but_wrong_abi}`
let _ = produces_string().and_then(takes_str_but_unsafe);
//~^ ERROR expected a `FnOnce<(String,)>` closure, found `for<'a> unsafe fn(&'a str) -> Option<()> {takes_str_but_unsafe}`
//~^ ERROR expected a `FnOnce(String)` closure, found `for<'a> unsafe fn(&'a str) -> Option<()> {takes_str_but_unsafe}`
let _ = produces_string().and_then(no_args);
//~^ ERROR function is expected to take 1 argument, but it takes 0 arguments
let _ = Some(TypeWithoutDeref).and_then(takes_str_but_too_many_refs);
Expand Down
Loading

0 comments on commit 32abbdc

Please sign in to comment.