Skip to content

Oddity with closures that "mention" uninitialized places #2140

@theemathas

Description

@theemathas

It is unclear whether a closure is allowed to "mention" an uninitialized place, and when. Consider the following code:

fn fails() {
    let a = String::new();
    drop(a);
    let _closure = || { let _ = a; };
}

fn also_fails() {
    let a = (String::new(), String::new());
    drop(a.0);
    let _closure = || { let (_, _s) = a; };
}

fn works() {
    let a = (String::new(), String::new());
    drop(a.0);
    let _closure = || { let _s = a.1; };
}

When compiled with edition 2024 (stable rust 1.93.0), we get the following errors:

error[E0382]: use of moved value: `a`
 --> src/lib.rs:4:33
  |
2 |     let a = String::new();
  |         - move occurs because `a` has type `String`, which does not implement the `Copy` trait
3 |     drop(a);
  |          - value moved here
4 |     let _closure = || { let _ = a; };
  |                                 ^ value used here after move
  |
help: consider cloning the value if the performance cost is acceptable
  |
3 |     drop(a.clone());
  |           ++++++++

error[E0382]: use of partially moved value: `a`
  --> src/lib.rs:10:20
   |
 9 |     drop(a.0);
   |          --- value partially moved here
10 |     let _closure = || { let (_, _s) = a; };
   |                    ^^                 - use occurs due to use in closure
   |                    |
   |                    value used here after partial move
   |
   = note: partial move occurs because `a.0` has type `String`, which does not implement the `Copy` trait

For more information about this error, try `rustc --explain E0382`.

That is, works compiles, but fails and also_fails do not compile. This seems inconsistent. Why is this the case, and is this intended?

Co-discovered in #2121 with @Nadrieril

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