0

In my code I have the following traits:

pub trait ParseTree {}

pub trait CharMatchable: ParseTree {}

pub struct Character {}
impl CharMatchable for Character {}
impl ParseTree for Character {}
impl Character {
    fn new() -> Self {
        Self {}
    }
}

pub struct TreePart {}
impl ParseTree for TreePart {}
impl TreePart {
    fn new() -> Self {
        Self {}
    }
}

Then I have a function that returns Box<CharMatchable> and another function that returns Box<ParseTree>:

fn returns_char_matchable() -> Box<CharMatchable> {
    Box::new(Character::new())
}

fn returns_parse_tree(p: bool) -> Box<ParseTree> {
    if p {
        returns_char_matchable() // <-- Here is the error
    } else {
        Box::new(TreePart::new())
    }
}

This doesn't work in Rust as when I compile the code I get following error:

error[E0308]: mismatched types
   --> src/parser.rs:348:40
    |
348 |             Some(class) => return Some(class),
    |                                        ^^^^^ expected trait `parser::ParseTree`, found trait `parser::CharMatchable`
    |
    = note: expected type `std::boxed::Box<dyn parser::ParseTree>`
               found type `std::boxed::Box<dyn parser::CharMatchable>`

As was mentioned in the comments, this might not be the Idiomatic way to achieve such behavior in Rust. I am asking specifically how one would Implement something like this in an idiomatic way.

This question is different from this one as I am asking not why this isn't working, but rather how this should be done idiomatically in Rust.

Ian Rehwinkel
  • 2,486
  • 5
  • 22
  • 56
  • That's not "trait inheritance", that's trait bounds. Just like when you write `T: Trait`. – Boiethios Jul 10 '19 at 14:36
  • 1
    @FrenchBoiethios The OP is likely referring to the [supertrait](https://doc.rust-lang.org/stable/book/ch19-03-advanced-traits.html#using-supertraits-to-require-one-traits-functionality-within-another-trait) in `trait CharMatchable: ParseTree`, and a `Box`ed trait object of the former not coercing into a `Box` of the latter. – E_net4 Jul 10 '19 at 14:42
  • @E_net4theClose-voter Supertrait mechanism is not a mechanism of inheritance. – Boiethios Jul 10 '19 at 14:43
  • @FrenchBoiethios I know, but it's not far out to assume that the OP doesn't know the precise naming of this feature. – E_net4 Jul 10 '19 at 14:44
  • 1
    *no function or associated item named `new` found for type `dyn CharMatchable`*; *no function or associated item named `new` found for type `dyn ParseTree`* – Shepmaster Jul 10 '19 at 15:57
  • 1
    As friendly advice, you are going to run into some strong resistance if you try to do everything in a classical object-oriented manner. Rust is a different language with different idioms. Sometimes those mesh well with existing OO patterns (e.g. dependency injection) and sometimes not (inheritance). – Shepmaster Jul 10 '19 at 15:59
  • @Shepmaster I clarified my question to show how it differs from the question this is supposedly a duplicate of. It would be nice if my question could be reopened. – Ian Rehwinkel Jul 10 '19 at 17:13

0 Answers0