Playing with non_lifetime_binders

Trying to find a solution for this problem, I played with #![feature(non_lifetime_binders)] and ran into this problem:

trait Recursive<B> {
    type TyCon<C>: for<D> Recursive<D>;
}

impl<A, B> Recursive<B> for Vec<A> {
    type TyCon<C> = Vec<C>;
}

(Nightly Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
 --> src/lib.rs:1:12
  |
1 | #![feature(non_lifetime_binders)]
  |            ^^^^^^^^^^^^^^^^^^^^
  |
  = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
  = note: `#[warn(incomplete_features)]` on by default

error[E0277]: the size for values of type `D` cannot be known at compilation time
 --> src/lib.rs:8:21
  |
8 |     type TyCon<C> = Vec<C>;
  |                     ^^^^^^ doesn't have a size known at compile-time
  |
  = help: the trait `Sized` is not implemented for `D`
  = help: the trait `Recursive<B>` is implemented for `Vec<A>`
note: required for `Vec<C>` to implement `Recursive<D>`
 --> src/lib.rs:7:12
  |
7 | impl<A, B> Recursive<B> for Vec<A> {
  |         -  ^^^^^^^^^^^^     ^^^^^^
  |         |
  |         unsatisfied trait bound introduced here
note: required by a bound in `Recursive::TyCon`
 --> src/lib.rs:4:20
  |
4 |     type TyCon<C>: for<D> Recursive<D>;
  |                    ^^^^^^^^^^^^^^^^^^^ required by this bound in `Recursive::TyCon`

For more information about this error, try `rustc --explain E0277`.
warning: `playground` (lib) generated 1 warning
error: could not compile `playground` (lib) due to previous error; 1 warning emitted

I tried:

-    type TyCon<C>: for<D> Recursive<D>;
+    type TyCon<C>: for<D: Sized> Recursive<D>;

But:

(modified Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error: lifetime bounds cannot be used in this context
 --> src/lib.rs:4:27
  |
4 |     type TyCon<C>: for<D: Sized> Recursive<D>;
  |                           ^^^^^
…

Is there any way around this?

1 Like

I'm not sure if this satisfies your other requirements downstream, but doing the obvious thing and just making implicitly-Sized lifetimes parameters ?Sized appears to work. Would this be acceptable?

2 Likes

Hmmm, maybe in theory it could work if I do this for all traits and put extra B: Sized bounds at all methods, but it would be super tedious (and not sure if it helps me to achieve my overall goal in the end). But it could be a solution actually.

trait Recursive<B: ?Sized> {
    type TyCon<C>: for<D> Recursive<D>;
    fn foo(self) -> B
    where
        B: Sized;
}

(Playground)

Not sure if I will / want to pursue it though (due to the work it involves).

I wonder, is it planned to allow bounds in for<…> expressions? As far as I understand, it's also not allowed for lifetimes, right?

For my particular problem, I most likely found a workaround that works without unstable features.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.