Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pretty.rs: Update Closure and Generator print #77069

Merged
merged 2 commits into from
Sep 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, did you try using def_span here?

Copy link
Member Author

@arora-aman arora-aman Sep 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't try def_span, I guess I could've. I was mostly trying to keep changes minimal to non-verbose mode with this PR. Main motivation is to remove printing upvar_tys for non-verbose.

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() {
Copy link
Member Author

@arora-aman arora-aman Sep 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't need this check when rust-lang/project-rfc-2229#4 is implemented, because then the is_valid() check itself will fail because the tupled_upvar_tys will be an inference variable.

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() {
davidtwco marked this conversation as resolved.
Show resolved Hide resolved
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