Skip to content

Commit 2362659

Browse files
Rollup merge of #78292 - bugadani:recursion, r=nagisa
Loop instead of recursion I saw the comment `// FIXME: consider not using recursion to lower this.` and considered not using recursion :)
2 parents b6ae1fa + f88d6e8 commit 2362659

File tree

1 file changed

+79
-71
lines changed
  • compiler/rustc_ast_lowering/src

1 file changed

+79
-71
lines changed

compiler/rustc_ast_lowering/src/pat.rs

+79-71
Original file line numberDiff line numberDiff line change
@@ -10,82 +10,90 @@ use rustc_span::symbol::Ident;
1010
use rustc_span::{source_map::Spanned, Span};
1111

1212
impl<'a, 'hir> LoweringContext<'a, 'hir> {
13-
crate fn lower_pat(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> {
13+
crate fn lower_pat(&mut self, mut pattern: &Pat) -> &'hir hir::Pat<'hir> {
1414
ensure_sufficient_stack(|| {
15-
let node = match p.kind {
16-
PatKind::Wild => hir::PatKind::Wild,
17-
PatKind::Ident(ref binding_mode, ident, ref sub) => {
18-
let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s));
19-
let node = self.lower_pat_ident(p, binding_mode, ident, lower_sub);
20-
node
21-
}
22-
PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)),
23-
PatKind::TupleStruct(ref path, ref pats) => {
24-
let qpath = self.lower_qpath(
25-
p.id,
26-
&None,
27-
path,
28-
ParamMode::Optional,
29-
ImplTraitContext::disallowed(),
30-
);
31-
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
32-
hir::PatKind::TupleStruct(qpath, pats, ddpos)
33-
}
34-
PatKind::Or(ref pats) => hir::PatKind::Or(
35-
self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat(x))),
36-
),
37-
PatKind::Path(ref qself, ref path) => {
38-
let qpath = self.lower_qpath(
39-
p.id,
40-
qself,
41-
path,
42-
ParamMode::Optional,
43-
ImplTraitContext::disallowed(),
44-
);
45-
hir::PatKind::Path(qpath)
46-
}
47-
PatKind::Struct(ref path, ref fields, etc) => {
48-
let qpath = self.lower_qpath(
49-
p.id,
50-
&None,
51-
path,
52-
ParamMode::Optional,
53-
ImplTraitContext::disallowed(),
54-
);
15+
// loop here to avoid recursion
16+
let node = loop {
17+
match pattern.kind {
18+
PatKind::Wild => break hir::PatKind::Wild,
19+
PatKind::Ident(ref binding_mode, ident, ref sub) => {
20+
let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s));
21+
break self.lower_pat_ident(pattern, binding_mode, ident, lower_sub);
22+
}
23+
PatKind::Lit(ref e) => break hir::PatKind::Lit(self.lower_expr(e)),
24+
PatKind::TupleStruct(ref path, ref pats) => {
25+
let qpath = self.lower_qpath(
26+
pattern.id,
27+
&None,
28+
path,
29+
ParamMode::Optional,
30+
ImplTraitContext::disallowed(),
31+
);
32+
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
33+
break hir::PatKind::TupleStruct(qpath, pats, ddpos);
34+
}
35+
PatKind::Or(ref pats) => {
36+
break hir::PatKind::Or(
37+
self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat(x))),
38+
);
39+
}
40+
PatKind::Path(ref qself, ref path) => {
41+
let qpath = self.lower_qpath(
42+
pattern.id,
43+
qself,
44+
path,
45+
ParamMode::Optional,
46+
ImplTraitContext::disallowed(),
47+
);
48+
break hir::PatKind::Path(qpath);
49+
}
50+
PatKind::Struct(ref path, ref fields, etc) => {
51+
let qpath = self.lower_qpath(
52+
pattern.id,
53+
&None,
54+
path,
55+
ParamMode::Optional,
56+
ImplTraitContext::disallowed(),
57+
);
5558

56-
let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::FieldPat {
57-
hir_id: self.next_id(),
58-
ident: f.ident,
59-
pat: self.lower_pat(&f.pat),
60-
is_shorthand: f.is_shorthand,
61-
span: f.span,
62-
}));
63-
hir::PatKind::Struct(qpath, fs, etc)
64-
}
65-
PatKind::Tuple(ref pats) => {
66-
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple");
67-
hir::PatKind::Tuple(pats, ddpos)
68-
}
69-
PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)),
70-
PatKind::Ref(ref inner, mutbl) => hir::PatKind::Ref(self.lower_pat(inner), mutbl),
71-
PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => {
72-
hir::PatKind::Range(
73-
e1.as_deref().map(|e| self.lower_expr(e)),
74-
e2.as_deref().map(|e| self.lower_expr(e)),
75-
self.lower_range_end(end, e2.is_some()),
76-
)
77-
}
78-
PatKind::Slice(ref pats) => self.lower_pat_slice(pats),
79-
PatKind::Rest => {
80-
// If we reach here the `..` pattern is not semantically allowed.
81-
self.ban_illegal_rest_pat(p.span)
59+
let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::FieldPat {
60+
hir_id: self.next_id(),
61+
ident: f.ident,
62+
pat: self.lower_pat(&f.pat),
63+
is_shorthand: f.is_shorthand,
64+
span: f.span,
65+
}));
66+
break hir::PatKind::Struct(qpath, fs, etc);
67+
}
68+
PatKind::Tuple(ref pats) => {
69+
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple");
70+
break hir::PatKind::Tuple(pats, ddpos);
71+
}
72+
PatKind::Box(ref inner) => {
73+
break hir::PatKind::Box(self.lower_pat(inner));
74+
}
75+
PatKind::Ref(ref inner, mutbl) => {
76+
break hir::PatKind::Ref(self.lower_pat(inner), mutbl);
77+
}
78+
PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => {
79+
break hir::PatKind::Range(
80+
e1.as_deref().map(|e| self.lower_expr(e)),
81+
e2.as_deref().map(|e| self.lower_expr(e)),
82+
self.lower_range_end(end, e2.is_some()),
83+
);
84+
}
85+
PatKind::Slice(ref pats) => break self.lower_pat_slice(pats),
86+
PatKind::Rest => {
87+
// If we reach here the `..` pattern is not semantically allowed.
88+
break self.ban_illegal_rest_pat(pattern.span);
89+
}
90+
// return inner to be processed in next loop
91+
PatKind::Paren(ref inner) => pattern = inner,
92+
PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span),
8293
}
83-
// FIXME: consider not using recursion to lower this.
84-
PatKind::Paren(ref inner) => return self.lower_pat(inner),
85-
PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", p.span),
8694
};
8795

88-
self.pat_with_node_id_of(p, node)
96+
self.pat_with_node_id_of(pattern, node)
8997
})
9098
}
9199

0 commit comments

Comments
 (0)