Skip to content

Associated traits #2190

Open
Open

Description

RFC 1733 added trait aliases, like:

trait IntoIntIterator = IntoIterator<Item=i32>;

Well, why not allow putting those in traits, by analogy with associated types looking like type aliases? For example:

trait Handler {
    trait Arg;
    fn handle<ArgImpl: Self::Arg>(&self, arg: ArgImpl);
}

struct MyHandler;
impl Handler for MyHandler {
    trait Arg = IntoIterator<Item=i32>;
    fn handle<ArgImpl: Self::Arg>(&self, arg: ArgImpl) {
        for number in arg { println!("{}", number); }
    }
}

Example of a function that's generic over implementations of Handler:

fn example_generic_helper<HandlerImpl, ArgImpl>(handler: HandlerImpl, args: Vec<ArgImpl>)
    where HandlerImpl: Handler,
          ArgImpl: <HandlerImpl as Handler>::Arg {
    for arg in args {
        handler.handle(arg);
    }
}

Associated traits could also have supertrait bounds.

And if impl Trait syntax is extended to function arguments, they'd be a natural fit:

trait Handler {
    trait Arg;
    fn handle(&self, arg: impl Self::Arg);
}

(I was just writing some code where this could have come in handy.)

There's also the natural dual of allowing traits as generic parameters, just as associated types mirror regular type parameters and associated consts mirror the upcoming 'const generics'. Something like

fn foo<Impl, trait Trait> where Impl: Trait {}

I think this has been proposed before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    T-langRelevant to the language team, which will review and decide on the RFC.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions