Skip to content

Claims that deduced parameter to lambda has type &mut T, which makes calling functions that take a &mut T fail; actually making it arg: &mut T makes it work #151066

@nabijaczleweli

Description

@nabijaczleweli

I tried this code:

pub type WalkedSample = (std::path::PathBuf, std::fs::File, ());
pub fn user((_, _, _): &mut WalkedSample) -> Result<(), String> { unimplemented!() }
pub fn gen() -> impl Iterator<Item = WalkedSample> { #[allow(unreachable_code)] vec![unimplemented!()].into_iter() }
fn main() -> Result<(), String> {
    let single = |bundle| -> Result<(), String> {
        user(bundle)?;
        user(bundle)?;
        Ok(())
    };
    for mut bundle in gen() {
        let _ = single(&mut bundle);
    }
    Ok(())
}

I expected to see this happen: it working

Instead, this happened:

error[E0382]: borrow of moved value: `bundle`
 --> a.rs:7:14
  |
5 |     let single = |bundle| -> Result<(), String> {
  |                   ------ move occurs because `bundle` has type `&mut (PathBuf, File, ())`, which does not implement the `Copy` trait
6 |         user(bundle)?;
  |              ------ value moved here
7 |         user(bundle)?;
  |              ^^^^^^ value borrowed here after move
  |
note: consider changing this parameter type in function `user` to borrow instead if owning the value isn't necessary
 --> a.rs:2:24
  |
2 | pub fn user((_, _, _): &mut WalkedSample) -> Result<(), String> { unimplemented!() }
  |        ----            ^^^^^^^^^^^^^^^^^ this parameter takes ownership of the value
  |        |
  |        in this function

error[E0597]: `bundle` does not live long enough
  --> a.rs:11:24
   |
10 |     for mut bundle in gen() {
   |         ---------- binding `bundle` declared here
11 |         let _ = single(&mut bundle);
   |                 ------ ^^^^^^^^^^^ borrowed value does not live long enough
   |                 |
   |                 borrow later used here
12 |     }
   |     - `bundle` dropped here while still borrowed

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0382, E0597.
For more information about an error, try `rustc --explain E0382`.

Obviously weird, since given let a: &mut T; fn f(&mut T);, f(a); f(a); is valid.

Even worse: if you do

    let single = |bundle: &mut WalkedSample| -> Result<(), String> {

this works.

So the deduced type is clearly not &mut WalkedSample, in spite of the diagnostic, because then it would've worked.

Meta

rustc --version --verbose:

rustc 1.92.0 (ded5c06cf 2025-12-08)
binary: rustc
commit-hash: ded5c06cf21d2b93bffd5d884aa6e96934ee4234
commit-date: 2025-12-08
host: x86_64-unknown-linux-gnu
release: 1.92.0
LLVM version: 21.1.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-coercionsArea: implicit and explicit `expr as Type` coercionsA-inferenceArea: Type inferenceC-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.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions