Existential keyword?

#1

I was doing something when I came across a funny looking error:

[rustc]
expected one of `async`, `const`, `crate`, `default`, `existential`, `extern`, `fn`, `pub`, `type`, `unsafe`, or `}`, found `static`

And was just wondering what the error meant by existential?

#2

It’s an unfinished feature adding impl Trait type aliases and it intentionally uses a different keyword as a placeholder until a final syntax is decided.

3 Likes
#3

Oh, okay. I just found this right after posting, and it seems like it’s meant to be something like so?

existential type Foo = ATrait;
let var: impl Foo = //...

IE:

existential type IteratorOverU32 = Iterator<Item=u32>;
let var: impl IteratorOverU32 = [1, 2, 3, 4, 5].into_iter();
#4

Almost, I think the full usage wouldn’t involve saying impl IteratorOverU32, just IteratorOverU32 to reference it.

It’d just be

existential type IteratorOverU32 = Iterator<Item=u32>;
// or
existential type IteratorOverU32: Iterator<Item=u32>;
// (the above syntax choice is undecided as far as I know)

fn uses_impl() -> IteratorOverU32 {
    [1, 2, 3, 4, 5].into_iter()
}

It allows impl Trait things to be uniquely named without their type being specified. Someone could do let x: foo_crate::IteratorOverU32 = foo_crate::uses_impl(); without knowing the concrete type, or store IteratorOverU32 as a struct field without using generics.

The other possible use is in impl Trait for Struct, I think?

trait DoThing {
    type ThingResult: Display;
    fn thing(&self) -> Self::ThingResult;
}

impl DoThing for u32 {
    existential type ThingResult: Display;
    // or, if a different syntax is decided on:
    existential type ThingResult = Display;

    fn thing(&self) -> Self::ThingResult {
       *self
    }
}
1 Like