mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Prefer -1 for None
Currently we pick "weird" numbers like `1114112` for `None::<char>`. While that's not *wrong*, it's kinda *unnatural* -- a human wouldn't make that choice. This PR instead picks `-1` for thinge like `None::<char>` -- like clang's `WEOF` -- and `None::<bool>` and such. Any enums with more than one niched value (so not `Result` nor `Option`) remain as they were before.
This commit is contained in:
@@ -2051,8 +2051,7 @@ pub fn reserve<C: HasDataLayout>(&self, cx: &C, count: u128) -> Option<(u128, Sc
|
||||
assert!(size.bits() <= 128);
|
||||
let max_value = size.unsigned_int_max();
|
||||
|
||||
let niche = v.end.wrapping_add(1)..v.start;
|
||||
let available = niche.end.wrapping_sub(niche.start) & max_value;
|
||||
let available = v.start.wrapping_sub(v.end).wrapping_sub(1) & max_value;
|
||||
if count > available {
|
||||
return None;
|
||||
}
|
||||
@@ -2080,7 +2079,17 @@ pub fn reserve<C: HasDataLayout>(&self, cx: &C, count: u128) -> Option<(u128, Sc
|
||||
Some((start, Scalar::Initialized { value, valid_range: v.with_end(end) }))
|
||||
};
|
||||
let distance_end_zero = max_value - v.end;
|
||||
if v.start > v.end {
|
||||
// FIXME: this ought to work for `bool` too, but that seems to be hitting a miscompilation
|
||||
// <https://github.com/rust-lang/rust/pull/155473#issuecomment-4302036343>
|
||||
if count == 1 && v != (WrappingRange { start: 0, end: 1 }) {
|
||||
// We only need one, so just pick the one closest to zero.
|
||||
// Not only does that obviously use zero if it's possible, but it also
|
||||
// simplifies testing things like `Option<char>`, since looking for `-1`
|
||||
// is easier than looking for `1114112` (and matches clang's `WEOF`).
|
||||
let next_up = size.sign_extend(v.end.wrapping_add(1)).unsigned_abs();
|
||||
let next_down = size.sign_extend(v.start.wrapping_sub(1)).unsigned_abs();
|
||||
if next_down <= next_up { move_start(v) } else { move_end(v) }
|
||||
} else if v.start > v.end {
|
||||
// zero is unavailable because wrapping occurs
|
||||
move_end(v)
|
||||
} else if v.start <= distance_end_zero {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
//@ only-64bit
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(pattern_types, pattern_type_macro)]
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::num::NonZero;
|
||||
@@ -123,3 +124,14 @@ fn make_fully_uninhabited_result(v: u32, n: Never) -> Result<(u32, Never), (Neve
|
||||
}
|
||||
|
||||
enum Never {}
|
||||
|
||||
#[repr(transparent)]
|
||||
struct NewtypeIndex(std::pat::pattern_type!(u32 is 0..=0xFFFFFF00));
|
||||
|
||||
#[no_mangle]
|
||||
pub fn make_none_newtype_index() -> Option<NewtypeIndex> {
|
||||
// CHECK-LABEL: @make_none_newtype_index
|
||||
// CHECK-NEXT: start:
|
||||
// CHECK-NEXT: ret i32 -1
|
||||
None
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ pub fn opt_bool_eq_discr(a: Option<bool>, b: Option<bool>) -> bool {
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn opt_ord_eq_discr(a: Option<Ordering>, b: Option<Ordering>) -> bool {
|
||||
// CHECK-LABEL: @opt_ord_eq_discr(
|
||||
// CHECK: %[[A:.+]] = icmp ne i8 %a, 2
|
||||
// CHECK: %[[B:.+]] = icmp eq i8 %b, 2
|
||||
// CHECK: %[[A:.+]] = icmp ne i8 %a, -2
|
||||
// CHECK: %[[B:.+]] = icmp eq i8 %b, -2
|
||||
// CHECK: %[[R:.+]] = xor i1 %[[A]], %[[B]]
|
||||
// CHECK: ret i1 %[[R]]
|
||||
|
||||
@@ -58,8 +58,8 @@ pub fn opt_nz32_eq_discr(a: Option<NonZero<u32>>, b: Option<NonZero<u32>>) -> bo
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn opt_ac_eq_discr(a: Option<AC>, b: Option<AC>) -> bool {
|
||||
// CHECK-LABEL: @opt_ac_eq_discr(
|
||||
// CHECK: %[[A:.+]] = icmp ne i8 %a, -128
|
||||
// CHECK: %[[B:.+]] = icmp eq i8 %b, -128
|
||||
// CHECK: %[[A:.+]] = icmp ne i8 %a, -1
|
||||
// CHECK: %[[B:.+]] = icmp eq i8 %b, -1
|
||||
// CHECK: %[[R:.+]] = xor i1 %[[A]], %[[B]]
|
||||
// CHECK: ret i1 %[[R]]
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ pub fn option_bool_match(x: Option<bool>) -> char {
|
||||
#[no_mangle]
|
||||
pub fn option_ordering_match(x: Option<Ordering>) -> char {
|
||||
// CHECK: %[[RAW:.+]] = load i8, ptr %x
|
||||
// CHECK: %[[IS_NONE:.+]] = icmp eq i8 %[[RAW]], 2
|
||||
// CHECK: %[[IS_NONE:.+]] = icmp eq i8 %[[RAW]], -2
|
||||
// CHECK: %[[OPT_DISCR:.+]] = select i1 %[[IS_NONE]], i64 0, i64 1
|
||||
// CHECK: %[[OPT_DISCR_T:.+]] = trunc nuw i64 %[[OPT_DISCR]] to i1
|
||||
// CHECK: br i1 %[[OPT_DISCR_T]], label %[[BB_SOME:.+]], label %[[BB_NONE:.+]]
|
||||
|
||||
@@ -82,3 +82,14 @@ pub fn bool_eq(l: Option<bool>, r: Option<bool>) -> bool {
|
||||
// CHECK-NEXT: ret i1
|
||||
l == r
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @bool_ref_eq
|
||||
#[no_mangle]
|
||||
pub fn bool_ref_eq(l: &Option<bool>, r: &Option<bool>) -> bool {
|
||||
// CHECK: start:
|
||||
// CHECK-NEXT: load i8
|
||||
// CHECK-NEXT: load i8
|
||||
// CHECK-NEXT: icmp eq i8
|
||||
// CHECK-NEXT: ret i1
|
||||
l == r
|
||||
}
|
||||
|
||||
@@ -745,7 +745,7 @@ error: layout_of(Option<char>) = Layout {
|
||||
I32,
|
||||
false,
|
||||
),
|
||||
valid_range: 0..=1114112,
|
||||
valid_range: (..=1114111) | (4294967295..),
|
||||
},
|
||||
),
|
||||
fields: Arbitrary {
|
||||
@@ -763,7 +763,7 @@ error: layout_of(Option<char>) = Layout {
|
||||
I32,
|
||||
false,
|
||||
),
|
||||
valid_range: 0..=1114112,
|
||||
valid_range: (..=1114111) | (4294967295..),
|
||||
},
|
||||
),
|
||||
uninhabited: false,
|
||||
@@ -773,12 +773,12 @@ error: layout_of(Option<char>) = Layout {
|
||||
I32,
|
||||
false,
|
||||
),
|
||||
valid_range: 0..=1114112,
|
||||
valid_range: (..=1114111) | (4294967295..),
|
||||
},
|
||||
tag_encoding: Niche {
|
||||
untagged_variant: 1,
|
||||
niche_variants: 0..=0,
|
||||
niche_start: 1114112,
|
||||
niche_start: 4294967295,
|
||||
},
|
||||
tag_field: 0,
|
||||
variants: [
|
||||
|
||||
@@ -370,7 +370,7 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
|
||||
I16,
|
||||
false,
|
||||
),
|
||||
valid_range: 0..=1,
|
||||
valid_range: (..=0) | (65535..),
|
||||
},
|
||||
),
|
||||
uninhabited: false,
|
||||
@@ -380,12 +380,12 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
|
||||
I16,
|
||||
false,
|
||||
),
|
||||
valid_range: 0..=1,
|
||||
valid_range: (..=0) | (65535..),
|
||||
},
|
||||
tag_encoding: Niche {
|
||||
untagged_variant: 1,
|
||||
niche_variants: 0..=0,
|
||||
niche_start: 1,
|
||||
niche_start: 65535,
|
||||
},
|
||||
tag_field: 0,
|
||||
variants: [
|
||||
|
||||
@@ -57,7 +57,7 @@ error: layout_of(Option<(*const ()) is !null>) = Layout {
|
||||
0,
|
||||
),
|
||||
),
|
||||
valid_range: (..=0) | (1..),
|
||||
valid_range: 0..=18446744073709551615,
|
||||
},
|
||||
),
|
||||
fields: Arbitrary {
|
||||
@@ -77,7 +77,7 @@ error: layout_of(Option<(*const ()) is !null>) = Layout {
|
||||
0,
|
||||
),
|
||||
),
|
||||
valid_range: (..=0) | (1..),
|
||||
valid_range: 0..=18446744073709551615,
|
||||
},
|
||||
tag_encoding: Niche {
|
||||
untagged_variant: 1,
|
||||
|
||||
@@ -99,7 +99,7 @@ error: layout_of(Option<(u32) is 1..>) = Layout {
|
||||
I32,
|
||||
false,
|
||||
),
|
||||
valid_range: (..=0) | (1..),
|
||||
valid_range: 0..=4294967295,
|
||||
},
|
||||
),
|
||||
fields: Arbitrary {
|
||||
@@ -118,7 +118,7 @@ error: layout_of(Option<(u32) is 1..>) = Layout {
|
||||
I32,
|
||||
false,
|
||||
),
|
||||
valid_range: (..=0) | (1..),
|
||||
valid_range: 0..=4294967295,
|
||||
},
|
||||
tag_encoding: Niche {
|
||||
untagged_variant: 1,
|
||||
@@ -210,7 +210,7 @@ error: layout_of(Option<NonZero<u32>>) = Layout {
|
||||
I32,
|
||||
false,
|
||||
),
|
||||
valid_range: (..=0) | (1..),
|
||||
valid_range: 0..=4294967295,
|
||||
},
|
||||
),
|
||||
fields: Arbitrary {
|
||||
@@ -229,7 +229,7 @@ error: layout_of(Option<NonZero<u32>>) = Layout {
|
||||
I32,
|
||||
false,
|
||||
),
|
||||
valid_range: (..=0) | (1..),
|
||||
valid_range: 0..=4294967295,
|
||||
},
|
||||
tag_encoding: Niche {
|
||||
untagged_variant: 1,
|
||||
|
||||
Reference in New Issue
Block a user