Point at definition of item with type parameters that couldn't be inferred#153890
Point at definition of item with type parameters that couldn't be inferred#153890estebank wants to merge 1 commit intorust-lang:mainfrom
Conversation
|
Some changes occurred in need_type_info.rs cc @lcnr |
|
r? @jieyouxu rustbot has assigned @jieyouxu. Use Why was this reviewer chosen?The reviewer was selected based on:
|
| note: type must be known for type parameter in this | ||
| --> $DIR/dedup-normalized-2-higher-ranked.rs:25:1 | ||
| | | ||
| LL | fn impls<T: for<'b> Bound<'b, U>, U>(_: T) {} | ||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
There was a problem hiding this comment.
Discussion (non-blocking): hm, the phrasing on this stderr looks a little bit strange:
- The current wording doesn't say the concrete types of which type parameter we don't know about
- Saying "this" I suppose works, it just reads somewhat strange
I wonder if it's worth the trouble to say something more like
the concrete type of type parameter
Tmust be known inimpls
... or
the concrete type of type parameter
Tmust be known in this function
s/function/$item_kind/
That being said, I don't think this PR needs to block on that.
There was a problem hiding this comment.
I agree that the output is not ideal. I'd tried an initial attempt at getting the same information from the existing label in the message, but I think I might have to do some mild refactoring to accomplish that. I agree that the wording should be closer to what you propose.
| note: type must be known for type parameter in this | ||
| --> $DIR/issue-99565.rs:3:1 | ||
| | | ||
| LL | fn foo<T, U>(_: U) {} | ||
| | ^^^^^^^^^^^^^^^^^^ |
There was a problem hiding this comment.
Remark: hm, my first reaction when reading this diff is that maybe this is slightly redundant?
The inline note above says
cannot infer type of the type parameter
Tdeclared on the functionfoo
which feels a bit redundant with the new outline note
note: type must be known for type parameter in this
I guess I could see the explicit reference being useful since otherwise the original inline note does not actually point at the definition of foo
EDIT: now I recall you mentioned this specifically in the description lol
We should further refine when we present this info to make sure we don't provide redundant notes in some cases. Also, there are cases (like those in issue 94969) that don't provide any new information with this change.
| note: type must be known for type parameter in this | ||
| --> $DIR/rp_impl_trait_fail.rs:16:1 | ||
| | | ||
| LL | fn uwu<const N: u8>() -> impl Traitor<N> { | ||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
There was a problem hiding this comment.
Question: wait hold on, we call N here a const (generic) parameter, not a type parameter usually right?
There was a problem hiding this comment.
yes, this is indeed incorrect
| note: type must be known for type parameter in this | ||
| --> $DIR/issue-77092.rs:3:1 | ||
| | | ||
| LL | fn take_array_from_mut<T, const N: usize>(data: &mut [T], start: usize) -> &mut [T; N] { | ||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
There was a problem hiding this comment.
Question: this is the reason I suggested a wording nit previously, while technically we can say there's 1 type parameter T and one const generic parameter N on this item so it isn't ambiguous, it's not immediately straightforward that we mean N and not T here.
Wait, actually, this note would be slightly misleading then, the one we can't infer is actually the const generic parameter N not the type parameter T looking at the inline note above, right?
| note: type must be known for type parameter in this | ||
| --> $DIR/one-param-uninferred.rs:2:1 | ||
| | | ||
| LL | fn foo<const N: usize, const M: usize>() -> [u8; N] { | ||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
There was a problem hiding this comment.
Remark: likewise, there are actually two const generic parameters on foo and the one we cannot infer is M, so the note as-is doesn't really tell that nuance.
| note: type must be known for type parameter in this | ||
| --> $DIR/trait-impl-wrong-args-count.rs:9:9 | ||
| | | ||
| LL | pub fn bar2<A, B, C, D, E, F, const X: usize, const Y: bool>(x: &super::XX) {} |
There was a problem hiding this comment.
Remark: likewise, hard to tell when there's not just only 1 type/const generic parameters.
| note: type must be known for type parameter in this | ||
| --> $DIR/issue-113264-incorrect-impl-trait-in-path-suggestion.rs:6:5 | ||
| | | ||
| LL | fn owo(&self, _: Option<&impl T>) {} |
There was a problem hiding this comment.
Discussion: hm, this is slightly more interesting, this is an APIT which we do not explicitly name a type parameter right? I wonder if in such cases we need to subspan highlight the impl T itself since you can have multiple impl Ts that users can only tell apart based on their source positions
fn foo(x: impl T, y: impl T) {}There was a problem hiding this comment.
The note should point at the bound itself, as well as the item name (that will require some changes to make that additional work with structured diagnostics).
| note: type must be known for type parameter in this | ||
| --> $DIR/issue-83606.rs:3:1 | ||
| | | ||
| LL | fn foo<const N: usize>(_: impl std::fmt::Display) -> [usize; N] { | ||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
There was a problem hiding this comment.
Remark: hm, and there can be a case where a user mixes explicit type params / const generic params and APITs
|
@rustbot author |
|
Reminder, once the PR becomes ready for a review, use |
This comment has been minimized.
This comment has been minimized.
…erred
When calling a function with type parameters that are unconstrained by the call expression, we mention the type parameter that couldn't be inferred, but the user previously didn't see where the name was coming from. By pointing at the function itself, including the type parameter, we give better context on what they should have done, specially when the inference machinery fails to provide any other context.
```
error[E0282]: type annotations needed
--> $DIR/unresolved_type_param.rs:9:5
|
LL | bar().await;
| ^^^ cannot infer type of the type parameter `T` declared on the function `bar`
|
note: type must be known for this
--> $DIR/unresolved_type_param.rs:6:1
|
LL | async fn bar<T>() -> () {}
| ^^^^^^^^^^^^^^^^^^^^^^^
help: consider specifying the generic argument
|
LL | bar::<T>().await;
| +++++
```
We should further refine when we present this info to make sure we don't provide redundant notes in some cases. Also, there are cases (like those in issue 94969) that don't provide any new information with this change.
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
When calling a function with type parameters that are unconstrained by the call expression, we mention the type parameter that couldn't be inferred, but the user previously didn't see where the name was coming from. By pointing at the function itself, including the type parameter, we give better context on what they should have done, specially when the inference machinery fails to provide any other context.
We should further refine when we present this info to make sure we don't provide redundant notes in some cases. Also, there are cases (like those in issue 94969) that don't provide any new information with this change.