From d9dd5509dcf56b22b6c1844ed3077f292e4a87bf Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 5 Aug 2024 15:53:37 -0400 Subject: [PATCH] Normalize when computing offset_of for slice tail --- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 13 ++++++- .../offset-of/offset-of-slice-normalized.rs | 37 +++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 tests/ui/offset-of/offset-of-slice-normalized.rs 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 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); +}