summaryrefslogtreecommitdiffstats
path: root/tests/ui/structs-enums
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/structs-enums')
-rw-r--r--tests/ui/structs-enums/issue-103869.fixed13
-rw-r--r--tests/ui/structs-enums/issue-103869.rs13
-rw-r--r--tests/ui/structs-enums/issue-103869.stderr17
-rw-r--r--tests/ui/structs-enums/type-sizes.rs67
4 files changed, 109 insertions, 1 deletions
diff --git a/tests/ui/structs-enums/issue-103869.fixed b/tests/ui/structs-enums/issue-103869.fixed
new file mode 100644
index 000000000..49fe32c71
--- /dev/null
+++ b/tests/ui/structs-enums/issue-103869.fixed
@@ -0,0 +1,13 @@
+// run-rustfix
+
+struct VecOrMap {
+ //~^ HELP: perhaps you meant to use `struct` here
+ vec: Vec<usize>,
+ //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `:`
+ //~| HELP: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
+}
+
+fn main() {
+ let o = VecOrMap { vec: vec![1, 2, 3] };
+ println!("{:?}", o.vec);
+}
diff --git a/tests/ui/structs-enums/issue-103869.rs b/tests/ui/structs-enums/issue-103869.rs
new file mode 100644
index 000000000..729079e05
--- /dev/null
+++ b/tests/ui/structs-enums/issue-103869.rs
@@ -0,0 +1,13 @@
+// run-rustfix
+
+enum VecOrMap {
+ //~^ HELP: perhaps you meant to use `struct` here
+ vec: Vec<usize>,
+ //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `:`
+ //~| HELP: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
+}
+
+fn main() {
+ let o = VecOrMap { vec: vec![1, 2, 3] };
+ println!("{:?}", o.vec);
+}
diff --git a/tests/ui/structs-enums/issue-103869.stderr b/tests/ui/structs-enums/issue-103869.stderr
new file mode 100644
index 000000000..4665ebf89
--- /dev/null
+++ b/tests/ui/structs-enums/issue-103869.stderr
@@ -0,0 +1,17 @@
+error: expected one of `(`, `,`, `=`, `{`, or `}`, found `:`
+ --> $DIR/issue-103869.rs:5:8
+ |
+LL | enum VecOrMap {
+ | -------- while parsing this enum
+LL |
+LL | vec: Vec<usize>,
+ | ^ expected one of `(`, `,`, `=`, `{`, or `}`
+ |
+ = help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
+help: perhaps you meant to use `struct` here
+ |
+LL | struct VecOrMap {
+ | ~~~~~~
+
+error: aborting due to previous error
+
diff --git a/tests/ui/structs-enums/type-sizes.rs b/tests/ui/structs-enums/type-sizes.rs
index 63e2f3150..406e5c844 100644
--- a/tests/ui/structs-enums/type-sizes.rs
+++ b/tests/ui/structs-enums/type-sizes.rs
@@ -4,9 +4,14 @@
#![allow(dead_code)]
#![feature(never_type)]
#![feature(pointer_is_aligned)]
+#![feature(ptr_from_ref)]
+#![feature(strict_provenance)]
use std::mem::size_of;
-use std::num::NonZeroU8;
+use std::num::{NonZeroU8, NonZeroU16};
+use std::ptr;
+use std::ptr::NonNull;
+use std::borrow::Cow;
struct t {a: u8, b: i8}
struct u {a: u8, b: i8, c: u8}
@@ -181,6 +186,41 @@ struct Reorder2 {
ary: [u8; 6],
}
+// We want the niche in the front, which means we can't treat the array as quasi-aligned more than
+// 4 bytes even though we also want to place it at an 8-aligned offset where possible.
+// So the ideal layout would look like: (char, u32, [u8; 8], u8)
+// The current layout algorithm does (char, [u8; 8], u32, u8)
+#[repr(align(8))]
+struct ReorderWithNiche {
+ a: u32,
+ b: char,
+ c: u8,
+ ary: [u8; 8]
+}
+
+#[repr(C)]
+struct EndNiche8([u8; 7], bool);
+
+#[repr(C)]
+struct MiddleNiche4(u8, u8, bool, u8);
+
+struct ReorderEndNiche {
+ a: EndNiche8,
+ b: MiddleNiche4,
+}
+
+
+// standins for std types which we want to be laid out in a reasonable way
+struct RawVecDummy {
+ ptr: NonNull<u8>,
+ cap: usize,
+}
+
+struct VecDummy {
+ r: RawVecDummy,
+ len: usize,
+}
+
pub fn main() {
assert_eq!(size_of::<u8>(), 1 as usize);
assert_eq!(size_of::<u32>(), 4 as usize);
@@ -270,4 +310,29 @@ pub fn main() {
let v = Reorder2 {a: 0, b: 0, ary: [0; 6]};
assert_eq!(size_of::<Reorder2>(), 10);
assert!((&v.ary).as_ptr().is_aligned_to(2), "[u8; 6] should group with align-2 fields");
+
+ let v = VecDummy { r: RawVecDummy { ptr: NonNull::dangling(), cap: 0 }, len: 1 };
+ assert_eq!(ptr::from_ref(&v), ptr::from_ref(&v.r.ptr).cast(),
+ "sort niches to the front where possible");
+
+ // Ideal layouts: (bool, u8, NonZeroU16) or (NonZeroU16, u8, bool)
+ // Currently the layout algorithm will choose the latter because it doesn't attempt
+ // to aggregate multiple smaller fields to move a niche before a higher-alignment one.
+ let b = BoolInTheMiddle( NonZeroU16::new(1).unwrap(), true, 0);
+ assert!(ptr::from_ref(&b.1).addr() > ptr::from_ref(&b.2).addr());
+
+ assert_eq!(size_of::<Cow<'static, str>>(), size_of::<String>());
+
+ let v = ReorderWithNiche {a: 0, b: ' ', c: 0, ary: [0; 8]};
+ assert!((&v.ary).as_ptr().is_aligned_to(4),
+ "here [u8; 8] should group with _at least_ align-4 fields");
+ assert_eq!(ptr::from_ref(&v), ptr::from_ref(&v.b).cast(),
+ "sort niches to the front where possible");
+
+ // Neither field has a niche at the beginning so the layout algorithm should try move niches to
+ // the end which means the 8-sized field shouldn't be alignment-promoted before the 4-sized one.
+ let v = ReorderEndNiche { a: EndNiche8([0; 7], false), b: MiddleNiche4(0, 0, false, 0) };
+ assert!(ptr::from_ref(&v.a).addr() > ptr::from_ref(&v.b).addr());
+
+
}