18

I have an existential type defined like this:

trait Collection {
    type Element;
}
impl<T> Collection for Vec<T> {
    type Element = T;
}

type Existential<T> = impl Collection<Element = T>;

A function, which takes a type implementing a trait with an associated type, returns this type. Why does this code work:

fn return_existential<I, T>(iter: I) -> Existential<T>
where
    I: IntoIterator<Item = T>,
    I::Item: Collection,
{
    let item = iter.into_iter().next().unwrap();
    vec![item]
}

playground

while this does not:

fn return_existential<I>(iter: I) -> Existential<I::Item>
where
    I: IntoIterator,
    I::Item: Collection,
{
    let item = iter.into_iter().next().unwrap();
    vec![item]
}
error: type parameter `I` is part of concrete type but not used in parameter list for the `impl Trait` type alias
  --> src/lib.rs:16:1
   |
16 | / {
17 | |     let item = iter.into_iter().next().unwrap();
18 | |     vec![item]
19 | | }
   | |_^

error: defining opaque type use does not fully define opaque type
  --> src/lib.rs:12:1
   |
12 | / fn return_existential<I>(iter: I) -> Existential<I::Item>
13 | | where
14 | |     I: IntoIterator,
15 | |     I::Item: Collection,
...  |
18 | |     vec![item]
19 | | }
   | |_^

error: could not find defining uses
  --> src/lib.rs:10:1
   |
10 | type Existential<T> = impl Collection<Element = T>;
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

playground

When using a Vec directly, this works fine:

fn return_existential<I>(iter: I) -> Vec<I::Item>
where
    I: IntoIterator,
    I::Item: Collection,
{
    let item = iter.into_iter().next().unwrap();
    vec![item]
}

playground

Note: Those examples are constructed while playing around with this feature. I won't use it anyway as long as my IDE is not aware of existential types. Additionally, the exact syntax is subject to change.

mcarton
  • 27,633
  • 5
  • 85
  • 95
Tim Diekmann
  • 7,755
  • 11
  • 41
  • 69
  • 6
    Are you asking (1) why a Work In Progress feature does not seem to be fully implemented OR (2) whether there is a fundamental limitation linked to existential types? – Matthieu M. Apr 24 '19 at 11:16
  • 1
    @Matthieu The latter. – Tim Diekmann Apr 24 '19 at 11:29
  • To me, this just looks like the feature isn't fully polished. You should report a bug. – Peter Hall Apr 25 '19 at 08:44
  • 1
    I [filed this](https://github.com/rust-lang/rust/issues/34511#issuecomment-486614871). – Tim Diekmann Apr 25 '19 at 10:20
  • @oli-obk [replied to this](https://github.com/rust-lang/rust/issues/34511#issuecomment-486698629): *I'm not 100% sure we can support this case out of the box* and proposed the same solution as in my first code snippet as workaround. – Tim Diekmann Apr 25 '19 at 14:47

0 Answers0