"expected type parameter, found struct"
You have two different problems so I guess I'll write two different answers.
In your first code sample, 2 and 3 don't work because B is an input type parameter; it is the caller of barr
that decides what B is. However, you are trying to force it to be Foo
.
Let's suppose we have another implementation of Bar
:
struct Quux;
impl Bar for Quux {}
And let's suppose we call barr
like this:
barr::<Quux>()
barr
would essentially be compiled as this:
fn barr() {
bar(Foo);
let foo: Quux = Foo;
let foo_vec: Vec<Quux> = vec![Foo];
}
Foo
and Quux
are not compatible, and Vec<Foo>
and Vec<Quux>
are not compatible either.
If you're trying to create a vector of arbitrary Bar
objects, you need to use Bar
in a non-generic way. As trait types are unsized, you can't store them directly in a Vec
, so you must use Vec<Box<Bar>>
, Vec<&Bar>
or some other type that wraps a pointer.
fn barr() {
bar(Foo);
let foo: Box<Bar> = Box::new(Foo);
let foo_vec: Vec<Box<Bar>> = vec![Box::new(Foo) as Box<Bar>];
}
In your second code sample, the error is that None
has the type Option<T>
, and the compiler is unable to infer an appropriate type for T
. We can explicitly specify T
like this:
fn circle_vec<B: Bar>() {
bar(Foo2);
Foo {
bar: Some(Foo { bar: None::<Foo2> }),
};
}