Don't understand this E0117 compilaation error

I got the following E0117 error
impl sailfish::runtime::Render for Option {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------
| |
| Option is not defined in the current crate

when trying to compile the above code :

impl<T : sailfish::runtime::Render> sailfish::runtime::Render for Option<T> {
  fn render(&self, b: &mut Buffer) -> Result<(), RenderError> {
    if self.is_some() {
      Render::render(&self.unwrap(), b)
    }
    else {
      b.push_str("");
      Ok(())
    }
  }
}

Knowing that I put at the top of the file use std::option::Option;
I tried to put std::option::Option instead of Option, but it doesn't change, the error is still there.

I don't understand since Option is part of the std library and I included it manually with use std::option::Option;.

You've likely got not just the error, but a couple of notes like this:

  = note: impl doesn't have any local type before any uncovered type parameters
  = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
  = note: define and implement a trait or new type instead

Is there anything unclear if we take them into account?

Yes I don't understand what he means by

impl doesn't have any local type before any uncovered type parameters

When implementing a foreign trait, the orphan rules look at types in the following positions:

//             vv  vv  vv      vvvvvvvv
impl SomeTrait<P1, P2, P3> for SomeType

The order considered is SomeType, P1, P2, P3 -- the implementing type and then any type parameters on the trait.

The rule is that at least one of those must be a local type, and that there are no uncovered generic type parameters before the local type.

You don't have a local type at all, so that's enough to explain the error in your OP.

A generic type parameter is a parameter declared on the impl, like your T. It is uncovered if one of the types in the above position is T, &T, &mut T, or Box<T>. An example of it being covered is Option<T>.

// This is ok because the `T` is covered and `MyType<..>` is local
impl<T> From<MyType<T>> for Vec<T> { ... }

// This is not ok because `T` is uncovered and comes before `MyType<..>`
// in the order described above
impl<T> From<MyType<T>> for T { ... }
1 Like