Skip to content

Commit 6ac6c67

Browse files
committed
Auto merge of #77069 - sexxi-goose:closure_print_2, r=nikomatsakis
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`
2 parents 0d9afb6 + adda0cd commit 6ac6c67

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+513
-122
lines changed

compiler/rustc_middle/src/ty/print/pretty.rs

+54-72
Original file line numberDiff line numberDiff line change
@@ -641,104 +641,86 @@ pub trait PrettyPrinter<'tcx>:
641641
}
642642
ty::Str => p!(write("str")),
643643
ty::Generator(did, substs, movability) => {
644+
p!(write("["));
644645
match movability {
645-
hir::Movability::Movable => p!(write("[generator")),
646-
hir::Movability::Static => p!(write("[static generator")),
646+
hir::Movability::Movable => {}
647+
hir::Movability::Static => p!(write("static ")),
647648
}
648649

649-
// FIXME(eddyb) should use `def_span`.
650-
if let Some(did) = did.as_local() {
651-
let hir_id = self.tcx().hir().local_def_id_to_hir_id(did);
652-
let span = self.tcx().hir().span(hir_id);
653-
p!(write("@{}", self.tcx().sess.source_map().span_to_string(span)));
654-
655-
if substs.as_generator().is_valid() {
656-
let upvar_tys = substs.as_generator().upvar_tys();
657-
let mut sep = " ";
658-
for (&var_id, upvar_ty) in self
659-
.tcx()
660-
.upvars_mentioned(did)
661-
.as_ref()
662-
.iter()
663-
.flat_map(|v| v.keys())
664-
.zip(upvar_tys)
665-
{
666-
p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
667-
sep = ", ";
668-
}
650+
if !self.tcx().sess.verbose() {
651+
p!(write("generator"));
652+
// FIXME(eddyb) should use `def_span`.
653+
if let Some(did) = did.as_local() {
654+
let hir_id = self.tcx().hir().local_def_id_to_hir_id(did);
655+
let span = self.tcx().hir().span(hir_id);
656+
p!(write("@{}", self.tcx().sess.source_map().span_to_string(span)));
657+
} else {
658+
p!(write("@{}", self.tcx().def_path_str(did)));
669659
}
670660
} else {
671-
p!(write("@{}", self.tcx().def_path_str(did)));
672-
661+
p!(print_def_path(did, substs));
673662
if substs.as_generator().is_valid() {
674-
let upvar_tys = substs.as_generator().upvar_tys();
675-
let mut sep = " ";
676-
for (index, upvar_ty) in upvar_tys.enumerate() {
677-
p!(write("{}{}:", sep, index), print(upvar_ty));
678-
sep = ", ";
663+
// Search for the first inference variable
664+
p!(write(" upvar_tys=("));
665+
let mut uninferred_ty =
666+
substs.as_generator().upvar_tys().filter(|ty| ty.is_ty_infer());
667+
if uninferred_ty.next().is_some() {
668+
p!(write("unavailable"));
669+
} else {
670+
self = self.comma_sep(substs.as_generator().upvar_tys())?;
679671
}
672+
p!(write(")"));
680673
}
681674
}
682675

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

687-
p!(write("]"))
680+
p!(write("]"));
688681
}
689682
ty::GeneratorWitness(types) => {
690683
p!(in_binder(&types));
691684
}
692685
ty::Closure(did, substs) => {
693-
p!(write("[closure"));
694-
695-
// FIXME(eddyb) should use `def_span`.
696-
if let Some(did) = did.as_local() {
697-
let hir_id = self.tcx().hir().local_def_id_to_hir_id(did);
698-
if self.tcx().sess.opts.debugging_opts.span_free_formats {
699-
p!(write("@"), print_def_path(did.to_def_id(), substs));
700-
} else {
701-
let span = self.tcx().hir().span(hir_id);
702-
p!(write("@{}", self.tcx().sess.source_map().span_to_string(span)));
703-
}
704-
705-
if substs.as_closure().is_valid() {
706-
let upvar_tys = substs.as_closure().upvar_tys();
707-
let mut sep = " ";
708-
for (&var_id, upvar_ty) in self
709-
.tcx()
710-
.upvars_mentioned(did)
711-
.as_ref()
712-
.iter()
713-
.flat_map(|v| v.keys())
714-
.zip(upvar_tys)
715-
{
716-
p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
717-
sep = ", ";
686+
p!(write("["));
687+
if !self.tcx().sess.verbose() {
688+
p!(write("closure"));
689+
// FIXME(eddyb) should use `def_span`.
690+
if let Some(did) = did.as_local() {
691+
let hir_id = self.tcx().hir().local_def_id_to_hir_id(did);
692+
if self.tcx().sess.opts.debugging_opts.span_free_formats {
693+
p!(write("@"), print_def_path(did.to_def_id(), substs));
694+
} else {
695+
let span = self.tcx().hir().span(hir_id);
696+
p!(write("@{}", self.tcx().sess.source_map().span_to_string(span)));
718697
}
698+
} else {
699+
p!(write("@{}", self.tcx().def_path_str(did)));
719700
}
720701
} else {
721-
p!(write("@{}", self.tcx().def_path_str(did)));
722-
702+
p!(print_def_path(did, substs));
723703
if substs.as_closure().is_valid() {
724-
let upvar_tys = substs.as_closure().upvar_tys();
725-
let mut sep = " ";
726-
for (index, upvar_ty) in upvar_tys.enumerate() {
727-
p!(write("{}{}:", sep, index), print(upvar_ty));
728-
sep = ", ";
704+
// Search for the first inference variable
705+
let mut uninferred_ty =
706+
substs.as_closure().upvar_tys().filter(|ty| ty.is_ty_infer());
707+
if uninferred_ty.next().is_some() {
708+
// If the upvar substs contain an inference variable we haven't
709+
// finished capture analysis.
710+
p!(write(" closure_substs=(unavailable)"));
711+
} else {
712+
p!(write(" closure_kind_ty="), print(substs.as_closure().kind_ty()));
713+
p!(
714+
write(" closure_sig_as_fn_ptr_ty="),
715+
print(substs.as_closure().sig_as_fn_ptr_ty())
716+
);
717+
p!(write(" upvar_tys=("));
718+
self = self.comma_sep(substs.as_closure().upvar_tys())?;
719+
p!(write(")"));
729720
}
730721
}
731722
}
732-
733-
if self.tcx().sess.verbose() && substs.as_closure().is_valid() {
734-
p!(write(" closure_kind_ty="), print(substs.as_closure().kind_ty()));
735-
p!(
736-
write(" closure_sig_as_fn_ptr_ty="),
737-
print(substs.as_closure().sig_as_fn_ptr_ty())
738-
);
739-
}
740-
741-
p!(write("]"))
723+
p!(write("]"));
742724
}
743725
ty::Array(ty, sz) => {
744726
p!(write("["), print(ty), write("; "));

src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ fn foo(_1: T, _2: i32) -> (i32, T) {
44
debug t => _1; // in scope 0 at $DIR/inline-closure-captures.rs:10:17: 10:18
55
debug q => _2; // in scope 0 at $DIR/inline-closure-captures.rs:10:23: 10:24
66
let mut _0: (i32, T); // return place in scope 0 at $DIR/inline-closure-captures.rs:10:34: 10:42
7-
let _3: [closure@foo<T>::{closure#0} q:&i32, t:&T]; // in scope 0 at $DIR/inline-closure-captures.rs:11:9: 11:10
7+
let _3: [closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-captures.rs:11:9: 11:10
88
let mut _4: &i32; // in scope 0 at $DIR/inline-closure-captures.rs:11:13: 11:24
99
let mut _5: &T; // in scope 0 at $DIR/inline-closure-captures.rs:11:13: 11:24
10-
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
10+
let mut _6: &[closure@foo<T>::{closure#0}]; // in scope 0 at $DIR/inline-closure-captures.rs:12:5: 12:6
1111
let mut _7: (i32,); // in scope 0 at $DIR/inline-closure-captures.rs:12:5: 12:9
1212
let mut _8: i32; // in scope 0 at $DIR/inline-closure-captures.rs:12:7: 12:8
1313
let mut _10: i32; // in scope 0 at $DIR/inline-closure-captures.rs:12:5: 12:9

src/test/ui/async-await/issue-68112.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ LL | require_send(send_fut);
4141
|
4242
= help: the trait `Sync` is not implemented for `RefCell<i32>`
4343
= note: required because of the requirements on the impl of `Send` for `Arc<RefCell<i32>>`
44-
= note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:47:31: 47:36 t:Arc<RefCell<i32>> {}]`
45-
= 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>> {}]>`
44+
= note: required because it appears within the type `[static generator@$DIR/issue-68112.rs:47:31: 47:36 {}]`
45+
= note: required because it appears within the type `from_generator::GenFuture<[static generator@$DIR/issue-68112.rs:47:31: 47:36 {}]>`
4646
= note: required because it appears within the type `impl Future`
4747
= note: required because it appears within the type `impl Future`
4848
= note: required because it appears within the type `impl Future`

src/test/ui/block-result/issue-20862.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | |y| x + y
77
| ^^^^^^^^^ expected `()`, found closure
88
|
99
= note: expected unit type `()`
10-
found closure `[closure@$DIR/issue-20862.rs:2:5: 2:14 x:_]`
10+
found closure `[closure@$DIR/issue-20862.rs:2:5: 2:14]`
1111

1212
error[E0618]: expected function, found `()`
1313
--> $DIR/issue-20862.rs:7:13

src/test/ui/borrowck/issue-53432-nested-closure-outlives-borrowed-value.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error: lifetime may not live long enough
44
LL | let _action = move || {
55
| -------
66
| | |
7-
| | 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]]
7+
| | return type of closure is [closure@$DIR/issue-53432-nested-closure-outlives-borrowed-value.rs:4:9: 4:15]
88
| lifetime `'1` represents this closure's body
99
LL | || f() // The `nested` closure
1010
| ^^^^^^ returning this value requires that `'1` must outlive `'2`

