about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2015-06-16 22:20:30 +1200
committerNick Cameron <ncameron@mozilla.com>2015-06-30 17:21:26 +1200
commitb23ddc60e9fcb188421060a83f1af2b815fc60e2 (patch)
treecc87feb3dc28243acb5c26f229a158d1ae556937
parentbbf0daa19276354d5759d0b0bd7d31bcd3cc301c (diff)
downloadrust-b23ddc60e9fcb188421060a83f1af2b815fc60e2.tar.gz
rust-b23ddc60e9fcb188421060a83f1af2b815fc60e2.zip
Implement get_enclosing_scope and use it in save-analysis
-rw-r--r--src/librustc/ast_map/mod.rs28
-rw-r--r--src/librustc_trans/save/mod.rs16
2 files changed, 36 insertions, 8 deletions
diff --git a/src/librustc/ast_map/mod.rs b/src/librustc/ast_map/mod.rs
index 39ad2022183..7c80ba376c3 100644
--- a/src/librustc/ast_map/mod.rs
+++ b/src/librustc/ast_map/mod.rs
@@ -321,6 +321,34 @@ impl<'ast> Map<'ast> {
         self.find_entry(id).and_then(|x| x.parent_node()).unwrap_or(id)
     }
 
+    /// Returns the nearest enclosing scope. A scope is an item or block.
+    /// FIXME it is not clear to me that all items qualify as scopes - statics
+    /// and associated types probably shouldn't, for example. Behaviour in this
+    /// regard should be expected to be highly unstable.
+    pub fn get_enclosing_scope(&self, id: NodeId) -> Option<NodeId> {
+        let mut last_id = id;
+        // Walk up the chain of parents until we find a 'scope'.
+        loop {
+            let cur_id = self.get_parent_node(last_id);
+            if cur_id == last_id {
+                return None;
+            }
+
+            match self.get(cur_id) {
+                NodeItem(_) |
+                NodeForeignItem(_) |
+                NodeTraitItem(_) |
+                NodeImplItem(_) |
+                NodeBlock(_) => {
+                    return Some(cur_id);
+                }
+                _ => {}
+            }
+
+            last_id = cur_id;
+        }
+    }
+
     pub fn get_parent_did(&self, id: NodeId) -> DefId {
         let parent = self.get_parent(id);
         match self.find_entry(parent) {
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index 27805b9d833..e9c91f4f4c1 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -172,7 +172,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     qualname: qualname,
                     declaration: None,
                     span: sub_span.unwrap(),
-                    scope: self.tcx.map.get_parent(item.id),
+                    scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(),
                 })
             }
             ast::ItemStatic(ref typ, mt, ref expr) => {
@@ -191,7 +191,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     name: get_ident(item.ident).to_string(),
                     qualname: qualname,
                     span: sub_span.unwrap(),
-                    scope: self.tcx.map.get_parent(item.id),
+                    scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(),
                     value: value,
                     type_value: ty_to_string(&typ),
                 })
@@ -205,7 +205,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     name: get_ident(item.ident).to_string(),
                     qualname: qualname,
                     span: sub_span.unwrap(),
-                    scope: self.tcx.map.get_parent(item.id),
+                    scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(),
                     value: self.span_utils.snippet(expr.span),
                     type_value: ty_to_string(&typ),
                 })
@@ -223,7 +223,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     name: get_ident(item.ident).to_string(),
                     qualname: qualname,
                     span: sub_span.unwrap(),
-                    scope: self.tcx.map.get_parent(item.id),
+                    scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(),
                     filename: filename,
                 })
             },
@@ -237,14 +237,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     value: val,
                     span: sub_span.unwrap(),
                     qualname: enum_name,
-                    scope: self.tcx.map.get_parent(item.id),
+                    scope: self.tcx.map.get_enclosing_scope(item.id).unwrap(),
                 })
             },
             ast::ItemImpl(_, _, _, ref trait_ref, ref typ, _) => {
                 let mut type_data = None;
                 let sub_span;
 
-                let parent = self.tcx.map.get_parent(item.id);
+                let parent = self.tcx.map.get_enclosing_scope(item.id).unwrap();
 
                 match typ.node {
                     // Common case impl for a struct or something basic.
@@ -337,7 +337,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                                 return Some(Data::VariableRefData(VariableRefData {
                                     name: get_ident(ident.node).to_string(),
                                     span: sub_span.unwrap(),
-                                    scope: self.tcx.map.get_parent(expr.id),
+                                    scope: self.tcx.map.get_enclosing_scope(expr.id).unwrap(),
                                     ref_id: f.id,
                                 }));
                             }
@@ -360,7 +360,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                         let sub_span = self.span_utils.span_for_last_ident(path.span);
                         Some(Data::TypeRefData(TypeRefData {
                             span: sub_span.unwrap(),
-                            scope: self.tcx.map.get_parent(expr.id),
+                            scope: self.tcx.map.get_enclosing_scope(expr.id).unwrap(),
                             ref_id: def_id,
                         }))
                     }