7

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

Produces 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 successfully compiled in the January version of Rust; how can I implement it now?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
pavlov-dmitry
  • 73
  • 1
  • 3
  • For future searchers, note that this error has nothing to do with generics or parameterized types — "Can not implement trait from another crate for type from another crate" would suffice. A [MCVE](http://stackoverflow.com/help/mcve) would have helped the OP reduce the problem to the core issue. – Shepmaster Apr 22 '15 at 13:24

1 Answers1

13

There's no direct way to solve this for a pure alias like type.

The code is the same as

impl Display for Result<MyLocalType, String>

and the compiler can't ensure that there will be no conflicting implementations in other crates (aka, can't ensure that the implementation is 'coherent'). Being able to do it is definitely useful sometimes, but it was unfortunately a bug that the compiler accepted it before.

Solutions include:

  • defining a proper wrapper type for Result, e.g. struct MyResult(Result<MyLocalType, String>);,
  • defining your own enum: enum MyResult { Ok(MyType), Err(String) },
  • define a wrapper type, but only use it when printing, i.e. write println!("{}", Wrapper(r)); instead of println!("{}", r);.

Both of these make MyResult a local type, and so the impl then should be legal.

huon
  • 94,605
  • 21
  • 231
  • 225
  • With all your solutions, I can not use try! macro from std with MyResult. – pavlov-dmitry Apr 22 '15 at 07:28
  • Yes. What problem are you trying to solve by implementing `Display` for `MyResult`, is the `Debug` implementation insufficient? (I've added another solution.) – huon Apr 22 '15 at 07:45
  • `Display` is only for example. I wanted to know that this is not a bug in the compiler. I'll use one of the solutions to fix my real code. Thank you for your help. – pavlov-dmitry Apr 22 '15 at 08:01