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

Point out shadowed associated types on E0191 #117642

Conversation

TheLazyDutchman
Copy link
Contributor

Previously, when you tried to set an associated type that is shadowed by an associated type in a subtrait, like this:

trait A {
    type X;
}

trait B: A {
    type X; // note: this is legal
}

impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
    fn clone(&self) -> Self {
        todo!()
    }
}

you got a confusing error message, that says nothing about the shadowing:

error[E0719]: the value of the associated type `X` (from trait `B`) is already specified
 --> test.rs:9:34
  |
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
  |                             ---  ^^^ re-bound here
  |                             |
  |                             `X` bound here first

error[E0191]: the value of the associated type `X` (from trait `A`) must be specified
 --> test.rs:9:27
  |
2 |     type X;
  |     ------ `X` defined here
...
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
  |                           ^^^^^^^^^^^ help: specify the associated type: `B<X=Y, X=Y, X = Type>`

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0191, E0719.
For more information about an error, try `rustc --explain E0191`.

Now instead, the error shows that the associated type is shadowed, and suggests renaming as a potential fix.

error[E0719]: the value of the associated type `X` in trait `B` is already specified
 --> test.rs:9:34
  |
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
  |                             ---  ^^^ re-bound here
  |                             |
  |                             `X` bound here first

error[E0191]: the value of the associated type `X` in `A` must be specified
 --> test.rs:9:27
  |
2 |     type X;
  |     ------ `A::X` defined here
...
6 |     type X; // note: this is legal
  |     ------ `A::X` shadowed here
...
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
  |                           ^^^^^^^^^^^ associated type `X` must be specified
  |
help: consider renaming this associated type
 --> test.rs:2:5
  |
2 |     type X;
  |     ^^^^^^
help: consider renaming this associated type
 --> test.rs:6:5
  |
6 |     type X; // note: this is legal
  |     ^^^^^^

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0191, E0719.
For more information about an error, try `rustc --explain E0191`.

The rename help message is only emitted when the trait is local. This is true both for the supertrait as for the subtrait.

There might be cases where you can use the fully qualified path (for instance, in a where clause), but this PR currently does not deal with that.

@rustbot
Copy link
Collaborator

rustbot commented Nov 6, 2023

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @jackh726 (or someone else) soon.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 6, 2023
@TheLazyDutchman
Copy link
Contributor Author

fixes #100109

@rust-log-analyzer
Copy link
Collaborator

The job x86_64-gnu-llvm-15 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
GITHUB_ACTION=__run_7
GITHUB_ACTIONS=true
GITHUB_ACTION_REF=
GITHUB_ACTION_REPOSITORY=
GITHUB_ACTOR=TheLazyDutchman
GITHUB_API_URL=https://api.github.com
GITHUB_BASE_REF=master
GITHUB_ENV=/home/runner/work/_temp/_runner_file_commands/set_env_66055dfa-671e-4518-873b-b9ebcb3edf6f
GITHUB_EVENT_NAME=pull_request
---
GITHUB_SERVER_URL=https://github.com
GITHUB_SHA=f4114698dd28d2d5cb2e0871098fc58fd6957c39
GITHUB_STATE=/home/runner/work/_temp/_runner_file_commands/save_state_66055dfa-671e-4518-873b-b9ebcb3edf6f
GITHUB_STEP_SUMMARY=/home/runner/work/_temp/_runner_file_commands/step_summary_66055dfa-671e-4518-873b-b9ebcb3edf6f
GITHUB_TRIGGERING_ACTOR=TheLazyDutchman
GITHUB_WORKFLOW_REF=rust-lang/rust/.github/workflows/ci.yml@refs/pull/117642/merge
GITHUB_WORKFLOW_SHA=f4114698dd28d2d5cb2e0871098fc58fd6957c39
GITHUB_WORKSPACE=/home/runner/work/rust/rust
GOROOT_1_19_X64=/opt/hostedtoolcache/go/1.19.13/x64
---
---- [ui] tests/ui/associated-type-bounds/overlaping-bound-suggestion.rs stdout ----
diff of stderr:

6    |             |                  |
7    |             |                  associated types `Item`, `IntoIter` must be specified
8    |             associated types `Item`, `IntoIter` must be specified
+   --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+    = note: `IntoIterator::Item` shadowed here
+    |
+    = note: `IntoIterator::Item` shadowed here
9 
---
status: exit status: 1
command: RUSTC_ICE="0" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui/associated-type-bounds/overlaping-bound-suggestion.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/associated-type-bounds/overlaping-bound-suggestion" "-A" "unused" "-A" "internal_features" "-Crpath" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/associated-type-bounds/overlaping-bound-suggestion/auxiliary"
stdout: none
--- stderr -------------------------------
error[E0191]: the value of the associated types `Item`, `Item`, `IntoIter` and `IntoIter` in `IntoIterator` must be specified
   |
   |
