From edcb7aba6b75444aabc309dd5564df8f9eab8937 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 11 Dec 2023 13:45:03 +0100 Subject: [PATCH] also test projecting to some sized fields at non-zero offset in structs with an extern type tail --- .../issue-91827-extern-types-field-offset.rs | 7 ++++++- .../issue-91827-extern-types-field-offset.stderr | 2 +- tests/ui/extern/extern-types-field-offset.rs | 12 +++++++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.rs b/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.rs index 0a6d31204b774..c6960fa7259db 100644 --- a/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.rs +++ b/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.rs @@ -13,7 +13,8 @@ struct Newtype(Opaque); struct S { i: i32, - a: Opaque, + j: i32, + a: Newtype, } const NEWTYPE: () = unsafe { @@ -28,6 +29,10 @@ const OFFSET: () = unsafe { let buf = [0i32; 4]; let x: &S = &*(&buf as *const _ as *const S); + // Accessing sized fields is perfectly fine, even at non-zero offsets. + let field = &x.i; + let field = &x.j; + // This needs to compute the field offset, but we don't know the type's alignment, so this // fails. let field = &x.a; diff --git a/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr b/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr index a45c548584e08..99f37fedd3dd3 100644 --- a/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr +++ b/tests/ui/consts/const-eval/issue-91827-extern-types-field-offset.stderr @@ -1,5 +1,5 @@ error[E0080]: evaluation of constant value failed - --> $DIR/issue-91827-extern-types-field-offset.rs:33:17 + --> $DIR/issue-91827-extern-types-field-offset.rs:38:17 | LL | let field = &x.a; | ^^^^ `extern type` does not have a known offset diff --git a/tests/ui/extern/extern-types-field-offset.rs b/tests/ui/extern/extern-types-field-offset.rs index 9c364538025d1..bfbc1e9bffacf 100644 --- a/tests/ui/extern/extern-types-field-offset.rs +++ b/tests/ui/extern/extern-types-field-offset.rs @@ -12,16 +12,22 @@ struct Newtype(Opaque); struct S { i: i32, - a: Opaque, + j: i32, + a: Newtype, } fn main() { + let buf = [0i32; 4]; + + let x: &Newtype = unsafe { &*(&buf as *const _ as *const Newtype) }; // Projecting to the newtype works, because it is always at offset 0. - let x: &Newtype = unsafe { &*(1usize as *const Newtype) }; let field = &x.0; + let x: &S = unsafe { &*(&buf as *const _ as *const S) }; + // Accessing sized fields is perfectly fine, even at non-zero offsets. + let field = &x.i; + let field = &x.j; // This needs to compute the field offset, but we don't know the type's alignment, // so this panics. - let x: &S = unsafe { &*(1usize as *const S) }; let field = &x.a; }