about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/std/src/sys/unix/fd.rs9
-rw-r--r--library/std/src/sys/unix/fd/tests.rs2
-rw-r--r--src/test/ui/print_type_sizes/niche-filling.rs16
-rw-r--r--src/test/ui/print_type_sizes/niche-filling.stdout6
4 files changed, 27 insertions, 6 deletions
diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs
index d3a279a2355..821851a6c65 100644
--- a/library/std/src/sys/unix/fd.rs
+++ b/library/std/src/sys/unix/fd.rs
@@ -12,6 +12,11 @@ use crate::sys_common::AsInner;
 use libc::{c_int, c_void};
 
 #[derive(Debug)]
+#[rustc_layout_scalar_valid_range_start(0)]
+// libstd/os/raw/mod.rs assures me that every libstd-supported platform has a
+// 32-bit c_int. Below is -2, in two's complement, but that only works out
+// because c_int is 32 bits.
+#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
 pub struct FileDesc {
     fd: c_int,
 }
@@ -63,7 +68,9 @@ const fn max_iov() -> usize {
 
 impl FileDesc {
     pub fn new(fd: c_int) -> FileDesc {
-        FileDesc { fd }
+        assert_ne!(fd, -1i32);
+        // SAFETY: we just asserted that the value is in the valid range and isn't `-1` (the only value bigger than `0xFF_FF_FF_FE` unsigned)
+        unsafe { FileDesc { fd } }
     }
 
     pub fn raw(&self) -> c_int {
diff --git a/library/std/src/sys/unix/fd/tests.rs b/library/std/src/sys/unix/fd/tests.rs
index a932043cbc6..c9520485c3c 100644
--- a/library/std/src/sys/unix/fd/tests.rs
+++ b/library/std/src/sys/unix/fd/tests.rs
@@ -3,7 +3,7 @@ use core::mem::ManuallyDrop;
 
 #[test]
 fn limit_vector_count() {
-    let stdout = ManuallyDrop::new(FileDesc { fd: 1 });
+    let stdout = ManuallyDrop::new(unsafe { FileDesc { fd: 1 } });
     let bufs = (0..1500).map(|_| IoSlice::new(&[])).collect::<Vec<_>>();
     assert!(stdout.write_vectored(&bufs).is_ok());
 }
diff --git a/src/test/ui/print_type_sizes/niche-filling.rs b/src/test/ui/print_type_sizes/niche-filling.rs
index 37ac45f7e05..0716cee21c6 100644
--- a/src/test/ui/print_type_sizes/niche-filling.rs
+++ b/src/test/ui/print_type_sizes/niche-filling.rs
@@ -15,12 +15,19 @@
 // padding and overall computed sizes can be quite different.
 
 #![feature(start)]
+#![feature(rustc_attrs)]
 #![allow(dead_code)]
 
 use std::num::NonZeroU32;
 
 pub enum MyOption<T> { None, Some(T) }
 
+#[rustc_layout_scalar_valid_range_start(0)]
+#[rustc_layout_scalar_valid_range_end(0xFF_FF_FF_FE)]
+pub struct MyNotNegativeOne {
+  _i: i32,
+}
+
 impl<T> Default for MyOption<T> {
     fn default() -> Self { MyOption::None }
 }
@@ -77,17 +84,18 @@ fn start(_: isize, _: *const *const u8) -> isize {
     let _a: MyOption<bool> = Default::default();
     let _b: MyOption<char> = Default::default();
     let _c: MyOption<std::cmp::Ordering> = Default::default();
-    let _b: MyOption<MyOption<u8>> = Default::default();
+    let _d: MyOption<MyOption<u8>> = Default::default();
     let _e: Enum4<(), char, (), ()> = Enum4::One(());
     let _f: Enum4<(), (), bool, ()> = Enum4::One(());
     let _g: Enum4<(), (), (), MyOption<u8>> = Enum4::One(());
+    let _h: MyOption<MyNotNegativeOne> = Default::default();
 
     // Unions do not currently participate in niche filling.
-    let _h: MyOption<Union2<NonZeroU32, u32>> = Default::default();
+    let _i: MyOption<Union2<NonZeroU32, u32>> = Default::default();
 
     // ...even when theoretically possible.
-    let _i: MyOption<Union1<NonZeroU32>> = Default::default();
-    let _j: MyOption<Union2<NonZeroU32, NonZeroU32>> = Default::default();
+    let _j: MyOption<Union1<NonZeroU32>> = Default::default();
+    let _k: MyOption<Union2<NonZeroU32, NonZeroU32>> = Default::default();
 
     0
 }
diff --git a/src/test/ui/print_type_sizes/niche-filling.stdout b/src/test/ui/print_type_sizes/niche-filling.stdout
index 1894cd218ee..d1753c26ca8 100644
--- a/src/test/ui/print_type_sizes/niche-filling.stdout
+++ b/src/test/ui/print_type_sizes/niche-filling.stdout
@@ -43,6 +43,12 @@ print-type-size     variant `Three`: 0 bytes
 print-type-size         field `.0`: 0 bytes
 print-type-size     variant `Four`: 0 bytes
 print-type-size         field `.0`: 0 bytes
+print-type-size type: `MyNotNegativeOne`: 4 bytes, alignment: 4 bytes
+print-type-size     field `._i`: 4 bytes
+print-type-size type: `MyOption<MyNotNegativeOne>`: 4 bytes, alignment: 4 bytes
+print-type-size     variant `Some`: 4 bytes
+print-type-size         field `.0`: 4 bytes
+print-type-size     variant `None`: 0 bytes
 print-type-size type: `MyOption<char>`: 4 bytes, alignment: 4 bytes
 print-type-size     variant `Some`: 4 bytes
 print-type-size         field `.0`: 4 bytes