Skip to content

Commit

Permalink
Auto merge of #74699 - notriddle:fd-non-negative, r=m-ou-se
Browse files Browse the repository at this point in the history
Mark `-1` as an available niche for file descriptors

Based on discussion from <https://internals.rust-lang.org/t/can-the-standard-library-shrink-option-file/12768>, the file descriptor `-1` is chosen based on the POSIX API designs that use it as a sentinel to report errors. A bigger niche could've been chosen, particularly on Linux, but would not necessarily be portable.

This PR also adds a test case to ensure that the -1 niche (which is kind of hacky and has no obvious test case) works correctly. It requires the "upper" bound, which is actually -1, to be expressed in two's complement.
  • Loading branch information
bors committed Dec 20, 2020
2 parents 2ad5292 + 094b1da commit b0e5c7d
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 6 deletions.
9 changes: 8 additions & 1 deletion library/std/src/sys/unix/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sys/unix/fd/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
16 changes: 12 additions & 4 deletions src/test/ui/print_type_sizes/niche-filling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
}
Expand Down Expand Up @@ -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
}
6 changes: 6 additions & 0 deletions src/test/ui/print_type_sizes/niche-filling.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit b0e5c7d

Please sign in to comment.