Skip to content

Commit 78c25ea

Browse files
committed
save-analysis: API-ify impls
1 parent abe5f7b commit 78c25ea

File tree

2 files changed

+131
-53
lines changed

2 files changed

+131
-53
lines changed

src/librustc_trans/save/dump_csv.rs

Lines changed: 44 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -419,19 +419,15 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
419419
id);
420420
}
421421

422-
fn process_trait_ref(&mut self,
423-
trait_ref: &ast::TraitRef) {
424-
match self.lookup_type_ref(trait_ref.ref_id) {
425-
Some(id) => {
426-
let sub_span = self.span.sub_span_for_type_name(trait_ref.path.span);
427-
self.fmt.ref_str(recorder::TypeRef,
428-
trait_ref.path.span,
429-
sub_span,
430-
id,
431-
self.cur_scope);
432-
visit::walk_path(self, &trait_ref.path);
433-
},
434-
None => ()
422+
fn process_trait_ref(&mut self, trait_ref: &ast::TraitRef) {
423+
let trait_ref_data = self.save_ctxt.get_trait_ref_data(trait_ref, self.cur_scope);
424+
if let Some(trait_ref_data) = trait_ref_data {
425+
self.fmt.ref_str(recorder::TypeRef,
426+
trait_ref.path.span,
427+
Some(trait_ref_data.span),
428+
trait_ref_data.ref_id,
429+
trait_ref_data.scope);
430+
visit::walk_path(self, &trait_ref.path);
435431
}
436432
}
437433

@@ -600,8 +596,9 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
600596
Some(enum_data.span),
601597
enum_data.id,
602598
&enum_data.qualname,
603-
self.cur_scope,
599+
enum_data.scope,
604600
&enum_data.value);
601+
605602
for variant in &enum_definition.variants {
606603
let name = &get_ident(variant.node.name);
607604
let mut qualname = enum_data.qualname.clone();
@@ -618,7 +615,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
618615
&qualname,
619616
&enum_data.qualname,
620617
&val,
621-
item.id);
618+
enum_data.id);
622619
for arg in args {
623620
self.visit_ty(&*arg.ty);
624621
}
@@ -635,7 +632,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
635632
&qualname,
636633
&enum_data.qualname,
637634
&val,
638-
item.id);
635+
enum_data.id);
639636

