diff --git a/compiler/rustc_const_eval/src/util/alignment.rs b/compiler/rustc_const_eval/src/util/alignment.rs index 528274e6abac4..a8ef37432bb5a 100644 --- a/compiler/rustc_const_eval/src/util/alignment.rs +++ b/compiler/rustc_const_eval/src/util/alignment.rs @@ -22,7 +22,7 @@ where }; let ty = place.ty(local_decls, tcx).ty; - let unsized_tail = || tcx.struct_tail_with_normalize(ty, |ty| ty, || {}); + let unsized_tail = || tcx.struct_tail_erasing_lifetimes(ty, param_env); match tcx.layout_of(param_env.and(ty)) { Ok(layout) if layout.align.abi <= pack diff --git a/tests/ui/lint/unaligned_references.stderr b/tests/ui/lint/unaligned_references.current.stderr similarity index 93% rename from tests/ui/lint/unaligned_references.stderr rename to tests/ui/lint/unaligned_references.current.stderr index 328cafbd9864b..0f980c5301f37 100644 --- a/tests/ui/lint/unaligned_references.stderr +++ b/tests/ui/lint/unaligned_references.current.stderr @@ -1,5 +1,5 @@ error[E0793]: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:28:13 + --> $DIR/unaligned_references.rs:32:13 | LL | &self.x; | ^^^^^^^ @@ -9,7 +9,7 @@ LL | &self.x; = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:40:24 + --> $DIR/unaligned_references.rs:44:24 | LL | println!("{:?}", &*foo.0); | ^^^^^ @@ -19,7 +19,7 @@ LL | println!("{:?}", &*foo.0); = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:42:24 + --> $DIR/unaligned_references.rs:46:24 | LL | println!("{:?}", &*foo.0); | ^^^^^ @@ -29,7 +29,7 @@ LL | println!("{:?}", &*foo.0); = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:47:24 + --> $DIR/unaligned_references.rs:51:24 | LL | println!("{:?}", &*foo.0); | ^^^^^ @@ -39,7 +39,7 @@ LL | println!("{:?}", &*foo.0); = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:57:17 + --> $DIR/unaligned_references.rs:81:17 | LL | let _ = &good.ptr; | ^^^^^^^^^ @@ -49,7 +49,7 @@ LL | let _ = &good.ptr; = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:58:17 + --> $DIR/unaligned_references.rs:82:17 | LL | let _ = &good.data; | ^^^^^^^^^^ @@ -59,7 +59,7 @@ LL | let _ = &good.data; = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:60:17 + --> $DIR/unaligned_references.rs:84:17 | LL | let _ = &good.data as *const _; | ^^^^^^^^^^ @@ -69,7 +69,7 @@ LL | let _ = &good.data as *const _; = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:61:27 + --> $DIR/unaligned_references.rs:85:27 | LL | let _: *const _ = &good.data; | ^^^^^^^^^^ @@ -79,7 +79,7 @@ LL | let _: *const _ = &good.data; = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:63:17 + --> $DIR/unaligned_references.rs:87:17 | LL | let _ = good.data.clone(); | ^^^^^^^^^ @@ -89,7 +89,7 @@ LL | let _ = good.data.clone(); = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:65:17 + --> $DIR/unaligned_references.rs:89:17 | LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ @@ -99,7 +99,7 @@ LL | let _ = &good.data2[0]; = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:74:17 + --> $DIR/unaligned_references.rs:98:17 | LL | let _ = &packed2.x; | ^^^^^^^^^^ @@ -109,7 +109,7 @@ LL | let _ = &packed2.x; = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:113:20 + --> $DIR/unaligned_references.rs:137:20 | LL | let _ref = &m1.1.a; | ^^^^^^^ @@ -119,7 +119,7 @@ LL | let _ref = &m1.1.a; = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error[E0793]: reference to packed field is unaligned - --> $DIR/unaligned_references.rs:116:20 + --> $DIR/unaligned_references.rs:140:20 | LL | let _ref = &m2.1.a; | ^^^^^^^ diff --git a/tests/ui/lint/unaligned_references.next.stderr b/tests/ui/lint/unaligned_references.next.stderr new file mode 100644 index 0000000000000..0f980c5301f37 --- /dev/null +++ b/tests/ui/lint/unaligned_references.next.stderr @@ -0,0 +1,133 @@ +error[E0793]: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:32:13 + | +LL | &self.x; + | ^^^^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:44:24 + | +LL | println!("{:?}", &*foo.0); + | ^^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:46:24 + | +LL | println!("{:?}", &*foo.0); + | ^^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:51:24 + | +LL | println!("{:?}", &*foo.0); + | ^^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:81:17 + | +LL | let _ = &good.ptr; + | ^^^^^^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:82:17 + | +LL | let _ = &good.data; + | ^^^^^^^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:84:17 + | +LL | let _ = &good.data as *const _; + | ^^^^^^^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:85:27 + | +LL | let _: *const _ = &good.data; + | ^^^^^^^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:87:17 + | +LL | let _ = good.data.clone(); + | ^^^^^^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:89:17 + | +LL | let _ = &good.data2[0]; + | ^^^^^^^^^^^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:98:17 + | +LL | let _ = &packed2.x; + | ^^^^^^^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:137:20 + | +LL | let _ref = &m1.1.a; + | ^^^^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error[E0793]: reference to packed field is unaligned + --> $DIR/unaligned_references.rs:140:20 + | +LL | let _ref = &m2.1.a; + | ^^^^^^^ + | + = note: packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses + = note: creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + +error: aborting due to 13 previous errors + +For more information about this error, try `rustc --explain E0793`. diff --git a/tests/ui/lint/unaligned_references.rs b/tests/ui/lint/unaligned_references.rs index 3f6dab35475e8..321e3ed135c47 100644 --- a/tests/ui/lint/unaligned_references.rs +++ b/tests/ui/lint/unaligned_references.rs @@ -1,5 +1,9 @@ -use std::mem::ManuallyDrop; +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + use std::fmt::Debug; +use std::mem::ManuallyDrop; #[repr(packed)] pub struct Good { @@ -50,6 +54,26 @@ fn packed_dyn() { println!("{:?}", &*foo.0); // no error! } +// Test for #115396 +fn packed_slice_behind_alias() { + trait Mirror { + type Assoc: ?Sized; + } + impl Mirror for T { + type Assoc = T; + } + + struct W(::Assoc); + + #[repr(packed)] + struct Unaligned(ManuallyDrop>); + + // Even if the actual alignment is 1, we cannot know that when looking at `dyn Debug.` + let ref local: Unaligned<[_; 3]> = Unaligned(ManuallyDrop::new(W([3, 5, 8u8]))); + let foo: &Unaligned<[u8]> = local; + let x = &foo.0; // Fine, since the tail of `foo` is `[_]` +} + fn main() { unsafe { let good = Good { data: 0, ptr: &0, data2: [0, 0], aligned: [0; 32] };