【问题标题】:Mismatch between associated type and type parameter only when impl is marked `default`仅当 impl 标记为“默认”时,关联类型和类型参数之间的不匹配
【发布时间】: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`

这很奇怪,因为&lt;T as Foo&gt;::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 功能是否启用。在这种情况下,第一个示例失败的原因与第二个示例相同。

标签: rust traits


【解决方案1】:

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 将从另一个不太具体的实现“继承”:

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

那就有问题了。您的foo 将返回T,但是,只要T 为SomeConstraint,就会出现类型不匹配,因为它应该返回NotT

RFC 2532 — associated type defaults 在其Future Work section 中提到了一种可能的解决方案。可以使用假设的default 块来指示关联的类型和方法需要一起专门化。但是,没有迹象表明何时会考虑纳入此类功能。

【讨论】:

  • 哦,这可能吗?我会假设编译器会抱怨第二个 impl。嗯,所以我猜这个功能比我想象的更不稳定......谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-22
  • 1970-01-01
  • 1970-01-01
  • 2013-09-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多