@@ -10,82 +10,90 @@ use rustc_span::symbol::Ident;
1010use rustc_span:: { source_map:: Spanned , Span } ;
1111
1212impl < ' 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