Fix printing unit return ty, don't elaborate FnOnce unless we see it

This commit is contained in:
Michael Goulet 2021-11-23 10:34:01 -08:00
parent 9ae575c795
commit 9cc117930b
11 changed files with 40 additions and 31 deletions

View File

@ -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<ty::PolyTraitRef<'tcx>>,
fn_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
return_ty: Option<ty::Binder<'tcx, Ty<'tcx>>>,

View File

@ -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(<ZST>)) }
// + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(Scalar(<ZST>)) }
}
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 = <impl Fn() -> () as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
- _2 = <impl Fn() as Fn<()>>::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() -> (), ()) -> <impl Fn() -> () as std::ops::FnOnce<()>>::Output {<impl Fn() -> () as std::ops::Fn<()>>::call}, val: Value(Scalar(<ZST>)) }
- // + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> <impl Fn() as std::ops::FnOnce<()>>::Output {<impl Fn() as std::ops::Fn<()>>::call}, val: Value(Scalar(<ZST>)) }
+ _2 = move (*_3)() -> [return: bb5, unwind: bb3]; // scope 1 at $DIR/issue-78442.rs:11:5: 11:17
}

View File

@ -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(<ZST>)) }
// + literal: Const { ty: fn() -> impl Fn() {hide_foo}, val: Value(Scalar(<ZST>)) }
}
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 = <impl Fn() -> () as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/issue-78442.rs:11:5: 11:17
_2 = <impl Fn() as Fn<()>>::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() -> (), ()) -> <impl Fn() -> () as std::ops::FnOnce<()>>::Output {<impl Fn() -> () as std::ops::Fn<()>>::call}, val: Value(Scalar(<ZST>)) }
// + literal: Const { ty: for<'r> extern "rust-call" fn(&'r impl Fn(), ()) -> <impl Fn() as std::ops::FnOnce<()>>::Output {<impl Fn() as std::ops::Fn<()>>::call}, val: Value(Scalar(<ZST>)) }
}
bb2: {

View File

@ -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

View File

@ -2,16 +2,16 @@ error[E0277]: `Rc<Cell<i32>>` 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<Cell<i32>>` 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<Cell<i32>>`
= help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc<Cell<i32>>`
= 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<Cell<i32>>`
= help: within `impl Fn(i32)`, the trait `Send` is not implemented for `Rc<Cell<i32>>`
= 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
|

View File

@ -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

View File

@ -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

View File

@ -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]
}

View File

@ -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
|

View File

@ -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() {}

View File

@ -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);