LL |     inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::Core,
   |             |                  |
   |             |                  |
   |             |                  associated types `Item`, `IntoIter` must be specified
   |             associated types `Item`, `IntoIter` must be specified
  --> /rustc/FAKE_PREFIX/library/core/src/iter/traits/collect.rs:243:5
   = note: `IntoIterator::Item` shadowed here
   |
   = note: `IntoIterator::Item` shadowed here


error[E0223]: ambiguous associated type
##[error]  --> /checkout/tests/ui/associated-type-bounds/overlaping-bound-suggestion.rs:7:13
Build completed unsuccessfully in 0:12:56
   |
LL |     inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::Core,
   |
   |
help: if there were a trait named `Example` with associated type `IntoIterator` implemented for `(dyn IntoIterator + 'static)`, you could use the fully-qualified path
   |
LL |     inner: <<(dyn IntoIterator + 'static) as Example>::IntoIterator as Item>::Core,

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0191, E0223.

@compiler-errors
Copy link
Member

compiler-errors commented Nov 6, 2023

Thanks for the contribution! This needs a UI test. And tests need to be blessed with ./x.py test tests/ui --bless.

Also, can you amend the PR title to have some sort of verb? "[Point out] overlapping associated types [when...?]" or something is more conventional title for a PR like this.

Also, can you squash the commits into one?

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 6, 2023
@@ -585,6 +586,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
}

let bound_names = trait_bounds
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain what this code is doing? Some comments throuhout may be helpful.

.iter()
.flat_map(|poly_trait_ref| {
poly_trait_ref.trait_ref.path.segments.iter().flat_map(|x| {
x.args.iter().flat_map(|args| {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you looking at all of the segments in the trait ref? That shouldn't be necessary. Only the final path segment should be interesting here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, please don't iter() over an Option -- if let or let .. else should work here more effectively.

let name = binding.ident.name;
let trait_def = poly_trait_ref.trait_ref.path.res.opt_def_id();
let assoc_item = trait_def.and_then(|did| {
tcx.associated_items(did).filter_by_name_unhygienic(name).next()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't be filtering unhygenically. You have an identifier in binding.ident.

@TheLazyDutchman TheLazyDutchman deleted the overlapping_associated_types_diagnostics branch November 7, 2023 09:36
@TheLazyDutchman TheLazyDutchman changed the title Overlapping associated types diagnostics Point out shadowed associated types on E0191 Nov 7, 2023
@TheLazyDutchman
Copy link
Contributor Author

continues in #117661, because I didn't know renaming the branch would close the PR

bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 6, 2023
…ssociated_types, r=petrochenkov

Added shadowed hint for overlapping associated types

Previously, when you tried to set an associated type that is shadowed by an associated type in a subtrait, like this:

```rust
trait A {
    type X;
}

trait B: A {
    type X; // note: this is legal
}

impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
    fn clone(&self) -> Self {
        todo!()
    }
}

you got a confusing error message, that says nothing about the shadowing:

error[E0719]: the value of the associated type `X` (from trait `B`) is already specified
 --> test.rs:9:34
  |
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
  |                             ---  ^^^ re-bound here
  |                             |
  |                             `X` bound here first

error[E0191]: the value of the associated type `X` (from trait `A`) must be specified
 --> test.rs:9:27
  |
2 |     type X;
  |     ------ `X` defined here
...
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
  |                           ^^^^^^^^^^^ help: specify the associated type: `B<X=Y, X=Y, X = Type>`

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0191, E0719.
For more information about an error, try `rustc --explain E0191`.
```

Now instead, the error shows that the associated type is shadowed, and suggests renaming as a potential fix.

```rust
error[E0719]: the value of the associated type `X` in trait `B` is already specified
 --> test.rs:9:34
  |
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
  |                             ---  ^^^ re-bound here
  |                             |
  |                             `X` bound here first

error[E0191]: the value of the associated type `X` in `A` must be specified
 --> test.rs:9:27
  |
2 |     type X;
  |     ------ `A::X` defined here
...
6 |     type X; // note: this is legal
  |     ------ `A::X` shadowed here
...
9 | impl<Y> Clone for Box<dyn B<X=Y, X=Y>> {
  |                           ^^^^^^^^^^^ associated type `X` must be specified
  |
help: consider renaming this associated type
 --> test.rs:2:5
  |
2 |     type X;
  |     ^^^^^^
help: consider renaming this associated type
 --> test.rs:6:5
  |
6 |     type X; // note: this is legal
  |     ^^^^^^
```

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0191, E0719.
For more information about an error, try `rustc --explain E0191`.

The rename help message is only emitted when the trait is local. This is true both for the supertrait as for the subtrait.

There might be cases where you can use the fully qualified path (for instance, in a where clause), but this PR currently does not deal with that.

fixes rust-lang#100109

(continues from rust-lang#117642, because I didn't know renaming the branch would close the PR)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants