Skip to content

Commit bc09654

Browse files
committed
rustc: desugar use a::{b,c}; into use a::b; use a::c; in HIR.
1 parent 6ebc6d8 commit bc09654

File tree

29 files changed

+228
-395
lines changed

29 files changed

+228
-395
lines changed

src/librustc/hir/intravisit.rs

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,6 @@ pub trait Visitor<'v> : Sized {
250250
fn visit_path(&mut self, path: &'v Path, _id: NodeId) {
251251
walk_path(self, path)
252252
}
253-
fn visit_path_list_item(&mut self, prefix: &'v Path, item: &'v PathListItem) {
254-
walk_path_list_item(self, prefix, item)
255-
}
256253
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) {
257254
walk_path_segment(self, path_span, path_segment)
258255
}
@@ -352,23 +349,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
352349
visitor.visit_id(item.id);
353350
walk_opt_name(visitor, item.span, opt_name)
354351
}
355-
ItemUse(ref vp) => {
352+
ItemUse(ref path, _) => {
356353
visitor.visit_id(item.id);
357-
match vp.node {
358-
ViewPathSimple(name, ref path) => {
359-
visitor.visit_name(vp.span, name);
360-
visitor.visit_path(path, item.id);
361-
}
362-
ViewPathGlob(ref path) => {
363-
visitor.visit_path(path, item.id);
364-
}
365-
ViewPathList(ref prefix, ref list) => {
366-
visitor.visit_path(prefix, item.id);
367-
for item in list {
368-
visitor.visit_path_list_item(prefix, item)
369-
}
370-
}
371-
}
354+
visitor.visit_path(path, item.id);
372355
}
373356
ItemStatic(ref typ, _, ref expr) |
374357
ItemConst(ref typ, ref expr) => {
@@ -529,14 +512,6 @@ pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) {
529512
}
530513
}
531514

532-
pub fn walk_path_list_item<'v, V>(visitor: &mut V, _prefix: &'v Path, item: &'v PathListItem)
533-
where V: Visitor<'v>,
534-
{
535-
visitor.visit_id(item.node.id);
536-
visitor.visit_name(item.span, item.node.name);
537-
walk_opt_name(visitor, item.span, item.node.rename);
538-
}
539-
540515
pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
541516
path_span: Span,
542517
segment: &'v PathSegment) {

src/librustc/hir/lowering.rs

Lines changed: 121 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ use syntax::ptr::P;
5555
use syntax::codemap::{respan, Spanned};
5656
use syntax::std_inject;
5757
use syntax::symbol::{Symbol, keywords};
58+
use syntax::util::small_vector::SmallVector;
5859
use syntax::visit::{self, Visitor};
5960
use syntax_pos::Span;
6061

@@ -67,6 +68,11 @@ pub struct LoweringContext<'a> {
6768
// a definition, then we can properly create the def id.
6869
parent_def: Option<DefIndex>,
6970
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>,
7076
}
7177

7278
pub trait Resolver {
@@ -98,6 +104,8 @@ pub fn lower_crate(sess: &Session,
98104
sess: sess,
99105
parent_def: None,
100106
resolver: resolver,
107+
items: BTreeMap::new(),
108+
impl_items: BTreeMap::new(),
101109
}.lower_crate(krate)
102110
}
103111

@@ -110,41 +118,35 @@ enum ParamMode {
110118
}
111119

112120
impl<'a> LoweringContext<'a> {
113-
fn lower_crate(&mut self, c: &Crate) -> hir::Crate {
121+
fn lower_crate(mut self, c: &Crate) -> hir::Crate {
114122
struct ItemLowerer<'lcx, 'interner: 'lcx> {
115-
items: BTreeMap<NodeId, hir::Item>,
116-
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
117123
lctx: &'lcx mut LoweringContext<'interner>,
118124
}
119125

120126
impl<'lcx, 'interner> Visitor for ItemLowerer<'lcx, 'interner> {
121127
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);
123130
visit::walk_item(self, item);
124131
}
125132

126133
fn visit_impl_item(&mut self, item: &ImplItem) {
127134
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);
129137
visit::walk_impl_item(self, item);
130138
}
131139
}
132140

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);
140142

