Skip to content

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

@fmease

Description

@fmease

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.

Metadata

Metadata

Assignees

Labels

A-associated-itemsArea: Associated items (types, constants & functions)A-diagnosticsArea: Messages for errors, warnings, and lintsA-dyn-traitArea: trait objects, vtable layoutD-verboseDiagnostics: Too much output caused by a single piece of incorrect code.S-blockedStatus: Blocked on something else such as an RFC or other implementation work.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions