From 80bdcbf50a63845dd3cfeb05751ba3dcbd1025b8 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Mon, 27 Nov 2023 03:15:56 +0100 Subject: Parse a pattern with no arm --- compiler/rustc_ast/src/ast.rs | 22 ++++++++++++++++++++-- compiler/rustc_ast/src/mut_visit.rs | 2 +- compiler/rustc_ast/src/visit.rs | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) (limited to 'compiler/rustc_ast') diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index cba9121aa5a..62bacf97f49 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -658,6 +658,24 @@ impl Pat { pub fn is_rest(&self) -> bool { matches!(self.kind, PatKind::Rest) } + + /// Could this be a never pattern? I.e. is it a never pattern modulo macro invocations that + /// might return never patterns? + pub fn could_be_never_pattern(&self) -> bool { + let mut could_be_never_pattern = false; + self.walk(&mut |pat| match &pat.kind { + PatKind::Never | PatKind::MacCall(_) => { + could_be_never_pattern = true; + false + } + PatKind::Or(s) => { + could_be_never_pattern = s.iter().all(|p| p.could_be_never_pattern()); + false + } + _ => true, + }); + could_be_never_pattern + } } /// A single field in a struct pattern. @@ -1080,8 +1098,8 @@ pub struct Arm { pub pat: P, /// Match arm guard, e.g. `n > 10` in `match foo { n if n > 10 => {}, _ => {} }` pub guard: Option>, - /// Match arm body. - pub body: P, + /// Match arm body. Omitted if the pattern is a never pattern. + pub body: Option>, pub span: Span, pub id: NodeId, pub is_placeholder: bool, diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 8ce86bf9ecf..e909e8dc774 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -453,7 +453,7 @@ pub fn noop_flat_map_arm(mut arm: Arm, vis: &mut T) -> SmallVec<[ vis.visit_id(id); vis.visit_pat(pat); visit_opt(guard, |guard| vis.visit_expr(guard)); - vis.visit_expr(body); + visit_opt(body, |body| vis.visit_expr(body)); vis.visit_span(span); smallvec![arm] } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 9dbadcb49d3..773a7ebc707 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -951,7 +951,7 @@ pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) { pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) { visitor.visit_pat(&arm.pat); walk_list!(visitor, visit_expr, &arm.guard); - visitor.visit_expr(&arm.body); + walk_list!(visitor, visit_expr, &arm.body); walk_list!(visitor, visit_attribute, &arm.attrs); } -- cgit 1.4.1-3-g733a5