Add not-null pointer patterns to pattern types
This commit is contained in:
@@ -2579,6 +2579,9 @@ pub enum TyPatKind {
|
||||
/// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
|
||||
Range(Option<Box<AnonConst>>, Option<Box<AnonConst>>, Spanned<RangeEnd>),
|
||||
|
||||
/// A `!null` pattern for raw pointers.
|
||||
NotNull,
|
||||
|
||||
Or(ThinVec<TyPat>),
|
||||
|
||||
/// Placeholder for a pattern that wasn't syntactically well formed in some way.
|
||||
|
||||
@@ -143,7 +143,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
// return inner to be processed in next loop
|
||||
PatKind::Paren(inner) => pattern = inner,
|
||||
PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span),
|
||||
PatKind::MacCall(_) => {
|
||||
panic!("{pattern:#?} shouldn't exist here")
|
||||
}
|
||||
PatKind::Err(guar) => break hir::PatKind::Err(*guar),
|
||||
}
|
||||
};
|
||||
@@ -460,6 +462,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
)
|
||||
}),
|
||||
),
|
||||
TyPatKind::NotNull => hir::TyPatKind::NotNull,
|
||||
TyPatKind::Or(variants) => {
|
||||
hir::TyPatKind::Or(self.arena.alloc_from_iter(
|
||||
variants.iter().map(|pat| self.lower_ty_pat_mut(pat, base_type)),
|
||||
|
||||
@@ -1232,6 +1232,7 @@ impl<'a> State<'a> {
|
||||
self.print_expr_anon_const(end, &[]);
|
||||
}
|
||||
}
|
||||
rustc_ast::TyPatKind::NotNull => self.word("!null"),
|
||||
rustc_ast::TyPatKind::Or(variants) => {
|
||||
let mut first = true;
|
||||
for pat in variants {
|
||||
|
||||
@@ -30,15 +30,21 @@ fn parse_pat_ty<'a>(
|
||||
let ty = parser.parse_ty()?;
|
||||
parser.expect_keyword(exp!(Is))?;
|
||||
|
||||
let pat = pat_to_ty_pat(
|
||||
cx,
|
||||
parser.parse_pat_no_top_guard(
|
||||
None,
|
||||
RecoverComma::No,
|
||||
RecoverColon::No,
|
||||
CommaRecoveryMode::EitherTupleOrPipe,
|
||||
)?,
|
||||
);
|
||||
let start = parser.token.span;
|
||||
let pat = if parser.eat(exp!(Bang)) {
|
||||
parser.expect_keyword(exp!(Null))?;
|
||||
ty_pat(TyPatKind::NotNull, start.to(parser.token.span))
|
||||
} else {
|
||||
pat_to_ty_pat(
|
||||
cx,
|
||||
parser.parse_pat_no_top_guard(
|
||||
None,
|
||||
RecoverComma::No,
|
||||
RecoverColon::No,
|
||||
CommaRecoveryMode::EitherTupleOrPipe,
|
||||
)?,
|
||||
)
|
||||
};
|
||||
|
||||
if parser.token != token::Eof {
|
||||
parser.unexpected()?;
|
||||
|
||||
@@ -1261,9 +1261,10 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
|
||||
// When you extend this match, make sure to also add tests to
|
||||
// tests/ui/type/pattern_types/validity.rs((
|
||||
match **pat {
|
||||
// Range patterns are precisely reflected into `valid_range` and thus
|
||||
// Range and non-null patterns are precisely reflected into `valid_range` and thus
|
||||
// handled fully by `visit_scalar` (called below).
|
||||
ty::PatternKind::Range { .. } => {},
|
||||
ty::PatternKind::NotNull => {},
|
||||
|
||||
// FIXME(pattern_types): check that the value is covered by one of the variants.
|
||||
// For now, we rely on layout computation setting the scalar's `valid_range` to
|
||||
|
||||
@@ -1854,6 +1854,9 @@ pub enum TyPatKind<'hir> {
|
||||
/// A range pattern (e.g., `1..=2` or `1..2`).
|
||||
Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>),
|
||||
|
||||
/// A pattern that excludes null pointers
|
||||
NotNull,
|
||||
|
||||
/// A list of patterns where only one needs to be satisfied
|
||||
Or(&'hir [TyPat<'hir>]),
|
||||
|
||||
|
||||
@@ -725,7 +725,7 @@ pub fn walk_ty_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v TyPat<'v>)
|
||||
try_visit!(visitor.visit_const_arg_unambig(upper_bound));
|
||||
}
|
||||
TyPatKind::Or(patterns) => walk_list!(visitor, visit_pattern_type_pattern, patterns),
|
||||
TyPatKind::Err(_) => (),
|
||||
TyPatKind::NotNull | TyPatKind::Err(_) => (),
|
||||
}
|
||||
V::Result::output()
|
||||
}
|
||||
|
||||
@@ -2611,6 +2611,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
.span_delayed_bug(ty_span, "invalid base type for range pattern")),
|
||||
}
|
||||
}
|
||||
hir::TyPatKind::NotNull => Ok(ty::PatternKind::NotNull),
|
||||
hir::TyPatKind::Or(patterns) => {
|
||||
self.tcx()
|
||||
.mk_patterns_from_iter(patterns.iter().map(|pat| {
|
||||
|
||||
@@ -340,6 +340,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
self.add_constraints_from_const(current, start, variance);
|
||||
self.add_constraints_from_const(current, end, variance);
|
||||
}
|
||||
ty::PatternKind::NotNull => {}
|
||||
ty::PatternKind::Or(patterns) => {
|
||||
for pat in patterns {
|
||||
self.add_constraints_from_pat(current, variance, pat)
|
||||
|
||||
@@ -1888,6 +1888,10 @@ impl<'a> State<'a> {
|
||||
self.word("..=");
|
||||
self.print_const_arg(end);
|
||||
}
|
||||
TyPatKind::NotNull => {
|
||||
self.word_space("not");
|
||||
self.word("null");
|
||||
}
|
||||
TyPatKind::Or(patterns) => {
|
||||
self.popen();
|
||||
let mut first = true;
|
||||
|
||||
@@ -758,6 +758,7 @@ fn pat_ty_is_known_nonnull<'tcx>(
|
||||
// to ensure we aren't wrapping over zero.
|
||||
start > 0 && end >= start
|
||||
}
|
||||
ty::PatternKind::NotNull => true,
|
||||
ty::PatternKind::Or(patterns) => {
|
||||
patterns.iter().all(|pat| pat_ty_is_known_nonnull(tcx, typing_env, pat))
|
||||
}
|
||||
@@ -918,7 +919,9 @@ fn get_nullable_type_from_pat<'tcx>(
|
||||
pat: ty::Pattern<'tcx>,
|
||||
) -> Option<Ty<'tcx>> {
|
||||
match *pat {
|
||||
ty::PatternKind::Range { .. } => get_nullable_type(tcx, typing_env, base),
|
||||
ty::PatternKind::NotNull | ty::PatternKind::Range { .. } => {
|
||||
get_nullable_type(tcx, typing_env, base)
|
||||
}
|
||||
ty::PatternKind::Or(patterns) => {
|
||||
let first = get_nullable_type_from_pat(tcx, typing_env, base, patterns[0])?;
|
||||
for &pat in &patterns[1..] {
|
||||
|
||||
@@ -30,6 +30,7 @@ impl<'tcx> Flags for Pattern<'tcx> {
|
||||
}
|
||||
flags
|
||||
}
|
||||
ty::PatternKind::NotNull => rustc_type_ir::TypeFlags::empty(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +46,7 @@ impl<'tcx> Flags for Pattern<'tcx> {
|
||||
}
|
||||
idx
|
||||
}
|
||||
ty::PatternKind::NotNull => rustc_type_ir::INNERMOST,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,6 +93,7 @@ impl<'tcx> IrPrint<PatternKind<'tcx>> for TyCtxt<'tcx> {
|
||||
|
||||
write!(f, "..={end}")
|
||||
}
|
||||
PatternKind::NotNull => write!(f, "!null"),
|
||||
PatternKind::Or(patterns) => {
|
||||
write!(f, "(")?;
|
||||
let mut first = true;
|
||||
|
||||
@@ -35,6 +35,7 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for ty::Pattern<'tcx> {
|
||||
let end = relation.relate(end_a, end_b)?;
|
||||
Ok(tcx.mk_pat(ty::PatternKind::Range { start, end }))
|
||||
}
|
||||
(ty::PatternKind::NotNull, ty::PatternKind::NotNull) => Ok(a),
|
||||
(&ty::PatternKind::Or(a), &ty::PatternKind::Or(b)) => {
|
||||
if a.len() != b.len() {
|
||||
return Err(TypeError::Mismatch);
|
||||
@@ -43,7 +44,10 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for ty::Pattern<'tcx> {
|
||||
let patterns = tcx.mk_patterns_from_iter(v)?;
|
||||
Ok(tcx.mk_pat(ty::PatternKind::Or(patterns)))
|
||||
}
|
||||
(ty::PatternKind::Range { .. } | ty::PatternKind::Or(_), _) => Err(TypeError::Mismatch),
|
||||
(
|
||||
ty::PatternKind::NotNull | ty::PatternKind::Range { .. } | ty::PatternKind::Or(_),
|
||||
_,
|
||||
) => Err(TypeError::Mismatch),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,6 +139,7 @@ pub enum TokenType {
|
||||
SymNomem,
|
||||
SymNoreturn,
|
||||
SymNostack,
|
||||
SymNull,
|
||||
SymOptions,
|
||||
SymOut,
|
||||
SymPreservesFlags,
|
||||
@@ -273,6 +274,7 @@ impl TokenType {
|
||||
SymNomem,
|
||||
SymNoreturn,
|
||||
SymNostack,
|
||||
SymNull,
|
||||
SymOptions,
|
||||
SymOut,
|
||||
SymPreservesFlags,
|
||||
@@ -348,6 +350,7 @@ impl TokenType {
|
||||
TokenType::SymNomem => Some(sym::nomem),
|
||||
TokenType::SymNoreturn => Some(sym::noreturn),
|
||||
TokenType::SymNostack => Some(sym::nostack),
|
||||
TokenType::SymNull => Some(sym::null),
|
||||
TokenType::SymOptions => Some(sym::options),
|
||||
TokenType::SymOut => Some(sym::out),
|
||||
TokenType::SymPreservesFlags => Some(sym::preserves_flags),
|
||||
@@ -562,6 +565,7 @@ macro_rules! exp {
|
||||
(Nomem) => { exp!(@sym, nomem, SymNomem) };
|
||||
(Noreturn) => { exp!(@sym, noreturn, SymNoreturn) };
|
||||
(Nostack) => { exp!(@sym, nostack, SymNostack) };
|
||||
(Null) => { exp!(@sym, null, SymNull) };
|
||||
(Options) => { exp!(@sym, options, SymOptions) };
|
||||
(Out) => { exp!(@sym, out, SymOut) };
|
||||
(PreservesFlags) => { exp!(@sym, preserves_flags, SymPreservesFlags) };
|
||||
|
||||
@@ -485,6 +485,7 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> {
|
||||
end: Some(end.stable(tables, cx)),
|
||||
include_end: true,
|
||||
},
|
||||
ty::PatternKind::NotNull => todo!(),
|
||||
ty::PatternKind::Or(_) => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -968,7 +968,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc
|
||||
self.visit_ty_pat(pat)
|
||||
}
|
||||
}
|
||||
TyPatKind::Err(_) => {}
|
||||
TyPatKind::NotNull | TyPatKind::Err(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1554,6 +1554,7 @@ symbols! {
|
||||
not,
|
||||
notable_trait,
|
||||
note,
|
||||
null,
|
||||
nvptx_target_feature,
|
||||
object_safe_for_dispatch,
|
||||
of,
|
||||
|
||||
@@ -266,6 +266,9 @@ impl<'tcx> V0SymbolMangler<'tcx> {
|
||||
self.print_const(start)?;
|
||||
self.print_const(end)?;
|
||||
}
|
||||
ty::PatternKind::NotNull => {
|
||||
self.tcx.types.unit.print(self)?;
|
||||
}
|
||||
ty::PatternKind::Or(patterns) => {
|
||||
self.push("O");
|
||||
for pat in patterns {
|
||||
|
||||
@@ -705,6 +705,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
check(start);
|
||||
check(end);
|
||||
}
|
||||
ty::PatternKind::NotNull => {}
|
||||
ty::PatternKind::Or(patterns) => {
|
||||
for pat in patterns {
|
||||
self.add_wf_preds_for_pat_ty(base_ty, pat)
|
||||
|
||||
@@ -216,9 +216,7 @@ fn layout_of_uncached<'tcx>(
|
||||
let mut layout = LayoutData::clone(&layout.0);
|
||||
match *pat {
|
||||
ty::PatternKind::Range { start, end } => {
|
||||
if let BackendRepr::Scalar(scalar) | BackendRepr::ScalarPair(scalar, _) =
|
||||
&mut layout.backend_repr
|
||||
{
|
||||
if let BackendRepr::Scalar(scalar) = &mut layout.backend_repr {
|
||||
scalar.valid_range_mut().start = extract_const_value(cx, ty, start)?
|
||||
.try_to_bits(tcx, cx.typing_env)
|
||||
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
|
||||
@@ -266,6 +264,25 @@ fn layout_of_uncached<'tcx>(
|
||||
bug!("pattern type with range but not scalar layout: {ty:?}, {layout:?}")
|
||||
}
|
||||
}
|
||||
ty::PatternKind::NotNull => {
|
||||
if let BackendRepr::Scalar(scalar) | BackendRepr::ScalarPair(scalar, _) =
|
||||
&mut layout.backend_repr
|
||||
{
|
||||
scalar.valid_range_mut().start = 1;
|
||||
let niche = Niche {
|
||||
offset: Size::ZERO,
|
||||
value: scalar.primitive(),
|
||||
valid_range: scalar.valid_range(cx),
|
||||
};
|
||||
|
||||
layout.largest_niche = Some(niche);
|
||||
} else {
|
||||
bug!(
|
||||
"pattern type with `!null` pattern but not scalar/pair layout: {ty:?}, {layout:?}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ty::PatternKind::Or(variants) => match *variants[0] {
|
||||
ty::PatternKind::Range { .. } => {
|
||||
if let BackendRepr::Scalar(scalar) = &mut layout.backend_repr {
|
||||
@@ -282,7 +299,7 @@ fn layout_of_uncached<'tcx>(
|
||||
.try_to_bits(tcx, cx.typing_env)
|
||||
.ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?,
|
||||
)),
|
||||
ty::PatternKind::Or(_) => {
|
||||
ty::PatternKind::NotNull | ty::PatternKind::Or(_) => {
|
||||
unreachable!("mixed or patterns are not allowed")
|
||||
}
|
||||
})
|
||||
@@ -347,6 +364,7 @@ fn layout_of_uncached<'tcx>(
|
||||
)
|
||||
}
|
||||
}
|
||||
ty::PatternKind::NotNull => bug!("or patterns can't contain `!null` patterns"),
|
||||
ty::PatternKind::Or(..) => bug!("patterns cannot have nested or patterns"),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use crate::Interner;
|
||||
pub enum PatternKind<I: Interner> {
|
||||
Range { start: I::Const, end: I::Const },
|
||||
Or(I::PatList),
|
||||
NotNull,
|
||||
}
|
||||
|
||||
impl<I: Interner> Eq for PatternKind<I> {}
|
||||
|
||||
@@ -178,5 +178,6 @@ fn push_ty_pat<I: Interner>(stack: &mut TypeWalkerStack<I>, pat: I::Pat) {
|
||||
push_ty_pat::<I>(stack, pat)
|
||||
}
|
||||
}
|
||||
ty::PatternKind::NotNull => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1123,7 +1123,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
|
||||
self.hash_ty_pat(variant);
|
||||
}
|
||||
},
|
||||
TyPatKind::Err(_) => {},
|
||||
TyPatKind::NotNull | TyPatKind::Err(_) => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1099,7 +1099,7 @@ impl Rewrite for ast::TyPat {
|
||||
}
|
||||
Ok(s)
|
||||
}
|
||||
ast::TyPatKind::Err(_) => Err(RewriteError::Unknown),
|
||||
ast::TyPatKind::NotNull | ast::TyPatKind::Err(_) => Err(RewriteError::Unknown),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,4 +10,15 @@ type Positive2 = pattern_type!(i32 is 0..=);
|
||||
type Wild = pattern_type!(() is _);
|
||||
//~^ ERROR: pattern not supported in pattern types
|
||||
|
||||
// FIXME: confusing diagnostic because `not` can be a binding
|
||||
type NonNull = pattern_type!(*const () is not null);
|
||||
//~^ ERROR: expected one of `@` or `|`, found `null`
|
||||
//~| ERROR: pattern not supported in pattern types
|
||||
|
||||
type NonNull2 = pattern_type!(*const () is !nil);
|
||||
//~^ ERROR: expected `null`, found `nil`
|
||||
|
||||
// FIXME: reject with a type mismatch
|
||||
type Mismatch2 = pattern_type!(() is !null);
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -30,6 +30,24 @@ error: pattern not supported in pattern types
|
||||
LL | type Wild = pattern_type!(() is _);
|
||||
| ^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: pattern not supported in pattern types
|
||||
--> $DIR/bad_pat.rs:14:43
|
||||
|
|
||||
LL | type NonNull = pattern_type!(*const () is not null);
|
||||
| ^^^
|
||||
|
||||
error: expected one of `@` or `|`, found `null`
|
||||
--> $DIR/bad_pat.rs:14:47
|
||||
|
|
||||
LL | type NonNull = pattern_type!(*const () is not null);
|
||||
| ^^^^ expected one of `@` or `|`
|
||||
|
||||
error: expected `null`, found `nil`
|
||||
--> $DIR/bad_pat.rs:18:45
|
||||
|
|
||||
LL | type NonNull2 = pattern_type!(*const () is !nil);
|
||||
| ^^^ expected `null`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0586`.
|
||||
|
||||
21
tests/ui/type/pattern_types/non_null.rs
Normal file
21
tests/ui/type/pattern_types/non_null.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
//! Show that pattern-types non-null is the same as libstd's
|
||||
|
||||
//@ normalize-stderr: "randomization_seed: \d+" -> "randomization_seed: $$SEED"
|
||||
//@ only-64bit
|
||||
|
||||
#![feature(pattern_type_macro, pattern_types, rustc_attrs)]
|
||||
|
||||
use std::pat::pattern_type;
|
||||
|
||||
#[rustc_layout(debug)]
|
||||
type NonNull<T> = pattern_type!(*const T is !null); //~ ERROR layout_of
|
||||
|
||||
#[rustc_layout(debug)]
|
||||
type Test = Option<NonNull<()>>; //~ ERROR layout_of
|
||||
|
||||
#[rustc_layout(debug)]
|
||||
type Wide = pattern_type!(*const [u8] is !null); //~ ERROR layout_of
|
||||
|
||||
const _: () = assert!(size_of::<NonNull<()>>() == size_of::<Option<NonNull<()>>>());
|
||||
|
||||
fn main() {}
|
||||
218
tests/ui/type/pattern_types/non_null.stderr
Normal file
218
tests/ui/type/pattern_types/non_null.stderr
Normal file
@@ -0,0 +1,218 @@
|
||||
error: layout_of((*const T) is !null) = Layout {
|
||||
size: Size(8 bytes),
|
||||
align: AbiAlign {
|
||||
abi: Align(8 bytes),
|
||||
},
|
||||
backend_repr: Scalar(
|
||||
Initialized {
|
||||
value: Pointer(
|
||||
AddressSpace(
|
||||
0,
|
||||
),
|
||||
),
|
||||
valid_range: 1..=18446744073709551615,
|
||||
},
|
||||
),
|
||||
fields: Arbitrary {
|
||||
offsets: [
|
||||
Size(0 bytes),
|
||||
],
|
||||
memory_index: [
|
||||
0,
|
||||
],
|
||||
},
|
||||
largest_niche: Some(
|
||||
Niche {
|
||||
offset: Size(0 bytes),
|
||||
value: Pointer(
|
||||
AddressSpace(
|
||||
0,
|
||||
),
|
||||
),
|
||||
valid_range: 1..=18446744073709551615,
|
||||
},
|
||||
),
|
||||
uninhabited: false,
|
||||
variants: Single {
|
||||
index: 0,
|
||||
},
|
||||
max_repr_align: None,
|
||||
unadjusted_abi_align: Align(8 bytes),
|
||||
randomization_seed: $SEED,
|
||||
}
|
||||
--> $DIR/non_null.rs:11:1
|
||||
|
|
||||
LL | type NonNull<T> = pattern_type!(*const T is !null);
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: layout_of(Option<(*const ()) is !null>) = Layout {
|
||||
size: Size(8 bytes),
|
||||
align: AbiAlign {
|
||||
abi: Align(8 bytes),
|
||||
},
|
||||
backend_repr: Scalar(
|
||||
Initialized {
|
||||
value: Pointer(
|
||||
AddressSpace(
|
||||
0,
|
||||
),
|
||||
),
|
||||
valid_range: (..=0) | (1..),
|
||||
},
|
||||
),
|
||||
fields: Arbitrary {
|
||||
offsets: [
|
||||
Size(0 bytes),
|
||||
],
|
||||
memory_index: [
|
||||
0,
|
||||
],
|
||||
},
|
||||
largest_niche: None,
|
||||
uninhabited: false,
|
||||
variants: Multiple {
|
||||
tag: Initialized {
|
||||
value: Pointer(
|
||||
AddressSpace(
|
||||
0,
|
||||
),
|
||||
),
|
||||
valid_range: (..=0) | (1..),
|
||||
},
|
||||
tag_encoding: Niche {
|
||||
untagged_variant: 1,
|
||||
niche_variants: 0..=0,
|
||||
niche_start: 0,
|
||||
},
|
||||
tag_field: 0,
|
||||
variants: [
|
||||
Layout {
|
||||
size: Size(0 bytes),
|
||||
align: AbiAlign {
|
||||
abi: Align(1 bytes),
|
||||
},
|
||||
backend_repr: Memory {
|
||||
sized: true,
|
||||
},
|
||||
fields: Arbitrary {
|
||||
offsets: [],
|
||||
memory_index: [],
|
||||
},
|
||||
largest_niche: None,
|
||||
uninhabited: false,
|
||||
variants: Single {
|
||||
index: 0,
|
||||
},
|
||||
max_repr_align: None,
|
||||
unadjusted_abi_align: Align(1 bytes),
|
||||
randomization_seed: $SEED,
|
||||
},
|
||||
Layout {
|
||||
size: Size(8 bytes),
|
||||
align: AbiAlign {
|
||||
abi: Align(8 bytes),
|
||||
},
|
||||
backend_repr: Scalar(
|
||||
Initialized {
|
||||
value: Pointer(
|
||||
AddressSpace(
|
||||
0,
|
||||
),
|
||||
),
|
||||
valid_range: 1..=18446744073709551615,
|
||||
},
|
||||
),
|
||||
fields: Arbitrary {
|
||||
offsets: [
|
||||
Size(0 bytes),
|
||||
],
|
||||
memory_index: [
|
||||
0,
|
||||
],
|
||||
},
|
||||
largest_niche: Some(
|
||||
Niche {
|
||||
offset: Size(0 bytes),
|
||||
value: Pointer(
|
||||
AddressSpace(
|
||||
0,
|
||||
),
|
||||
),
|
||||
valid_range: 1..=18446744073709551615,
|
||||
},
|
||||
),
|
||||
uninhabited: false,
|
||||
variants: Single {
|
||||
index: 1,
|
||||
},
|
||||
max_repr_align: None,
|
||||
unadjusted_abi_align: Align(8 bytes),
|
||||
randomization_seed: $SEED,
|
||||
},
|
||||
],
|
||||
},
|
||||
max_repr_align: None,
|
||||
unadjusted_abi_align: Align(8 bytes),
|
||||
randomization_seed: $SEED,
|
||||
}
|
||||
--> $DIR/non_null.rs:14:1
|
||||
|
|
||||
LL | type Test = Option<NonNull<()>>;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: layout_of((*const [u8]) is !null) = Layout {
|
||||
size: Size(16 bytes),
|
||||
align: AbiAlign {
|
||||
abi: Align(8 bytes),
|
||||
},
|
||||
backend_repr: ScalarPair(
|
||||
Initialized {
|
||||
value: Pointer(
|
||||
AddressSpace(
|
||||
0,
|
||||
),
|
||||
),
|
||||
valid_range: 1..=18446744073709551615,
|
||||
},
|
||||
Initialized {
|
||||
value: Int(
|
||||
I64,
|
||||
false,
|
||||
),
|
||||
valid_range: 0..=18446744073709551615,
|
||||
},
|
||||
),
|
||||
fields: Arbitrary {
|
||||
offsets: [
|
||||
Size(0 bytes),
|
||||
],
|
||||
memory_index: [
|
||||
0,
|
||||
],
|
||||
},
|
||||
largest_niche: Some(
|
||||
Niche {
|
||||
offset: Size(0 bytes),
|
||||
value: Pointer(
|
||||
AddressSpace(
|
||||
0,
|
||||
),
|
||||
),
|
||||
valid_range: 1..=18446744073709551615,
|
||||
},
|
||||
),
|
||||
uninhabited: false,
|
||||
variants: Single {
|
||||
index: 0,
|
||||
},
|
||||
max_repr_align: None,
|
||||
unadjusted_abi_align: Align(8 bytes),
|
||||
randomization_seed: $SEED,
|
||||
}
|
||||
--> $DIR/non_null.rs:17:1
|
||||
|
|
||||
LL | type Wide = pattern_type!(*const [u8] is !null);
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Reference in New Issue
Block a user