Add more detail to type inference error#61361
Conversation
|
r? @varkor (rust_highfive has picked a reviewer for you, use r? to override) |
|
cc @rust-lang/wg-diagnostics
I think that's an important thing to focus on in the short/medium term, together with using the local ident for external paths ( |
This comment has been minimized.
This comment has been minimized.
Centril
left a comment
There was a problem hiding this comment.
I'm still not that sold on replacing _ but there seem to be bugs?
|
@varkor would you prefer the following output? We could also provide structured suggestions now that we have the type names, but I would like help to bikeshed the wording: Also, I'm not sure we can verify with certainty that we're pointing at a For patterns I need to change the wording as it is subtly incorrect now. |
When encountering code where type inference fails, add more actionable
information:
```
fn main() {
let foo = Vec::new();
}
```
```
error[E0282]: type annotations needed for `std::vec::Vec<_>`
--> $DIR/vector-no-ann.rs:2:16
|
LL | let foo = Vec::new();
| --- ^^^^^^^^ cannot infer type for `T`
| |
| consider giving `foo` the type `std::vec::Vec<_>` with the type parameter `T` specified
```
We still need to modify type printing to optionally accept a
`TypeVariableTable` in order to properly print `std::vec::Vec<T>`.
CC rust-lang#25633.
``` error[E0282]: type annotations needed in `std::result::Result<i32, E>` --> file7.rs:3:13 | 3 | let b = Ok(4); | - ^^ cannot infer type for `E` in `std::result::Result<i32, E>` | | | consider giving `b` a type` ```
| | | ||
| LL | let mut closure0 = None; | ||
| | ------------ consider giving `closure0` a type | ||
| | ------------ consider giving `closure0` the type `std::option::Option<T>` with the type parameter `_` specified |
There was a problem hiding this comment.
I think it's a problem when the type parameters don't match up. (It'd be better for both to be _, as long as it's unambiguous.)
There was a problem hiding this comment.
I believe what is happening here is that _ and T are actually not unified, they are separate types as far as typeck is concerned. I'm not sure what the best way to go about it here would be :-/
There was a problem hiding this comment.
Cheated a bit and changed it to be:
error[E0282]: type annotations needed for `std::option::Option<T>`
--> $DIR/unboxed-closures-failed-recursive-fn-2.rs:16:32
|
LL | let mut closure0 = None;
| ------------ consider giving `closure0` the explicit type `std::option::Option<T>`, with the type parameters specified
...
LL | return c();
| ^^^ cannot infer type
|
= note: type must be known at this point
There was a problem hiding this comment.
Yeah, that's probably better.
|
I think a tweak to the message makes it slightly clearer (i.e. not to have users thinking: "but
Structured suggestions would be nice, but only if we don't get it wrong, yeah. |
|
Okay, I think this is good now! Thanks for being patient with all the back and forth about wording 😄 r=me if you're happy with the wording now too. |
|
📌 Commit e420f44 has been approved by |
Add more detail to type inference error
When encountering code where type inference fails, add more actionable
information:
```
fn main() {
let foo = Vec::new();
}
```
```
error[E0282]: type annotations needed in `std::vec::Vec<T>`
--> $DIR/vector-no-ann.rs:2:16
|
LL | let foo = Vec::new();
| --- ^^^^^^^^ cannot infer type for `T` in `std::vec::Vec<T>`
| |
| consider giving `foo` a type
```
Fix #25633.
|
☀️ Test successful - checks-travis, status-appveyor |
|
|
||
| pub region_highlight_mode: RegionHighlightMode, | ||
|
|
||
| pub name_resolver: Option<Box<&'a dyn Fn(ty::sty::TyVid) -> Option<String>>>, |
There was a problem hiding this comment.
Please cc me on ty::print changes - but also, I have a few questions, such as "why is this a Box<&dyn Trait>?" - you can just remove the Box and everything would still work.
| ty::Infer(infer_ty) => p!(write("{}", infer_ty)), | ||
| ty::Infer(infer_ty) => { | ||
| if let ty::TyVar(ty_vid) = infer_ty { | ||
| if let Some(name) = self.infer_ty_name(ty_vid) { |
There was a problem hiding this comment.
I'd probably override this in FmtPrinter's print_ty tbh, instead of adding infer_ty_name.
|
|
||
| impl<F: fmt::Write> PrettyPrinter<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> { | ||
| fn infer_ty_name(&self, id: ty::TyVid) -> Option<String> { | ||
| self.0.name_resolver.as_ref().and_then(|func| func(id)) |
There was a problem hiding this comment.
There's a Deref impl, you don't need to write self.0.
When encountering code where type inference fails, add more actionable
information:
Fix #25633.