Can't implement a trait from another box for a generic type from another box parameterized with a local type

This test code ( 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); 
}

      

Throws this error message:

<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 }

      

This code compiled successfully in the January version of Rust; how can i implement it now?

+3


source to share


1 answer


There is no direct way to solve this for a pure alias, for example type

.

The code is the same as

impl Display for Result<MyLocalType, String>

      

and the compiler cannot guarantee that there will be no conflicting implementations in other boxes (otherwise, it cannot guarantee that the implementation is "consistent"). Being able to do this is definitely useful sometimes, but this is unfortunately a mistake the compiler has accepted before.



Solutions include:

  • determining the correct shell type for Result

    eg. struct MyResult(Result<MyLocalType, String>);

    ,
  • Defining your own listing: enum MyResult { Ok(MyType), Err(String) }

    ,
  • define the shell type, but only use it when printing, i.e. write println!("{}", Wrapper(r));

    instead of println!("{}", r);

    .

Both of them make it a MyResult

local type, so it impl

should be legal.

+7


source







All Articles