Closed
Description
#![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