Loop instead of recursion
This commit is contained in:
parent
a9cd294cf2
commit
f88d6e8437
1 changed files with 79 additions and 71 deletions
|
@ -10,82 +10,90 @@ use rustc_span::symbol::Ident;
|
||||||
use rustc_span::{source_map::Spanned, Span};
|
use rustc_span::{source_map::Spanned, Span};
|
||||||
|
|
||||||
impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
crate fn lower_pat(&mut self, p: &Pat) -> &'hir hir::Pat<'hir> {
|
crate fn lower_pat(&mut self, mut pattern: &Pat) -> &'hir hir::Pat<'hir> {
|
||||||
ensure_sufficient_stack(|| {
|
ensure_sufficient_stack(|| {
|
||||||
let node = match p.kind {
|
// loop here to avoid recursion
|
||||||
PatKind::Wild => hir::PatKind::Wild,
|
let node = loop {
|
||||||
PatKind::Ident(ref binding_mode, ident, ref sub) => {
|
match pattern.kind {
|
||||||
let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s));
|
PatKind::Wild => break hir::PatKind::Wild,
|
||||||
let node = self.lower_pat_ident(p, binding_mode, ident, lower_sub);
|
PatKind::Ident(ref binding_mode, ident, ref sub) => {
|
||||||
node
|
let lower_sub = |this: &mut Self| sub.as_ref().map(|s| this.lower_pat(&*s));
|
||||||
}
|
break self.lower_pat_ident(pattern, binding_mode, ident, lower_sub);
|
||||||
PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)),
|
}
|
||||||
PatKind::TupleStruct(ref path, ref pats) => {
|
PatKind::Lit(ref e) => break hir::PatKind::Lit(self.lower_expr(e)),
|
||||||
let qpath = self.lower_qpath(
|
PatKind::TupleStruct(ref path, ref pats) => {
|
||||||
p.id,
|
let qpath = self.lower_qpath(
|
||||||
&None,
|
pattern.id,
|
||||||
path,
|
&None,
|
||||||
ParamMode::Optional,
|
path,
|
||||||
ImplTraitContext::disallowed(),
|
ParamMode::Optional,
|
||||||
);
|
ImplTraitContext::disallowed(),
|
||||||
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
|
);
|
||||||
hir::PatKind::TupleStruct(qpath, pats, ddpos)
|
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
|
||||||
}
|
break hir::PatKind::TupleStruct(qpath, pats, ddpos);
|
||||||
PatKind::Or(ref pats) => hir::PatKind::Or(
|
}
|
||||||
self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat(x))),
|
PatKind::Or(ref pats) => {
|
||||||
),
|
break hir::PatKind::Or(
|
||||||
PatKind::Path(ref qself, ref path) => {
|
self.arena.alloc_from_iter(pats.iter().map(|x| self.lower_pat(x))),
|
||||||
let qpath = self.lower_qpath(
|
);
|
||||||
p.id,
|
}
|
||||||
qself,
|
PatKind::Path(ref qself, ref path) => {
|
||||||
path,
|
let qpath = self.lower_qpath(
|
||||||
ParamMode::Optional,
|
pattern.id,
|
||||||
ImplTraitContext::disallowed(),
|
qself,
|
||||||
);
|
path,
|
||||||
hir::PatKind::Path(qpath)
|
ParamMode::Optional,
|
||||||
}
|
ImplTraitContext::disallowed(),
|
||||||
PatKind::Struct(ref path, ref fields, etc) => {
|
);
|
||||||
let qpath = self.lower_qpath(
|
break hir::PatKind::Path(qpath);
|
||||||
p.id,
|
}
|
||||||
&None,
|
PatKind::Struct(ref path, ref fields, etc) => {
|
||||||
path,
|
let qpath = self.lower_qpath(
|
||||||
ParamMode::Optional,
|
pattern.id,
|
||||||
ImplTraitContext::disallowed(),
|
&None,
|
||||||
);
|
path,
|
||||||
|
ParamMode::Optional,
|
||||||
|
ImplTraitContext::disallowed(),
|
||||||
|
);
|
||||||
|
|
||||||
let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::FieldPat {
|
let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::FieldPat {
|
||||||
hir_id: self.next_id(),
|
hir_id: self.next_id(),
|
||||||
ident: f.ident,
|
ident: f.ident,
|
||||||
pat: self.lower_pat(&f.pat),
|
pat: self.lower_pat(&f.pat),
|
||||||
is_shorthand: f.is_shorthand,
|
is_shorthand: f.is_shorthand,
|
||||||
span: f.span,
|
span: f.span,
|
||||||
}));
|
}));
|
||||||
hir::PatKind::Struct(qpath, fs, etc)
|
break hir::PatKind::Struct(qpath, fs, etc);
|
||||||
|
}
|
||||||
|
PatKind::Tuple(ref pats) => {
|
||||||
|
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple");
|
||||||
|
break hir::PatKind::Tuple(pats, ddpos);
|
||||||
|
}
|
||||||
|
PatKind::Box(ref inner) => {
|
||||||
|
break hir::PatKind::Box(self.lower_pat(inner));
|
||||||
|
}
|
||||||
|
PatKind::Ref(ref inner, mutbl) => {
|
||||||
|
break hir::PatKind::Ref(self.lower_pat(inner), mutbl);
|
||||||
|
}
|
||||||
|
PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => {
|
||||||
|
break hir::PatKind::Range(
|
||||||
|
e1.as_deref().map(|e| self.lower_expr(e)),
|
||||||
|
e2.as_deref().map(|e| self.lower_expr(e)),
|
||||||
|
self.lower_range_end(end, e2.is_some()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
PatKind::Slice(ref pats) => break self.lower_pat_slice(pats),
|
||||||
|
PatKind::Rest => {
|
||||||
|
// If we reach here the `..` pattern is not semantically allowed.
|
||||||
|
break self.ban_illegal_rest_pat(pattern.span);
|
||||||
|
}
|
||||||
|
// return inner to be processed in next loop
|
||||||
|
PatKind::Paren(ref inner) => pattern = inner,
|
||||||
|
PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", pattern.span),
|
||||||
}
|
}
|
||||||
PatKind::Tuple(ref pats) => {
|
|
||||||
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple");
|
|
||||||
hir::PatKind::Tuple(pats, ddpos)
|
|
||||||
}
|
|
||||||
PatKind::Box(ref inner) => hir::PatKind::Box(self.lower_pat(inner)),
|
|
||||||
PatKind::Ref(ref inner, mutbl) => hir::PatKind::Ref(self.lower_pat(inner), mutbl),
|
|
||||||
PatKind::Range(ref e1, ref e2, Spanned { node: ref end, .. }) => {
|
|
||||||
hir::PatKind::Range(
|
|
||||||
e1.as_deref().map(|e| self.lower_expr(e)),
|
|
||||||
e2.as_deref().map(|e| self.lower_expr(e)),
|
|
||||||
self.lower_range_end(end, e2.is_some()),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
PatKind::Slice(ref pats) => self.lower_pat_slice(pats),
|
|
||||||
PatKind::Rest => {
|
|
||||||
// If we reach here the `..` pattern is not semantically allowed.
|
|
||||||
self.ban_illegal_rest_pat(p.span)
|
|
||||||
}
|
|
||||||
// FIXME: consider not using recursion to lower this.
|
|
||||||
PatKind::Paren(ref inner) => return self.lower_pat(inner),
|
|
||||||
PatKind::MacCall(_) => panic!("{:?} shouldn't exist here", p.span),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.pat_with_node_id_of(p, node)
|
self.pat_with_node_id_of(pattern, node)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue