仅当 impl 标记为“default"时关联类型和类型参数不匹配 [英] Mismatch between associated type and type parameter only when impl is marked `default`

查看:21
本文介绍了仅当 impl 标记为“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`

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

This is strange since <T as Foo>::Assoc is T, so it should work. Stranger even: when I remove the default keyword from the impl, it works (but of course, in my real code, I need to mark the impl as default).

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

The same error happens when providing default values in the trait definition (Playground):

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

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

<小时>

这是怎么回事?这是编译器错误吗?或者——这就是我问这个问题的原因——这个错误是否有意义,因为我还没有理解专业化的一些特殊之处?如果这是一个错误,mem::transmute 肯定是安全的,对吗?


What's going on here? Is this a compiler bug? Or -- and that's why I'm asking this question -- does this error make sense because there is something special about specialization that I haven't understood yet? In case this is a bug, mem::transmute is surely safe, riiiight?

推荐答案

Specialization 功能没有显示出稳定的迹象,主要是因为 健全性问题,所以你应该预料到一些问题.

The Specialization feature is showing no signs of stabilising, mostly because of soundness concerns, so you should expect some problems.

你有这个:

#![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 将从另一个不太具体的实现继承":

But imagine that you added another implementation with its own associated type but without implementing foo. This implementation's foo will be "inherited" from the other, less specific, implementation:

impl<T: SomeConstraint> Foo for T {
    type Assoc = NotT;
}

那就有问题了.你的 foo 将返回一个 T 但是,只要 T 是 SomeConstraint 就会有类型不匹配,因为它应该返回一个 不是.

Then there'd be a problem. Your foo would be returning a T but, whenever T is SomeConstraint there'd be a type mismatch because it should be returning a NotT.

RFC 2532 — 关联类型默认值 提及未来工作部分.可以使用假设的 default 块来指示关联的类型和方法需要一起专门化.但是,没有迹象表明何时会考虑包含此类功能.

RFC 2532 — associated type defaults mentions a possible solution in its Future Work section. A hypothetical default block could be used to indicate that associated type(s) and method(s) would need to be specialized together. There's no sign of when such a feature would be considered for inclusion, however.

这篇关于仅当 impl 标记为“default"时关联类型和类型参数不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