640637
for field in &struct_def.fields {
641638
self.process_struct_field_def(field, variant.node.id);
@@ -644,7 +641,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
644641
}
645642
}
646643
}
647-
self.process_generic_params(ty_params, item.span, &enum_data.qualname, item.id);
644+
self.process_generic_params(ty_params, item.span, &enum_data.qualname, enum_data.id);
648645
} else {
649646
self.sess.span_bug(item.span, "expected EnumData");
650647
}
@@ -656,43 +653,37 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
656653
trait_ref: &Option<ast::TraitRef>,
657654
typ: &ast::Ty,
658655
impl_items: &[P<ast::ImplItem>]) {
659-
let trait_id = trait_ref.as_ref().and_then(|tr| self.lookup_type_ref(tr.ref_id));
660-
match typ.node {
661-
// Common case impl for a struct or something basic.
662-
ast::TyPath(None, ref path) => {
663-
let sub_span = self.span.sub_span_for_type_name(path.span);
664-
let self_id = self.lookup_type_ref(typ.id).map(|id| {
656+
let impl_data = self.save_ctxt.get_item_data(item);
657+
if let super::Data::ImplData(impl_data) = impl_data {
658+
match impl_data.self_ref {
659+
Some(ref self_ref) => {
665660
self.fmt.ref_str(recorder::TypeRef,
666-
path.span,
667-
sub_span,
668-
id,
669-
self.cur_scope);
670-
id
671-
});
672-
self.fmt.impl_str(path.span,
673-
sub_span,
674-
item.id,
675-
self_id,
676-
trait_id,
677-
self.cur_scope);
678-
},
679-
_ => {
680-
// Less useful case, impl for a compound type.
681-
self.visit_ty(&*typ);
682-
683-
let sub_span = self.span.sub_span_for_type_name(typ.span);
684-
self.fmt.impl_str(typ.span,
685-
sub_span,
686-
item.id,
687-
None,
688-
trait_id,
689-
self.cur_scope);
661+
item.span,
662+
Some(self_ref.span),
663+
self_ref.ref_id,
664+
self_ref.scope);
665+
}
666+
None => {
667+
self.visit_ty(&typ);
668+
}
669+
}
670+
if let Some(ref trait_ref_data) = impl_data.trait_ref {
671+
self.fmt.ref_str(recorder::TypeRef,
672+
item.span,
673+
Some(trait_ref_data.span),
674+
trait_ref_data.ref_id,
675+
trait_ref_data.scope);
676+
visit::walk_path(self, &trait_ref.as_ref().unwrap().path);
690677
}
691-
}
692678

693-
match *trait_ref {
694-
Some(ref trait_ref) => self.process_trait_ref(trait_ref),
695-
None => (),
679+
self.fmt.impl_str(item.span,
680+
Some(impl_data.span),
681+
impl_data.id,
682+
impl_data.self_ref.map(|data| data.ref_id),
683+
impl_data.trait_ref.map(|data| data.ref_id),
684+
impl_data.scope);
685+
} else {
686+
self.sess.span_bug(item.span, "expected ImplData");
696687
}
697688

698689
self.process_generic_params(type_parameters, item.span, "", item.id);
@@ -717,7 +708,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
717708
&val);
718709

719710
// super-traits
720-
for super_bound in trait_refs.iter() {
711+
for super_bound in &trait_refs {
721712
let trait_ref = match *super_bound {
722713
ast::TraitTyParamBound(ref trait_ref, _) => {
723714
trait_ref
@@ -1164,7 +1155,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
11641155
self.process_impl(item,
11651156
ty_params,
11661157
trait_ref,
1167-
&**typ,
1158+
&typ,
11681159
impl_items)
11691160
}
11701161
ast::ItemTrait(_, ref generics, ref trait_refs, ref methods) =>

src/librustc_trans/save/mod.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
use session::Session;
1212
use middle::ty;
13+
use middle::def;
1314

1415
use std::env;
1516
use std::fs::{self, File};
@@ -55,10 +56,14 @@ pub enum Data {
5556
ModData(ModData),
5657
/// Data for Enums.
5758
EnumData(EnumData),
59+
/// Data for impls.
60+
ImplData(ImplData),
5861

5962
/// Data for the use of some variable (e.g., the use of a local variable, which
6063
/// will refere to that variables declaration).
6164
VariableRefData(VariableRefData),
65+
/// Data for a reference to a type or trait.
66+
TypeRefData(TypeRefData),
6267
}
6368

6469
/// Data for all kinds of functions and methods.
@@ -98,6 +103,18 @@ pub struct EnumData {
98103
pub value: String,
99104
pub qualname: String,
100105
pub span: Span,
106+
pub scope: NodeId,
107+
}
108+
109+
pub struct ImplData {
110+
pub id: NodeId,
111+
pub span: Span,
112+
pub scope: NodeId,
113+
// FIXME: I'm not really sure inline data is the best way to do this. Seems
114+
// OK in this case, but generalising leads to returning chunks of AST, which
115+
// feels wrong.
116+
pub trait_ref: Option<TypeRefData>,
117+
pub self_ref: Option<TypeRefData>,
101118
}
102119

103120
/// Data for the use of some item (e.g., the use of a local variable, which
@@ -109,6 +126,13 @@ pub struct VariableRefData {
109126
pub ref_id: DefId,
110127
}
111128

129+
/// Data for a reference to a type or trait.
130+
pub struct TypeRefData {
131+
pub span: Span,
132+
pub scope: NodeId,
133+
pub ref_id: DefId,
134+
}
135+
112136

113137
impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
114138
pub fn new(sess: &'l Session,
@@ -211,8 +235,42 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
211235
value: val,
212236
span: sub_span.unwrap(),
213237
qualname: enum_name,
238+
scope: self.analysis.ty_cx.map.get_parent(item.id),
214239
})
215240
},
241+
ast::ItemImpl(_, _, _, ref trait_ref, ref typ, _) => {
242+
let mut type_data = None;
243+
let sub_span;
244+
245+
let parent = self.analysis.ty_cx.map.get_parent(item.id);
246+
247+
match typ.node {
248+
// Common case impl for a struct or something basic.
249+
ast::TyPath(None, ref path) => {
250+
sub_span = self.span_utils.sub_span_for_type_name(path.span);
251+
type_data = self.lookup_ref_id(typ.id).map(|id| TypeRefData {
252+
span: sub_span.unwrap(),
253+
scope: parent,
254+
ref_id: id,
255+
});
256+
},
257+
_ => {
258+
// Less useful case, impl for a compound type.
259+
sub_span = self.span_utils.sub_span_for_type_name(typ.span);
260+
}
261+
}
262+
263+
let trait_data =
264+
trait_ref.as_ref().and_then(|tr| self.get_trait_ref_data(tr, parent));
265+
266+
Data::ImplData(ImplData {
267+
id: item.id,
268+
span: sub_span.unwrap(),
269+
scope: parent,
270+
trait_ref: trait_data,
271+
self_ref: type_data,
272+
})
273+
}
216274
_ => {
217275
// FIXME
218276
unimplemented!();
@@ -247,6 +305,22 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
247305
}
248306
}
249307

308+
// FIXME: we ought to be able to get the parent id ourselves, but we can't
309+
// for now.
310+
pub fn get_trait_ref_data(&self,
311+
trait_ref: &ast::TraitRef,
312+
parent: NodeId)
313+
-> Option<TypeRefData> {
314+
self.lookup_ref_id(trait_ref.ref_id).map(|def_id| {
315+
let sub_span = self.span_utils.sub_span_for_type_name(trait_ref.path.span);
316+
TypeRefData {
317+
span: sub_span.unwrap(),
318+
scope: parent,
319+
ref_id: def_id,
320+
}
321+
})
322+
}
323+
250324
pub fn get_expr_data(&self, expr: &ast::Expr) -> Data {
251325
match expr.node {
252326
ast::ExprField(ref sub_ex, ident) => {
@@ -286,6 +360,19 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
286360
// FIXME
287361
unimplemented!();
288362
}
363+
364+
fn lookup_ref_id(&self, ref_id: NodeId) -> Option<DefId> {
365+
if !self.analysis.ty_cx.def_map.borrow().contains_key(&ref_id) {
366+
self.sess.bug(&format!("def_map has no key for {} in lookup_type_ref",
367+
ref_id));
368+
}
369+
let def = self.analysis.ty_cx.def_map.borrow().get(&ref_id).unwrap().full_def();
370+
match def {
371+
def::DefPrimTy(_) => None,
372+
_ => Some(def.def_id()),
373+
}
374+
}
375+
289376
}
290377

291378
// An AST visitor for collecting paths from patterns.

0 commit comments

Comments
 (0)