Is it at all possible to define functions inside of traits as having impl Trait
return types? I want to create a trait that can be implemented by multiple structs so that the new()
functions of all of them returns an object that they can all be used in the same way without having to write code specific to each one.
trait A {
fn new() -> impl A;
}
However, I get the following error:
error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
--> src/lib.rs:2:17
|
2 | fn new() -> impl A;
| ^^^^^^
Is this a limitation of the current implementation of impl Trait
or am I using it wrong?
You can get something similar even in the case where it's not returning "Self", by explicitly naming the return type.
As trentcl mentions, you cannot currently place
impl Trait
in the return position of a trait method.From RFC 1522:
For now, you must use a boxed trait object:
See also:
Nightly only
If you wish to use unstable nightly features, you can use existential types (RFC 2071):
Fairly new to Rust, so may need checking.
You could parametrise over the return type. This has limits, but they're less restrictive than simply returning
Self
.The limit in this case is that you can only return a type
T
that implementsA<T>
. Here,St1
implementsA<St1>
, so it's OK forSt2
toimpl A<St2>
. However, it wouldn't work with, for example,For that you'd need to restrict the types further, with e.g.
but I'm struggling to get my head round this last one.
If you only need to return the specific type for which the trait is currently being implemented, you may be looking for
Self
.For example, this will compile:
Or, a fuller example, demonstrating using the trait:
Playground
As a side note.. I have used
String
here in favor of&str
references.. to reduce the need for explicit lifetimes and potentially a loss of focus on the question at hand. I believe it's generally the convention to return a&str
reference when borrowing the content and that seems appropriate here.. however I didn't want to distract from the actual example too much.