From a4c43a3a4c7db1a39a136df50d9e1c24c738d386 Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Wed, 2 Sep 2020 16:13:00 -0400 Subject: [PATCH 1/2] Propose updates to closure pretty print --- update_closure_printing.md | 84 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 update_closure_printing.md diff --git a/update_closure_printing.md b/update_closure_printing.md new file mode 100644 index 0000000..f6ca7de --- /dev/null +++ b/update_closure_printing.md @@ -0,0 +1,84 @@ +# Update closure pretty printing + +Currently the compiler prints the capture information (name and type) of the root variable being captured. For example, current pretty print: + +```rust +struct Point { + x: i32, + y: i32, +} + +let p = Point { x: 10, y: 20 }; + +// pretty print: [closure@src/main.rs:8:14: 10:6 p:_] +let c1 = || { + println!("{}", p.x); +}; + +// pretty print: [closure@src/main.rs:11:14: 13:6 p:_] +let c2 = || { + println!("{}", p.y); +}; +``` +(`p:_`, means p is captured and its type hasn't been inferred yet) + + +## Motivation for change +- This information isn't really diagnostically useful to the end user. +- Once [RFC 2229](https://github.com/rust-lang/rfcs/blob/master/text/2229-capture-disjoint-fields.md) is implemented, the current closure pretty print won't be completely accurate. In the above example, after RFC-2229 `c1` only captures `p.x` and c2 only captures `p.y`. +- Closures don't print information about generics they inherit from their parent scope. + +## Proposed changes +- Don't print capture information for closures unless `-Zverbose` is specified. +- When the compiler is invoked with `-Zverbose` only print the type of the capture and not the name of or path to the variable. + +Applying these two changes to example above we get +```rust +// pretty print: [closure@src/main.rs:8:14: 10:6] +let c1 = || { + println!("{}", p.x); +}; + +// compile-flags: -Zverbose +// pretty print: [closure@src/main.rs:8:14: 10:6 (&i32)] +let c1 = || { + println!("{}", p.x); +}; +``` +(Note this example is missing changes explained below) + +- If type information about captures isn't available or can't be verified as available then the information won't be printed out. + +```rust +// compile-flags: -Zverbose +// pretty print: [closure@src/main.rs:8:14: 10:6 (unavailable)] +let c1 = || { + println!("{}", p.x); +}; + +let c :() = c1; // Error here prevents us from doing capture analysis +``` +(Note this example is missing changes explained below) + +- Print the path to the closure instead of the `[closure]` notation, similar to how types defined within the closure are printed. If `-Zverbose` is passed to the compiler then we print generics as part of the path. + +```rust +mod mod1 { + pub fn f(t: T) + { + let x = 20; + + // pretty print: mod1::f::{{closure}}#0 + let c = || println!("{} {}", t, x); + c(); // * + } +} + +fn main() { + f(format!("S")); +} +``` + +If `-Zverbose` is set then pretty print for the closure will be `mod1::f::{{closure}}#0 (&T, &i32)`. + +If `-Zverbose` is set and the line marked with `*` is changed to `let c1 :() = c`, that is it prevents us from starting capture analysis, the pretty print will be `mod1::f::{{closure}}#0 (unavailable)`. From b9381cbc2210a450e389ffca9b4e0c8fe7e1f2ee Mon Sep 17 00:00:00 2001 From: Aman Arora Date: Tue, 15 Sep 2020 01:29:24 -0400 Subject: [PATCH 2/2] Update proposal --- update_closure_printing.md | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/update_closure_printing.md b/update_closure_printing.md index f6ca7de..488629c 100644 --- a/update_closure_printing.md +++ b/update_closure_printing.md @@ -22,14 +22,16 @@ let c2 = || { ``` (`p:_`, means p is captured and its type hasn't been inferred yet) +If `-Zverbose` is set the closure pretty print will also include the closure signature and closure kind (eg: i32 for FnOnce). + ## Motivation for change -- This information isn't really diagnostically useful to the end user. +- Information about closure kind, signature and capture types isn't really diagnostically useful to the end user. - Once [RFC 2229](https://github.com/rust-lang/rfcs/blob/master/text/2229-capture-disjoint-fields.md) is implemented, the current closure pretty print won't be completely accurate. In the above example, after RFC-2229 `c1` only captures `p.x` and c2 only captures `p.y`. - Closures don't print information about generics they inherit from their parent scope. ## Proposed changes -- Don't print capture information for closures unless `-Zverbose` is specified. +- Don't print closure information (kind, signature, capture types) unless `-Zverbose` is specified. - When the compiler is invoked with `-Zverbose` only print the type of the capture and not the name of or path to the variable. Applying these two changes to example above we get @@ -40,18 +42,17 @@ let c1 = || { }; // compile-flags: -Zverbose -// pretty print: [closure@src/main.rs:8:14: 10:6 (&i32)] +// pretty print: [closure@src/main.rs:8:14: 10:6 closure_kind_ty=, closure_sig_as_fn_ptr_ty=, upvar_tys=(&i32)] let c1 = || { println!("{}", p.x); }; ``` (Note this example is missing changes explained below) -- If type information about captures isn't available or can't be verified as available then the information won't be printed out. - +- If type information captures isn't available or can't be verified as available then the information won't be printed out. ```rust // compile-flags: -Zverbose -// pretty print: [closure@src/main.rs:8:14: 10:6 (unavailable)] +// pretty print: [closure@src/main.rs:8:14: 10:6 substs=(unavailable)] let c1 = || { println!("{}", p.x); }; @@ -60,7 +61,10 @@ let c :() = c1; // Error here prevents us from doing capture analysis ``` (Note this example is missing changes explained below) -- Print the path to the closure instead of the `[closure]` notation, similar to how types defined within the closure are printed. If `-Zverbose` is passed to the compiler then we print generics as part of the path. +- In case of -Zverbose, print the path (including generics) to the closure instead of the `[closure]` notation, similar to how types defined within the closure are printed. + +Note: If the path is non-ambigous it will be truncated automaitcally, this behaviour can be disbaled using `-Z trim-diagnostic-paths=off`. Check https://github.com/rust-lang/rust/pull/73996 +for more details. ```rust mod mod1 { @@ -68,7 +72,7 @@ mod mod1 { { let x = 20; - // pretty print: mod1::f::{{closure}}#0 + // pretty print: [closure@rc/main.rs:line:col line:col] let c = || println!("{} {}", t, x); c(); // * } @@ -79,6 +83,6 @@ fn main() { } ``` -If `-Zverbose` is set then pretty print for the closure will be `mod1::f::{{closure}}#0 (&T, &i32)`. - -If `-Zverbose` is set and the line marked with `*` is changed to `let c1 :() = c`, that is it prevents us from starting capture analysis, the pretty print will be `mod1::f::{{closure}}#0 (unavailable)`. +- If `-Zverbose` is set then pretty print for the closure will be `f::{{closure}}#0 closure_kind_ty=i8, closure_sig_as_fn_ptr_ty=, closure_signature=(&T, &i32)`. +- If `-Z trim-diagnostic-paths=off` is _also_ set then pretty print for the closure will be `mod1::f::{{closure}}#0 closure_kind_ty=i8, closure_sig_as_fn_ptr_ty=, closure_signature=(&T, &i32)`. +- If `-Zverbose` is set and the line marked with `*` is changed to `let c1 :() = c`, that is it prevents us to start capture analysis, the pretty print will be `f::{{closure}}#0 substs=(unavailable)`.