Is it possible to declare a type alias inside a trait?

Viewed 1475

Existing syntax allows us to write a default value for associated type:

trait Foo {
    type Bar = i32;
}

I want something like C++:

trait Foo {
    typedef int Bar;
}

This is not valid Rust code, but tries to show my intention:

trait Foo<T> {
    trait Trait = Into<T> + /* 10 other traits dependent on T */;
    
    fn foo(x: Type) -> Trait;
}
2 Answers

No, it is not possible to declare a type alias inside a trait as of Rust 1.48.

Instead, use the existing type alias functionality:

type FooBar = i32;

trait Foo {
    fn usage(&self, _: FooBar);
}

Your specific example may be solved by a combination of two unstable features:

#![feature(type_alias_impl_trait)]
#![feature(trait_alias)] // Stable alternative available in link below.

trait FooBar<T> = Into<T>; // And 10 other traits dependent on T

trait Foo<T> {
    type Ret: FooBar<T>;

    fn example(&self) -> Self::Ret;
}

impl Foo<i32> for i32 {
    type Ret = impl FooBar<i32>;

    fn example(&self) -> Self::Ret {
        42
    }
}

See also:

While trait aliases are currently unstable, you can emulate them. To create an "alias", define a new empty trait and write a blanket implementation for all types that satisfy the traits you want the alias to match. For example:

trait Short<T>: Into<T> /* plus others */ {}
impl<T, U> Short<T> for U where U: Into<T> /* plus others */ {}

The new trait can be used the same way you'd use an alias:

trait Foo<T> {
    // Ret is bound by Into<T> and other bounds provided by Short
    type Ret: Short<T>;

    fn example(&self) -> Self::Ret;
}

struct X;

impl Foo<u32> for X {
    type Ret = u8;  // compiles because u8 is Into<u32>

    fn example(&self) -> u8 {
        0
    }
}
Related