about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src/errors.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-09-16 05:29:23 +0000
committerbors <bors@rust-lang.org>2023-09-16 05:29:23 +0000
commit790309b102a0f0459f0ca0ac0386cec2b8a9b0db (patch)
tree26f6dfa990032abee81c1969f4af7b6842fe4b87 /compiler/rustc_codegen_llvm/src/errors.rs
parent635c4a5e612b0ee8af6615635599702d3dce9906 (diff)
parenta671127941921bc11be4d99106fea5cba398b383 (diff)
downloadrust-790309b102a0f0459f0ca0ac0386cec2b8a9b0db.tar.gz
rust-790309b102a0f0459f0ca0ac0386cec2b8a9b0db.zip
Auto merge of #115315 - RalfJung:field-capture-packed-alignment, r=oli-obk
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`
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/errors.rs')
0 files changed, 0 insertions, 0 deletions