Skip to content

Commit

Permalink
Auto merge of #77069 - sexxi-goose:closure_print_2, r=nikomatsakis
Browse files Browse the repository at this point in the history
pretty.rs: Update Closure and Generator print

More detailed outline: rust-lang/project-rfc-2229#17

Closes: rust-lang/project-rfc-2229#11

r? `@nikomatsakis`
cc `@eddyb` `@davidtwco` `@estebank`
  • Loading branch information
bors committed Sep 30, 2020
2 parents 0d9afb6 + adda0cd commit 6ac6c67
Show file tree
Hide file tree
Showing 41 changed files with 513 additions and 122 deletions.
126 changes: 54 additions & 72 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -641,104 +641,86 @@ pub trait PrettyPrinter<'tcx>:
}
ty::Str => p!(write("str")),
ty::Generator(did, substs, movability) => {
p!(write("["));
match movability {
hir::Movability::Movable => p!(write("[generator")),
hir::Movability::Static => p!(write("[static generator")),
hir::Movability::Movable => {}
hir::Movability::Static => p!(write("static ")),
}

// FIXME(eddyb) should use `def_span`.
if let Some(did) = did.as_local() {
let hir_id = self.tcx().hir().local_def_id_to_hir_id(did);
let span = self.tcx().hir().span(hir_id);
p!(write("@{}", self.tcx().sess.source_map().span_to_string(span)));

if substs.as_generator().is_valid() {
let upvar_tys = substs.as_generator().upvar_tys();
let mut sep = " ";
for (&var_id, upvar_ty) in self
.tcx()
.upvars_mentioned(did)
.as_ref()
.iter()
.flat_map(|v| v.keys())
.zip(upvar_tys)
{
p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
sep = ", ";
}
if !self.tcx().sess.verbose() {
p!(write("generator"));
// FIXME(eddyb) should use `def_span`.
if let Some(did) = did.as_local() {
let hir_id = self.tcx().hir().local_def_id_to_hir_id(did);
let span = self.tcx().hir().span(hir_id);
p!(write("@{}", self.tcx().sess.source_map().span_to_string(span)));
} else {
p!(write("@{}", self.tcx().def_path_str(did)));
}
} else {
p!(write("@{}", self.tcx().def_path_str(did)));

p!(print_def_path(did, substs));
if substs.as_generator().is_valid() {
let upvar_tys = substs.as_generator().upvar_tys();
let mut sep = " ";
for (index, upvar_ty) in upvar_tys.enumerate() {
p!(write("{}{}:", sep, index), print(upvar_ty));
sep = ", ";
// Search for the first inference variable
p!(write(" upvar_tys=("));
let mut uninferred_ty =
substs.as_generator().upvar_tys().filter(|ty| ty.is_ty_infer());
if uninferred_ty.next().is_some() {
p!(write("unavailable"));
} else {
self = self.comma_sep(substs.as_generator().upvar_tys())?;
}
p!(write(")"));
}
}

if substs.as_generator().is_valid() {
p!(write(" "), print(substs.as_generator().witness()));
}

p!(write("]"))
p!(write("]"));
}
ty::GeneratorWitness(types) => {
p!(in_binder(&types));
}
ty::Closure(did, substs) => {
p!(write("[closure"));

// FIXME(eddyb) should use `def_span`.
if let Some(did) = did.as_local() {
let hir_id = self.tcx().hir().local_def_id_to_hir_id(did);
if self.tcx().sess.opts.debugging_opts.span_free_formats {
p!(write("@"), print_def_path(did.to_def_id(), substs));
} else {
let span = self.tcx().hir().span(hir_id);
p!(write("@{}", self.tcx().sess.source_map().span_to_string(span)));
}

if substs.as_closure().is_valid() {
let upvar_tys = substs.as_closure().upvar_tys();
let mut sep = " ";
for (&var_id, upvar_ty) in self
.tcx()
.upvars_mentioned(did)
.as_ref()
.iter()
.flat_map(|v| v.keys())
.zip(upvar_tys)
{
p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
sep = ", ";
p!(write("["));
if !self.tcx().sess.verbose() {
p!(write("closure"));
// FIXME(eddyb) should use `def_span`.
if let Some(did) = did.as_local() {
let hir_id = self.tcx().hir().local_def_id_to_hir_id(did);
if self.tcx().sess.opts.debugging_opts.span_free_formats {
p!(write("@"), print_def_path(did.to_def_id(), substs));
} else {
let span = self.tcx().hir().span(hir_id);
p!(write("@{}", self.tcx().sess.source_map().span_to_string(span)));
}
} else {
p!(write("@{}", self.tcx().def_path_str(did)));
}
} else {
p!(write("@{}", self.tcx().def_path_str(did)));

p!(print_def_path(did, substs));
if substs.as_closure().is_valid() {
let upvar_tys = substs.as_closure().upvar_tys();
let mut sep = " ";
for (index, upvar_ty) in upvar_tys.enumerate() {
p!(write("{}{}:", sep, index), print(upvar_ty));
sep = ", ";
// Search for the first inference variable
let mut uninferred_ty =
substs.as_closure().upvar_tys().filter(|ty| ty.is_ty_infer());
if uninferred_ty.next().is_some() {
// If the upvar substs contain an inference variable we haven't
// finished capture analysis.
p!(write(" closure_substs=(unavailable)"));
} else {
p!(write(" closure_kind_ty="), print(substs.as_closure().kind_ty()));
p!(
write(" closure_sig_as_fn_ptr_ty="),
print(substs.as_closure().sig_as_fn_ptr_ty())
);
p!(write(" upvar_tys=("));
self = self.comma_sep(substs.as_closure().upvar_tys())?;
p!(write(")"));
}
}
}

if self.tcx().sess.verbose() && substs.as_closure().is_valid() {
p!(write(" closure_kind_ty="), print(substs.as_closure().kind_ty()));
p!(
write(" closure_sig_as_fn_ptr_ty="),
print(substs.as_closure().sig_as_fn_ptr_ty())
);
}

p!(write("]"))
p!(write("]"));
}
ty::Array(ty, sz) => {
p!(write("["), print(ty), write("; "));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ fn foo(_1: T, _2: i32) -> (i32, T) {
debug t => _1; // in scope 0 at $DIR/inline-closure-captures.rs:10:17: 10:18
debug q => _2; // in scope 0 at $DIR/inline-closure-captures.rs:10:23: 10:24
let mut _0: (i32, T); // return place in scope 0 at $DIR/inline-closure-captures.rs:10:34: 10:42
let _3: [closure@foo<T>::{closure#0} q:&i32, t:&T]; // in scope 0 at $DIR/inline-closure-captures.rs:11:9: 11:10
let _3: [closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-captures.rs:11:9: 11:10
let mut _4: &i32; // in scope 0 at $DIR/inline-closure-captures.rs:11:13: 11:24
let mut _5: &T; // in scope 0 at $DIR/inline-closure-captures.rs:11:13: 11:24
let mut _6: &[closure@foo<T>::{closure#0} q:&i32, t:&T]; // in scope 0 at $DIR/inline-closure-captures.rs:12:5: 12:6
let mut _6: &[closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-captures.rs:12:5: 12:6
let mut _7: (i32,); // in scope 0 at $DIR/inline-closure-captures.rs:12:5: 12:9
let mut _8: i32; // in scope 0 at $DIR/inline-closure-captures.rs:12:7: 12:8
let mut _10: i32; // in scope 0 at $DIR/inline-closure-captures.rs:12:5: 12:9
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/async-await/issue-68112.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ LL | require_send(send_fut);
|
= help: the trait `Sync` is not implemented for `RefCell<i32>`
= note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
= note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:47:31: 47:36 t:Arc<RefCell<i32>> {}]`
= note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:47:31: 47:36 t:Arc<RefCell<i32>> {}]>`
= note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:47:31: 47:36 {}]`
= note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:47:31: 47:36 {}]>`
= note: required because it appears within the type `impl Future`
= note: required because it appears within the type `impl Future`
= note: required because it appears within the type `impl Future`
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/block-result/issue-20862.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LL | |y| x + y
| ^^^^^^^^^ expected `()`, found closure
|
= note: expected unit type `()`
found closure `[closure@$DIR/issue-20862.rs:2:5: 2:14 x:_]`
found closure `[closure@$DIR/issue-20862.rs:2:5: 2:14]`

error[E0618]: expected function, found `()`
--> $DIR/issue-20862.rs:7:13
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error: lifetime may not live long enough
LL | let _action = move || {
| -------
| | |
| | return type of closure is [closure@$DIR/issue-53432-nested-closure-outlives-borrowed-value.rs:4:9: 4:15 f:&'2 [closure@$DIR/issue-53432-nested-closure-outlives-borrowed-value.rs:2:13: 2:23]]
| | return type of closure is [closure@$DIR/issue-53432-nested-closure-outlives-borrowed-value.rs:4:9: 4:15]
| lifetime `'1` represents this closure's body
LL | || f() // The `nested` closure
| ^^^^^^ returning this value requires that `'1` must outlive `'2`
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/closures/closure-move-sync.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ LL | F: Send + 'static,
|
= help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<()>`
= note: required because of the requirements on the impl of `Send` for `&std::sync::mpsc::Receiver<()>`
= note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:6:27: 9:6 recv:&std::sync::mpsc::Receiver<()>]`
= note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:6:27: 9:6]`

error[E0277]: `Sender<()>` cannot be shared between threads safely
--> $DIR/closure-move-sync.rs:18:5
Expand All @@ -26,7 +26,7 @@ LL | F: Send + 'static,
|
= help: the trait `Sync` is not implemented for `Sender<()>`
= note: required because of the requirements on the impl of `Send` for `&Sender<()>`
= note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:18:19: 18:42 tx:&Sender<()>]`
= note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:18:19: 18:42]`

error: aborting due to 2 previous errors

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/closures/closure-no-fn-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
| expected due to this
|
= note: expected fn pointer `fn(u8) -> u8`
found closure `[closure@$DIR/closure-no-fn-1.rs:6:29: 6:50 a:_]`
found closure `[closure@$DIR/closure-no-fn-1.rs:6:29: 6:50]`

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/closures/closure-no-fn-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LL | let bar: fn() -> u8 = || { b };
| expected due to this
|
= note: expected fn pointer `fn() -> u8`
found closure `[closure@$DIR/closure-no-fn-2.rs:6:27: 6:35 b:_]`
found closure `[closure@$DIR/closure-no-fn-2.rs:6:27: 6:35]`

error: aborting due to previous error

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/closures/closure-no-fn-3.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0605]: non-primitive cast: `[closure@$DIR/closure-no-fn-3.rs:6:27: 6:37 b:_]` as `fn() -> u8`
error[E0605]: non-primitive cast: `[closure@$DIR/closure-no-fn-3.rs:6:27: 6:37]` as `fn() -> u8`
--> $DIR/closure-no-fn-3.rs:6:27
|
LL | let baz: fn() -> u8 = (|| { b }) as fn() -> u8;
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/closures/closure-reform-bad.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LL | call_bare(f)
| ^ expected fn pointer, found closure
|
= note: expected fn pointer `for<'r> fn(&'r str)`
found closure `[closure@$DIR/closure-reform-bad.rs:10:13: 10:50 string:_]`
found closure `[closure@$DIR/closure-reform-bad.rs:10:13: 10:50]`

error: aborting due to previous error

Expand Down
14 changes: 7 additions & 7 deletions src/test/ui/closures/closure_cap_coerce_many_fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ LL | | };
| |_____- `match` arms have incompatible types
|
= note: expected type `fn(i32, i32) -> i32 {add}`
found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:9:16: 9:43 cap:_]`
found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:9:16: 9:43]`

error[E0308]: `match` arms have incompatible types
--> $DIR/closure_cap_coerce_many_fail.rs:18:16
Expand All @@ -28,7 +28,7 @@ LL | | };
| |_____- `match` arms have incompatible types
|
= note: expected type `[closure@$DIR/closure_cap_coerce_many_fail.rs:17:16: 17:37]`
found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:18:16: 18:43 cap:_]`
found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:18:16: 18:43]`
= note: no two closures, even if identical, have the same type
= help: consider boxing your closure and/or using it as a trait object

Expand All @@ -38,14 +38,14 @@ error[E0308]: `match` arms have incompatible types
LL | let _ = match "+" {
| _____________-
LL | | "+" => |a, b| (a + b + cap) as i32,
| | --------------------------- this is found to be of type `[closure@$DIR/closure_cap_coerce_many_fail.rs:26:16: 26:43 cap:_]`
| | --------------------------- this is found to be of type `[closure@$DIR/closure_cap_coerce_many_fail.rs:26:16: 26:43]`
LL | | "-" => |a, b| (a - b) as i32,
| | ^^^^^^^^^^^^^^^^^^^^^ expected closure, found a different closure
LL | | _ => unimplemented!(),
LL | | };
| |_____- `match` arms have incompatible types
|
= note: expected type `[closure@$DIR/closure_cap_coerce_many_fail.rs:26:16: 26:43 cap:_]`
= note: expected type `[closure@$DIR/closure_cap_coerce_many_fail.rs:26:16: 26:43]`
found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:27:16: 27:37]`
= note: no two closures, even if identical, have the same type
= help: consider boxing your closure and/or using it as a trait object
Expand All @@ -56,15 +56,15 @@ error[E0308]: `match` arms have incompatible types
LL | let _ = match "+" {
| _____________-
LL | | "+" => |a, b| (a + b + cap) as i32,
| | --------------------------- this is found to be of type `[closure@$DIR/closure_cap_coerce_many_fail.rs:34:16: 34:43 cap:_]`
| | --------------------------- this is found to be of type `[closure@$DIR/closure_cap_coerce_many_fail.rs:34:16: 34:43]`
LL | | "-" => |a, b| (a - b + cap) as i32,
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected closure, found a different closure
LL | | _ => unimplemented!(),
LL | | };
| |_____- `match` arms have incompatible types
|
= note: expected type `[closure@$DIR/closure_cap_coerce_many_fail.rs:34:16: 34:43 cap:_]`
found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:35:16: 35:43 cap:_]`
= note: expected type `[closure@$DIR/closure_cap_coerce_many_fail.rs:34:16: 34:43]`
found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:35:16: 35:43]`
= note: no two closures, even if identical, have the same type
= help: consider boxing your closure and/or using it as a trait object

Expand Down
23 changes: 23 additions & 0 deletions src/test/ui/closures/print/closure-print-generic-1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
fn to_fn_once<F: FnOnce()>(f: F) -> F {
f
}

fn f<T: std::fmt::Display>(y: T) {
struct Foo<U: std::fmt::Display> {
x: U,
};

let foo = Foo { x: "x" };

let c = to_fn_once(move || {
println!("{} {}", foo.x, y);
});

c();
c();
//~^ ERROR use of moved value
}

fn main() {
f("S");
}
20 changes: 20 additions & 0 deletions src/test/ui/closures/print/closure-print-generic-1.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error[E0382]: use of moved value: `c`
--> $DIR/closure-print-generic-1.rs:17:5
|
LL | let c = to_fn_once(move || {
| - move occurs because `c` has type `[closure@$DIR/closure-print-generic-1.rs:12:24: 14:6]`, which does not implement the `Copy` trait
...
LL | c();
| --- `c` moved due to this call
LL | c();
| ^ value used here after move
|
note: this value implements `FnOnce`, which causes it to be moved when called
--> $DIR/closure-print-generic-1.rs:16:5
|
LL | c();
| ^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0382`.
13 changes: 13 additions & 0 deletions src/test/ui/closures/print/closure-print-generic-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
mod mod1 {
pub fn f<T: std::fmt::Display>(t: T) {
let x = 20;

let c = || println!("{} {}", t, x);
let c1: () = c;
//~^ ERROR mismatched types
}
}

fn main() {
mod1::f(5i32);
}
20 changes: 20 additions & 0 deletions src/test/ui/closures/print/closure-print-generic-2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error[E0308]: mismatched types
--> $DIR/closure-print-generic-2.rs:6:22
|
LL | let c = || println!("{} {}", t, x);
| -------------------------- the found closure
LL | let c1: () = c;
| -- ^ expected `()`, found closure
| |
| expected due to this
|
= note: expected unit type `()`
found closure `[closure@$DIR/closure-print-generic-2.rs:5:17: 5:43]`
help: use parentheses to call this closure
|
LL | let c1: () = c();
| ^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
Loading

0 comments on commit 6ac6c67

Please sign in to comment.