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

Ambiguous associated type when using associated_type_bounds feature #76593

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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