Skip to content

Ambiguous associated type when using associated_type_bounds feature #76593

Closed
@petertodd

Description

@petertodd
#![feature(associated_type_bounds)]

trait Load : Sized {
    type Blob;
}

trait Primitive : Load<Blob = Self> { }

trait BlobPtr : Primitive { }

trait CleanPtr : Load<Blob : BlobPtr> {
    fn to_blob(&self) -> Self::Blob;
}


impl Load for () {
    type Blob = Self;
}
impl Primitive for () { }
impl BlobPtr for () { }

fn main() {
}

produces an ambiguous, and nonsensical, associated type error even though Blob is introduced only once via Load:

$ rustc test.rs 
error[E0221]: ambiguous associated type `Blob` in bounds of `Self`
  --> test.rs:12:26
   |
4  |     type Blob;
   |     ----------
   |     |
   |     ambiguous `Blob` from `Load`
   |     ambiguous `Blob` from `Load`
...
12 |     fn to_blob(&self) -> Self::Blob;
   |                          ^^^^^^^^^^ ambiguous associated type `Blob`
   |
help: use fully qualified syntax to disambiguate
   |
12 |     fn to_blob(&self) -> <Self as Load>::Blob;
   |                          ^^^^^^^^^^^^^^^^^^^^
help: use fully qualified syntax to disambiguate
   |
12 |     fn to_blob(&self) -> <Self as Load>::Blob;
   |                          ^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0221`.

If the use of associated type bounds is removed and replaced by equivalent where clauses, the problem goes away. This version compiles without error:

trait Load : Sized {
    type Blob;
}

trait Primitive : Load<Blob = Self> { } 

trait BlobPtr : Primitive { } 

trait CleanPtr : Load
where Self::Blob: BlobPtr
{
    fn to_blob(&self) -> Self::Blob;
}


impl Load for () {
    type Blob = Self;
}
impl Primitive for () { } 
impl BlobPtr for () { } 


fn _use_ptr<P: CleanPtr>(_ptr: P)
    where P::Blob: BlobPtr
{
}

fn main() {
}

FWIW in this codebase it looks like associated types could save quite a lot of boilerplate, as these will be quite common type bounds. So if you have a better idea how to do this, I'd love to hear!

Meta

rustc --version --verbose:

rustc 1.48.0-nightly (a1947b3f9 2020-09-10)
binary: rustc
commit-hash: a1947b3f9e2831e2060bc42f0c78e4a2bb67930a
commit-date: 2020-09-10
host: x86_64-unknown-linux-gnu
release: 1.48.0-nightly
LLVM version: 11.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.F-associated_type_bounds`#![feature(associated_type_bounds)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions