rfcs icon indicating copy to clipboard operation
rfcs copied to clipboard

RFC: extended_hrtbs

Open tema3210 opened this issue 2 years ago • 5 comments

RFC for bounded universal quantification for lifetimes

Rendered

Internals thread

tema3210 avatar May 08 '22 12:05 tema3210

Could you please, somewhere in the RFC, define HRTBs as higher-rank trait bounds? I had to look that up even though I understand the for<'a> syntax.

clarfonthey avatar May 08 '22 15:05 clarfonthey

So, two thoughts:

First, I'd like for this to not really be needed in most cases if ever. We should be able to use some form of implied bounds here. We've had some discussion around a-mir-formality about this.

Second, I personally prefer for<'a> where <'i: 'a> I::Item<'a>: Debug, since that would match more closely with how we expect the predicates to be defined during trait solving. You could also in theory have for<'a> where<I: Trait> I::Item<'a>: Debug, for example (thought I can't think of a reason for that off the top of my head).

jackh726 avatar May 22 '22 18:05 jackh726

@jackh726

First, I'd like for this to not really be needed in most cases if ever. We should be able to use some form of implied bounds here. We've had some discussion around a-mir-formality about this.

I'm not sure what do you want here. With for<'_> syntax for closures we can specify that a closure should be generic over lifetimes and this feature plays nicely with that. Plain closures already can be inferred to be both generic and non - generic (I'm not sure about exact rules though) - you want to specify an algorithm?

Second, I personally prefer for<'a> where <'i: 'a> I::Item<'a>: Debug, since that would match more closely with how we expect the predicates to be defined during trait solving. You could also in theory have for<'a> where<I: Trait> I::Item<'a>: Debug, for example (thought I can't think of a reason for that off the top of my head).

Such syntax feels strange with closures: for<'a> where<'b: 'a> |arg: &'a T| ....

tema3210 avatar May 24 '22 17:05 tema3210

First, I'd like for this to not really be needed in most cases if ever. We should be able to use some form of implied bounds here.

Related to HRTBs with two lifetimes and implied bounds:

  • https://github.com/rust-lang/rust/issues/113967.

JanBeh avatar Jul 22 '23 17:07 JanBeh

@jackh726

First, I'd like for this to not really be needed in most cases if ever. We should be able to use some form of implied bounds here. We've had some discussion around a-mir-formality about this.

I'm trying to define a trait abstraction for std::thread::scope interface. But it seems impossible to be defined without bounds 'env: 'scope. It can be implicitly inferred with freestanding functions, but not inside trait with GATs.

playground

trait SupportScoped {
    type Scope<'scope, 'env: 'scope>;

    fn scope<'env, F>(f: F)
    where
        for<'scope> F: FnOnce(&'scope Self::Scope<'scope, 'env>);
}

struct Thread;

impl SupportScoped for Thread {
    type Scope<'scope, 'env: 'scope> = std::thread::Scope<'scope, 'env>;

    fn scope<'env, F>(f: F)
    where
        for<'scope> F: FnOnce(&'scope Self::Scope<'scope, 'env>),
        //             ^ error[E0478]: lifetime bound not satisfied
    {
        std::thread::scope(f);
    }
}

I think the explicit type of scope should be like this, which is impossible to write without this RFC:

fn scope<'env, F>(f: F)
where
    for<'scope where 'env: 'scope> F: FnOnce(&'scope Self::Scope<'scope, 'env>);

oxalica avatar Jan 18 '24 20:01 oxalica