I have a HTTP api that uses pagination, and I want to wrap it into a general Rust stream so that the same interface can be used for all endpoints, and so that I can use the trait functions that come with the Stream trait.
I'm getting this error that I do not quite understand:
error[E0599]: no method named `try_collect` found for opaque type `impl futures::Future` in the current scope
--> src/lib.rs:316:69
|
316 | let result: Result<Vec<Vec<NotificationEvent>>, _> = stream.try_collect().await;
| ^^^^^^^^^^^ method not found in `impl futures::Future`
|
= note: the method `try_collect` exists but the following trait bounds were not satisfied:
`impl futures::Future: futures::TryStream`
which is required by `impl futures::Future: futures::TryStreamExt`
`&impl futures::Future: futures::TryStream`
which is required by `&impl futures::Future: futures::TryStreamExt`
`&mut impl futures::Future: futures::TryStream`
which is required by `&mut impl futures::Future: futures::TryStreamExt`
This is my implementation:
pub async fn v1_events_get_st(
&self,
params: &Option<GetEvents>,
) -> impl TryStream<Item = Result<Vec<NotificationEvent>, UniErr>> + '_ {
let x = stream::try_unfold((true, (*params).clone()), move |state: (bool, Option<GetEvents>)| async move {
let (remaining, mut thisParams) = state;
if !remaining {
return Ok(None);
}
return match self.v1_events_get(&thisParams).await {
Ok(res) => {
if let Some(ref mut p) = thisParams {
if let Some((_, last)) = res.get_from_to() {
p.set_after(last);
}
}
Ok(Some((res.data, (res.remaining, thisParams))))
},
Err(err) => Err(err),
}
});
return x;
}
let stream = c.v1_events_get_st(&p);
let result: Result<Vec<Vec<NotificationEvent>>, _> = stream.try_collect().await;
These are the bounds on try_collect:
fn try_collect<C: Default + Extend<Self::Ok>>(self) -> TryCollect<Self, C>
where
Self: Sized,
{
assert_future::<Result<C, Self::Error>, _>(TryCollect::new(self))
}
Why would I need to implement Default and Extend?
I cannot easily implement Default as it cannot be derived with structs with enums, I have a lot of enums.
And as for extend, wouldn't the Vec already have this?
Question: Is there a way to get a more detailed error on the exact trait bounds that are not satisfied?
Question: Is there a better way to wrap this into a Stream or other common interface? I'm starting to think it may be better just to use a for loop and not implement the Stream trait.
Thanks.
When you use async fn, it automatically wraps the return value in a future, hence the error about impl futures::Future. Just remove the async keyword and it should work.
Related
Assuming the following code is present
use core::any::Any;
enum Value {
Any(Box<dyn Any>),
Other, // placeholder, this code is adapted from mine
}
This code raises a diagnostic that I can't quite understand
impl<T: Any> TryFrom<Value> for T {
type Error = &'static str;
fn try_from(val: Value) -> Result<Self, Self::Error> {
if let Value::Any(any) = val {
if let Ok(down) = any.downcast::<T>() {
Ok(*down)
} else {
Err("incorrect type")
}
} else { Err("not an any") }
}
}
fn main() {
let res: Result<usize, &'static str> = Value::Any(Box::new(1usize)).try_into();
dbg!(res);
}
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Value`)
--> src/main.rs:9:6
|
9 | impl<T: Any> TryFrom<Value> for T {
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`Value`)
|
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
I still don't quite understand what "must be covered by another type" means, nor "when it appears before the first local type".
However, if I modify the impl signature to target a single-element tuple containing T, the impl does not raise an error, and the code functions correctly:
impl<T: Any> TryFrom<Value> for (T,) {
type Error = &'static str;
fn try_from(val: Value) -> Result<Self, Self::Error> {
if let Value::Any(any) = val {
if let Ok(down) = any.downcast::<T>() {
Ok((*down,))
} else {
Err("incorrect type")
}
} else { Err("not an any") }
}
}
fn main() {
let res: Result<(usize,), &'static str> = Value::Any(Box::new(1usize)).try_into();
dbg!(res);
}
What purpose does the single-element tuple actually serve?
(Playground Link)
From RFC 2451:
Covered Type: A type which appears as a parameter to another type. For example, T is uncovered, but the T in Vec<T> is covered. This is only relevant for type parameters.
It is important to note that the type T does not equal the tuple type (T,). (T,) can be considered equivalent to a hypothetical generic newtype/tuple struct struct Tuple1<T>(T) defined in the standard library crate std. With this analogy, impl<T: Any> TryFrom<Value> for (T,) is equivalent to impl<T: Any> TryFrom<Value> for std::Tuple1<T>.
Note that the covering type (in this case the single element tuple type, or in our analogy Tuple1) need not be defined locally in the same crate. To put it simply, consider an impl<T> ForeignTrait<LocalType> for ForeignType<T>:
The covering type ForeignType has already been defined. So:
The only way ForeignTrait<LocalType> can be implemented for
ForeignType<T> outside of the current crate is through a generic
impl <S, T> ForeignTrait<S> for ForeignType<T> (where S covers
LocalType).
Because of these rules, an impl <S, T> ForeignTrait<S> for ForeignType<T> that covers ForeignTrait<LocalType> is only possible in the crate declaring ForeignType.
Hence it is impossible for a conflicting implementation of ForeignTrait<LocalType> to exist for ForeignType<T> outside of a) the local crate and b) the crate declaring ForeignType, and so the impl is allowed. The RFC discusses this in more detail.
I'm getting blocked on what I think it's a simple problem. I'm still learning Rust, and I want to do the following:
I want to create an async trait (using async-trait) that will instantiate a DB connection instance and it will return the struct that is implementing that trait.
mongo.rs
#[async_trait]
pub trait DB {
async fn init<T, E>() -> Result<T, E>;
}
Then: favorites.rs (See the implementation of the DB trait down below)
use async_trait::async_trait;
use mongodb::Collection;
use rocket::form::FromForm;
use rocket::serde::ser::StdError;
use serde::{Deserialize, Serialize};
use std::error::Error;
use uuid::Uuid;
pub struct FavoritesDB {
collection: Collection<Favorite>,
}
#[derive(Debug)]
pub enum FavoritesError {
UnknownError(Box<dyn Error>),
}
// Conflicts with the one down below
// impl From<Box<dyn Error>> for FavoritesError {
// fn from(err: Box<dyn Error>) -> FavoritesError {
// FavoritesError::UnknownError(err)
// }
// }
impl From<Box<dyn StdError>> for FavoritesError {
fn from(err: Box<dyn StdError>) -> FavoritesError {
FavoritesError::UnknownError(err)
}
}
#[async_trait]
impl mongo::DB for FavoritesDB {
async fn init<FavoritesDB, FavoritesError>() -> Result<FavoritesDB, FavoritesError> {
let main_db = mongo::init::<Favorite>("Favorites").await?;
let db = FavoritesDB {
collection: main_db.collection,
};
Ok(db)
}
}
There are a list of problems with this:
1)
error[E0574]: expected struct, variant or union type, found type parameter `FavoritesDB`
--> src\db\favorites.rs:41:18
|
41 | let db = FavoritesDB {
| ^^^^^^^^^^^ not a struct, variant or union type
|
help: consider importing this struct instead
I've tried implementing From<Box<dyn tdError>> manually but it conflicts with what I have.
error[E0277]: `?` couldn't convert the error to `FavoritesError`
--> src\db\favorites.rs:40:65
|
40 | let main_db = mongo::init::<Favorite>("Favorites").await?;
| ^ the trait `From<Box<dyn StdError>>` is not implemented for `FavoritesError`
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= note: required because of the requirements on the impl of `FromResidual<Result<Infallible, Box<dyn StdError>>>` for `Result<FavoritesDB, FavoritesError>`
note: required by `from_residual`
--> C:\Users\asili\.rustup\toolchains\nightly-2021-11-15-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\ops\try_trait.rs:339:5
|
339 | fn from_residual(residual: R) -> Self;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider further restricting this bound
|
39 | async fn init<FavoritesDB, FavoritesError + std::convert::From<std::boxed::Box<dyn std::error::Error>>>() -> Result<FavoritesDB, FavoritesError> {
| ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Some errors have detailed explanations: E0277, E0282, E0574.
For more information about an error, try `rustc --explain E0277`.
Just for more context, here's the DB struct and impl (Currently connecting to a local MongoDB) included in mongo.rs
pub struct Database<T> {
client: mongodb::Database,
pub collection: Collection<T>,
}
impl<T> Database<T> {
pub async fn init() -> Result<mongodb::Database, Box<dyn Error>> {
let mut client_options = ClientOptions::parse("mongodb://localhost:27017").await?;
client_options.app_name = Some("My App".to_string());
// Get a handle to the deployment.
let client = Client::with_options(client_options)?;
let db = client.database("rust-svelte");
return Ok(db);
}
}
pub async fn init<T>(collection: &str) -> Result<Database<T>, Box<dyn Error>> {
let client = Database::<T>::init().await?;
let collection = client.collection::<T>(collection);
let db = Database { client, collection };
Ok(db)
}
I've been searching for a few days over SO and the Rust community and my Google-Rust-Fu isn't good enough to spot what's the problem. Any ideas?
You've declared init to take 2 generic parameters: T and E.
This means that the code that calls init has to provide the concrete types to fill in those parameters. For example, if someone was using your library, it would be totally feasible for them to write init::<i64, ()>(), and your code should deal with that.
Because of that, when you define your impl DB for FavouritesDB, you write this:
async fn init<FavoritesDB, FavoritesError>() -> Result<FavoritesDB, FavoritesError>
This is no different to writing:
async fn init<T, E>() -> Result<T, E>
you've just given the type parameters different names that happen to match a struct that you're probably trying to use.
A better pattern might be an associated type. Instead of the caller deciding what the concrete types are (as is the case with generics), with associated types, the implementation of the trait on the type sets the type.
This is common with things like Iterator. Iterator has no generic parameters, but a single associated type Item. This is because it wouldn't make sense to be able to impl Iterator<String> for MyStruct and impl Iterator<i64> for MyStruct at the same time. Instead, we want to implement Iterator for a type once, and that implementation carries with it the definition of the types it expects.
So something like this (I've omitted the async-ness for brevity since it doesn't seem to be a factor here):
trait DB {
type InitOk;
type InitErr;
fn init() -> Result<Self::InitOk, Self::InitErr>;
}
impl Db for FavouritesDB {
type InitOk = FavouritesDB;
type InitErr = FavouritesError;
fn init() -> Result<Self::InitOk, Self::InitErr> {
// now you can reference FavouritesDB the struct, rather than the generic parameter
}
}
I'd also add you may want to not have the InitOk type, and just return Self, but that's up to you if you think you might want a struct to be able to create a different type.
For part 2, Rust assumes nothing (other than Sized) about generic parameters. If you want Rust to force a generic to have some property, you have to add a bound.
The compiler is telling you here that it can't use the ? operator to convert automatically, because it doesn't know that your error type has a From<Box<dyn Error>> implementation.
If you know that every error type is going to implement that, you can add it as a bound on the associated type, like this:
trait DB {
type InitOk;
type InitErr: From<Box<dyn Error>>;
// ...
}
I have an async function save that has a Save struct as argument which optionally contains an async function (validator). The problem is that the following code only works when Some(..) is specified, with None the compiler throws an error.
use std::future::Future;
trait SomeTrait {}
enum SomeError {}
#[derive(Debug)]
struct User {}
impl SomeTrait for User {}
struct Save<T, F>
where
T: SomeTrait,
F: Future<Output = Result<(), SomeError>>,
{
pub validator: Option<Box<dyn Fn(&T) -> F>>,
}
async fn save<T, F>(obj: &T, args: Save<T, F>) -> Result<(), SomeError>
where
T: SomeTrait,
F: Future<Output = Result<(), SomeError>>,
{
if let Some(v) = args.validator {
(*v)(obj).await?;
}
Ok(())
}
#[tokio::test]
async fn test_func() {
let user = User {};
save(&user, Save { validator: None }).await;
save(
&user,
Save {
validator: Some(Box::new(|obj| async {
println!("input: {:?}", obj);
Ok(())
})),
},
)
.await;
}
The error:
error[E0698]: type inside `async` block must be known in this context
--> test_utils/src/testin.rs:35:17
|
35 | save(&user, Save { validator: None }).await;
| ^^^^ cannot infer type for type parameter `F` declared on the struct `Save`
|
note: the type is part of the `async` block because of this `await`
--> test_utils/src/testin.rs:35:5
|
35 | save(&user, Save { validator: None }).await;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
How can I make the above code work? Is there an alternative implementation without the use of the F generic parameter in the Save struct? I can work with it for now, but might become unwieldy when there are multiple functions in the Save struct.
Using BoxFuture
Since you want to hide the type, using a trait object is useful. BoxFuture is well-suited for this, combined with the boxed method to create it:
use futures::{future::BoxFuture, FutureExt};
struct Save<T>
where
T: SomeTrait,
{
pub validator: Option<Box<dyn Fn(&T) -> BoxFuture<Result<(), SomeError>>>>,
}
let _ = save(
&user,
Save {
validator: Some(Box::new(|obj| {
async move {
println!("input: {:?}", obj);
Ok(())
}
.boxed()
})),
},
)
.await;
See also:
How can one await a result of a boxed future?
Cannot use `impl Future` to store async function in a vector
How do I erase the type of future in the new future API?
Using None with a generic type
The problem here is that the generic type must be known, even if you aren't using it because you've picked None. You could provide a type that fits the constraints (implements Future, Output is a Result<(), SomeError>). Here I use Ready:
type Dummy = futures::future::Ready<Result<(), SomeError>>;
save::<_, Dummy>(&user, Save { validator: None }).await;
Unfortunately, this creates an error I don't know how to solve yet ("borrowed data cannot be stored outside of its closure").
See also:
Create a generic struct with Option<T> without specifying T when instantiating with None
Pass None into a function that accepts Option
Is there a way to hint to the compiler to use some kind of default generic type when using Option::None?
I'm trying add HTTPS enforcement to my Warp-based web app on GKE.
The GKE platform is mostly irrelevant; the cromulent detail is that the load balancer terminates SSL/TLS connections, so the “real” scheme is provided in the X-Forwarded-Proto header. The literal scheme parsed by Warp will always be HTTP.
The logic goes as follows:
If the scheme is HTTPS, process requests normally.
If the scheme is HTTP, send a 301 redirect to the equivalent HTTPS URL.
If the scheme is anything else, send a 421 (misdirected request) error.
If the X-Forwarded-Proto header is missing (or any other realistically impossible scenario occurs), send a 400 (bad request) error.
The error responses have no body content in this example, and all HTTPS requests should respond with the text Hello, world!.
The problem:
error[E0277]: the trait bound `std::result::Result<(), warp::reject::Rejection>: core::future::future::Future` is not satisfied
--> src/main.rs:23:10
|
23 | .and_then(|scheme_header: Option<String>, host: String, path: FullPath| {
| ^^^^^^^^ the trait `core::future::future::Future` is not implemented for `std::result::Result<(), warp::reject::Rejection>`
|
= note: required because of the requirements on the impl of `futures_core::future::TryFuture` for `std::result::Result<(), warp::reject::Rejection>`
error[E0599]: no method named `and` found for type `warp::filter::and_then::AndThen<warp::filter::and::And<warp::filter::and::And<impl warp::filter::Filter+std::marker::Copy, impl warp::filter::Filter+std::marker::Copy>, impl warp::filter::Filter+std::marker::Copy>, [closure#src/main.rs:23:19: 43:10]>` in the current scope
--> src/main.rs:44:10
|
44 | .and(filter)
| ^^^ method not found in `warp::filter::and_then::AndThen<warp::filter::and::And<warp::filter::and::And<impl warp::filter::Filter+std::marker::Copy, impl warp::filter::Filter+std::marker::Copy>, impl warp::filter::Filter+std::marker::Copy>, [closure#src/main.rs:23:19: 43:10]>`
|
= note: the method `and` exists but the following trait bounds were not satisfied:
`&mut warp::filter::and_then::AndThen<warp::filter::and::And<warp::filter::and::And<impl warp::filter::Filter+std::marker::Copy, impl warp::filter::Filter+std::marker::Copy>, impl warp::filter::Filter+std::marker::Copy>, [closure#src/main.rs:23:19: 43:10]> : warp::filter::Filter`
`&warp::filter::and_then::AndThen<warp::filter::and::And<warp::filter::and::And<impl warp::filter::Filter+std::marker::Copy, impl warp::filter::Filter+std::marker::Copy>, impl warp::filter::Filter+std::marker::Copy>, [closure#src/main.rs:23:19: 43:10]> : warp::filter::Filter`
`warp::filter::and_then::AndThen<warp::filter::and::And<warp::filter::and::And<impl warp::filter::Filter+std::marker::Copy, impl warp::filter::Filter+std::marker::Copy>, impl warp::filter::Filter+std::marker::Copy>, [closure#src/main.rs:23:19: 43:10]> : warp::filter::Filter`
Clearly I’m missing something obvious here, so I’m hoping someone can nudge me in the right direction!
use futures::{FutureExt, StreamExt};
use warp::{Filter, Rejection};
use warp::filters::path::{FullPath};
use warp::http::{StatusCode, Uri};
use warp::http::uri::{Parts, Scheme};
use warp::reply::Reply;
enum SchemeError {
InsecureScheme(Uri),
UnknownScheme,
MissingScheme,
}
impl warp::reject::Reject for SchemeError {}
async fn requires_https(filter: impl Filter<Extract = (Scheme,), Error = Rejection> + Copy) -> impl Filter<Extract = (), Error = Rejection> + Copy {
warp::header::optional("X-Forwarded-Proto")
.and(warp::header("Host"))
.and(warp::path::full())
.and_then(|scheme_header: Option<String>, host: String, path: FullPath| {
if let Some(scheme) = scheme_header {
match scheme.to_ascii_lowercase().as_str() {
"https" => Ok(()),
"http" => {
let mut uri_parts = Parts::default();
uri_parts.scheme = Some(Scheme::HTTPS);
uri_parts.authority = Some(host.parse().unwrap());
uri_parts.path_and_query = Some(path.as_str().parse().unwrap());
let uri_parts = uri_parts;
let new_uri = Uri::from_parts(uri_parts).unwrap();
println!("Redirecting to secure URL: {}", new_uri);
Err(warp::reject::custom(SchemeError::InsecureScheme(new_uri)))
},
_ => Err(warp::reject::custom(SchemeError::UnknownScheme)),
}
} else {
Err(warp::reject::custom(SchemeError::MissingScheme))
}
})
.and(filter)
.recover(|err: Rejection| {
if let Some(scheme_error) = err.find::<SchemeError>() {
match scheme_error {
SchemeError::InsecureScheme(new_uri) => Ok(warp::redirect(new_uri)),
SchemeError::UnknownScheme => Ok(StatusCode::MISDIRECTED_REQUEST),
SchemeError::MissingScheme => Ok(StatusCode::BAD_REQUEST),
}
} else {
Err(err)
}
})
}
#[tokio::main]
async fn main() {
let routes = requires_https(warp::any().map(|| "Hello, world!"));
warp::serve(routes)
.run(([0, 0, 0, 0], 8080))
.await;
}
I am rust newbie but ran into similar compiler error
My issue was looking at warp 0.1 docs, whilst using warp 0.2
https://docs.rs/warp/0.2.0/warp/trait.Filter.html#example-3
I needed to put async move after the closure pipes in and_then
If it's not that, could be similar to
understanding error: trait `futures::future::Future` is not implemented for `()`
where std::result::Result<(), warp::reject::Rejection> indicates you are returning a unit type as left-result, which might not have future implemented for it.
The following code does not compile for me.
trait A {
fn fun0(&self);
fn fun2(&self) -> Option<Box<Self>>;
}
struct B0 {
id: usize,
}
impl A for B0 {
fn fun0(&self) { println!("Value: {:?}", self.id); }
fn fun2(&self) -> Option<Box<Self>> { Option::None }
}
struct B1 {
id: isize,
}
impl A for B1 {
fn fun0(&self) { println!("Value: {:?}", self.id); }
fn fun2(&self) -> Option<Box<Self>> { Option::Some(Box::new(B1 { id: self.id, })) }
}
enum C {
None,
Put { object: Box<A>, },
}
fn fun1(values: Vec<C>) {
for it in values.iter() {
match *it {
C::Put { object: ref val, } => val.fun0(),
C::None => (),
};
}
}
fn main() {
let obj_b0 = Box::new(B0 { id: 778, });
let obj_b1 = Box::new(B1 { id: -8778, });
let obj_c0 = C::Put { object: obj_b0, };
let obj_c1 = C::Put { object: obj_b1, };
let mut vec = Vec::new();
vec.push(obj_c0);
vec.push(obj_c1);
fun1(vec);
}
gives an error:
cargo run
Compiling misc v0.0.1 (file:///home/spandan/virtualization/coding/my/rust-tests/misc/misc)
src/main.rs:188:48: 188:54 error: the trait `A` is not implemented for the type `A` [E0277]
src/main.rs:188 C::Put { object: ref val, } => val.fun0(),
^~~~~~
src/main.rs:197:35: 197:41 error: cannot convert to a trait object because trait `A` is not object-safe [E0038]
src/main.rs:197 let obj_c0 = C::Put { object: obj_b0, };
^~~~~~
src/main.rs:197:35: 197:41 note: method `fun2` references the `Self` type in its arguments or return type
src/main.rs:197 let obj_c0 = C::Put { object: obj_b0, };
^~~~~~
src/main.rs:198:35: 198:41 error: cannot convert to a trait object because trait `A` is not object-safe [E0038]
src/main.rs:198 let obj_c1 = C::Put { object: obj_b1, };
^~~~~~
src/main.rs:198:35: 198:41 note: method `fun2` references the `Self` type in its arguments or return type
src/main.rs:198 let obj_c1 = C::Put { object: obj_b1, };
^~~~~~
error: aborting due to 3 previous errors
Could not compile `misc`.
working with
rustc --version
rustc 1.0.0-nightly (00978a987 2015-04-18) (built 2015-04-19)
The problem appears when fun2(&self) is brought into the picture. It compiles and runs fine if fun0 is the only existing function in the trait. But my code needs such a pattern - How do i do it ?
Edit: the correct answer for the above has been given here (https://stackoverflow.com/a/29985438/1060004) . But i am running into the same problem if i remove the &self from function signature (ie., make it static):
fn fun2() -> Option<Box<A>>
what is the issue now ?
As you have noticed, the problem vanishes when you remove fun2 method. Let's look at it more closely:
fn fun2(&self) -> Option<Box<Self>>;
Note that its output type contains Self, that is, the type which the trait is implemented for. For example, if A is implemented for String, it would be String:
impl A for String {
fn fun2(&self) -> Option<Box<String>> { ... }
}
However! With the trait objects the actual type of the value is erased, and the only thing that we know about trait objects is that it is a value which implements the trait, but we don't know the actual type the trait is implemented for. Trait object methods are dispatched dynamically, so the program selects the actual method to call at runtime. These methods have to behave identically, that is, accept the same number of parameters of the same size (pairwise) and return values of the same size too. If a method uses Self somewhere in its signature, like fun2, its implementations won't be compatible with each other because they would need to operate on values of different size, and hence such methods can't be unified.
Such methods (which can't work with trait objects) are called object-unsafe (or not object-safe). If a trait contains such methods, it can't be made a trait object - it is also called not object-safe.
What would work, I believe, is that you can make the trait return a trait object:
fn fun2(&self) -> Option<Box<A>>
Now the dependency on the actual type is lifted, and the trait becomes object-safe again.
Well, the error message pretty much spells out the immediate problem: you're trying to use a non-object-safe trait in an object context, and you can't do that.
You can remove fun2 from the trait A, and define it in a different trait: its presence will prevent A from ever being used as a "trait object"; so &A, Box<A>, etc. will all out of the question. Each type can then implement both of these traits.
Another alternative is to change fun2 so that its result does not contain the Self type; your example is too abstract to know, but would Option<Box<A>> be acceptable?
As for why: in order for a trait to be used as a trait object, the compiler has to be able to generate a vtable for the trait's methods so that it can do dynamic, runtime dispatch. This means that every method in the trait has to be implementable with the same types (the self parameter is a special case). So what does fun2 return? It has to return an Option<Box<Self>>, but Self is a different type for every implementation! There's no possible way to unify it!