about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2014-12-28 14:37:08 +1300
committerNick Cameron <ncameron@mozilla.com>2014-12-28 14:37:08 +1300
commit4c4eabfd6c7e39e2b01851af2e58d38d898aac39 (patch)
tree0bcde9fa93319b6879f7f03a272a80d2c6a4a5f5
parent25a77fbd4837d07fe752c648562e68d6e19111f0 (diff)
downloadrust-4c4eabfd6c7e39e2b01851af2e58d38d898aac39.tar.gz
rust-4c4eabfd6c7e39e2b01851af2e58d38d898aac39.zip
save-analysis: fix spans for paths to struct variants
-rw-r--r--src/librustc_trans/save/mod.rs99
-rw-r--r--src/librustc_trans/save/recorder.rs2
2 files changed, 54 insertions, 47 deletions
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index b7982de5076..1992708eeb9 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -763,37 +763,38 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
     }
 
     fn process_path(&mut self,
-                    ex: &ast::Expr,
-                    path: &ast::Path) {
+                    id: NodeId,
+                    span: Span,
+                    path: &ast::Path,
+                    ref_kind: Option<recorder::Row>) {
         if generated_code(path.span) {
             return
         }
 
         let def_map = self.analysis.ty_cx.def_map.borrow();
-        if !def_map.contains_key(&ex.id) {
-            self.sess.span_bug(ex.span,
-                               format!("def_map has no key for {} in visit_expr",
-                                       ex.id)[]);
+        if !def_map.contains_key(&id) {
+            self.sess.span_bug(span,
+                               format!("def_map has no key for {} in visit_expr", id)[]);
         }
-        let def = &(*def_map)[ex.id];
-        let sub_span = self.span.span_for_last_ident(ex.span);
+        let def = &(*def_map)[id];
+        let sub_span = self.span.span_for_last_ident(span);
         match *def {
             def::DefUpvar(..) |
             def::DefLocal(..) |
             def::DefStatic(..) |
             def::DefConst(..) |
-            def::DefVariant(..) => self.fmt.ref_str(recorder::VarRef,
-                                                    ex.span,
+            def::DefVariant(..) => self.fmt.ref_str(ref_kind.unwrap_or(recorder::VarRef),
+                                                    span,
                                                     sub_span,
                                                     def.def_id(),
                                                     self.cur_scope),
             def::DefStruct(def_id) => self.fmt.ref_str(recorder::StructRef,
-                                                       ex.span,
+                                                       span,
                                                        sub_span,
                                                        def_id,
-                                                        self.cur_scope),
+                                                       self.cur_scope),
             def::DefStaticMethod(declid, provenence) => {
-                let sub_span = self.span.sub_span_for_meth_name(ex.span);
+                let sub_span = self.span.sub_span_for_meth_name(span);
                 let defid = if declid.krate == ast::LOCAL_CRATE {
                     let ti = ty::impl_or_trait_item(&self.analysis.ty_cx,
                                                     declid);
@@ -828,34 +829,31 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
                 } else {
                     None
                 };
-                self.fmt.meth_call_str(ex.span,
+                self.fmt.meth_call_str(span,
                                        sub_span,
                                        defid,
                                        Some(declid),
                                        self.cur_scope);
             },
-            def::DefFn(def_id, _) => self.fmt.fn_call_str(ex.span,
-                                                             sub_span,
-                                                             def_id,
-                                                             self.cur_scope),
-            _ => self.sess.span_bug(ex.span,
+            def::DefFn(def_id, _) => self.fmt.fn_call_str(span,
+                                                          sub_span,
+                                                          def_id,
+                                                          self.cur_scope),
+            _ => self.sess.span_bug(span,
                                     format!("Unexpected def kind while looking up path in '{}'",
-                                            self.span.snippet(ex.span))[]),
+                                            self.span.snippet(span))[]),
         }
         // modules or types in the path prefix
         match *def {
-            def::DefStaticMethod(..) => {
-                self.write_sub_path_trait_truncated(path);
-            },
+            def::DefStaticMethod(..) => self.write_sub_path_trait_truncated(path),
             def::DefLocal(_) |
             def::DefStatic(_,_) |
             def::DefConst(..) |
             def::DefStruct(_) |
+            def::DefVariant(..) |
             def::DefFn(..) => self.write_sub_paths_truncated(path),
             _ => {},
         }
-
-        visit::walk_path(self, path);
     }
 
     fn process_struct_lit(&mut self,
@@ -1309,7 +1307,10 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
                 // because just walking the callee path does what we want.
                 visit::walk_expr(self, ex);
             },
-            ast::ExprPath(ref path) => self.process_path(ex, path),
+            ast::ExprPath(ref path) => {
+                self.process_path(ex.id, ex.span, path, None);
+                visit::walk_path(self, path);
+            }
             ast::ExprStruct(ref path, ref fields, ref base) =>
                 self.process_struct_lit(ex, path, fields, base),
             ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, args),
