仅当 impl 标记为“默认”时关联类型和类型参数之间不匹配
Mismatch between associated type and type parameter only when impl is marked `default`
以下代码导致错误 (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
)。
在特征定义中提供默认值时会发生同样的错误(Playground):
#![feature(specialization)]
#![feature(associated_type_defaults)]
trait Foo {
type Assoc = Self;
fn foo(&self) -> &Self::Assoc {
self
}
}
这是怎么回事?这是编译器错误吗?或者——这就是我问这个问题的原因——这个错误是否有意义,因为我还没有理解专业化的特殊之处?如果这是一个错误,mem::transmute
肯定是安全的,riiiight?
Specialization
功能没有显示出稳定的迹象,主要是因为 soundness concerns,因此您应该预料到会出现一些问题。
你有这个:
#![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
}
}
但是想象一下,您添加了另一个具有自己关联类型的实现,但没有实现 foo
。此实现的 foo
将 "inherited" 来自另一个不太具体的实现:
impl<T: SomeConstraint> Foo for T {
type Assoc = NotT;
}
那就有问题了。您的 foo
将返回一个 T
但是,只要 T 是 SomeConstraint
就会出现类型不匹配,因为它应该返回一个 NotT
.
RFC 2532 — associated type defaults mentions a possible solution in its Future Work section。假设的 default
块可用于指示关联的类型和方法需要一起专门化。但是,没有迹象表明何时会考虑包含这样的功能。
以下代码导致错误 (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
)。
在特征定义中提供默认值时会发生同样的错误(Playground):
#![feature(specialization)]
#![feature(associated_type_defaults)]
trait Foo {
type Assoc = Self;
fn foo(&self) -> &Self::Assoc {
self
}
}
这是怎么回事?这是编译器错误吗?或者——这就是我问这个问题的原因——这个错误是否有意义,因为我还没有理解专业化的特殊之处?如果这是一个错误,mem::transmute
肯定是安全的,riiiight?
Specialization
功能没有显示出稳定的迹象,主要是因为 soundness concerns,因此您应该预料到会出现一些问题。
你有这个:
#![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
}
}
但是想象一下,您添加了另一个具有自己关联类型的实现,但没有实现 foo
。此实现的 foo
将 "inherited" 来自另一个不太具体的实现:
impl<T: SomeConstraint> Foo for T {
type Assoc = NotT;
}
那就有问题了。您的 foo
将返回一个 T
但是,只要 T 是 SomeConstraint
就会出现类型不匹配,因为它应该返回一个 NotT
.
RFC 2532 — associated type defaults mentions a possible solution in its Future Work section。假设的 default
块可用于指示关联的类型和方法需要一起专门化。但是,没有迹象表明何时会考虑包含这样的功能。