Skip to content

Commit c11bdb8

Browse files
committed
Add not-null pointer patterns to pattern types
1 parent 3c30dbb commit c11bdb8

File tree

28 files changed

+289
-22
lines changed

28 files changed

+289
-22
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2632,6 +2632,9 @@ pub enum TyPatKind {
26322632
/// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
26332633
Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
26342634

2635+
/// A `!null` pattern for raw pointers.
2636+
NotNull,
2637+
26352638
Or(ThinVec<P<TyPat>>),
26362639

26372640
/// Placeholder for a pattern that wasn't syntactically well formed in some way.

compiler/rustc_ast_lowering/src/pat.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
143143
}
144144
// return inner to be processed in next loop
145145
PatKind::Paren(inner) => pattern = inner,
146-
PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span),
146+
PatKind::MacCall(_) => {
147+
panic!("{pattern:#?} shouldn't exist here")
148+
}
147149
PatKind::Err(guar) => break hir::PatKind::Err(*guar),
148150
}
149151
};
@@ -460,6 +462,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
460462
)
461463
}),
462464
),
465+
TyPatKind::NotNull => hir::TyPatKind::NotNull,
463466
TyPatKind::Or(variants) => {
464467
hir::TyPatKind::Or(self.arena.alloc_from_iter(
465468
variants.iter().map(|pat| self.lower_ty_pat_mut(pat, base_type)),

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,7 @@ impl<'a> State<'a> {
12341234
self.print_expr_anon_const(end, &[]);
12351235
}
12361236
}
1237+
rustc_ast::TyPatKind::NotNull => self.word("!null"),
12371238
rustc_ast::TyPatKind::Or(variants) => {
12381239
let mut first = true;
12391240
for pat in variants {

compiler/rustc_builtin_macros/src/pattern_type.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,21 @@ fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P
2828
let ty = parser.parse_ty()?;
2929
parser.expect_keyword(exp!(Is))?;
3030

31-
let pat = pat_to_ty_pat(
32-
cx,
33-
*parser.parse_pat_no_top_guard(
34-
None,
35-
RecoverComma::No,
36-
RecoverColon::No,
37-
CommaRecoveryMode::EitherTupleOrPipe,
38-
)?,
39-
);
31+
let start = parser.token.span;
32+
let pat = if parser.eat(exp!(Bang)) {
33+
parser.expect_keyword(exp!(Null))?;
34+
ty_pat(TyPatKind::NotNull, start.to(parser.token.span))
35+
} else {
36+
pat_to_ty_pat(
37+
cx,
38+
*parser.parse_pat_no_top_guard(
39+
None,
40+
RecoverComma::No,
41+
RecoverColon::No,
42+
CommaRecoveryMode::EitherTupleOrPipe,
43+
)?,
44+
)
45+
};
4046

4147
if parser.token != token::Eof {
4248
parser.unexpected()?;

compiler/rustc_const_eval/src/interpret/validity.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1259,9 +1259,10 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt,
12591259
// When you extend this match, make sure to also add tests to
12601260
// tests/ui/type/pattern_types/validity.rs((
12611261
match **pat {
1262-
// Range patterns are precisely reflected into `valid_range` and thus
1262+
// Range and non-null patterns are precisely reflected into `valid_range` and thus
12631263
// handled fully by `visit_scalar` (called below).
12641264
ty::PatternKind::Range { .. } => {},
1265+
ty::PatternKind::NotNull => {},
12651266

12661267
// FIXME(pattern_types): check that the value is covered by one of the variants.
12671268
// For now, we rely on layout computation setting the scalar's `valid_range` to

compiler/rustc_hir/src/hir.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,6 +1830,9 @@ pub enum TyPatKind<'hir> {
18301830
/// A range pattern (e.g., `1..=2` or `1..2`).
18311831
Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>),
18321832

1833+
/// A pattern that excludes null pointers
1834+
NotNull,
1835+
18331836
/// A list of patterns where only one needs to be satisfied
18341837
Or(&'hir [TyPat<'hir>]),
18351838

compiler/rustc_hir/src/intravisit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ pub fn walk_ty_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v TyPat<'v>)
731731
try_visit!(visitor.visit_const_arg_unambig(upper_bound));
732732
}
733733
TyPatKind::Or(patterns) => walk_list!(visitor, visit_pattern_type_pattern, patterns),
734-
TyPatKind::Err(_) => (),
734+
TyPatKind::NotNull | TyPatKind::Err(_) => (),
735735
}
736736
V::Result::output()
737737
}

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2593,6 +2593,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
25932593
.span_delayed_bug(ty_span, "invalid base type for range pattern")),
25942594
}
25952595
}
2596+
hir::TyPatKind::NotNull => Ok(ty::PatternKind::NotNull),
25962597
hir::TyPatKind::Or(patterns) => {
25972598
self.tcx()
25982599
.mk_patterns_from_iter(patterns.iter().map(|pat| {

compiler/rustc_hir_analysis/src/variance/constraints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
340340
self.add_constraints_from_const(current, start, variance);
341341
self.add_constraints_from_const(current, end, variance);
342342
}
343+
ty::PatternKind::NotNull => {}
343344
ty::PatternKind::Or(patterns) => {
344345
for pat in patterns {
345346
self.add_constraints_from_pat(current, variance, pat)

compiler/rustc_hir_pretty/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,6 +1883,10 @@ impl<'a> State<'a> {
18831883
self.word("..=");
18841884
self.print_const_arg(end);
18851885
}
1886+
TyPatKind::NotNull => {
1887+
self.word_space("not");
1888+
self.word("null");
1889+
}
18861890
TyPatKind::Or(patterns) => {
18871891
self.popen();
18881892
let mut first = true;

0 commit comments

Comments
 (0)