Skip to content

Commit f6d324f

Browse files
authored
Rollup merge of #142339 - oli-obk:not-null-pattern-types, r=BoxyUwU
Add NonNull pattern types These are the final piece missing for * #136006 We cannot use the previous scheme of using an integer range for raw pointers, as we're not just changing the layout of raw pointers anymore, but also the type representation. And we can't represent "any provenance or NonZero<usize>" natively as patterns. So I created a new `!null` pattern. Since this is all unstable representation stuff for replacing rustc_layout_scalar_range_start with pattern types, the divergence from normal patterns is fine, especially since T-lang seems interested in exploring general negation patterns r? `@BoxyUwU`
2 parents 664e3b0 + 375899c commit f6d324f

File tree

48 files changed

+548
-33
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+548
-33
lines changed

compiler/rustc_ast/src/ast.rs

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

2582+
/// A `!null` pattern for raw pointers.
2583+
NotNull,
2584+
25822585
Or(ThinVec<TyPat>),
25832586

25842587
/// 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
@@ -1232,6 +1232,7 @@ impl<'a> State<'a> {
12321232
self.print_expr_anon_const(end, &[]);
12331233
}
12341234
}
1235+
rustc_ast::TyPatKind::NotNull => self.word("!null"),
12351236
rustc_ast::TyPatKind::Or(variants) => {
12361237
let mut first = true;
12371238
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
@@ -30,15 +30,21 @@ fn parse_pat_ty<'a>(
3030
let ty = parser.parse_ty()?;
3131
parser.expect_keyword(exp!(Is))?;
3232

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

4349
if parser.token != token::Eof {
4450
parser.unexpected()?;

compiler/rustc_codegen_cranelift/src/unsize.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ pub(crate) fn coerce_unsized_into<'tcx>(
131131
dst.write_cvalue(fx, CValue::by_val_pair(base, info, dst.layout()));
132132
};
133133
match (&src_ty.kind(), &dst_ty.kind()) {
134+
(ty::Pat(a, _), ty::Pat(b, _)) => {
135+
let src = src.cast_pat_ty_to_base(fx.layout_of(*a));
136+
let dst = dst.place_transmute_type(fx, *b);
137+
return coerce_unsized_into(fx, src, dst);
138+
}
134139
(&ty::Ref(..), &ty::Ref(..))
135140
| (&ty::Ref(..), &ty::RawPtr(..))
136141
| (&ty::RawPtr(..), &ty::RawPtr(..)) => coerce_ptr(),

compiler/rustc_codegen_cranelift/src/value_and_place.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,14 @@ impl<'tcx> CValue<'tcx> {
342342
assert_eq!(self.layout().backend_repr, layout.backend_repr);
343343
CValue(self.0, layout)
344344
}
345+
346+
pub(crate) fn cast_pat_ty_to_base(self, layout: TyAndLayout<'tcx>) -> Self {
347+
let ty::Pat(base, _) = *self.layout().ty.kind() else {
348+
panic!("not a pattern type: {:#?}", self.layout())
349+
};
350+
assert_eq!(layout.ty, base);
351+
CValue(self.0, layout)
352+
}
345353
}
346354

347355
/// A place where you can write a value to or read a value from

compiler/rustc_codegen_ssa/src/base.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ pub(crate) fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
228228
) -> (Bx::Value, Bx::Value) {
229229
debug!("unsize_ptr: {:?} => {:?}", src_ty, dst_ty);
230230
match (src_ty.kind(), dst_ty.kind()) {
231+
(&ty::Pat(a, _), &ty::Pat(b, _)) => unsize_ptr(bx, src, a, b, old_info),
231232
(&ty::Ref(_, a, _), &ty::Ref(_, b, _) | &ty::RawPtr(b, _))
232233
| (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => {
233234
assert_eq!(bx.cx().type_is_sized(a), old_info.is_none());

compiler/rustc_const_eval/src/interpret/cast.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
466466
) -> InterpResult<'tcx> {
467467
trace!("Unsizing {:?} of type {} into {}", *src, src.layout.ty, cast_ty.ty);
468468
match (src.layout.ty.kind(), cast_ty.ty.kind()) {
469+
(&ty::Pat(_, s_pat), &ty::Pat(cast_ty, c_pat)) if s_pat == c_pat => {
470+
let src = self.project_field(src, FieldIdx::ZERO)?;
471+
let dest = self.project_field(dest, FieldIdx::ZERO)?;
472+
let cast_ty = self.layout_of(cast_ty)?;
473+
self.unsize_into(&src, cast_ty, &dest)
474+
}
469475
(&ty::Ref(_, s, _), &ty::Ref(_, c, _) | &ty::RawPtr(c, _))
470476
| (&ty::RawPtr(s, _), &ty::RawPtr(c, _)) => self.unsize_into_ptr(src, dest, s, c),
471477
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {

compiler/rustc_const_eval/src/interpret/validity.rs

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

12681269
// FIXME(pattern_types): check that the value is covered by one of the variants.
12691270
// 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
@@ -1854,6 +1854,9 @@ pub enum TyPatKind<'hir> {
18541854
/// A range pattern (e.g., `1..=2` or `1..2`).
18551855
Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>),
18561856

1857+
/// A pattern that excludes null pointers
1858+
NotNull,
1859+
18571860
/// A list of patterns where only one needs to be satisfied
18581861
Or(&'hir [TyPat<'hir>]),
18591862

0 commit comments

Comments
 (0)