about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-08-05 15:53:37 -0400
committerMichael Goulet <michael@errs.io>2024-08-08 11:58:11 -0400
commitd9dd5509dcf56b22b6c1844ed3077f292e4a87bf (patch)
tree18f92baeaa701a96bf4d56d47bde5e5570012e25
parent85b5e42d5e5d53b828a55bb01676bbdc495e5077 (diff)
downloadrust-d9dd5509dcf56b22b6c1844ed3077f292e4a87bf.tar.gz
rust-d9dd5509dcf56b22b6c1844ed3077f292e4a87bf.zip
Normalize when computing offset_of for slice tail
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs13
-rw-r--r--tests/ui/offset-of/offset-of-slice-normalized.rs37
2 files changed, 48 insertions, 2 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 8c1aa66332f..841d25b54cc 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -404,8 +404,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         code: traits::ObligationCauseCode<'tcx>,
     ) {
         if !ty.references_error() {
-            let tail =
-                self.tcx.struct_tail_with_normalize(ty, |ty| self.normalize(span, ty), || {});
+            let tail = self.tcx.struct_tail_with_normalize(
+                ty,
+                |ty| {
+                    if self.next_trait_solver() {
+                        self.try_structurally_resolve_type(span, ty)
+                    } else {
+                        self.normalize(span, ty)
+                    }
+                },
+                || {},
+            );
             // Sized types have static alignment, and so do slices.
             if tail.is_trivially_sized(self.tcx) || matches!(tail.kind(), ty::Slice(..)) {
                 // Nothing else is required here.
diff --git a/tests/ui/offset-of/offset-of-slice-normalized.rs b/tests/ui/offset-of/offset-of-slice-normalized.rs
new file mode 100644
index 00000000000..9d1fd9dd2ee
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-slice-normalized.rs
@@ -0,0 +1,37 @@
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+//@ run-pass
+
+#![feature(offset_of_slice)]
+
+use std::mem::offset_of;
+
+trait Mirror {
+    type Assoc: ?Sized;
+}
+impl<T: ?Sized> Mirror for T {
+    type Assoc = T;
+}
+
+#[repr(C)]
+struct S {
+    a: u8,
+    b: (u8, u8),
+    c: <[i32] as Mirror>::Assoc,
+}
+
+#[repr(C)]
+struct T {
+    x: i8,
+    y: S,
+}
+
+type Tup = (i16, <[i32] as Mirror>::Assoc);
+
+fn main() {
+    assert_eq!(offset_of!(S, c), 4);
+    assert_eq!(offset_of!(T, y), 4);
+    assert_eq!(offset_of!(T, y.c), 8);
+    assert_eq!(offset_of!(Tup, 1), 4);
+}