790309b102
closure field capturing: don't depend on alignment of packed fields This fixes the closure field capture part of https://github.com/rust-lang/rust/issues/115305: field capturing always stops at projections into packed structs, no matter the alignment of the field. This means changing a private field type from `u8` to `u64` can never change how closures capture fields, which is probably what we want. Here's an example where, before this PR, changing the type of a private field in a repr(Rust) struct can change the output of a program: ```rust #![allow(dead_code)] mod m { // before patch #[derive(Default)] pub struct S1(u8); // after patch #[derive(Default)] pub struct S2(u64); } struct NoisyDrop; impl Drop for NoisyDrop { fn drop(&mut self) { eprintln!("dropped!"); } } #[repr(packed)] struct MyType { field: m::S1, // output changes when this becomes S2 other_field: NoisyDrop, third_field: Vec<()>, } fn test(r: MyType) { let c = || { let _val = std::ptr::addr_of!(r.field); let _val = r.third_field; }; drop(c); eprintln!("before dropping"); } fn main() { test(MyType { field: Default::default(), other_field: NoisyDrop, third_field: Vec::new(), }); } ``` Of course this is a breaking change for the same reason that doing field capturing in the first place was a breaking change. Packed fields are relatively rare and depending on drop order is relatively rare, so I don't expect this to have much impact, but it's hard to be sure and even a crater run will only tell us so much. Also see the [nomination comment](https://github.com/rust-lang/rust/pull/115315#issuecomment-1702807825). Cc `@rust-lang/wg-rfc-2229` `@ehuss` |
||
---|---|---|
.. | ||
diagnostics | ||
match | ||
migrations | ||
optimization | ||
run_pass | ||
array_subslice.rs | ||
array_subslice.stderr | ||
arrays-completely-captured.rs | ||
arrays-completely-captured.stderr | ||
bad-pattern.rs | ||
bad-pattern.stderr | ||
by_value.rs | ||
by_value.stderr | ||
capture-analysis-1.rs | ||
capture-analysis-1.stderr | ||
capture-analysis-2.rs | ||
capture-analysis-2.stderr | ||
capture-analysis-3.rs | ||
capture-analysis-3.stderr | ||
capture-analysis-4.rs | ||
capture-analysis-4.stderr | ||
capture-disjoint-field-struct.rs | ||
capture-disjoint-field-struct.stderr | ||
capture-disjoint-field-tuple.rs | ||
capture-disjoint-field-tuple.stderr | ||
capture-enum-field.rs | ||
capture-enums.rs | ||
capture-enums.stderr | ||
deep-multilevel-struct.rs | ||
deep-multilevel-struct.stderr | ||
deep-multilevel-tuple.rs | ||
deep-multilevel-tuple.stderr | ||
destructure_patterns.rs | ||
destructure_patterns.stderr | ||
feature-gate-capture_disjoint_fields.rs | ||
feature-gate-capture_disjoint_fields.stderr | ||
filter-on-struct-member.rs | ||
filter-on-struct-member.stderr | ||
issue_88118.rs | ||
issue-87378.rs | ||
issue-87378.stderr | ||
issue-87987.rs | ||
issue-87987.stderr | ||
issue-88118-2.rs | ||
issue-88118-2.stderr | ||
issue-88476.rs | ||
issue-88476.stderr | ||
issue-89606.rs | ||
issue-90465.fixed | ||
issue-90465.rs | ||
issue-90465.stderr | ||
issue-92724-needsdrop-query-cycle.rs | ||
move_closure.rs | ||
move_closure.stderr | ||
multilevel-path-1.rs | ||
multilevel-path-1.stderr | ||
multilevel-path-2.rs | ||
multilevel-path-2.stderr | ||
nested-closure.rs | ||
nested-closure.stderr | ||
path-with-array-access.rs | ||
path-with-array-access.stderr | ||
preserve_field_drop_order2.rs | ||
preserve_field_drop_order2.twenty_eighteen.run.stdout | ||
preserve_field_drop_order2.twenty_twentyone.run.stdout | ||
preserve_field_drop_order.rs | ||
preserve_field_drop_order.stderr | ||
repr_packed.rs | ||
repr_packed.stderr | ||
simple-struct-min-capture.rs | ||
simple-struct-min-capture.stderr | ||
unique-borrows-are-invariant-1.rs | ||
unique-borrows-are-invariant-1.stderr | ||
unique-borrows-are-invariant-2.rs | ||
unique-borrows-are-invariant-2.stderr | ||
unsafe_ptr.rs | ||
unsafe_ptr.stderr | ||
wild_patterns.rs | ||
wild_patterns.stderr |