-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
On type mismatch involving associated type, suggest constraint #71108
On type mismatch involving associated type, suggest constraint #71108
Conversation
r? @davidtwco (rust_highfive has picked a reviewer for you, use r? to override) |
for param in hir_generics.params { | ||
if self.hir().opt_local_def_id(param.hir_id).map(|id| id.to_def_id()) | ||
== Some(def_id) |
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.
I would love it if we had a better way of doing this, but I guess this works 🤷.
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.
if it occurs more often, we can introduce a helper for it.
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.
Maybe LocalDefId
just needs to implement PartialEq<DefId>
and vice versa?
src/test/ui/suggestions/trait-with-missing-associated-type-restriction-fixable.stderr
Show resolved
Hide resolved
@@ -21,7 +21,7 @@ LL | Example::generate(t) | |||
| | |||
= note: expected struct `std::boxed::Box<T>` | |||
found associated type `<T as Example>::Output` | |||
= note: consider constraining the associated type `<T as Example>::Output` to `std::boxed::Box<T>` | |||
= help: consider constraining the associated type `<T as Example>::Output` to `std::boxed::Box<T>` |
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.
We should eventually handle the case of #![feature(specialization)]
, but I won't on this PR.
7df311a
to
0a78df2
Compare
error[E0308]: mismatched types | ||
--> $DIR/trait-with-missing-associated-type-restriction.rs:25:12 | ||
| | ||
LL | x.funk(3); | ||
| ^ expected associated type, found integer | ||
| | ||
= note: expected associated type `<T as Trait<i32>>::A` | ||
found type `{integer}` | ||
help: a method is available that returns `<T as Trait<i32>>::A` | ||
--> $DIR/trait-with-missing-associated-type-restriction.rs:8:5 | ||
| | ||
LL | fn func(&self) -> Self::A; | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ consider calling `Trait::func` | ||
help: consider constraining the associated type `<T as Trait<i32>>::A` to `{integer}` | ||
| | ||
LL | fn bar2<T: Trait<i32, A = {integer}>>(x: T) { | ||
| ^^^^^^^^^^^^^^^ |
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.
For this suggestion to use i32
instead of {integer}
we need to run resolve_vars_if_possible
, but that's not available in rustc_middle
:-|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
d259710
to
48ee6bd
Compare
r? @oli-obk |
This comment has been minimized.
This comment has been minimized.
48ee6bd
to
2e46d52
Compare
When an associated type is found when a specific type was expected, if possible provide a structured suggestion constraining the associated type in a bound. ``` error[E0271]: type mismatch resolving `<T as Foo>::Y == i32` --> $DIR/associated-types-multiple-types-one-trait.rs:13:5 | LL | want_y(t); | ^^^^^^ expected `i32`, found associated type ... LL | fn want_y<T:Foo<Y=i32>>(t: &T) { } | ----- required by this bound in `want_y` | = note: expected type `i32` found associated type `<T as Foo>::Y` help: consider constraining the associated type `<T as Foo>::Y` to `i32` | LL | fn have_x_want_y<T:Foo<X=u32, Y = i32>>(t: &T) | ^^^^^^^^^ ``` ``` error[E0308]: mismatched types --> $DIR/trait-with-missing-associated-type-restriction.rs:12:9 | LL | qux(x.func()) | ^^^^^^^^ expected `usize`, found associated type | = note: expected type `usize` found associated type `<impl Trait as Trait>::A` help: consider constraining the associated type `<impl Trait as Trait>::A` to `usize` | LL | fn foo(x: impl Trait<A = usize>) { | ^^^^^^^^^^ ```
Associated types with a default type in a trait can't be relied upon to remain of that default type when in use, so literals of that type can't be used in the trait's items. Point at the associated type and state that information. Reduce verbosity for associated consts of the wrong type.
2e46d52
to
74b7ed7
Compare
This comment has been minimized.
This comment has been minimized.
@@ -8,8 +8,6 @@ LL | const C: S0<u8> = Self(0); | |||
| | |||
= note: expected type parameter `T` | |||
found type `{integer}` | |||
= help: type parameters must be constrained to match other types |
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.
maybe we should keep a help
around that informs the user that a type parameter can never be equal to a concrete type, even if the caller would always choose that specific type?
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.
I would prefer for us to detect these kind of cases proactively and give a more targeted error. In the case of
struct S0<T>(T);
impl<T> S0<T> {
const C: S0<u8> = Self(0);
fn foo() {
Self(0);
}
}
we should come up with a more extensive explanation of what Self
resolves to, something closer to
error[E0308]: mismatched types
--> $DIR/issue-69306.rs:5:28
|
LL | impl<T> S0<T> {
| - this type parameter
LL | const C: S0<u8> = Self(0);
| ---- ^ expected type parameter `T`, found integer
| |
| expected `T` because of this
|
= note: expected type parameter `T`
found type `{integer}`
note: `Self` resolves to `S0<T>`, which doesn't match `S0<{integer}>` becaue it is more general
|
LL | const C: S0<u8> = Self(0);
| ^^^^
error[E0308]: mismatched types
--> $DIR/issue-69306.rs:5:28
|
LL | impl<T> S0<T> {
| - this type parameter
LL | const C: S0<u8> = Self(0);
| ------ ^^^^^^^ expected `u8`, found type parameter `T`
| |
| expected `u8` because of this
|
= note: expected type parameter `T`
found type `{integer}`
note: `Self` resolves to `S0<T>`, which doesn't match `S0<u8>` becaue it is more general
|
LL | const C: S0<u8> = Self(0);
| ^^^^
error[E0308]: mismatched types
--> $DIR/issue-69306.rs:10:14
|
LL | impl<T> S0<T> {
| - this type parameter
...
LL | Self(0);
| ^ expected type parameter `T`, found integer
|
= note: expected type parameter `T`
found type `{integer}`
@bors r+ |
📌 Commit b368229 has been approved by |
☀️ Test successful - checks-azure |
When an associated type is found when a specific type was expected, if
possible provide a structured suggestion constraining the associated
type in a bound.
Fix #71035. Related to #70908.