Skip to content

Closure breaks function with higher-ranked trait bound #131677

Open
@drewtato

Description

@drewtato

I tried this code:

pub fn f<T>()
where
    for<'a> &'a T:,
{
    || {};
}

I expected this to compile, perhaps with warnings. Instead, I get this error:

error: `T` does not live long enough
 --> src\lib.rs:5:5
  |
5 |     || {};
  |     ^^^^^

Rust version: rustc 1.84.0-nightly (27861c4 2024-10-13)

As best as I can tell, this happens when a generic is involved in a higher-ranked trait bound, and a closure is defined inside the function. It seems like since the closure is somewhat generic over T, the closure needs to satisfy something about the bound. Things that also exhibit the issue:

  • Adding more bounds
  • Using the HRTB with a GAT, e.g. T: for<'a> Trait<Item<'a> = &'a ()>
  • Adding arguments or a return to the closure
  • Using or calling the closure (calling the closure adds another error on the call expression)
  • Replacing the closure with an async block

Things that don't exhibit the issue:

  • A HRTB with a trait generic over a lifetime: T: for<'a> Trait<'a> or for<'a> T: Trait<'a>
  • A HRTB on a concrete type: for<'a> &'a ():
  • Defining the closure inside a function inside f

This is probably the same as #102540 but that issue misidentified the problem and is old. I did some quick checking of old versions and this compiles in 1.20.0 and 1.30.1, throws ICE in 1.40.0, and gives an error in 1.50.0 and 1.60.0. The 1.60.0 error has a little more info.

error: higher-ranked lifetime error
 --> src\lib.rs:5:5
  |
5 |     || {};
  |     ^^^^^
  |
  = note: could not prove for<'a, 'r> &'a T: 'r

The ICE from 1.40.0 looks similar to #59311 (weirdly, predates 1.30) and #71546 and looks like this:

error: internal compiler error: broken MIR in DefId(0:12 ~ rusttest[7b76]::f[0]) (NoSolution): could not prove Binder(OutlivesPredicate(&'a T, ReEmpty))
 --> src\lib.rs:5:5
  |
5 |     || {};
  |     ^^^^^

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-closuresArea: Closures (`|…| { … }`)A-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions