Skip to content

Commit aad75b1

Browse files
authored
Unrolled build for rust-lang#136646
Rollup merge of rust-lang#136646 - oli-obk:pattern-types-ast, r=BoxyUwU Add a TyPat in the AST to reuse the generic arg lowering logic This simplifies ast lowering significantly with little cost to the pattern types parser. Also fixes any problems we've had with generic args (well, pushes any problems onto the `generic_const_exprs` feature gate) follow-up to rust-lang#136284 (comment) r? ``@BoxyUwU``
2 parents 672e3aa + 6d7ce4e commit aad75b1

21 files changed

+241
-264
lines changed

compiler/rustc_ast/src/ast.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -2249,7 +2249,7 @@ pub enum TyKind {
22492249
CVarArgs,
22502250
/// Pattern types like `pattern_type!(u32 is 1..=)`, which is the same as `NonZero<u32>`,
22512251
/// just as part of the type system.
2252-
Pat(P<Ty>, P<Pat>),
2252+
Pat(P<Ty>, P<TyPat>),
22532253
/// Sometimes we need a dummy value when no error has occurred.
22542254
Dummy,
22552255
/// Placeholder for a kind that has failed to be defined.
@@ -2277,6 +2277,27 @@ impl TyKind {
22772277
}
22782278
}
22792279

2280+
/// A pattern type pattern.
2281+
#[derive(Clone, Encodable, Decodable, Debug)]
2282+
pub struct TyPat {
2283+
pub id: NodeId,
2284+
pub kind: TyPatKind,
2285+
pub span: Span,
2286+
pub tokens: Option<LazyAttrTokenStream>,
2287+
}
2288+
2289+
/// All the different flavors of pattern that Rust recognizes.
2290+
//
2291+
// Adding a new variant? Please update `test_pat` in `tests/ui/macros/stringify.rs`.
2292+
#[derive(Clone, Encodable, Decodable, Debug)]
2293+
pub enum TyPatKind {
2294+
/// A range pattern (e.g., `1...2`, `1..2`, `1..`, `..2`, `1..=2`, `..=2`).
2295+
Range(Option<P<AnonConst>>, Option<P<AnonConst>>, Spanned<RangeEnd>),
2296+
2297+
/// Placeholder for a pattern that wasn't syntactically well formed in some way.
2298+
Err(ErrorGuaranteed),
2299+
}
2300+
22802301
/// Syntax used to declare a trait object.
22812302
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
22822303
#[repr(u8)]

compiler/rustc_ast/src/mut_visit.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ pub trait MutVisitor: Sized {
210210
walk_ty(self, t);
211211
}
212212

213+
fn visit_ty_pat(&mut self, t: &mut P<TyPat>) {
214+
walk_ty_pat(self, t);
215+
}
216+
213217
fn visit_lifetime(&mut self, l: &mut Lifetime) {
214218
walk_lifetime(self, l);
215219
}
@@ -570,7 +574,7 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
570574
TyKind::Paren(ty) => vis.visit_ty(ty),
571575
TyKind::Pat(ty, pat) => {
572576
vis.visit_ty(ty);
573-
vis.visit_pat(pat);
577+
vis.visit_ty_pat(pat);
574578
}
575579
TyKind::Path(qself, path) => {
576580
vis.visit_qself(qself);
@@ -594,6 +598,20 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
594598
vis.visit_span(span);
595599
}
596600

601+
pub fn walk_ty_pat<T: MutVisitor>(vis: &mut T, ty: &mut P<TyPat>) {
602+
let TyPat { id, kind, span, tokens } = ty.deref_mut();
603+
vis.visit_id(id);
604+
match kind {
605+
TyPatKind::Range(start, end, _include_end) => {
606+
visit_opt(start, |c| vis.visit_anon_const(c));
607+
visit_opt(end, |c| vis.visit_anon_const(c));
608+
}
609+
TyPatKind::Err(_) => {}
610+
}
611+
visit_lazy_tts(vis, tokens);
612+
vis.visit_span(span);
613+
}
614+
597615
fn walk_foreign_mod<T: MutVisitor>(vis: &mut T, foreign_mod: &mut ForeignMod) {
598616
let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
599617
visit_safety(vis, safety);

compiler/rustc_ast/src/visit.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ pub trait Visitor<'ast>: Sized {
179179
fn visit_ty(&mut self, t: &'ast Ty) -> Self::Result {
180180
walk_ty(self, t)
181181
}
182+
fn visit_ty_pat(&mut self, t: &'ast TyPat) -> Self::Result {
183+
walk_ty_pat(self, t)
184+
}
182185
fn visit_generic_param(&mut self, param: &'ast GenericParam) -> Self::Result {
183186
walk_generic_param(self, param)
184187
}
@@ -534,7 +537,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
534537
}
535538
TyKind::Pat(ty, pat) => {
536539
try_visit!(visitor.visit_ty(ty));
537-
try_visit!(visitor.visit_pat(pat));
540+
try_visit!(visitor.visit_ty_pat(pat));
538541
}
539542
TyKind::Array(ty, length) => {
540543
try_visit!(visitor.visit_ty(ty));
@@ -555,6 +558,18 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result {
555558
V::Result::output()
556559
}
557560

561+
pub fn walk_ty_pat<'a, V: Visitor<'a>>(visitor: &mut V, tp: &'a TyPat) -> V::Result {
562+
let TyPat { id: _, kind, span: _, tokens: _ } = tp;
563+
match kind {
564+
TyPatKind::Range(start, end, _include_end) => {
565+
visit_opt!(visitor, visit_anon_const, start);
566+
visit_opt!(visitor, visit_anon_const, end);
567+
}
568+
TyPatKind::Err(_) => {}
569+
}
570+
V::Result::output()
571+
}
572+
558573
fn walk_qself<'a, V: Visitor<'a>>(visitor: &mut V, qself: &'a Option<P<QSelf>>) -> V::Result {
559574
if let Some(qself) = qself {
560575
let QSelf { ty, path_span: _, position: _ } = &**qself;

compiler/rustc_ast_lowering/src/pat.rs

+11-69
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ use rustc_ast::ptr::P;
44
use rustc_ast::*;
55
use rustc_data_structures::stack::ensure_sufficient_stack;
66
use rustc_hir as hir;
7-
use rustc_hir::def::{DefKind, Res};
7+
use rustc_hir::def::Res;
88
use rustc_middle::span_bug;
99
use rustc_span::source_map::{Spanned, respan};
10-
use rustc_span::{Ident, Span, kw};
10+
use rustc_span::{Ident, Span};
1111

1212
use super::errors::{
1313
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
@@ -430,78 +430,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
430430
self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
431431
}
432432

433-
pub(crate) fn lower_ty_pat(&mut self, pattern: &Pat) -> &'hir hir::TyPat<'hir> {
433+
pub(crate) fn lower_ty_pat(&mut self, pattern: &TyPat) -> &'hir hir::TyPat<'hir> {
434434
self.arena.alloc(self.lower_ty_pat_mut(pattern))
435435
}
436436

437-
fn lower_ty_pat_mut(&mut self, mut pattern: &Pat) -> hir::TyPat<'hir> {
437+
fn lower_ty_pat_mut(&mut self, pattern: &TyPat) -> hir::TyPat<'hir> {
438438
// loop here to avoid recursion
439439
let pat_hir_id = self.lower_node_id(pattern.id);
440-
let node = loop {
441-
match &pattern.kind {
442-
PatKind::Range(e1, e2, Spanned { node: end, .. }) => {
443-
// FIXME(pattern_types): remove this closure and call `lower_const_arg` instead.
444-
// That requires first modifying the AST to have const args here.
445-
let mut lower_expr = |e: &Expr| -> &_ {
446-
if let ExprKind::Path(None, path) = &e.kind
447-
&& let Some(res) = self
448-
.resolver
449-
.get_partial_res(e.id)
450-
.and_then(|partial_res| partial_res.full_res())
451-
{
452-
self.lower_const_path_to_const_arg(path, res, e.id, e.span)
453-
} else {
454-
let node_id = self.next_node_id();
455-
let def_id = self.create_def(
456-
self.current_hir_id_owner.def_id,
457-
node_id,
458-
kw::Empty,
459-
DefKind::AnonConst,
460-
e.span,
461-
);
462-
let hir_id = self.lower_node_id(node_id);
463-
let ac = self.arena.alloc(hir::AnonConst {
464-
def_id,
465-
hir_id,
466-
body: self.lower_const_body(pattern.span, Some(e)),
467-
span: self.lower_span(pattern.span),
468-
});
469-
self.arena.alloc(hir::ConstArg {
470-
hir_id: self.next_id(),
471-
kind: hir::ConstArgKind::Anon(ac),
472-
})
473-
}
474-
};
475-
break hir::TyPatKind::Range(
476-
e1.as_deref().map(|e| lower_expr(e)),
477-
e2.as_deref().map(|e| lower_expr(e)),
478-
self.lower_range_end(end, e2.is_some()),
479-
);
480-
}
481-
// return inner to be processed in next loop
482-
PatKind::Paren(inner) => pattern = inner,
483-
PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span),
484-
PatKind::Err(guar) => break hir::TyPatKind::Err(*guar),
485-
PatKind::Deref(..)
486-
| PatKind::Box(..)
487-
| PatKind::Or(..)
488-
| PatKind::Struct(..)
489-
| PatKind::TupleStruct(..)
490-
| PatKind::Tuple(..)
491-
| PatKind::Ref(..)
492-
| PatKind::Expr(..)
493-
| PatKind::Guard(..)
494-
| PatKind::Slice(_)
495-
| PatKind::Ident(..)
496-
| PatKind::Path(..)
497-
| PatKind::Wild
498-
| PatKind::Never
499-
| PatKind::Rest => {
500-
break hir::TyPatKind::Err(
501-
self.dcx().span_err(pattern.span, "pattern not supported in pattern types"),
502-
);
503-
}
504-
}
440+
let node = match &pattern.kind {
441+
TyPatKind::Range(e1, e2, Spanned { node: end, .. }) => hir::TyPatKind::Range(
442+
e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
443+
e2.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
444+
self.lower_range_end(end, e2.is_some()),
445+
),
446+
TyPatKind::Err(guar) => hir::TyPatKind::Err(*guar),
505447
};
506448

507449
hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) }

compiler/rustc_ast_pretty/src/pprust/state.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,28 @@ impl<'a> State<'a> {
11481148
}
11491149
}
11501150

1151+
pub fn print_ty_pat(&mut self, pat: &ast::TyPat) {
1152+
match &pat.kind {
1153+
rustc_ast::TyPatKind::Range(start, end, include_end) => {
1154+
if let Some(start) = start {
1155+
self.print_expr_anon_const(start, &[]);
1156+
}
1157+
self.word("..");
1158+
if let Some(end) = end {
1159+
if let RangeEnd::Included(_) = include_end.node {
1160+
self.word("=");
1161+
}
1162+
self.print_expr_anon_const(end, &[]);
1163+
}
1164+
}
1165+
rustc_ast::TyPatKind::Err(_) => {
1166+
self.popen();
1167+
self.word("/*ERROR*/");
1168+
self.pclose();
1169+
}
1170+
}
1171+
}
1172+
11511173
pub fn print_type(&mut self, ty: &ast::Ty) {
11521174
self.maybe_print_comment(ty.span.lo());
11531175
self.ibox(0);
@@ -1252,7 +1274,7 @@ impl<'a> State<'a> {
12521274
ast::TyKind::Pat(ty, pat) => {
12531275
self.print_type(ty);
12541276
self.word(" is ");
1255-
self.print_pat(pat);
1277+
self.print_ty_pat(pat);
12561278
}
12571279
}
12581280
self.end();

compiler/rustc_builtin_macros/src/pattern_type.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_ast::ptr::P;
22
use rustc_ast::tokenstream::TokenStream;
3-
use rustc_ast::{Pat, Ty, ast};
3+
use rustc_ast::{AnonConst, DUMMY_NODE_ID, Ty, TyPat, TyPatKind, ast};
44
use rustc_errors::PResult;
55
use rustc_expand::base::{self, DummyResult, ExpandResult, ExtCtxt, MacroExpanderResult};
66
use rustc_parse::exp;
@@ -21,12 +21,24 @@ pub(crate) fn expand<'cx>(
2121
ExpandResult::Ready(base::MacEager::ty(cx.ty(sp, ast::TyKind::Pat(ty, pat))))
2222
}
2323

24-
fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P<Ty>, P<Pat>)> {
24+
fn parse_pat_ty<'a>(cx: &mut ExtCtxt<'a>, stream: TokenStream) -> PResult<'a, (P<Ty>, P<TyPat>)> {
2525
let mut parser = cx.new_parser_from_tts(stream);
2626

