【发布时间】:2018-06-25 11:40:17
【问题描述】:
以下代码导致错误 (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
}
}
错误:
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`
这很奇怪,因为<T as Foo>::Assoc 是 T,所以它应该可以工作。更奇怪的是:当我从 impl 中删除 default 关键字时,它可以工作(当然,在我的真实代码中,我需要将 impl 标记为 default)。
在 trait 定义 (Playground) 中提供默认值时会发生同样的错误:
#![feature(specialization)]
#![feature(associated_type_defaults)]
trait Foo {
type Assoc = Self;
fn foo(&self) -> &Self::Assoc {
self
}
}
这里发生了什么?这是编译器错误吗?或者——这就是我问这个问题的原因——这个错误是否有意义,因为我还没有理解专业化的一些特殊之处?如果这是一个错误,mem::transmute 肯定是安全的,对吧?
【问题讨论】:
-
第一个示例在操场上运行。第二个应该失败,因为你可以写
impl Foo for String { type Assoc = i32; } -
@trentcl 对不起,第一个游乐场链接是错误的 :( 我刚刚修复了它。现在它的代码与我的问题中的代码相同并且无法编译。关于第二个示例的要点!
-
在'default impl' tracking issue 中它说:“默认 impl 中的所有项目都是(隐式)默认的,因此是可特化的”我猜,这意味着将 impl 标记为默认值也会将关联类型转换为可特化的默认类型- 无论
associated_type_defaults功能是否启用。在这种情况下,第一个示例失败的原因与第二个示例相同。