Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unhelpful higher-ranked lifetime error in non-async context #111465

Open
veprolet opened this issue May 11, 2023 · 0 comments
Open

Unhelpful higher-ranked lifetime error in non-async context #111465

veprolet opened this issue May 11, 2023 · 0 comments
Labels
A-borrow-checker Area: The borrow checker A-diagnostics Area: Messages for errors, warnings, and lints A-higher-ranked Area: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@veprolet
Copy link

veprolet commented May 11, 2023

Here is somewhat minified code producing the unhelpful error message (playground)

fn map<F, M, I, X, O>(function: F, mapper: M) -> impl Fn(I) -> O
where
    F: Fn(I) -> X,
    M: Fn(X) -> O,
{
    move |input| {
        mapper(function(input))
    }
}

fn pack<F, O>(function: F) -> impl Fn(&u32) -> ((), O)
where
    F: Fn(&u32) -> O,
{
    move |input| {
        ((), function(input))
    }
}

fn unpack<F, O>(function: F) -> impl Fn(&u32)
where
    F: Fn(&u32) -> O,
{
    map(pack(function), |(unit, _)| unit)
}

fn main() {}

This code produces the following error message, which is in my opinon quite unhelpful:

error: higher-ranked lifetime error
  --> src/main.rs:24:5
   |
24 |     map(pack(function), |(unit, _)| unit)
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I assume the lifetimes in the code desugar into something like this:

fn map<F, M, I, X, O>(function: F, mapper: M) -> impl Fn(I) -> O
where
    F: Fn(I) -> X,
    M: Fn(X) -> O,
{
    move |input| {
        mapper(function(input))
    }
}

fn pack<F, O>(function: F) -> impl for<'a> Fn(&'a u32) -> ((), O)
where
    for<'b> F: Fn(&'b u32) -> O,
{
    move |input| {
        ((), function(input))
    }
}

fn unpack<F, O>(function: F) -> impl for<'a> Fn(&'a u32)
where
    for<'b> F: Fn(&'b u32) -> O,
{
    map(pack(function), |(unit, _)| unit)
}

fn main() {}

This code produces the same error and does seem vaguely incorrect, as I'd expect the two lifetimes to be at least somewhat related. Specifying the lifetimes in almost any other way resolves the error. For example:

fn map<F, M, I, X, O>(function: F, mapper: M) -> impl Fn(I) -> O
where
    F: Fn(I) -> X,
    M: Fn(X) -> O,
{
    move |input| {
        mapper(function(input))
    }
}

fn pack<'a, F, O>(function: F) -> impl Fn(&'a u32) -> ((), O)
where
    for<'b> F: Fn(&'b u32) -> O,
{
    move |input| {
        ((), function(input))
    }
}

fn unpack<'a, F, O>(function: F) -> impl Fn(&'a u32)
where
    for<'b> F: Fn(&'b u32) -> O,
{
    map(pack(function), |(unit, _)| unit)
}

fn main() {}

This issue seems closely related to other issues with this error, such as: #102211, #102870, #99492. This issue is probably a duplicate of those, but I'm submitting a new issue, because all the aforementioned issues deal with complex async types and contexts, and apart from #102870 seem to include at least some helpful info in the error message. Also I don't completely understand the error, so I'm not sure whether it should even occur, which seems to be the main focus of those other issues, but I'm fairly confident the error message could provide more information.

Meta

rustc --version --verbose:

rustc 1.69.0 (84c898d65 2023-04-16)
binary: rustc
commit-hash: 84c898d65adf2f39a5a98507f1fe0ce10a2b8dbc
commit-date: 2023-04-16
host: x86_64-unknown-linux-gnu
release: 1.69.0
LLVM version: 15.0.7
@jyn514 jyn514 added A-diagnostics Area: Messages for errors, warnings, and lints A-borrow-checker Area: The borrow checker T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels May 13, 2023
@fmease fmease added the A-higher-ranked Area: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs) label Sep 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-borrow-checker Area: The borrow checker A-diagnostics Area: Messages for errors, warnings, and lints A-higher-ranked Area: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants