Defining a trait with associated type and fn returning Result<Self,AssocType>?

A beginner Rustacean here.
I wanted to define a trait like this, which I want to implement for multiple types:

trait AsfaloadKeyPairB {
    type KeyErr;
    fn new(pw: &str) -> Result<Self, Self::KeyErr>;
    fn save(&self, p: Path) -> &Self;
}

but it gives the error

the size for values of type `Self` cannot be known at compilation time
doesn't have a size known at compile-time [E0277]

Running rustc --explain E0277 gives me explanation about types not implementing a trait, which seems not related to my problem. So I try to define the trait differently:

trait AsfaloadKeyPair<'a> {
    type KeyErr;
    fn new(pw: &str) -> Result<&'a Self, Self::KeyErr>;
    fn save(&self, p: Path) -> &Self;
}

This trait definition is accepted, but now I don't know how to implemented...

impl<'a> AsfaloadKeyPair<'a> for minisign::KeyPair {
    type KeyErr = errs::KeyError;
    fn new(password: &str) -> Result<&'a Self, errs::KeyError> {
        let kp = KeyPair::generate_encrypted_keypair(Some(password.to_string()))?;
        Ok(&kp)
    }

I understand why this is not accepted, but I don't see how to fix it. My trait function needs to return a reference, but in my function implementation I can't because it is created locally.
What's the right solution in this situation?

Thanks in advance!

1 Like

You perhaps want:

trait AsfaloadKeyPairB {
    type KeyErr;
    fn new(pw: &str) -> Result<Self, Self::KeyErr>
    // vvvvvvvvvvvvv the new part
    where
        Self: Sized,
    ;
    fn save(&self, p: Path) -> &Self;
}
2 Likes

This works, thanks!
Do I understand it correctly that the compiler will raise an error in the case that I write code where Self is not Sized and that I don't have to take any precaution until then as most types are Sized?

1 Like

If you implement the trait for a type which is not Sized, you can just leave that particular method out. (Or if you're on an older compiler, you might have to include it, but don't mention the bound and just put unreachable!() in the body. You won't be able to call it.)

And yes, most types are Sized, so it will probably be an exceptional situation.

1 Like