rust-lang / rust-lang/rust

Ability to infer lifetime of closure argument depends on syntax

Open
#117,532 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-inference C-bug T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I tried this code:

use futures::future::BoxFuture;
use futures::FutureExt;
use std::sync::Arc;

type Result<T, E = String> = std::result::Result<T, E>;
struct InterpreterInner;

pub struct Interpreter {
    inner: Arc<InterpreterInner>,
}

enum Value {
    Pumpkin,
}

enum Node {
    A,
    B,
}

impl Interpreter {
    fn visit<'a>(
        &self,
        node: Node,
    ) -> Arc<dyn (Fn(&Arc<InterpreterInner>) -> BoxFuture<'static, Result<Value>>) + Send + Sync>
    {
        match node {
            Node::A => Arc::new(self.visit_object(vec![])),
            _ => panic!(),
        }
    }

    fn visit_object<'a>(
        &self,
        values: Vec<Node>,
    ) -> impl Fn(&Arc<InterpreterInner>) -> BoxFuture<'static, Result<Value>> {
        let values = values
            .into_iter()
            .map(|x| {
                match x {
                    Node::B => {
                        /* THIS VERSION WORKS

                        Arc::new(move |_: &'_ _| { async move { Ok(Value::Pumpkin) }.boxed() })
                        */

                        Arc::new(move |_| async move { Ok(Value::Pumpkin) }.boxed())
                    }
                    x => self.visit(x),
                }
            })
            .collect::<Arc<[_]>>();

        move |_inner| {
            let _values = Arc::clone(&values);

            async move { Ok(Value::Pumpkin) }.boxed()
        }
    }
}

I expected to see this happen: The code should compile

Instead, this happened: The code only compiles if I use the commented out version of the innermost closure (i.e. specify explicitly that I'd like the lifetime to be inferred).

Meta

rustc --version --verbose:

rustc 1.75.0-nightly (9d1e4b787 2023-10-11)
binary: rustc
commit-hash: 9d1e4b7870f0aecb9f53e71f3cca3529b21d677a
commit-date: 2023-10-11
host: x86_64-unknown-linux-gnu
release: 1.75.0-nightly
LLVM version: 17.0.2

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by compiling the provided closure example with the referenced nightly rustc version and compare the two innermost closure forms. Trace the compiler's lifetime inference for the closure argument; done means both syntactic forms compile consistently, with a regression test covering the reproducer.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.