2727
let ty = parser.parse_ty()?;
2828
parser.expect_keyword(exp!(Is))?;
29-
let pat = parser.parse_pat_no_top_alt(None, None)?;
29+
let pat = parser.parse_pat_no_top_alt(None, None)?.into_inner();
30+
31+
let kind = match pat.kind {
32+
ast::PatKind::Range(start, end, include_end) => TyPatKind::Range(
33+
start.map(|value| P(AnonConst { id: DUMMY_NODE_ID, value })),
34+
end.map(|value| P(AnonConst { id: DUMMY_NODE_ID, value })),
35+
include_end,
36+
),
37+
ast::PatKind::Err(guar) => TyPatKind::Err(guar),
38+
_ => TyPatKind::Err(cx.dcx().span_err(pat.span, "pattern not supported in pattern types")),
39+
};
40+
41+
let pat = P(TyPat { id: pat.id, kind, span: pat.span, tokens: pat.tokens });
3042

3143
Ok((ty, pat))
3244
}

compiler/rustc_resolve/src/late.rs

+15
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,21 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
923923
self.diag_metadata.current_trait_object = prev;
924924
self.diag_metadata.current_type_path = prev_ty;
925925
}
926+
927+
fn visit_ty_pat(&mut self, t: &'ast TyPat) -> Self::Result {
928+
match &t.kind {
929+
TyPatKind::Range(start, end, _) => {
930+
if let Some(start) = start {
931+
self.resolve_anon_const(start, AnonConstKind::ConstArg(IsRepeatExpr::No));
932+
}
933+
if let Some(end) = end {
934+
self.resolve_anon_const(end, AnonConstKind::ConstArg(IsRepeatExpr::No));
935+
}
936+
}
937+
TyPatKind::Err(_) => {}
938+
}
939+
}
940+
926941
fn visit_poly_trait_ref(&mut self, tref: &'ast PolyTraitRef) {
927942
let span = tref.span.shrink_to_lo().to(tref.trait_ref.path.span.shrink_to_lo());
928943
self.with_generic_param_rib(

0 commit comments

Comments
 (0)