-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Rework "long type names" printing logic #136328
base: master
Are you sure you want to change the base?
Conversation
Make it so more type-system types can be printed in a shortened version (like `Predicate`s). Centralize printing the information about the "full type name path". Make the "long type path" for the file where long types are written part of `Diag`, so that it becomes easier to keep track of it, and ensure it will always will be printed out last in the diagnostic by making its addition to the output implicit. Tweak the shortening of types in "expected/found" labels. Remove dead file `note.rs`.
r? @spastorino rustbot has assigned @spastorino. Use |
Some changes occurred in match checking cc @Nadrieril Some changes occurred in need_type_info.rs cc @lcnr |
pub fn short_string<'a, T>(self, p: T, path: &mut Option<PathBuf>) -> String | ||
where | ||
T: Print<'tcx, FmtPrinter<'a, 'tcx>> + Lift<TyCtxt<'tcx>> + Copy + Hash, | ||
<T as Lift<TyCtxt<'tcx>>>::Lifted: Print<'tcx, FmtPrinter<'a, 'tcx>>, | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With these changes now anything that can be printed can be passed to this, and the printing logic already handles the shortening gracefully. Look at the long E0277 error for an example of the effect.
fn take_diag(&mut self) -> DiagInner { | ||
if let Some(path) = &self.long_ty_path { | ||
self.note(format!( | ||
"the full name for the type has been written to '{}'", | ||
path.display() | ||
)); | ||
self.note("consider using `--verbose` to print the full type name to the console"); | ||
} | ||
Box::into_inner(self.diag.take().unwrap()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now there's no chance of forgetting to print this path (although we need to remember to use long_ty_path()
to set the path right after error construction if we've made short strings before that).
@@ -635,19 +629,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { | |||
self.suggest_cloning(err, place_ty, expr, Some(use_spans)); | |||
} | |||
|
|||
let mut path = None; | |||
let ty = self.infcx.tcx.short_ty_string(place_ty, &mut path); | |||
let ty = self.infcx.tcx.short_string(place_ty, err.long_ty_path()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an example of the intended way of using this. This is the safest way of creating a short string because there's no way of forgetting to print the "full name written to path
" message.
if self.should_truncate() { | ||
write!(self, "@...}}")?; | ||
return Ok(()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changes the closure printing so when the closure is right at the edge of being replaced with ...
, we print it as {closure@...}
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file was in the repo but wasn't mod
ded 😵
@@ -29,7 +29,7 @@ error[E0308]: mismatched types | |||
--> $DIR/coerce-expect-unsized-ascribed.rs:14:27 | |||
| | |||
LL | let _ = type_ascribe!(Box::new( { |x| (x as u8) }), Box<dyn Fn(i32) -> _>); | |||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Fn(i32) -> u8>`, found `Box<{closure@coerce-expect-unsized-ascribed.rs:14:39}>` | |||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Fn(i32) -> u8>`, found `Box<{closure@...}>` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example of the "short closure" logic mentioned before.
@@ -7,14 +7,16 @@ LL | | Err::<(), _>( | |||
LL | | Ok::<_, ()>( | |||
... | | |||
LL | | ) | |||
| |_____^ type mismatch resolving `<Result<Result<(), Result<Result<(), ...>, ...>>, ...> as Future>::Error == Foo` | |||
| |_____^ type mismatch resolving `<Result<..., ()> as Future>::Error == Foo` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example of the allowlisting of "known short" types so we don't replace them with ...
unnecessarily.
error[E0277]: the trait bound `(..., ..., ..., ...): Trait` is not satisfied | ||
--> $DIR/long-e0277.rs:13:21 | ||
| | ||
LL | require_trait::<D>(); | ||
| ^ unsatisfied trait bound | ||
| | ||
= help: the trait `Trait` is not implemented for `(..., ..., ..., ...)` | ||
help: this trait has no implementations, consider adding one | ||
--> $DIR/long-e0277.rs:8:1 | ||
| | ||
LL | trait Trait {} | ||
| ^^^^^^^^^^^ | ||
note: required by a bound in `require_trait` | ||
--> $DIR/long-e0277.rs:10:21 | ||
| | ||
LL | fn require_trait<T: Trait>() {} | ||
| ^^^^^ required by this bound in `require_trait` | ||
= note: the full name for the type has been written to '$TEST_BUILD_DIR/diagnostic-width/long-e0277/long-e0277.long-type-hash.txt' | ||
= note: consider using `--verbose` to print the full type name to the console |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the error I had set out to clean up, and ended up being a slightly larger refactor than I intended. You can see that the bound is reusing the "short type" printing logic now.
= note: the full name for the type has been written to '$TEST_BUILD_DIR/traits/on_unimplemented_long_types/on_unimplemented_long_types.long-type-hash.txt' | ||
= note: consider using `--verbose` to print the full type name to the console |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another benefit of making Diag
carry the path: it's impossible to have redundant notes now.
#136315 will conflict with this PR. |
@@ -1,6 +1,6 @@ | |||
//@ revisions: ascii unicode | |||
//@[ascii] compile-flags: --diagnostic-width=40 | |||
//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40 | |||
//@[ascii] compile-flags: --diagnostic-width=40 -Zwrite-long-types-to-disk=yes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Random comment while I was in the neighborhood.
When using -Zwrite-long-types-to-disk=yes
, we usually normalize away the hash in the long type file name, but that's not enough. Using a compare-mode will embed the compare mode in the long type file path as well.
The path note: the full name for the type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271.unicode/E0271.long-type-hash.txt'
will become note: the full name for the type has been written to '$TEST_BUILD_DIR/diagnostic-width.$compare-mode/E0271.unicode/E0271.long-type-hash.txt'
and the test will fail.
I encountered this while looking over the test failures under the new solver, i.e. ./x test bla --compare-mode=next-solver
. While this specific test will currently fail for different reasons, it should pass in general without any changes required to diagnostics. (you can check that this test will fail under e.g. --compare-mode polonius
)
For that, we'd need either:
- compiletest to take care of all normalizations needing to be done due to compare-modes
- expand what we manually normalize in the tests, taking care of the compare-mode suffix, as well as the possible hash
Since we already do part of the latter, I personally went with option 2 in #136310, and expanded the regex to look for the complete file path to remove the subdirectories.
For cases that have a hash suffix to normalize away, like in this E0271 test, it looks like:
// The regex below normalizes the long type file name to make it suitable for compare-modes.
//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
One could remove the comment to avoid reblessing the new line numbers.
I already took care of long-E0308
and so on in that other PR (so they will conflict/require reblessing), but the same issue will also appear in the new long-e0277.rs
test here.
Thanks for coming to my TED talk.
Make it so more type-system types can be printed in a shortened version (like
Predicate
s).Centralize printing the information about the "full type name path".
Make the "long type path" for the file where long types are written part of
Diag
, so that it becomes easier to keep track of it, and ensure it will always will be printed out last in the diagnostic by making its addition to the output implicit.Tweak the shortening of types in "expected/found" labels.
Remove dead file
note.rs
.