From 4c4eabfd6c7e39e2b01851af2e58d38d898aac39 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Sun, 28 Dec 2014 14:37:08 +1300 Subject: [PATCH] save-analysis: fix spans for paths to struct variants --- src/librustc_trans/save/mod.rs | 99 +++++++++++++++-------------- src/librustc_trans/save/recorder.rs | 2 +- 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) { 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 { - "".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 { + "".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,