代码之家  ›  专栏  ›  技术社区  ›  Lukas Kalbertodt

仅当IMPL标记为“默认”时,关联类型和类型参数之间不匹配。

  •  7
  • Lukas Kalbertodt  · 技术社区  · 6 年前

    以下代码导致错误( 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 ,所以应该有效。甚至陌生人:当我移除 default 关键字从IMPL中起作用(当然,在我的真实代码中,我需要标记IMPL)。 违约 )

    在特征定义中提供缺省值时会发生同样的错误( Playground )以下内容:

    #![feature(specialization)]
    #![feature(associated_type_defaults)]
    
    trait Foo {
        type Assoc = Self;
        fn foo(&self) -> &Self::Assoc {
            self
        }
    }
    

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

    1 回复  |  直到 6 年前
        1
  •  5
  •   Shepmaster Tim Diekmann    5 年前

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

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

    那就有问题了。你的 将返回一个 T 但是,无论何时 SomeConstraint 类型不匹配,因为它应该返回 NotT 是的。

    RFC 2532 — associated type defaults 在ITS中提到了一个可能的解决方案 Future Work section .假想的 default 块可以用来指示关联类型和方法需要被专门化在一起。不过,目前还没有迹象表明这种功能何时会被考虑纳入其中。