rust-lang / rust-lang/rust

On conflicting assoc item bindings in trait object types, two similar errors are emitted

Open
#150,936 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-associated-items A-diagnostics A-dyn-trait D-verbose T-compiler T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Reproducer:

fn main() {
    let _: dyn Iterator<Item = (), Item = i32>;
}

Compiler output:

error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
 --> <anon>:1:44
  |
1 | fn main() { let _: dyn Iterator<Item = (), Item = i32>; }
  |                                 ---------  ^^^^^^^^^^ re-bound here
  |                                 |
  |                                 `Item` bound here first

error: conflicting associated type bounds for `Item`
 --> <anon>:1:20
  |
1 | fn main() { let _: dyn Iterator<Item = (), Item = i32>; }
  |                    ^^^^^^^^^^^^^---------^^----------^
  |                                 |          |
  |                                 |          `Item` is specified to be `i32` here
  |                                 `Item` is specified to be `()` here

This only happens if the provided types are "syntactically" unequal (i.e., using middle::Ty's ==, not unification). If they're equal only the 1st one is emitted.

What happens here is that the 1st diagnostic stems from our (formerly general) check we use when HIR-ty-lowering assoc item bindings and the 2nd one comes from the lowerer for trait object types, more specifically from a check that's meant to trigger in the presence of trait aliases only I'm pretty sure. I'm claiming that because the 2nd diagnostic used to say the following prior to PR #146593 / 1.92:

error: conflicting associated type bounds for `Item` when expanding trait alias
 --> <anon>:1:20
  |
1 | fn main() { let _: dyn Iterator<Item = (), Item = i32>; }
  |                    ^^^^^^^^^^^^^---------^^----------^
  |                                 |          |
  |                                 |          `Item` is specified to be `i32` here
  |                                 `Item` is specified to be `()` here

This was factually incorrect in this case obviously.

So why did PR #146593 generalize the wording (w/o addressing the "double" emission)? Well, that change originates from its closed predecessor #143146 where the (formerly general) check in lower_assoc_item_constraint was dropped entirely in favor of the one in lower_trait_object_ty, so it made sense to generalize it.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reproducer and inspect the checks in lower_assoc_item_constraint and lower_trait_object_ty, along with the diagnostic changes from PRs #146593 and #143146. Trace why both checks emit diagnostics for syntactically unequal bindings; done means the duplicate emission is removed and the remaining wording is accurate for trait objects and trait aliases.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.