diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index aa175baa8c7..175295b3199 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -839,19 +839,25 @@ pub trait PrettyPrinter<'tcx>: p!(print(ty)); } - p!(") -> ", print(return_ty), write("{}", if paren_needed { ")" } else { "" })); + p!(")"); + if !return_ty.skip_binder().is_unit() { + p!("-> ", print(return_ty)); + } + p!(write("{}", if paren_needed { ")" } else { "" })); first = false; } // If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the // trait_refs we collected in the OpaqueFnEntry as normal trait refs. _ => { - traits.entry(fn_once_trait_ref).or_default().extend( - // Group the return ty with its def id, if we had one. - entry - .return_ty - .map(|ty| (self.tcx().lang_items().fn_once_output().unwrap(), ty)), - ); + if entry.has_fn_once { + traits.entry(fn_once_trait_ref).or_default().extend( + // Group the return ty with its def id, if we had one. + entry + .return_ty + .map(|ty| (self.tcx().lang_items().fn_once_output().unwrap(), ty)), + ); + } if let Some(trait_ref) = entry.fn_mut_trait_ref { traits.entry(trait_ref).or_default(); } @@ -943,6 +949,7 @@ pub trait PrettyPrinter<'tcx>: if let Some((_, ty)) = proj_ty { entry.return_ty = Some(ty); } + entry.has_fn_once = true; return; } else if Some(trait_def_id) == self.tcx().lang_items().fn_mut_trait() { let super_trait_ref = crate::traits::util::supertraits(self.tcx(), trait_ref) @@ -2695,6 +2702,8 @@ pub fn provide(providers: &mut ty::query::Providers) { #[derive(Default)] pub struct OpaqueFnEntry<'tcx> { + // The trait ref is already stored as a key, so just track if we have it as a real predicate + has_fn_once: bool, fn_mut_trait_ref: Option>, fn_trait_ref: Option>, return_ty: Option>>, diff --git a/src/test/mir-opt/inline/issue_78442.bar.Inline.diff b/src/test/mir-opt/inline/issue_78442.bar.Inline.diff index 3e72d1c42fa..045bc720ca7 100644 --- a/src/test/mir-opt/inline/issue_78442.bar.Inline.diff +++ b/src/test/mir-opt/inline/issue_78442.bar.Inline.diff @@ -19,16 +19,16 @@ + _4 = hide_foo() -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 // mir::Constant // + span: $DIR/issue-78442.rs:11:5: 11:13 - // + literal: Const { ty: fn() -> impl Fn() -> () {hide_foo}, val: Value(Scalar()) } + // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(Scalar()) } } bb1: { _3 = &_4; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 -- _2 = () as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 +- _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 - // mir::Constant - // + span: $DIR/issue-78442.rs:11:5: 11:15 -- // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn() -> (), ()) -> () as std::ops::FnOnce<()>>::Output { () as std::ops::Fn<()>>::call}, val: Value(Scalar()) } +- // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> >::Output {>::call}, val: Value(Scalar()) } + _2 = move (*_3)() -> [return: bb5, unwind: bb3]; // scope 1 at $DIR/issue-78442.rs:11:5: 11:17 } diff --git a/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff b/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff index 622599a2d18..3190db52286 100644 --- a/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff +++ b/src/test/mir-opt/inline/issue_78442.bar.RevealAll.diff @@ -5,8 +5,8 @@ debug _baz => _1; // in scope 0 at $DIR/issue-78442.rs:9:5: 9:9 let mut _0: (); // return place in scope 0 at $DIR/issue-78442.rs:10:3: 10:3 let _2: (); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:17 -- let mut _3: &impl Fn() -> (); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 -- let _4: impl Fn() -> (); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 +- let mut _3: &impl Fn(); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 +- let _4: impl Fn(); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 + let mut _3: &fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 + let _4: fn() {foo}; // in scope 0 at $DIR/issue-78442.rs:11:5: 11:15 let mut _5: (); // in scope 0 at $DIR/issue-78442.rs:11:5: 11:17 @@ -18,17 +18,17 @@ _4 = hide_foo() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 // mir::Constant // + span: $DIR/issue-78442.rs:11:5: 11:13 - // + literal: Const { ty: fn() -> impl Fn() -> () {hide_foo}, val: Value(Scalar()) } + // + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(Scalar()) } } bb1: { _3 = &_4; // scope 0 at $DIR/issue-78442.rs:11:5: 11:15 StorageLive(_5); // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 nop; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 - _2 = () as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 + _2 = >::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17 // mir::Constant // + span: $DIR/issue-78442.rs:11:5: 11:15 - // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn() -> (), ()) -> () as std::ops::FnOnce<()>>::Output { () as std::ops::Fn<()>>::call}, val: Value(Scalar()) } + // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> >::Output {>::call}, val: Value(Scalar()) } } bb2: { diff --git a/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr b/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr index 42c6de20127..c731c328322 100644 --- a/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr +++ b/src/test/ui/entry-point/imported_main_const_fn_item_type_forbidden.stderr @@ -21,7 +21,7 @@ LL | type MainFn = impl Fn(); LL | pub const BAR: MainFn = bar; | ^^^ expected opaque type, found fn item | - = note: expected opaque type `impl Fn() -> ()` + = note: expected opaque type `impl Fn()` found fn item `fn() {bar}` error: could not find defining uses diff --git a/src/test/ui/impl-trait/auto-trait-leak2.stderr b/src/test/ui/impl-trait/auto-trait-leak2.stderr index 2ca180029ae..37ae3c68029 100644 --- a/src/test/ui/impl-trait/auto-trait-leak2.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak2.stderr @@ -2,16 +2,16 @@ error[E0277]: `Rc>` cannot be sent between threads safely --> $DIR/auto-trait-leak2.rs:13:10 | LL | fn before() -> impl Fn(i32) { - | ------------ within this `impl Fn(i32) -> ()` + | ------------ within this `impl Fn(i32)` ... LL | send(before()); | ---- ^^^^^^^^ `Rc>` cannot be sent between threads safely | | | required by a bound introduced by this call | - = help: within `impl Fn(i32) -> ()`, the trait `Send` is not implemented for `Rc>` + = help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc>` = note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:7:5: 7:22]` - = note: required because it appears within the type `impl Fn(i32) -> ()` + = note: required because it appears within the type `impl Fn(i32)` note: required by a bound in `send` --> $DIR/auto-trait-leak2.rs:10:12 | @@ -27,11 +27,11 @@ LL | send(after()); | required by a bound introduced by this call ... LL | fn after() -> impl Fn(i32) { - | ------------ within this `impl Fn(i32) -> ()` + | ------------ within this `impl Fn(i32)` | - = help: within `impl Fn(i32) -> ()`, the trait `Send` is not implemented for `Rc>` + = help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc>` = note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:24:5: 24:22]` - = note: required because it appears within the type `impl Fn(i32) -> ()` + = note: required because it appears within the type `impl Fn(i32)` note: required by a bound in `send` --> $DIR/auto-trait-leak2.rs:10:12 | diff --git a/src/test/ui/impl-trait/issue-87450.stderr b/src/test/ui/impl-trait/issue-87450.stderr index 9b7d225a53e..5019e544bd5 100644 --- a/src/test/ui/impl-trait/issue-87450.stderr +++ b/src/test/ui/impl-trait/issue-87450.stderr @@ -17,10 +17,10 @@ LL | fn foo() -> impl Fn() { | ^^^^^^^^^ recursive opaque type ... LL | wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo()))))))) - | ----------------------------------------------- returning here with type `impl Fn() -> ()` + | ----------------------------------------------- returning here with type `impl Fn()` ... LL | fn wrap(f: impl Fn()) -> impl Fn() { - | --------- returning this opaque type `impl Fn() -> ()` + | --------- returning this opaque type `impl Fn()` error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/impl-trait/issues/issue-86201.stderr b/src/test/ui/impl-trait/issues/issue-86201.stderr index d65bddf7cfa..b1460096ded 100644 --- a/src/test/ui/impl-trait/issues/issue-86201.stderr +++ b/src/test/ui/impl-trait/issues/issue-86201.stderr @@ -7,7 +7,7 @@ LL | LL | static STATIC_FN: FunType = some_fn; | ^^^^^^^ expected opaque type, found fn item | - = note: expected opaque type `impl Fn<()> + FnOnce<()>` + = note: expected opaque type `impl Fn<()>` found fn item `fn() {some_fn}` error: could not find defining uses diff --git a/src/test/ui/issues/issue-59494.rs b/src/test/ui/issues/issue-59494.rs index 65ef436129e..a53e28f7246 100644 --- a/src/test/ui/issues/issue-59494.rs +++ b/src/test/ui/issues/issue-59494.rs @@ -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] } diff --git a/src/test/ui/issues/issue-59494.stderr b/src/test/ui/issues/issue-59494.stderr index 0af54f567f0..a9284535e4d 100644 --- a/src/test/ui/issues/issue-59494.stderr +++ b/src/test/ui/issues/issue-59494.stderr @@ -1,12 +1,12 @@ -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 | - = help: the trait `Fn<(_,)>` is not implemented for `impl Fn(((_, _), _)) -> ()` + = help: the trait `Fn<(_,)>` is not implemented for `impl Fn(((_, _), _))` note: required by a bound in `t8n` --> $DIR/issue-59494.rs:5:45 | diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.rs b/src/test/ui/lint/opaque-ty-ffi-unsafe.rs index efdc4037b63..3a62b6a21a5 100644 --- a/src/test/ui/lint/opaque-ty-ffi-unsafe.rs +++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.rs @@ -9,7 +9,7 @@ pub fn ret_closure() -> A { extern "C" { pub fn a(_: A); - //~^ ERROR `extern` block uses type `impl Fn() -> ()`, which is not FFI-safe [improper_ctypes] + //~^ ERROR `extern` block uses type `impl Fn()`, which is not FFI-safe [improper_ctypes] } fn main() {} diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr index c77d8c0c18b..5afbef778b3 100644 --- a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr +++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr @@ -1,4 +1,4 @@ -error: `extern` block uses type `impl Fn() -> ()`, which is not FFI-safe +error: `extern` block uses type `impl Fn()`, which is not FFI-safe --> $DIR/opaque-ty-ffi-unsafe.rs:11:17 | LL | pub fn a(_: A);