@@ -2,7 +2,7 @@ use crate::{ImplTraitContext, ImplTraitPosition, LoweringContext};
22use rustc_ast:: { Block , BlockCheckMode , Local , Stmt , StmtKind } ;
33use rustc_hir as hir;
44
5- use smallvec:: { smallvec , SmallVec } ;
5+ use smallvec:: SmallVec ;
66
77impl < ' a , ' hir > LoweringContext < ' a , ' hir > {
88 pub ( super ) fn lower_block (
@@ -18,66 +18,67 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1818 b : & Block ,
1919 targeted_by_break : bool ,
2020 ) -> hir:: Block < ' hir > {
21- let ( stmts, expr) = match & * b. stmts {
22- [ stmts @ .., Stmt { kind : StmtKind :: Expr ( e) , .. } ] => ( stmts, Some ( & * e) ) ,
23- stmts => ( stmts, None ) ,
24- } ;
25- let stmts = self . arena . alloc_from_iter ( stmts. iter ( ) . flat_map ( |stmt| self . lower_stmt ( stmt) ) ) ;
26- let expr = expr. map ( |e| self . lower_expr ( e) ) ;
21+ let ( stmts, expr) = self . lower_stmts ( & b. stmts ) ;
2722 let rules = self . lower_block_check_mode ( & b. rules ) ;
2823 let hir_id = self . lower_node_id ( b. id ) ;
29-
3024 hir:: Block { hir_id, stmts, expr, rules, span : self . lower_span ( b. span ) , targeted_by_break }
3125 }
3226
33- fn lower_stmt ( & mut self , s : & Stmt ) -> SmallVec < [ hir:: Stmt < ' hir > ; 1 ] > {
34- let ( hir_id, kind) = match s. kind {
35- StmtKind :: Local ( ref l) => {
36- let l = self . lower_local ( l) ;
37- let hir_id = self . lower_node_id ( s. id ) ;
38- self . alias_attrs ( hir_id, l. hir_id ) ;
39- return smallvec ! [ hir:: Stmt {
40- hir_id,
41- kind: hir:: StmtKind :: Local ( self . arena. alloc( l) ) ,
42- span: self . lower_span( s. span) ,
43- } ] ;
44- }
45- StmtKind :: Item ( ref it) => {
46- // Can only use the ID once.
47- let mut id = Some ( s. id ) ;
48- return self
49- . lower_item_id ( it)
50- . into_iter ( )
51- . map ( |item_id| {
52- let hir_id = id
53- . take ( )
54- . map ( |id| self . lower_node_id ( id) )
55- . unwrap_or_else ( || self . next_id ( ) ) ;
56-
57- hir:: Stmt {
58- hir_id,
59- kind : hir:: StmtKind :: Item ( item_id) ,
60- span : self . lower_span ( s. span ) ,
61- }
62- } )
63- . collect ( ) ;
64- }
65- StmtKind :: Expr ( ref e) => {
66- let e = self . lower_expr ( e) ;
67- let hir_id = self . lower_node_id ( s. id ) ;
68- self . alias_attrs ( hir_id, e. hir_id ) ;
69- ( hir_id, hir:: StmtKind :: Expr ( e) )
70- }
71- StmtKind :: Semi ( ref e) => {
72- let e = self . lower_expr ( e) ;
73- let hir_id = self . lower_node_id ( s. id ) ;
74- self . alias_attrs ( hir_id, e. hir_id ) ;
75- ( hir_id, hir:: StmtKind :: Semi ( e) )
27+ fn lower_stmts (
28+ & mut self ,
29+ mut ast_stmts : & [ Stmt ] ,
30+ ) -> ( & ' hir [ hir:: Stmt < ' hir > ] , Option < & ' hir hir:: Expr < ' hir > > ) {
31+ let mut stmts = SmallVec :: < [ hir:: Stmt < ' hir > ; 8 ] > :: new ( ) ;
32+ let mut expr = None ;
33+ while let [ s, tail @ ..] = ast_stmts {
34+ match s. kind {
35+ StmtKind :: Local ( ref l) => {
36+ let l = self . lower_local ( l) ;
37+ let hir_id = self . lower_node_id ( s. id ) ;
38+ self . alias_attrs ( hir_id, l. hir_id ) ;
39+ let kind = hir:: StmtKind :: Local ( self . arena . alloc ( l) ) ;
40+ let span = self . lower_span ( s. span ) ;
41+ stmts. push ( hir:: Stmt { hir_id, kind, span } ) ;
42+ }
43+ StmtKind :: Item ( ref it) => {
44+ stmts. extend ( self . lower_item_id ( it) . into_iter ( ) . enumerate ( ) . map (
45+ |( i, item_id) | {
46+ let hir_id = match i {
47+ 0 => self . lower_node_id ( s. id ) ,
48+ _ => self . next_id ( ) ,
49+ } ;
50+ let kind = hir:: StmtKind :: Item ( item_id) ;
51+ let span = self . lower_span ( s. span ) ;
52+ hir:: Stmt { hir_id, kind, span }
53+ } ,
54+ ) ) ;
55+ }
56+ StmtKind :: Expr ( ref e) => {
57+ let e = self . lower_expr ( e) ;
58+ if tail. is_empty ( ) {
59+ expr = Some ( e) ;
60+ } else {
61+ let hir_id = self . lower_node_id ( s. id ) ;
62+ self . alias_attrs ( hir_id, e. hir_id ) ;
63+ let kind = hir:: StmtKind :: Expr ( e) ;
64+ let span = self . lower_span ( s. span ) ;
65+ stmts. push ( hir:: Stmt { hir_id, kind, span } ) ;
66+ }
67+ }
68+ StmtKind :: Semi ( ref e) => {
69+ let e = self . lower_expr ( e) ;
70+ let hir_id = self . lower_node_id ( s. id ) ;
71+ self . alias_attrs ( hir_id, e. hir_id ) ;
72+ let kind = hir:: StmtKind :: Semi ( e) ;
73+ let span = self . lower_span ( s. span ) ;
74+ stmts. push ( hir:: Stmt { hir_id, kind, span } ) ;
75+ }
76+ StmtKind :: Empty => { }
77+ StmtKind :: MacCall ( ..) => panic ! ( "shouldn't exist here" ) ,
7678 }
77- StmtKind :: Empty => return smallvec ! [ ] ,
78- StmtKind :: MacCall ( ..) => panic ! ( "shouldn't exist here" ) ,
79- } ;
80- smallvec ! [ hir:: Stmt { hir_id, kind, span: self . lower_span( s. span) } ]
79+ ast_stmts = & ast_stmts[ 1 ..] ;
80+ }
81+ ( self . arena . alloc_from_iter ( stmts) , expr)
8182 }
8283
8384 fn lower_local ( & mut self , l : & Local ) -> hir:: Local < ' hir > {
0 commit comments