@@ -1406,20 +1407,15 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
     fn visit_arm(&mut self, arm: &ast::Arm) {
         assert!(self.collected_paths.len() == 0 && !self.collecting);
         self.collecting = true;
-
         for pattern in arm.pats.iter() {
             // collect paths from the arm's patterns
             self.visit_pat(&**pattern);
         }
-        self.collecting = false;
+
+        // This is to get around borrow checking, because we need mut self to call process_path.
+        let mut paths_to_process = vec![];
         // process collected paths
         for &(id, ref p, ref immut, ref_kind) in self.collected_paths.iter() {
-            let value = if *immut {
-                self.span.snippet(p.span).to_string()
-            } else {
-                "<mutable>".to_string()
-            };
-            let sub_span = self.span.span_for_first_ident(p.span);
             let def_map = self.analysis.ty_cx.def_map.borrow();
             if !def_map.contains_key(&id) {
                 self.sess.span_bug(p.span,
@@ -1427,23 +1423,34 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
             }
             let def = &(*def_map)[id];
             match *def {
-                def::DefLocal(id)  => self.fmt.variable_str(p.span,
-                                                            sub_span,
-                                                            id,
-                                                            path_to_string(p)[],
-                                                            value[],
-                                                            ""),
-                def::DefVariant(_, id ,_) => self.fmt.ref_str(ref_kind,
-                                                              p.span,
-                                                              sub_span,
-                                                              id,
-                                                              self.cur_scope),
-                // FIXME(nrc) what is this doing here?
+                def::DefLocal(id)  => {
+                    let value = if *immut {
+                        self.span.snippet(p.span).to_string()
+                    } else {
+                        "<mutable>".to_string()
+                    };
+
+                    assert!(p.segments.len() == 1, "qualified path for local variable def in arm");
+                    self.fmt.variable_str(p.span,
+                                          Some(p.span),
+                                          id,
+                                          path_to_string(p)[],
+                                          value[],
+                                          "")
+                }
+                def::DefVariant(..) => {
+                    paths_to_process.push((id, p.span, p.clone(), Some(ref_kind)))
+                }
+                // FIXME(nrc) what are these doing here?
                 def::DefStatic(_, _) => {}
                 def::DefConst(..) => {}
                 _ => error!("unexpected definition kind when processing collected paths: {}", *def)
             }
         }
+        for &(id, span, ref path, ref_kind) in paths_to_process.iter() {
+            self.process_path(id, span, path, ref_kind);
+        }
+        self.collecting = false;
         self.collected_paths.clear();
         visit::walk_expr_opt(self, &arm.guard);
         self.visit_expr(&*arm.body);
diff --git a/src/librustc_trans/save/recorder.rs b/src/librustc_trans/save/recorder.rs
index b2dd9218f17..f62073e54e6 100644
--- a/src/librustc_trans/save/recorder.rs
+++ b/src/librustc_trans/save/recorder.rs
@@ -61,7 +61,7 @@ macro_rules! svec {
     })
 }
 
-#[deriving(Copy)]
+#[deriving(Copy,Show)]
 pub enum Row {
     Variable,
     Enum,