无法从另一个用本地类型参数化的板条箱实现通用类型的另一个板条箱的特征

Can not implement trait from another crate for generic type from another crate parameterized with local type

本次测试代码(playpen):

use std::fmt::{Display, Formatter, Error};

struct MyLocalType;

type MyResult = Result<MyLocalType, String>;

impl Display for MyResult {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        f.write_str("some test string")
    }
}

fn main() { 
    let r: MyResult = Ok(MyLocalType); 
    println!("{}" , r); 
}

产生此错误消息:

<anon>:7:1: 11:2 error: the impl does not reference any types defined in this crate; only traits defined in the current crate can be implemented for arbitrary types [E0117]
<anon>:7 impl Display for MyResult {
<anon>:8     fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
<anon>:9         f.write_str("some test string")
<anon>:10     }
<anon>:11 }

此代码在一月版 Rust 中成功编译;我现在该如何实施?

对于像 type.

这样的纯别名,没有直接的方法来解决这个问题

代码同

impl Display for Result<MyLocalType, String>

并且编译器无法确保在其他 crate 中不会有冲突的实现(也就是,无法确保实现是 'coherent')。能做到有时候肯定是有用的,可惜之前是编译器接受的bug

解决方案包括:

  • Result 定义合适的包装器类型,例如struct MyResult(Result<MyLocalType, String>);,
  • 定义您自己的枚举:enum MyResult { Ok(MyType), Err(String) },
  • 定义一个包装器类型,但只在打印时使用它,即写println!("{}", Wrapper(r));而不是println!("{}", r);

这两个都使 MyResult 成为本地类型,因此 impl 应该是合法的。