Repository navigation
“closure references itself” error when it’s not #97680
Description
Activity
Here's a shorter repro (sort of) that involves closures without
async:// Trait blanket implemented for Fn trait StrFn<'a>: Fn(&'a str) -> Self::SOutput { type SOutput; } impl<'a, O, F: Fn(&'a str) -> O> StrFn<'a> for F { type SOutput = O; } // Usage of the trait with HRTB fn go<F: for<'a> StrFn<'a>>(f: F) { f(""); } fn main() { go(str::chars); // no error go(|line: &str| line.chars()); // error }
This fails with “closure/generator type that references itself” on 1.67.0 stable. However, on nightly (2023-02-05 75a0be9) it gives a new error:
error: lifetime may not live long enough --> src/main.rs:16:21 | 16 | go(|line: &str| line.chars()); // error | - - ^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2` | | | | | return type of closure is Chars<'2> | let's call the lifetime of this reference `'1`
which suggests that PR #105409, where @compiler-errors wrote
This also doesn't fix #97680, but it makes it possible to compile with the standard "closure wasn't smart enough at inferring higher-ranked lifetime" trick
doesn't fix as much as might be hoped, because in this case I am giving a type to the closure parameter but it still isn't accepted. (Or maybe I'm missing something about the required lifetime bounds.)
in this case I am giving a type to the closure parameter but it still isn't accepted
I think the problem here is that the return type is inferred to some specific lifetime, while the argument is inferred to be higher ranked (so the code is basically equivalent to "
for<'a> |line: &'a str| -> Chars<'?> { line.chars() }"- addedA-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsA-closuresArea: Closures (`|…| { … }`)Area: Closures (`|…| { … }`)T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.A-inferenceArea: Type inferenceArea: Type inferenceT-typesRelevant to the types team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.and removed
on Jan 25, 2024
I tried this code (playground):
Trying to compile it produces the following error:
I’m not sure if it should compile, but the diagnostic is misleading either way: this closure doesn’t have infinite size (in fact, it’s zero-sized), doesn’t capture itself (it captures nothing) and doesn’t take itself as argument (it only takes
()).I don’t see a reason why it shouldn’t compile though, since all the types are known without evaluating the recursive bound on
hrc().Meta
This bug is reproducible on playground on stable, beta and nightly (1.61.0, 1.62.0-beta3 and 1.63.0-nightly (2022-06-02 e714405) respectively)
Links