仅当impl标记为"default"时,关联类型和类型参数之间不匹配

Luk*_*odt 7 traits rust

以下代码导致错误(Playground)

#![feature(specialization)]

trait Foo {
    type Assoc;
    fn foo(&self) -> &Self::Assoc;
}

default impl<T> Foo for T {
    type Assoc = T;
    fn foo(&self) -> &Self::Assoc {
        self
    }
}
Run Code Online (Sandbox Code Playgroud)

错误:

error[E0308]: mismatched types
  --> src/main.rs:20:9
   |
20 |         self
   |         ^^^^ expected associated type, found type parameter
   |
   = note: expected type `&<T as Foo>::Assoc`
              found type `&T`
Run Code Online (Sandbox Code Playgroud)

这是奇怪<T as Foo>::Assoc T,所以它应该工作.甚至更奇怪:当我default从impl中删除关键字时,它可以工作(但当然,在我的真实代码中,我需要将impl标记为default).

在特征定义(Playground)中提供默认值时会发生同样的错误:

#![feature(specialization)]
#![feature(associated_type_defaults)]

trait Foo {
    type Assoc = Self;
    fn foo(&self) -> &Self::Assoc {
        self
    }
}
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?这是编译器错误吗?或者 - 这就是我问这个问题的原因 - 这个错误是否有意义,因为我还没有理解专业化方面有什么特别之处?如果这是一个错误,mem::transmute肯定是安全的,riiiight?

Pet*_*all 5

Specialization功能没有显示任何稳定的迹象,主要是由于对声音的担心,因此您应该会遇到一些问题。

你有这个:

#![feature(specialization)]

trait Foo {
    type Assoc;
    fn foo(&self) -> &Self::Assoc;
}

default impl<T> Foo for T {
    type Assoc = T;
    fn foo(&self) -> &Self::Assoc {
        self
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,假设您添加了另一个实现,该实现具有其自己的关联类型,但没有实现foo。该实现的实现foo将从其他不太具体的实现中“继承”:

impl<T: SomeConstraint> Foo for T {
    type Assoc = NotT;
}
Run Code Online (Sandbox Code Playgroud)

那就有问题了。您foo将返回a,T但是每当T SomeConstraint为时,类型都会不匹配,因为它应该返回a NotT

RFC 2532-关联类型默认值在“ 未来工作”部分中提到了一种可能的解决方案。假设default框可用于指示关联的类型和方法需要一起专门化。但是,没有迹象表明何时考虑包含此功能。