Generalize `get_nullable_type` to allow types where null is all-ones.

Generalize get_nullable_type to accept types that have an all-ones bit
pattern as their sentry "null" value.

This will allow [`OwnedFd`], [`BorrowedFd`], [`OwnedSocket`], and
[`BorrowedSocket`] to be marked with
`#[rustc_nonnull_optimization_guaranteed]`, which will allow
`Option<OwnedFd>`, `Option<BorrowedFd>`, `Option<OwnedSocket>`, and
`Option<BorrowedSocket>` to be used in FFI declarations, as described
in the [I/O safety RFC].

For example, it will allow a function like `open` on Unix and `WSASocketW`
on Windows to be declared using `Option<OwnedFd>` and `Option<OwnedSocket>`
return types, respectively.

The actual change to add `#[rustc_nonnull_optimization_guaranteed]`
to the abovementioned types will be a separate PR, as it'll depend on
having this patch in the stage0 compiler.

Also, update the diagnostics to mention that "niche optimizations" are
used in libstd as well as libcore, as `rustc_layout_scalar_valid_range_start`
and `rustc_layout_scalar_valid_range_end` are already in use in libstd.

[`OwnedFd`]: c9dc44be24/library/std/src/os/fd/owned.rs (L49)
[`BorrowedFd`]: c9dc44be24/library/std/src/os/fd/owned.rs (L29)
[`OwnedSocket`]: c9dc44be24/library/std/src/os/windows/io/socket.rs (L51)
[`BorrowedSocket`]: c9dc44be24/library/std/src/os/windows/io/socket.rs (L29)
[I/O safety RFC]: https://github.com/rust-lang/rfcs/blob/master/text/3128-io-safety.md#ownedfd-and-borrowedfdfd-1
This commit is contained in:
Dan Gohman 2022-03-03 14:41:10 -08:00
parent 10913c0001
commit 86b4658c56
4 changed files with 8 additions and 6 deletions

View File

@ -606,17 +606,17 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
rustc_attr!( rustc_attr!(
rustc_layout_scalar_valid_range_start, Normal, template!(List: "value"), ErrorFollowing, rustc_layout_scalar_valid_range_start, Normal, template!(List: "value"), ErrorFollowing,
"the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \ "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \
niche optimizations in libcore and will never be stable", niche optimizations in libcore and libstd and will never be stable",
), ),
rustc_attr!( rustc_attr!(
rustc_layout_scalar_valid_range_end, Normal, template!(List: "value"), ErrorFollowing, rustc_layout_scalar_valid_range_end, Normal, template!(List: "value"), ErrorFollowing,
"the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \ "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \
niche optimizations in libcore and will never be stable", niche optimizations in libcore and libstd and will never be stable",
), ),
rustc_attr!( rustc_attr!(
rustc_nonnull_optimization_guaranteed, Normal, template!(Word), WarnFollowing, rustc_nonnull_optimization_guaranteed, Normal, template!(Word), WarnFollowing,
"the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable \ "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable \
niche optimizations in libcore and will never be stable", niche optimizations in libcore and libstd and will never be stable",
), ),
// ========================================================================== // ==========================================================================

View File

@ -795,7 +795,9 @@ crate fn repr_nullable_ptr<'tcx>(
let field_ty_abi = &cx.layout_of(field_ty).unwrap().abi; let field_ty_abi = &cx.layout_of(field_ty).unwrap().abi;
if let Abi::Scalar(field_ty_scalar) = field_ty_abi { if let Abi::Scalar(field_ty_scalar) = field_ty_abi {
match (field_ty_scalar.valid_range.start, field_ty_scalar.valid_range.end) { match (field_ty_scalar.valid_range.start, field_ty_scalar.valid_range.end) {
(0, _) => unreachable!("Non-null optimisation extended to a non-zero value."), (0, x) if x == field_ty_scalar.value.size(&cx.tcx).unsigned_int_max() - 1 => {
return Some(get_nullable_type(cx, field_ty).unwrap());
}
(1, _) => { (1, _) => {
return Some(get_nullable_type(cx, field_ty).unwrap()); return Some(get_nullable_type(cx, field_ty).unwrap());
} }

View File

@ -2,6 +2,6 @@
#[rustc_variance] //~ ERROR the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable #[rustc_variance] //~ ERROR the `#[rustc_variance]` attribute is just used for rustc unit tests and will never be stable
#[rustc_error] //~ ERROR the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable #[rustc_error] //~ ERROR the `#[rustc_error]` attribute is just used for rustc unit tests and will never be stable
#[rustc_nonnull_optimization_guaranteed] //~ ERROR the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable niche optimizations in libcore and will never be stable #[rustc_nonnull_optimization_guaranteed] //~ ERROR the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable niche optimizations in libcore and libstd and will never be stable
fn main() {} fn main() {}

View File

@ -14,7 +14,7 @@ LL | #[rustc_error]
| |
= help: add `#![feature(rustc_attrs)]` to the crate attributes to enable = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
error[E0658]: the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable niche optimizations in libcore and will never be stable error[E0658]: the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable niche optimizations in libcore and libstd and will never be stable
--> $DIR/feature-gate-rustc-attrs-1.rs:5:1 --> $DIR/feature-gate-rustc-attrs-1.rs:5:1
| |
LL | #[rustc_nonnull_optimization_guaranteed] LL | #[rustc_nonnull_optimization_guaranteed]