src/test/ui/closures/closure-move-sync.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LL | F: Send + 'static,
1111
|
1212
= help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<()>`
1313
= note: required because of the requirements on the impl of `Send` for `&std::sync::mpsc::Receiver<()>`
14-
= note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:6:27: 9:6 recv:&std::sync::mpsc::Receiver<()>]`
14+
= note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:6:27: 9:6]`
1515

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

3131
error: aborting due to 2 previous errors
3232

src/test/ui/closures/closure-no-fn-1.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
77
| expected due to this
88
|
99
= note: expected fn pointer `fn(u8) -> u8`
10-
found closure `[closure@$DIR/closure-no-fn-1.rs:6:29: 6:50 a:_]`
10+
found closure `[closure@$DIR/closure-no-fn-1.rs:6:29: 6:50]`
1111

1212
error: aborting due to previous error
1313

src/test/ui/closures/closure-no-fn-2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | let bar: fn() -> u8 = || { b };
77
| expected due to this
88
|
99
= note: expected fn pointer `fn() -> u8`
10-
found closure `[closure@$DIR/closure-no-fn-2.rs:6:27: 6:35 b:_]`
10+
found closure `[closure@$DIR/closure-no-fn-2.rs:6:27: 6:35]`
1111

1212
error: aborting due to previous error
1313

src/test/ui/closures/closure-no-fn-3.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0605]: non-primitive cast: `[closure@$DIR/closure-no-fn-3.rs:6:27: 6:37 b:_]` as `fn() -> u8`
1+
error[E0605]: non-primitive cast: `[closure@$DIR/closure-no-fn-3.rs:6:27: 6:37]` as `fn() -> u8`
22
--> $DIR/closure-no-fn-3.rs:6:27
33
|
44
LL | let baz: fn() -> u8 = (|| { b }) as fn() -> u8;

src/test/ui/closures/closure-reform-bad.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | call_bare(f)
77
| ^ expected fn pointer, found closure
88
|
99
= note: expected fn pointer `for<'r> fn(&'r str)`
10-
found closure `[closure@$DIR/closure-reform-bad.rs:10:13: 10:50 string:_]`
10+
found closure `[closure@$DIR/closure-reform-bad.rs:10:13: 10:50]`
1111

1212
error: aborting due to previous error
1313

src/test/ui/closures/closure_cap_coerce_many_fail.stderr

+7-7
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ LL | | };
1212
| |_____- `match` arms have incompatible types
1313
|
1414
= note: expected type `fn(i32, i32) -> i32 {add}`
15-
found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:9:16: 9:43 cap:_]`
15+
found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:9:16: 9:43]`
1616

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

@@ -38,14 +38,14 @@ error[E0308]: `match` arms have incompatible types
3838
LL | let _ = match "+" {
3939
| _____________-
4040
LL | | "+" => |a, b| (a + b + cap) as i32,
41-
| | --------------------------- this is found to be of type `[closure@$DIR/closure_cap_coerce_many_fail.rs:26:16: 26:43 cap:_]`
41+
| | --------------------------- this is found to be of type `[closure@$DIR/closure_cap_coerce_many_fail.rs:26:16: 26:43]`
4242
LL | | "-" => |a, b| (a - b) as i32,
4343
| | ^^^^^^^^^^^^^^^^^^^^^ expected closure, found a different closure
4444
LL | | _ => unimplemented!(),
4545
LL | | };
4646
| |_____- `match` arms have incompatible types
4747
|
48-
= note: expected type `[closure@$DIR/closure_cap_coerce_many_fail.rs:26:16: 26:43 cap:_]`
48+
= note: expected type `[closure@$DIR/closure_cap_coerce_many_fail.rs:26:16: 26:43]`
4949
found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:27:16: 27:37]`
5050
= note: no two closures, even if identical, have the same type
5151
= help: consider boxing your closure and/or using it as a trait object
@@ -56,15 +56,15 @@ error[E0308]: `match` arms have incompatible types
5656
LL | let _ = match "+" {
5757
| _____________-
5858
LL | | "+" => |a, b| (a + b + cap) as i32,
59-
| | --------------------------- this is found to be of type `[closure@$DIR/closure_cap_coerce_many_fail.rs:34:16: 34:43 cap:_]`
59+
| | --------------------------- this is found to be of type `[closure@$DIR/closure_cap_coerce_many_fail.rs:34:16: 34:43]`
6060
LL | | "-" => |a, b| (a - b + cap) as i32,
6161
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected closure, found a different closure
6262
LL | | _ => unimplemented!(),
6363
LL | | };
6464
| |_____- `match` arms have incompatible types
6565
|
66-
= note: expected type `[closure@$DIR/closure_cap_coerce_many_fail.rs:34:16: 34:43 cap:_]`
67-
found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:35:16: 35:43 cap:_]`
66+
= note: expected type `[closure@$DIR/closure_cap_coerce_many_fail.rs:34:16: 34:43]`
67+
found closure `[closure@$DIR/closure_cap_coerce_many_fail.rs:35:16: 35:43]`
6868
= note: no two closures, even if identical, have the same type
6969
= help: consider boxing your closure and/or using it as a trait object
7070

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
fn to_fn_once<F: FnOnce()>(f: F) -> F {
2+
f
3+
}
4+
5+
fn f<T: std::fmt::Display>(y: T) {
6+
struct Foo<U: std::fmt::Display> {
7+
x: U,
8+
};
9+
10+
let foo = Foo { x: "x" };
11+
12+
let c = to_fn_once(move || {
13+
println!("{} {}", foo.x, y);
14+
});
15+
16+
c();
17+
c();
18+
//~^ ERROR use of moved value
19+
}
20+
21+
fn main() {
22+
f("S");
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0382]: use of moved value: `c`
2+
--> $DIR/closure-print-generic-1.rs:17:5
3+
|
4+
LL | let c = to_fn_once(move || {
5+
| - move occurs because `c` has type `[closure@$DIR/closure-print-generic-1.rs:12:24: 14:6]`, which does not implement the `Copy` trait
6+
...
7+
LL | c();
8+
| --- `c` moved due to this call
9+
LL | c();
10+
| ^ value used here after move
11+
|
12+
note: this value implements `FnOnce`, which causes it to be moved when called
13+
--> $DIR/closure-print-generic-1.rs:16:5
14+
|
15+
LL | c();
16+
| ^
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0382`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
mod mod1 {
2+
pub fn f<T: std::fmt::Display>(t: T) {
3+
let x = 20;
4+
5+
let c = || println!("{} {}", t, x);
6+
let c1: () = c;
7+
//~^ ERROR mismatched types
8+
}
9+
}
10+
11+
fn main() {
12+
mod1::f(5i32);
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/closure-print-generic-2.rs:6:22
3+
|
4+
LL | let c = || println!("{} {}", t, x);
5+
| -------------------------- the found closure
6+
LL | let c1: () = c;
7+
| -- ^ expected `()`, found closure
8+
| |
9+
| expected due to this
10+
|
11+
= note: expected unit type `()`
12+
found closure `[closure@$DIR/closure-print-generic-2.rs:5:17: 5:43]`
13+
help: use parentheses to call this closure
14+
|
15+
LL | let c1: () = c();
16+
| ^^
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)