# Expected trait object dyn Trait, found struct Struct

**URL:** <https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198>\
**Category:** help\
**Created:** [October 3, 2022, 4:58pm UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198 "2022-10-03T16:58:34Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![62mkv](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/62mkv/32/9822_2.png) [@62mkv](https://users.rust-lang.org/u/62mkv)\
**Post date:** [October 3, 2022, 4:58pm UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/1 "2022-10-03T16:58:34Z")

</div>

Hi everyone,

This question has already been asked a lot of times, but I still can't make sense of the answers I've found ([rust - expected trait object `dyn Responsability`, found type parameter `T` - Stack Overflow](https://stackoverflow.com/questions/70402220/expected-trait-object-dyn-responsability-found-type-parameter-t), [https://www.reddit.com/r/rust/comments/2m98c1/why\_cant\_i\_treat\_this\_struct\_as\_a\_trait\_it/](https://www.reddit.com/r/rust/comments/2m98c1/why_cant_i_treat_this_struct_as_a_trait_it/), [Trait objects and structs - #2 by alice](https://users.rust-lang.org/t/trait-objects-and-structs/48776/2))

I am trying to implement very simple polymorphism, that exists in any OOP language, by defining a "behaviour" and then having structs that implement this behaviour differently

But then, as I try to produce instance of a "dyn trait" object, I can't think of how to do it:

```rust
trait ClassNameEvaluator {
    fn evaluate_if_class_needed(&mut self, class_name: &str) -> anyhow::Result<bool> {
        return Ok(true);
    }
}

struct Dummy{}

impl ClassNameEvaluator for Dummy {}

struct LuaEvaluator<'a> {
    executor: Lua<'a>,
    luacode: &'a str
}

impl ClassNameEvaluator for LuaEvaluator<'_> {
    fn evaluate_if_class_needed(&mut self, class_name: &str) -> anyhow::Result<bool> {
        self.executor.set("classname", class_name);
        match self.executor.execute(self.luacode) {
            Ok(res) => anyhow::Ok(res),
            _ => Err(anyhow!("Error executing Lua code"))
        }
    }
}

```

and in the `fn main`:

```rust
    let mut evaluator: dyn ClassNameEvaluator =
        match cli.luaclassfilter.as_ref() {
            Some(code) => LuaEvaluator::new(code),
            None => dummy
        };

```

and expression in `Some(code)` branch, gives me

```rust
   |
89 | Some(code) => LuaEvaluator::new(code),
   | ^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn ClassNameEvaluator`, found struct `LuaEvaluator`
   |
   = note: expected trait object `dyn ClassNameEvaluator`
                    found struct `LuaEvaluator<'_>`

```

How should I go about it in a Rust-ish way? Thanks a lot!

---

<div class="post-metadata">

**Author:** ![H2CO3](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@H2CO3](https://users.rust-lang.org/u/H2CO3)\
**Post date:** [October 3, 2022, 5:03pm UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/2 "2022-10-03T17:03:29Z")

</div>

You can't hold a `dyn Trait` value by-value, because it's dynamically sized. You'll have to put it behind some indirection, e.g. `Box` (if you want to own it) or `&` (if you don't need to).

---

<div class="post-metadata">

**Author:** ![semicoleon](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/semicoleon/32/22313_2.png) [@semicoleon](https://users.rust-lang.org/u/semicoleon)\
**Post date:** [October 3, 2022, 5:04pm UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/3 "2022-10-03T17:04:36Z")

</div>

You can't have a bare trait object like that. It needs to be behind a pointer of some sort.

```rust
let mut evaluator: Box<dyn ClassNameEvaluator> =
        match cli.luaclassfilter.as_ref() {
            Some(code) => Box::new(LuaEvaluator::new(code)),
            None => Box::new(dummy),
        };

```

The error you're getting basically means "you're using a concrete struct but none of the coercion rules for changing into a trait object applied". And that's because they only apply to types that can contain a trait object like Box, Arc, and references

---

<div class="post-metadata">

**Author:** ![62mkv](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/62mkv/32/9822_2.png) [@62mkv](https://users.rust-lang.org/u/62mkv)\
**Post date:** [October 3, 2022, 5:05pm UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/4 "2022-10-03T17:05:23Z")

</div>

Ok, I think I needed some casting but it still does not help:

```rust
    let mut dummy = Dummy{};
    let mut evaluator: &mut dyn ClassNameEvaluator =
        match cli.luaclassfilter.as_ref() {
            Some(code) => &mut LuaEvaluator::new(code) as &mut dyn ClassNameEvaluator,
            None => &mut dummy
        };

```

this now complains about temporary value that is freed while still in use.... :(((

---

<div class="post-metadata">

**Author:** ![H2CO3](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@H2CO3](https://users.rust-lang.org/u/H2CO3)\
**Post date:** [October 3, 2022, 5:06pm UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/5 "2022-10-03T17:06:09Z")

</div>

You'll need the `Box` here. You are creating the value, so you own it, you have to hold onto it if you want a reference to it. References in themselves don't cause values to stick around.

---

<div class="post-metadata">

**Author:** ![62mkv](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/62mkv/32/9822_2.png) [@62mkv](https://users.rust-lang.org/u/62mkv)\
**Post date:** [October 3, 2022, 5:07pm UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/6 "2022-10-03T17:07:30Z")

</div>

phew.. I need to wrap my head around this. Why allow for declaring function arguments as _traits_ if one can not pass anything to such method??

---

<div class="post-metadata">

**Author:** ![62mkv](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/62mkv/32/9822_2.png) [@62mkv](https://users.rust-lang.org/u/62mkv)\
**Post date:** [October 3, 2022, 5:08pm UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/7 "2022-10-03T17:08:32Z")

</div>

ok, I will read this [Traits: Defining Shared Behavior - The Rust Programming Language](https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters).. tomorrow 😖

---

<div class="post-metadata">

**Author:** ![62mkv](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/62mkv/32/9822_2.png) [@62mkv](https://users.rust-lang.org/u/62mkv)\
**Post date:** [October 3, 2022, 5:19pm UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/8 "2022-10-03T17:19:04Z")

</div>

Fine, now I can call my method with both implementations like this:

```rust
fn list_zip_contents(reader: impl Read + Seek, class_name_evaluator: &mut (impl ClassNameEvaluator + ?Sized)) -> anyhow::Result<()> {
...
}

    let mut dummy = Dummy{};
    let mut lua_evaluator = LuaEvaluator::new("return true");
    list_zip_contents(jarfile, &mut lua_evaluator)?;
    list_zip_contents(jarfile, &mut dummy)?;

```

all of that compiles and works. So now question is how to build an owned mut value from an `Option`

---

<div class="post-metadata">

**Author:** ![62mkv](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/62mkv/32/9822_2.png) [@62mkv](https://users.rust-lang.org/u/62mkv)\
**Post date:** [October 3, 2022, 5:33pm UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/9 "2022-10-03T17:33:02Z")

</div>

Ok, here's what actually works:

```rust
fn list_zip_contents(reader: impl Read + Seek, class_name_evaluator: &mut dyn ClassNameEvaluator) -> anyhow::Result<()> {...}

    let mut evaluator: Box<dyn ClassNameEvaluator> =
          match cli.luaclassfilter.as_ref() {
              Some(code) => Box::new(LuaEvaluator::new(code)),
              None => Box::new(Dummy{})
          };
    list_zip_contents(jarfile, evaluator.deref_mut())?;

```

---

<div class="post-metadata">

**Author:** ![H2CO3](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@H2CO3](https://users.rust-lang.org/u/H2CO3)\
**Post date:** [October 4, 2022, 7:58am UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/10 "2022-10-04T07:58:28Z")

</div>

> [@62mkv](#):
>
> Why allow for declaring function arguments as _traits_ if one can not pass anything to such method??

You absolutely can; I don't understand what your new issue is.

---

<div class="post-metadata">

**Author:** ![62mkv](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/62mkv/32/9822_2.png) [@62mkv](https://users.rust-lang.org/u/62mkv)\
**Post date:** [October 4, 2022, 8:27am UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/11 "2022-10-04T08:27:40Z")

</div>

Whatever it was it is resolved for now 🙂 my biggest issue is confusion and misconceptions, coming from my Java background mostly

---

<div class="post-metadata">

**Author:** ![62mkv](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/62mkv/32/9822_2.png) [@62mkv](https://users.rust-lang.org/u/62mkv)\
**Post date:** [October 4, 2022, 8:34am UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/12 "2022-10-04T08:34:25Z")

</div>

Continuing the discussion from [Is Rust OOP? If not, what is it oriented to?](https://users.rust-lang.org/t/is-rust-oop-if-not-what-is-it-oriented-to/30777/7):

> [@Is Rust OOP? If not, what is it oriented to?](https://users.rust-lang.org/t/is-rust-oop-if-not-what-is-it-oriented-to/30777/7):
>
> Most people come to Rust from a `C++`/`Python`/`Java`/`C#`/etc background so that's the perspective they have. If you try to program in Rust the same way as you do using classes, then you're going to run into problems and get frustrated.

exactly my case 😂 (from the replies to the thread where you have also commented)

---

<div class="post-metadata">

**Author:** ![H2CO3](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@H2CO3](https://users.rust-lang.org/u/H2CO3)\
**Post date:** [October 4, 2022, 9:35am UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/13 "2022-10-04T09:35:56Z")

</div>

So the things to know are:

- The presence of a reference to a value necessarily means that someone, somewhere, _owns_ that value.
- References don't own values. You own things by value.
- You can only own something if you know its static size at compile tome. This is not obvious, as this is just a current technical requirement in Rust, which may be lifted in the future.
- dyn Trait is dynamically sized, so you have to put it behind indirection in order to own it.
- It's possible to own stuff and put it behind indirection, but that's not what references are for. Owning heap-allocating smart pointers include Box (when you want a single owner) and Rc/Arc (when you want multiple, refcounted owners).
- Therefore, when you create a trait object that you want to own, you _have_ to put it in Box or Rc or Arc.
- But if you already have a boxed or refcounted (ie. owned) trait object, you _can_ pass a mere _reference_ to it into another function.

That is, there is nothing special about your situation/error wrt. trait objects; ownership and borrowing rules apply in _exactly_ the same way to trait objects as they apply to any other type. What tripped you up is that you wanted to create a dynamically-sized value on the stack, which is not possible.

---

<div class="post-metadata">

**Author:** ![62mkv](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/62mkv/32/9822_2.png) [@62mkv](https://users.rust-lang.org/u/62mkv)\
**Post date:** [October 4, 2022, 10:01am UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/14 "2022-10-04T10:01:12Z")

</div>

Someone needs to go about writing "Rust misconceptions" book 🙂 I can see at least 3 audiences with their own pre-conceived expectations about "how programming works" approaching Rust and having different, but still quite typical, issues :

1. people from managed runtimes/languages, like Java/C#
2. people from dynamically typed languages, like node.js, Python, Ruby
3. people from C/C++ background

I kinda knew about ownership and references, and have some scars from fighting the BC in the past, but never used traits yet, at least not directly, so yeah, that was an exercise 🙂

---

<div class="post-metadata">

**Author:** ![jhelovuo](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/jhelovuo/32/30671_2.png) [@jhelovuo](https://users.rust-lang.org/u/jhelovuo)\
**Post date:** [December 1, 2022, 9:26am UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/15 "2022-12-01T09:26:36Z")

</div>

I still do not get it.

Here is my test code:

```rust
use std::rc::Rc;

trait SomeTrait {
  fn hello(&self);
}

struct SomeStruct { }

impl SomeTrait for SomeStruct {
  fn hello(&self) { println!("hello"); }
}

fn do_hello(trait_obj : Rc<dyn SomeTrait>) {
  trait_obj.hello()
} 

fn main() {
  let a = Rc::new(SomeStruct{} );

  let b = Rc::clone(&a);
  do_hello( b ); // This compiles ok

  do_hello( (|| Rc::clone(&a))() ); // Weird, but compiles

  do_hello( a.clone() ); // still ok

  // do_hello( Rc::clone(&a) ); // Why is this an error?
}

```

After reading the replies above, I cannot explain why the three first calls to `do_hello` compile ok, but the fourth one does not. I am under the impression that `Rc::clone(&a)` is just an alternative syntax for `a.clone()`, so they should be semantically the same.

Can someone please explain what is going on here?

---

<div class="post-metadata">

**Author:** ![quinedot](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/quinedot/32/17693_2.png) [@quinedot](https://users.rust-lang.org/u/quinedot)\
**Post date:** [December 1, 2022, 11:17pm UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/16 "2022-12-01T23:17:58Z")

</div>

In the first three cases, a clone of `Rc<SomeStruct>` happens, and is then coerced to `Rc<dyn SomeTrait>`. In the forth case, the compiler tries to figure out _which_ `Rc::<_>::clone` you're trying to call and -- based on the expected argument type -- wrongly decides on `Rc::<dyn SomeTrait>::clone`. [It works if you correct it.](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=da784f2ff82ddc690b2a2b251c9b23dd)

The difference from `a.clone()` is the lack of a generic type variable to infer, and the difference with the other cases is how far inference decides to look before falling back to `a`'s type (or not).

---

<div class="post-metadata">

**Author:** ![jhelovuo](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/jhelovuo/32/30671_2.png) [@jhelovuo](https://users.rust-lang.org/u/jhelovuo)\
**Post date:** [December 2, 2022, 10:26am UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/17 "2022-12-02T10:26:11Z")

</div>

Thanks for the sensible explanation.

My understanding is now that the code is not actually wrong, but this is just a shortcoming of the current type inference algorithm. So the compiler flags this as an error just to be on the safe side. But this may change as the compiler evolves.

---

<div class="post-metadata">

**Author:** ![62mkv](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/62mkv/32/9822_2.png) [@62mkv](https://users.rust-lang.org/u/62mkv)\
**Post date:** [December 2, 2022, 10:42am UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/18 "2022-12-02T10:42:28Z")

</div>

Yep, there's so much instances of such behaviour in rust for newcomers))) I so often struggle on some code and juggle bits around based on the suggestions from error messages, until BOOM 🤯 it just compiles ))) and when compiled it mostly just works

Nice but spooky 😃😃

---

<div class="post-metadata">

**Author:** ![H2CO3](https://avatars.discourse-cdn.com/v4/letter/h/b5ac83/32.png) [@H2CO3](https://users.rust-lang.org/u/H2CO3)\
**Post date:** [December 3, 2022, 7:24am UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/19 "2022-12-03T07:24:54Z")

</div>

> [@jhelovuo](#):
>
> the code is not actually wrong, but this is just a shortcoming of the current type inference

The code is not _technically_ wrong, but if you manage to confuse the compiler with it, imagine what it does to human brains. I wouldn't say the compiler is at fault here. You should really try to write your code in a way that it's unambiguous to a programmer too – and this instance clearly isn't.

Don't try to be excessively "clever" with inference (or any other language construct). These compiler non-bugs are a gentle reminder that you may be trying too hard to impress fellow programmers or the Rust Gods.

> [@62mkv](#):
>
> Nice but spooky

The compiler isn't trying to second-guess you. If anything, this should be _reassuring_ and not "spooky".

I work a lot with automated systems (let's _not_ call them "AI") where medical decisions are being made based on a statistical model's opinion of a physiological measurement, such as blood pressure or ECG. Of course, measurements can be noisy, absent, or just downright wrong.

What should a model decide to do when it doesn't know if the measurement is correct? Send the patient to 25 different kinds of surgeries, just to be safe? Surely that would not be a splendid idea. It should just tell the doctor that it should see patient no. 1337 because his/her measurements look not quite OK.

The point is, it's _vastly_ better for an automated system to have a well-calibrated sense of confidence, and bail out when it's obviously unsure, instead of trying hard to make a decision and screw up big time.

Inference coupled with coercions is hard. The compiler is intentionally not trying to see two steps into the future. Rust is protecting your life – instead of sending you to a potentially harmful surgery, it tells you to see a doctor.

---

<div class="post-metadata">

**Author:** ![jhelovuo](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/jhelovuo/32/30671_2.png) [@jhelovuo](https://users.rust-lang.org/u/jhelovuo)\
**Post date:** [December 5, 2022, 12:07pm UTC](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198/20 "2022-12-05T12:07:42Z")

</div>

> [@H2CO3](#):
>
> > [@jhelovuo](#):
> >
> > the code is not actually wrong, but this is just a shortcoming of the current type inference
> 
> The code is not _technically_ wrong, but if you manage to confuse the compiler with it, imagine what it does to human brains. I wouldn't say the compiler is at fault here. You should really try to write your code in a way that it's unambiguous to a programmer too – and this instance clearly isn't.
> 
> Don't try to be excessively "clever" with inference (or any other language construct). These compiler non-bugs are a gentle reminder that you may be trying too hard to impress fellow programmers or the Rust Gods.

I get what you are saying, and in general, I fully agree. Code should be clear and readable, unless you are participating in an obfuscated code contest.

However, this code is not trickery to confuse or impress anyone. While `a.clone()` may be the most straightforward way to write this, the problematic `Rc::clone(&a)` is the form recommended in [the documentation of Rc](https://doc.rust-lang.org/std/rc/#cloning-references). The reason for this recommendation is that it more clearly states that the cloning here applies to the `Rc` only, not the referenced object. This is, IMHO, a good recommendation, and there is just a small gap in the type inference implementation.

[Next page](https://users.rust-lang.org/t/expected-trait-object-dyn-trait-found-struct-struct/82198.md?page=2)