141143
hir::Crate {
142144
module: self.lower_mod(&c.module),
143145
attrs: self.lower_attrs(&c.attrs),
144146
span: c.span,
145147
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,
148150
}
149151
}
150152

@@ -183,38 +185,6 @@ impl<'a> LoweringContext<'a> {
183185
attrs.clone().into()
184186
}
185187

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-
218188
fn lower_arm(&mut self, arm: &Arm) -> hir::Arm {
219189
hir::Arm {
220190
attrs: self.lower_attrs(&arm.attrs),
@@ -382,19 +352,32 @@ impl<'a> LoweringContext<'a> {
382352
proj_start, p.segments.len())
383353
}
384354

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 {
389360
hir::Path {
390361
global: p.global,
391362
segments: p.segments.iter().map(|segment| {
392363
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(),
394370
span: p.span,
395371
}
396372
}
397373

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+
398381
fn lower_path_segment(&mut self,
399382
segment: &PathSegment,
400383
param_mode: ParamMode)
@@ -661,12 +644,10 @@ impl<'a> LoweringContext<'a> {
661644
}
662645

663646
fn lower_block(&mut self, b: &Block) -> P<hir::Block> {
664-
let mut stmts = Vec::new();
665647
let mut expr = None;
666648

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() {
670651
if let hir::StmtExpr(e, _) = last.node {
671652
expr = Some(e);
672653
} else {
@@ -683,11 +664,65 @@ impl<'a> LoweringContext<'a> {
683664
})
684665
}
685666

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_ {
687673
match *i {
688674
ItemKind::ExternCrate(string) => hir::ItemExternCrate(string),
689675
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)
691726
}
692727
ItemKind::Static(ref t, m, ref e) => {
693728
hir::ItemStatic(self.lower_ty(t),
@@ -835,7 +870,7 @@ impl<'a> LoweringContext<'a> {
835870
fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
836871
hir::Mod {
837872
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(),
839874
}
840875
}
841876

@@ -851,21 +886,30 @@ impl<'a> LoweringContext<'a> {
851886
}
852887
}
853888

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 })
856897
}
857898

858899
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);
859903
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)
861905
});
862906

863907
hir::Item {
864908
id: i.id,
865-
name: i.ident.name,
866-
attrs: self.lower_attrs(&i.attrs),
909+
name: name,
910+
attrs: attrs,
867911
node: node,
868-
vis: self.lower_visibility(&i.vis),
912+
vis: vis,
869913
span: i.span,
870914
}
871915
}
@@ -1701,22 +1745,26 @@ impl<'a> LoweringContext<'a> {
17011745
}
17021746
}
17031747

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 {
17061750
StmtKind::Local(ref l) => Spanned {
17071751
node: hir::StmtDecl(P(Spanned {
17081752
node: hir::DeclLocal(self.lower_local(l)),
17091753
span: s.span,
17101754
}), s.id),
17111755
span: s.span,
17121756
},
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())),
17161765
span: s.span,
1717-
}), s.id),
1718-
span: s.span,
1719-
},
1766+
}).collect();
1767+
}
17201768
StmtKind::Expr(ref e) => {
17211769
Spanned {
17221770
node: hir::StmtExpr(P(self.lower_expr(e)), s.id),
@@ -1730,7 +1778,7 @@ impl<'a> LoweringContext<'a> {
17301778
}
17311779
}
17321780
StmtKind::Mac(..) => panic!("Shouldn't exist here"),
1733-
}
1781+
})
17341782
}
17351783

17361784
fn lower_capture_clause(&mut self, c: CaptureBy) -> hir::CaptureClause {

src/librustc/hir/map/collector.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,16 +124,6 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
124124
this.insert(struct_def.id(), NodeStructCtor(struct_def));
125125
}
126126
}
127-
ItemUse(ref view_path) => {
128-
match view_path.node {
129-
ViewPathList(_, ref paths) => {
130-
for path in paths {
131-
this.insert(path.node.id, NodeItem(i));
132-
}
133-
}
134-
_ => ()
135-
}
136-
}
137127
_ => {}
138128
}
139129
intravisit::walk_item(this, i);

0 commit comments

Comments
 (0)