1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 use rustc::session::Session;
13 use rustc::util::nodemap::FnvHashMap;
15 use syntax::ext::hygiene::Mark;
16 use syntax::fold::{self, Folder};
18 use syntax::util::move_map::MoveMap;
19 use syntax::util::small_vector::SmallVector;
23 impl<'a> Resolver<'a> {
24 pub fn assign_node_ids(&mut self, krate: ast::Crate) -> ast::Crate {
27 macros_at_scope: &mut self.macros_at_scope,
32 struct NodeIdAssigner<'a> {
34 macros_at_scope: &'a mut FnvHashMap<ast::NodeId, Vec<Mark>>,
37 impl<'a> Folder for NodeIdAssigner<'a> {
38 fn new_id(&mut self, old_id: ast::NodeId) -> ast::NodeId {
39 assert_eq!(old_id, ast::DUMMY_NODE_ID);
40 self.sess.next_node_id()
43 fn fold_block(&mut self, block: P<ast::Block>) -> P<ast::Block> {
44 block.map(|mut block| {
45 block.id = self.new_id(block.id);
47 let stmt = block.stmts.pop();
48 let mut macros = Vec::new();
49 block.stmts = block.stmts.move_flat_map(|stmt| {
50 if let ast::StmtKind::Item(ref item) = stmt.node {
51 if let ast::ItemKind::Mac(..) = item.node {
52 macros.push(item.ident.ctxt.data().outer_mark);
57 let stmt = self.fold_stmt(stmt).pop().unwrap();
58 if !macros.is_empty() {
59 self.macros_at_scope.insert(stmt.id, mem::replace(&mut macros, Vec::new()));
64 stmt.and_then(|mut stmt| {
65 // Avoid wasting a node id on a trailing expression statement,
66 // which shares a HIR node with the expression itself.
67 if let ast::StmtKind::Expr(expr) = stmt.node {
68 let expr = self.fold_expr(expr);
70 stmt.node = ast::StmtKind::Expr(expr);
73 self.fold_stmt(stmt).pop()
76 if !macros.is_empty() {
77 self.macros_at_scope.insert(stmt.id, mem::replace(&mut macros, Vec::new()));
79 block.stmts.push(stmt);
86 fn fold_item(&mut self, item: P<ast::Item>) -> SmallVector<P<ast::Item>> {
88 ast::ItemKind::Mac(..) => SmallVector::zero(),
89 _ => fold::noop_fold_item(item, self),