Skip to content

HRTBs: lifetime "does not appear in the trait input types" #70262

Closed
@comex

Description

@comex

Consider this code:

#![feature(unboxed_closures)]
fn foo<F>(f: F) where
    for<'a> F: FnOnce<&'a i32>,
    for<'a> <F as FnOnce<&'a i32>>::Output: Iterator<Item=&'a i64> {}

The bound is intended to match functions roughly of the form

fn callback<'a>(x: &'a i32) -> impl Iterator<Item=&'a i64> { ... }

However, rustc rejects foo with this error:

error[E0582]: binding for associated type `Item` references lifetime `'a`, which does not appear in the trait input types
 --> src/lib.rs:4:54
  |
4 |     for<'a> <F as FnOnce<&'a i32>>::Output: Iterator<Item=&'a i64> {}
  |                                                      ^^^^^^^^^^^^

The rustc --explain output points to issue #33685, which had to do with declarations where a lifetime appeared in a function's return type and nowhere else, like:

fn foo<'a>() -> &'a u32 { .. }

In that issue, @nikomatsakis wrote:

These constructs are being rejected as part of the fix for issue #32330. This is a soundness bug that concerns cases like these.
[..]
These sorts of where-clauses and types are not only ill-formed, they are useless. For example, now that #32330 is fixed, there are no types that could satisfy such a where-clause, nor are there any functions with a type like for<'a> fn() -> &'a i32 (see next section for more details).
[..]
The crux of the problem concerns lifetime parameters that only appear in the return type of a fn declaration -- these are changing to no longer be considered "higher-ranked" (or "late-bound").

My example is different, though, in that the lifetime does appear in the function's arguments. Thus, while I don't know whether allowing the bound would implicate the same soundness issue, I'm pretty sure the bound is not useless: it seems like it should be possible to satisfy.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions