I tried this code:
#![expect(dead_code, irrefutable_let_patterns)]
struct Thing(String, String);
fn foo(x: Thing) {
let closure = || {
if let Thing(_a, _) = x {}
};
println!("{}", size_of_val(&closure));
}
fn bar(x: Thing) {
let closure = || {
match x {
Thing(_a, _) => {}
}
};
println!("{}", size_of_val(&closure));
}
fn baz(x: Thing) {
let closure = || {
let Thing(_a, _) = x;
};
println!("{}", size_of_val(&closure));
}
fn main() {
foo(Thing(String::from("a"), String::from("b")));
bar(Thing(String::from("a"), String::from("b")));
baz(Thing(String::from("a"), String::from("b")));
}
I expected the three printed numbers to be the same. Instead, in editions 2021 and 2024, the code prints 48 then 24 then 24.
It seems that if let causes the entire value of x to be captured, but let and match only capture the relevant field. This seems inconsistent.
cc @Nadrieril @meithecatte
Meta
Reproducible on the playground with version 1.96.0-nightly (2026-03-12 3102493c71626b5912d1) and also on version 1.94.0.
However, testing on Godbolt with version 1.93.0 (which is before #138961), it prints 48 then 48 then 24.
I tried this code:
I expected the three printed numbers to be the same. Instead, in editions 2021 and 2024, the code prints
48then24then24.It seems that
if letcauses the entire value ofxto be captured, butletandmatchonly capture the relevant field. This seems inconsistent.cc @Nadrieril @meithecatte
Meta
Reproducible on the playground with version
1.96.0-nightly (2026-03-12 3102493c71626b5912d1)and also on version1.94.0.However, testing on Godbolt with version
1.93.0(which is before #138961), it prints48then48then24.