Skip to content

Ambiguous associated type when using associated_type_bounds feature #76593

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
petertodd opened this issue Sep 11, 2020 · 1 comment · Fixed by #110512
Closed

Ambiguous associated type when using associated_type_bounds feature #76593

petertodd opened this issue Sep 11, 2020 · 1 comment · Fixed by #110512
Labels
C-bug Category: This is a bug. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. F-associated_type_bounds `#![feature(associated_type_bounds)]` requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@petertodd
Copy link
Contributor

#![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
@petertodd petertodd added the C-bug Category: This is a bug. label Sep 11, 2020
@petertodd
Copy link
Contributor Author

petertodd commented Sep 11, 2020

FWIW, if I remove the supertrait Load from Primitive and implement Load for T: Primitive, it works. The following compiles just fine:

#![feature(associated_type_bounds)]

trait Load : Sized {
    type Blob : Sized;
}

trait Primitive { } 

impl<T: Primitive> Load for T { 
    type Blob = Self;
}

trait BlobPtr : Primitive { } 

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


impl Primitive for () { } 
impl BlobPtr for () { } 

fn main() {
}

@jyn514 jyn514 added F-associated_type_bounds `#![feature(associated_type_bounds)]` requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. labels Sep 11, 2020
@bors bors closed this as completed in be4f9f5 May 2, 2023
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
C-bug Category: This is a bug. D-incorrect Diagnostics: A diagnostic that is giving misleading or incorrect information. F-associated_type_bounds `#![feature(associated_type_bounds)]` requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants