We are implementing a trait called Document
.
pub trait Document :
type Err;
fn index(self, off: usize) -> result::Result<Self, Self::Err>;
}
And enumeration type Json
implements this trait as:
impl Document for Json {
type Err=Error;
fn index(self, off: usize) -> result::Result<Json, Error> {
match self {
Json::Array(mut a) => if off < a.len() {
Ok(a.remove(off))
} else {
Err(Error::IndexUnbound(off, off))
},
_ => Err(Error::NotMyType("json is not array".to_string())),
}
}
}
where Error
is implemented in json module along with Json
type.
Subsequently we are invoking Document
methods on a type parameter like:
type Result = result::Result<T, myapp::Error>
fn do_index_lookup<D>(off: usize, doc: D) -> Result<D> where D: Document {
Ok(doc.index(off)?)
}
The above code is part of the application code, that defines its own Error type -
myapp::Error
, which implements.
impl From<json::Error> for myapp::Error {
fn from(err: json::Error) -> myapp::Error {
...
}
}
Going back to the do_index_lookup()
function compiler give the following error:
error[E0277]: the trait bound `myapp::Error: std::convert::From<<D as document::Document>::Err>` is not satisfied
--> src/myapp.rs:225:41
|
225 | Ok(doc.index(off)?)
| ^^^^^^^^^^^^^^^ the trait `std::convert::From<<D as document::Document>::Err>` is not implemented for `myapp::Error`
|
= help: consider adding a `where myapp::Error: std::convert::From<<D as document::Document>::Err>` bound
= note: required by `std::convert::From::from`
error: aborting due to previous error
The gears are not falling in place. Need some help.
I think you need to update the where clause in do_index_lookup()
. At the moment, it just says D
implements Document
, but you need to also say that D::Err
can be converted into myapp::Error
.
I imagine it'd look something like this:
fn do_index_lookup<D>(off: usize, doc: D) -> Result<D>
where D: Document,
D::Err : Into<myapp::Error>
{
...
}
1 Like
Adding that doesn't seem to solve the problem.
@Michael-F-Bryan I think you are right. We need to add type contraint, and the compiler error message already suggest them.
error[E0277]: the trait bound `myapp::Error: std::convert::From<<D as document::Document>::Err>` is not satisfied
--> src/myapp.rs:225:41
|
225 | Ok(doc.index(off)?)
| ^^^^^^^^^^^^^^^ the trait `std::convert::From<<D as document::Document>::Err>` is not implemented for `myapp::Error`
|
= help: consider adding a `where myapp::Error: std::convert::From<<D as document::Document>::Err>` bound
= note: required by `std::convert::From::from`
error: aborting due to previous error
Only that I had to wire up that constrain in every call path. Which is tedious and laborious . Wonder there is any way to avoid that ...
You can add a trait bound on the associated type itself:
pub trait Document {
type Err: Into<myapp::Error>;
...
}
Tried that, Throwing the following error:
error[E0277]: the trait bound `myapp::Error: std::convert::From<<D as document::Document>::Err>` is not satisfied
--> src/myapp.rs:238:25
|
238 | Some(off) => Ok(doc.index(off)?),
| ^^^^^^^^^^^^^^^ the trait `std::convert::From<<D as document::Document>::Err>` is not implemented for `myapp::Error`
|
= help: consider adding a `where myapp::Error: std::convert::From<<D as document::Document>::Err>` bound
= note: required by `std::convert::From::from`
error: aborting due to previous error
Although the documentation Into in std::convert - Rust claims that Into is reflexive, looks like Into<> does not imply a From<> ?
Right, it doesn't imply that. And one might be tempted to add the following bound to Document
instead:
trait Document where MyError: From<Self::Err> { ... }
But then you still need to repeat the same bound because implied bounds don't exist for anything other than the bounds on the associated type itself.
In your case, you can write the following slightly more verbose version (keeping your existing Into
bound on the associated type):
Some(off) => Ok(doc.index(off).map_err(Into::into)?),
2 Likes
Lovely. When all the gears fell in place this one issue was poking out like an ugly shaft. @vitalyd suggestion has beautifully sorted it out. I wish I can give a dozen likes for this.
Fixing it ASAP - https://github.com/bnclabs/db-rs/issues/8
Thank you,
2 Likes