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?
source to share
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 ofprintln!("{}", r);
.
Both of them make it a MyResult
local type, so it impl
should be legal.
source to share