6

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;
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Michael Galuza
  • 386
  • 6
  • 16
  • What exactly do you mean by "I want something like C++"? – phimuemue Nov 24 '20 at 15:13
  • 1
    And _why_ do you want this? How would you use it? – Shepmaster Nov 24 '20 at 15:14
  • @Shepmaster It's a very strange question for me. We have type aliases in Rust, why we shouldn't to want to use them inside a trait definition? – Michael Galuza Nov 24 '20 at 15:22
  • 1
    That second snippet does not make much sense, even if pseudo-code. One can add multiple trait bounds to an associated type, but not treat that sum of constraints as a type in itself. Perhaps you are interested in [this](https://stackoverflow.com/questions/26070559/is-there-any-way-to-create-a-type-alias-for-multiple-traits)? – E_net4 Nov 24 '20 at 15:29
  • 1
    Your example usage doesn't make sense to me. You have a generic *type* `T` and then you try to treat it as a trait because you add other traits to it (`+ Clone`). Those two concepts aren't compatible. – Shepmaster Nov 24 '20 at 15:30
  • 1
    Creating a new trait inheriting from the previous ones would probably solve the real problem here. – Denys Séguret Nov 24 '20 at 15:31
  • "Is Rust a really C++ killer" for the last time, no. no and no, rust in my opinion is not at all a C++ killer. It's a clear replacement for C that all. – Stargateur Nov 24 '20 at 15:39
  • 2
    *why people downvote this question* — I didn't downvote this question, but look at the amount of comments and edits that have been made in the short time since you posted it. The question was **very** unclear in it's original form. People presumably read it, saw it was unclear, downvoted, and moved on with their day. To avoid those types of downvotes, ensure that questions are abundantly clear from the beginning. – Shepmaster Nov 24 '20 at 15:44
  • *Is Rust a _really_ C++ killer* — why do you believe it is? Can you point to a Rust page that suggests that is its purpose? *if even such trivial things are rocket science* — oftentimes, things that we think are "trivial" **aren't** when additional constraints like memory safety or lack of undefined behavior are required. – Shepmaster Nov 24 '20 at 15:46

2 Answers2

3

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:

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
3

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
    }
}
user4815162342
  • 141,790
  • 18
  • 296
  • 355