Let me go through the compiler output to help you figure out these sort of questions for yourself in future:
warning: trait objects without an explicit `dyn` are deprecated
--> src/main.rs:8:13
|
8 | fn foo() -> std::iter::Iterator<Item = Rc<dyn AnimalT>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn std::iter::Iterator<Item = Rc<dyn AnimalT>>`
|
= note: `#[warn(bare_trait_objects)]` on by default
Here, it tells you that it interpreted the return type as the old (pre-dyn) trait object syntax, and suggests you replace it with dyn std::iter::Iterator<Item = Rc<dyn AnimalT>>.
error[E0746]: return type cannot have an unboxed trait object
--> src/main.rs:8:13
|
8 | fn foo() -> std::iter::Iterator<Item = Rc<dyn AnimalT>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
dyn Iterator doesn’t have a known size, though (it needs to be boxed or similar), so you need to change the return type. The compiler provides three suggestions:
help: use some type `T` that is `T: Sized` as the return type if all return paths have the same type
|
8 | fn foo() -> T {
| ^
Option 1 is to name the particular object that you’re constructing, instead of one of the traits that it implements.
help: use `impl std::iter::Iterator<Item = Rc<dyn AnimalT>>` as the return type if all return paths have the same type but you want to expose only the trait in the signature
|
8 | fn foo() -> impl std::iter::Iterator<Item = Rc<dyn AnimalT>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Option 2 is to use impl Trait syntax to return the same object you would have for Option 1, but only allowing callers to access Iterator methods.
help: use a boxed trait object if all return paths implement trait `std::iter::Iterator<Item = Rc<dyn AnimalT>>`
|
8 | fn foo() -> Box<dyn std::iter::Iterator<Item = Rc<dyn AnimalT>>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Option 3 is to use dynamic dispatch, and put the trait object in a Box so that it’s Sized and thus a valid return type.
warning: trait objects without an explicit `dyn` are deprecated
--> src/main.rs:11:17
|
11 | fn bar() -> std::iter::Iterator<Item = Rc<dyn AnimalT>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn std::iter::Iterator<Item = Rc<dyn AnimalT>>`
|
= note: `#[warn(bare_trait_objects)]` on by default
warning: trait objects without an explicit `dyn` are deprecated
--> src/main.rs:16:13
|
16 | fn foo() -> std::iter::Iterator<Item = Rc<dyn AnimalT>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `dyn`: `dyn std::iter::Iterator<Item = Rc<dyn AnimalT>>`
error[E0277]: the size for values of type `(dyn std::iter::Iterator<Item = std::rc::Rc<(dyn AnimalT + 'static)>> + 'static)` cannot be known at compilation time
--> src/main.rs:11:17
|
11 | fn bar() -> std::iter::Iterator<Item = Rc<dyn AnimalT>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `(dyn std::iter::Iterator<Item = std::rc::Rc<(dyn AnimalT + 'static)>> + 'static)`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: the return type of a function must have a statically known size
error[E0746]: return type cannot have an unboxed trait object
--> src/main.rs:16:13
|
16 | fn foo() -> std::iter::Iterator<Item = Rc<dyn AnimalT>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
help: use some type `T` that is `T: Sized` as the return type if all return paths have the same type
|
16 | fn foo() -> T {
| ^
help: use `impl std::iter::Iterator<Item = Rc<dyn AnimalT>>` as the return type if all return paths have the same type but you want to expose only the trait in the signature
|
16 | fn foo() -> impl std::iter::Iterator<Item = Rc<dyn AnimalT>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: use a boxed trait object if all return paths implement trait `std::iter::Iterator<Item = Rc<dyn AnimalT>>`
|
16 | fn foo() -> Box<dyn std::iter::Iterator<Item = Rc<dyn AnimalT>>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
i.e. we get the helpful message in the "pub fn foo()" case, but not in the "fn Bar::bar()" case
This is what threw me off. After I refactored to a minimal failure case, I saw taht it generated the same error, but did not realize their was followup suggestions.