@@ -55,6 +55,7 @@ use syntax::ptr::P;
55
55
use syntax:: codemap:: { respan, Spanned } ;
56
56
use syntax:: std_inject;
57
57
use syntax:: symbol:: { Symbol , keywords} ;
58
+ use syntax:: util:: small_vector:: SmallVector ;
58
59
use syntax:: visit:: { self , Visitor } ;
59
60
use syntax_pos:: Span ;
60
61
@@ -67,6 +68,11 @@ pub struct LoweringContext<'a> {
67
68
// a definition, then we can properly create the def id.
68
69
parent_def : Option < DefIndex > ,
69
70
resolver : & ' a mut Resolver ,
71
+
72
+ /// The items being lowered are collected here.
73
+ items : BTreeMap < NodeId , hir:: Item > ,
74
+
75
+ impl_items : BTreeMap < hir:: ImplItemId , hir:: ImplItem > ,
70
76
}
71
77
72
78
pub trait Resolver {
@@ -98,6 +104,8 @@ pub fn lower_crate(sess: &Session,
98
104
sess : sess,
99
105
parent_def : None ,
100
106
resolver : resolver,
107
+ items : BTreeMap :: new ( ) ,
108
+ impl_items : BTreeMap :: new ( ) ,
101
109
} . lower_crate ( krate)
102
110
}
103
111
@@ -110,41 +118,35 @@ enum ParamMode {
110
118
}
111
119
112
120
impl < ' a > LoweringContext < ' a > {
113
- fn lower_crate ( & mut self , c : & Crate ) -> hir:: Crate {
121
+ fn lower_crate ( mut self , c : & Crate ) -> hir:: Crate {
114
122
struct ItemLowerer < ' lcx , ' interner : ' lcx > {
115
- items : BTreeMap < NodeId , hir:: Item > ,
116
- impl_items : BTreeMap < hir:: ImplItemId , hir:: ImplItem > ,
117
123
lctx : & ' lcx mut LoweringContext < ' interner > ,
118
124
}
119
125
120
126
impl < ' lcx , ' interner > Visitor for ItemLowerer < ' lcx , ' interner > {
121
127
fn visit_item ( & mut self , item : & Item ) {
122
- self . items . insert ( item. id , self . lctx . lower_item ( item) ) ;
128
+ let hir_item = self . lctx . lower_item ( item) ;
129
+ self . lctx . items . insert ( item. id , hir_item) ;
123
130
visit:: walk_item ( self , item) ;
124
131
}
125
132
126
133
fn visit_impl_item ( & mut self , item : & ImplItem ) {
127
134
let id = self . lctx . lower_impl_item_ref ( item) . id ;
128
- self . impl_items . insert ( id, self . lctx . lower_impl_item ( item) ) ;
135
+ let hir_item = self . lctx . lower_impl_item ( item) ;
136
+ self . lctx . impl_items . insert ( id, hir_item) ;
129
137
visit:: walk_impl_item ( self , item) ;
130
138
}
131
139
}
132
140
133
- let ( items, impl_items) = {
134
- let mut item_lowerer = ItemLowerer { items : BTreeMap :: new ( ) ,
135
- impl_items : BTreeMap :: new ( ) ,
136
- lctx : self } ;
137
- visit:: walk_crate ( & mut item_lowerer, c) ;
138
- ( item_lowerer. items , item_lowerer. impl_items )
139
- } ;
141
+ visit:: walk_crate ( & mut ItemLowerer { lctx : & mut self } , c) ;
140
142
141
143
hir:: Crate {
142
144
module : self . lower_mod ( & c. module ) ,
143
145
attrs : self . lower_attrs ( & c. attrs ) ,
144
146
span : c. span ,
145
147
exported_macros : c. exported_macros . iter ( ) . map ( |m| self . lower_macro_def ( m) ) . collect ( ) ,
146
- items : items,
147
- impl_items : impl_items,
148
+ items : self . items ,
149
+ impl_items : self . impl_items ,
148
150
}
149
151
}
150
152
@@ -183,38 +185,6 @@ impl<'a> LoweringContext<'a> {
183
185
attrs. clone ( ) . into ( )
184
186
}
185
187
186
- fn lower_view_path ( & mut self , view_path : & ViewPath ) -> P < hir:: ViewPath > {
187
- P ( Spanned {
188
- node : match view_path. node {
189
- ViewPathSimple ( ident, ref path) => {
190
- hir:: ViewPathSimple ( ident. name ,
191
- self . lower_path ( path, ParamMode :: Explicit ) )
192
- }
193
- ViewPathGlob ( ref path) => {
194
- hir:: ViewPathGlob ( self . lower_path ( path, ParamMode :: Explicit ) )
195
- }
196
- ViewPathList ( ref path, ref path_list_idents) => {
197
- hir:: ViewPathList ( self . lower_path ( path, ParamMode :: Explicit ) ,
198
- path_list_idents. iter ( )
199
- . map ( |item| self . lower_path_list_item ( item) )
200
- . collect ( ) )
201
- }
202
- } ,
203
- span : view_path. span ,
204
- } )
205
- }
206
-
207
- fn lower_path_list_item ( & mut self , path_list_ident : & PathListItem ) -> hir:: PathListItem {
208
- Spanned {
209
- node : hir:: PathListItem_ {
210
- id : path_list_ident. node . id ,
211
- name : path_list_ident. node . name . name ,
212
- rename : path_list_ident. node . rename . map ( |rename| rename. name ) ,
213
- } ,
214
- span : path_list_ident. span ,
215
- }
216
- }
217
-
218
188
fn lower_arm ( & mut self , arm : & Arm ) -> hir:: Arm {
219
189
hir:: Arm {
220
190
attrs : self . lower_attrs ( & arm. attrs ) ,
@@ -382,19 +352,32 @@ impl<'a> LoweringContext<'a> {
382
352
proj_start, p. segments. len( ) )
383
353
}
384
354
385
- fn lower_path ( & mut self ,
386
- p : & Path ,
387
- param_mode : ParamMode )
388
- -> hir:: Path {
355
+ fn lower_path_extra ( & mut self ,
356
+ p : & Path ,
357
+ name : Option < Name > ,
358
+ param_mode : ParamMode )
359
+ -> hir:: Path {
389
360
hir:: Path {
390
361
global : p. global ,
391
362
segments : p. segments . iter ( ) . map ( |segment| {
392
363
self . lower_path_segment ( segment, param_mode)
393
- } ) . collect ( ) ,
364
+ } ) . chain ( name. map ( |name| {
365
+ hir:: PathSegment {
366
+ name : name,
367
+ parameters : hir:: PathParameters :: none ( )
368
+ }
369
+ } ) ) . collect ( ) ,
394
370
span : p. span ,
395
371
}
396
372
}
397
373
374
+ fn lower_path ( & mut self ,
375
+ p : & Path ,
376
+ param_mode : ParamMode )
377
+ -> hir:: Path {
378
+ self . lower_path_extra ( p, None , param_mode)
379
+ }
380
+
398
381
fn lower_path_segment ( & mut self ,
399
382
segment : & PathSegment ,
400
383
param_mode : ParamMode )
@@ -661,12 +644,10 @@ impl<'a> LoweringContext<'a> {
661
644
}
662
645
663
646
fn lower_block ( & mut self , b : & Block ) -> P < hir:: Block > {
664
- let mut stmts = Vec :: new ( ) ;
665
647
let mut expr = None ;
666
648
667
- if let Some ( ( last, rest) ) = b. stmts . split_last ( ) {
668
- stmts = rest. iter ( ) . map ( |s| self . lower_stmt ( s) ) . collect :: < Vec < _ > > ( ) ;
669
- let last = self . lower_stmt ( last) ;
649
+ let mut stmts = b. stmts . iter ( ) . flat_map ( |s| self . lower_stmt ( s) ) . collect :: < Vec < _ > > ( ) ;
650
+ if let Some ( last) = stmts. pop ( ) {
670
651
if let hir:: StmtExpr ( e, _) = last. node {
671
652
expr = Some ( e) ;
672
653
} else {
@@ -683,11 +664,65 @@ impl<'a> LoweringContext<'a> {
683
664
} )
684
665
}
685
666
686
- fn lower_item_kind ( & mut self , i : & ItemKind ) -> hir:: Item_ {
667
+ fn lower_item_kind ( & mut self ,
668
+ name : & mut Name ,
669
+ attrs : & hir:: HirVec < Attribute > ,
670
+ vis : & mut hir:: Visibility ,
671
+ i : & ItemKind )
672
+ -> hir:: Item_ {
687
673
match * i {
688
674
ItemKind :: ExternCrate ( string) => hir:: ItemExternCrate ( string) ,
689
675
ItemKind :: Use ( ref view_path) => {
690
- hir:: ItemUse ( self . lower_view_path ( view_path) )
676
+ let path = match view_path. node {
677
+ ViewPathSimple ( _, ref path) => path,
678
+ ViewPathGlob ( ref path) => path,
679
+ ViewPathList ( ref path, ref path_list_idents) => {
680
+ for & Spanned { node : ref import, span } in path_list_idents {
681
+ // `use a::{self as x, b as y};` lowers to
682
+ // `use a as x; use a::b as y;`
683
+ let mut ident = import. name ;
684
+ let suffix = if ident. name == keywords:: SelfValue . name ( ) {
685
+ if let Some ( last) = path. segments . last ( ) {
686
+ ident = last. identifier ;
687
+ }
688
+ None
689
+ } else {
690
+ Some ( ident. name )
691
+ } ;
692
+
693
+ let mut path = self . lower_path_extra ( path, suffix,
694
+ ParamMode :: Explicit ) ;
695
+ path. span = span;
696
+ self . items . insert ( import. id , hir:: Item {
697
+ id : import. id ,
698
+ name : import. rename . unwrap_or ( ident) . name ,
699
+ attrs : attrs. clone ( ) ,
700
+ node : hir:: ItemUse ( P ( path) , hir:: UseKind :: Single ) ,
701
+ vis : vis. clone ( ) ,
702
+ span : span,
703
+ } ) ;
704
+ }
705
+ path
706
+ }
707
+ } ;
708
+ let path = P ( self . lower_path ( path, ParamMode :: Explicit ) ) ;
709
+ let kind = match view_path. node {
710
+ ViewPathSimple ( ident, _) => {
711
+ * name = ident. name ;
712
+ hir:: UseKind :: Single
713
+ }
714
+ ViewPathGlob ( _) => {
715
+ hir:: UseKind :: Glob
716
+ }
717
+ ViewPathList ( ..) => {
718
+ // Privatize the degenerate import base, used only to check
719
+ // the stability of `use a::{};`, to avoid it showing up as
720
+ // a reexport by accident when `pub`, e.g. in documentation.
721
+ * vis = hir:: Inherited ;
722
+ hir:: UseKind :: ListStem
723
+ }
724
+ } ;
725
+ hir:: ItemUse ( path, kind)
691
726
}
692
727
ItemKind :: Static ( ref t, m, ref e) => {
693
728
hir:: ItemStatic ( self . lower_ty ( t) ,
@@ -835,7 +870,7 @@ impl<'a> LoweringContext<'a> {
835
870
fn lower_mod ( & mut self , m : & Mod ) -> hir:: Mod {
836
871
hir:: Mod {
837
872
inner : m. inner ,
838
- item_ids : m. items . iter ( ) . map ( |x| self . lower_item_id ( x) ) . collect ( ) ,
873
+ item_ids : m. items . iter ( ) . flat_map ( |x| self . lower_item_id ( x) ) . collect ( ) ,
839
874
}
840
875
}
841
876
@@ -851,21 +886,30 @@ impl<'a> LoweringContext<'a> {
851
886
}
852
887
}
853
888
854
- fn lower_item_id ( & mut self , i : & Item ) -> hir:: ItemId {
855
- hir:: ItemId { id : i. id }
889
+ fn lower_item_id ( & mut self , i : & Item ) -> SmallVector < hir:: ItemId > {
890
+ if let ItemKind :: Use ( ref view_path) = i. node {
891
+ if let ViewPathList ( _, ref imports) = view_path. node {
892
+ return iter:: once ( i. id ) . chain ( imports. iter ( ) . map ( |import| import. node . id ) )
893
+ . map ( |id| hir:: ItemId { id : id } ) . collect ( ) ;
894
+ }
895
+ }
896
+ SmallVector :: one ( hir:: ItemId { id : i. id } )
856
897
}
857
898
858
899
pub fn lower_item ( & mut self , i : & Item ) -> hir:: Item {
900
+ let mut name = i. ident . name ;
901
+ let attrs = self . lower_attrs ( & i. attrs ) ;
902
+ let mut vis = self . lower_visibility ( & i. vis ) ;
859
903
let node = self . with_parent_def ( i. id , |this| {
860
- this. lower_item_kind ( & i. node )
904
+ this. lower_item_kind ( & mut name , & attrs , & mut vis , & i. node )
861
905
} ) ;
862
906
863
907
hir:: Item {
864
908
id : i. id ,
865
- name : i . ident . name ,
866
- attrs : self . lower_attrs ( & i . attrs ) ,
909
+ name : name,
910
+ attrs : attrs,
867
911
node : node,
868
- vis : self . lower_visibility ( & i . vis ) ,
912
+ vis : vis,
869
913
span : i. span ,
870
914
}
871
915
}
@@ -1701,22 +1745,26 @@ impl<'a> LoweringContext<'a> {
1701
1745
}
1702
1746
}
1703
1747
1704
- fn lower_stmt ( & mut self , s : & Stmt ) -> hir:: Stmt {
1705
- match s. node {
1748
+ fn lower_stmt ( & mut self , s : & Stmt ) -> SmallVector < hir:: Stmt > {
1749
+ SmallVector :: one ( match s. node {
1706
1750
StmtKind :: Local ( ref l) => Spanned {
1707
1751
node : hir:: StmtDecl ( P ( Spanned {
1708
1752
node : hir:: DeclLocal ( self . lower_local ( l) ) ,
1709
1753
span : s. span ,
1710
1754
} ) , s. id ) ,
1711
1755
span : s. span ,
1712
1756
} ,
1713
- StmtKind :: Item ( ref it) => Spanned {
1714
- node : hir:: StmtDecl ( P ( Spanned {
1715
- node : hir:: DeclItem ( self . lower_item_id ( it) ) ,
1757
+ StmtKind :: Item ( ref it) => {
1758
+ // Can only use the ID once.
1759
+ let mut id = Some ( s. id ) ;
1760
+ return self . lower_item_id ( it) . into_iter ( ) . map ( |item_id| Spanned {
1761
+ node : hir:: StmtDecl ( P ( Spanned {
1762
+ node : hir:: DeclItem ( item_id) ,
1763
+ span : s. span ,
1764
+ } ) , id. take ( ) . unwrap_or_else ( || self . next_id ( ) ) ) ,
1716
1765
span : s. span ,
1717
- } ) , s. id ) ,
1718
- span : s. span ,
1719
- } ,
1766
+ } ) . collect ( ) ;
1767
+ }
1720
1768
StmtKind :: Expr ( ref e) => {
1721
1769
Spanned {
1722
1770
node : hir:: StmtExpr ( P ( self . lower_expr ( e) ) , s. id ) ,
@@ -1730,7 +1778,7 @@ impl<'a> LoweringContext<'a> {
1730
1778
}
1731
1779
}
1732
1780
StmtKind :: Mac ( ..) => panic ! ( "Shouldn't exist here" ) ,
1733
- }
1781
+ } )
1734
1782
}
1735
1783
1736
1784
fn lower_capture_clause ( & mut self , c : CaptureBy ) -> hir:: CaptureClause {
0 commit comments