Skip to content
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

Merged
merged 11 commits into from
May 4, 2020

Conversation

estebank
Copy link
Contributor

@estebank estebank commented Apr 13, 2020

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>) {
   |                     ^^^^^^^^^^

Fix #71035. Related to #70908.

@rust-highfive
Copy link
Collaborator

r? @davidtwco

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Apr 13, 2020
Comment on lines +559 to +569
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)
Copy link
Contributor Author

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 🤷.

Copy link
Contributor

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.

Copy link
Contributor

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?

@@ -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>`
Copy link
Contributor Author

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.

@estebank estebank force-pushed the suggest-proj-type-mismatch-constraint branch from 7df311a to 0a78df2 Compare April 14, 2020 22:21
Comment on lines +40 to +56
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) {
| ^^^^^^^^^^^^^^^
Copy link
Contributor Author

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 :-|

@rust-highfive

This comment has been minimized.

@estebank
Copy link
Contributor Author

r? @nikomatsakis

@bors

This comment has been minimized.

@estebank estebank force-pushed the suggest-proj-type-mismatch-constraint branch from d259710 to 48ee6bd Compare April 19, 2020 23:54
@joelpalmer joelpalmer added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 28, 2020
@Dylan-DPC-zz
Copy link

r? @oli-obk

@bors

This comment has been minimized.

@estebank estebank force-pushed the suggest-proj-type-mismatch-constraint branch from 48ee6bd to 2e46d52 Compare May 3, 2020 01:17
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.
@estebank estebank force-pushed the suggest-proj-type-mismatch-constraint branch from 2e46d52 to 74b7ed7 Compare May 3, 2020 01:24
@rust-highfive

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
Copy link
Contributor

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?

Copy link
Contributor Author

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}`

@oli-obk
Copy link
Contributor

oli-obk commented May 4, 2020

@bors r+

@bors
Copy link
Contributor

bors commented May 4, 2020

📌 Commit b368229 has been approved by oli-obk

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 4, 2020
@bors
Copy link
Contributor

bors commented May 4, 2020

⌛ Testing commit b368229 with merge d6823ba...

@bors
Copy link
Contributor

bors commented May 4, 2020

☀️ Test successful - checks-azure
Approved by: oli-obk
Pushing d6823ba to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label May 4, 2020
@bors bors merged commit d6823ba into rust-lang:master May 4, 2020
@estebank estebank deleted the suggest-proj-type-mismatch-constraint branch November 9, 2023 05:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improve compiler error on associated types
9 participants