about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2015-06-09 10:36:30 +1200
committerNick Cameron <ncameron@mozilla.com>2015-06-15 08:16:35 +1200
commit92d66764121a719d6755a7c33829598d32c9f4ba (patch)
tree9dcb9459996a7526556a2bc7ff87f9856657a409
parent788fdddf3735f49c06b847578a090a863ed1c32d (diff)
downloadrust-92d66764121a719d6755a7c33829598d32c9f4ba.tar.gz
rust-92d66764121a719d6755a7c33829598d32c9f4ba.zip
save-analysis: use a macro for 'downcasting'
-rw-r--r--src/librustc_trans/save/dump_csv.rs263
-rw-r--r--src/librustc_trans/save/mod.rs8
2 files changed, 132 insertions, 139 deletions
diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs
index 3b34fbab326..ffa8c524b58 100644
--- a/src/librustc_trans/save/dump_csv.rs
+++ b/src/librustc_trans/save/dump_csv.rs
@@ -54,6 +54,15 @@ use super::recorder::{Recorder, FmtStrs};
 
 use util::ppaux;
 
+macro_rules! down_cast_data {
+    ($id:ident, $kind:ident, $this:ident, $sp:expr) => {
+        let $id = if let super::Data::$kind(data) = $id {
+            data
+        } else {
+            $this.sess.span_bug($sp, &format!("unexpected data kind: {:?}", $id));
+        };
+    };
+}
 
 pub struct DumpCsvVisitor<'l, 'tcx: 'l> {
     save_ctxt: SaveContext<'l, 'tcx>,
@@ -436,17 +445,14 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                                 parent_id: NodeId) {
         let field_data = self.save_ctxt.get_field_data(field, parent_id);
         if let Some(field_data) = field_data {
-            if let super::Data::VariableData(field_data) = field_data {
-                self.fmt.field_str(field.span,
-                                   Some(field_data.span),
-                                   field_data.id,
-                                   &field_data.name,
-                                   &field_data.qualname,
-                                   &field_data.type_value,
-                                   field_data.scope);
-            } else {
-                self.sess.span_bug(field.span, "expected VariableData");
-            }
+            down_cast_data!(field_data, VariableData, self, field.span);
+            self.fmt.field_str(field.span,
+                               Some(field_data.span),
+                               field_data.id,
+                               &field_data.name,
+                               &field_data.qualname,
+                               &field_data.type_value,
+                               field_data.scope);
         }
     }
 
@@ -483,19 +489,16 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                   ty_params: &ast::Generics,
                   body: &ast::Block) {
         let fn_data = self.save_ctxt.get_item_data(item);
-        if let super::Data::FunctionData(fn_data) = fn_data {
-            self.fmt.fn_str(item.span,
-                            Some(fn_data.span),
-                            fn_data.id,
-                            &fn_data.qualname,
-                            fn_data.scope);
+        down_cast_data!(fn_data, FunctionData, self, item.span);
+        self.fmt.fn_str(item.span,
+                        Some(fn_data.span),
+                        fn_data.id,
+                        &fn_data.qualname,
+                        fn_data.scope);
 
 
-            self.process_formals(&decl.inputs, &fn_data.qualname);
-            self.process_generic_params(ty_params, item.span, &fn_data.qualname, item.id);
-        } else {
-            self.sess.span_bug(item.span, "expected FunctionData");
-        }
+        self.process_formals(&decl.inputs, &fn_data.qualname);
+        self.process_generic_params(ty_params, item.span, &fn_data.qualname, item.id);
 
         for arg in &decl.inputs {
             self.visit_ty(&arg.ty);
@@ -514,18 +517,15 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                                     expr: &ast::Expr)
     {
         let var_data = self.save_ctxt.get_item_data(item);
-        if let super::Data::VariableData(var_data) = var_data {
-            self.fmt.static_str(item.span,
-                                Some(var_data.span),
-                                var_data.id,
-                                &var_data.name,
-                                &var_data.qualname,
-                                &var_data.value,
-                                &var_data.type_value,
-                                var_data.scope);
-        } else {
-            self.sess.span_bug(item.span, "expected VariableData");
-        }
+        down_cast_data!(var_data, VariableData, self, item.span);
+        self.fmt.static_str(item.span,
+                            Some(var_data.span),
+                            var_data.id,
+                            &var_data.name,
+                            &var_data.qualname,
+                            &var_data.value,
+                            &var_data.type_value,
+                            var_data.scope);
 
         self.visit_ty(&typ);
         self.visit_expr(expr);
@@ -591,60 +591,57 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                     enum_definition: &ast::EnumDef,
                     ty_params: &ast::Generics) {
         let enum_data = self.save_ctxt.get_item_data(item);
-        if let super::Data::EnumData(enum_data) = enum_data {
-            self.fmt.enum_str(item.span,
-                              Some(enum_data.span),
-                              enum_data.id,
-                              &enum_data.qualname,
-                              enum_data.scope,
-                              &enum_data.value);
-
-            for variant in &enum_definition.variants {
-                let name = &get_ident(variant.node.name);
-                let mut qualname = enum_data.qualname.clone();
-                qualname.push_str("::");
-                qualname.push_str(name);
-                let val = self.span.snippet(variant.span);
-                match variant.node.kind {
-                    ast::TupleVariantKind(ref args) => {
-                        // first ident in span is the variant's name
-                        self.fmt.tuple_variant_str(variant.span,
-                                                   self.span.span_for_first_ident(variant.span),
-                                                   variant.node.id,
-                                                   name,
-                                                   &qualname,
-                                                   &enum_data.qualname,
-                                                   &val,
-                                                   enum_data.id);
-                        for arg in args {
-                            self.visit_ty(&*arg.ty);
-                        }
+        down_cast_data!(enum_data, EnumData, self, item.span);
+        self.fmt.enum_str(item.span,
+                          Some(enum_data.span),
+                          enum_data.id,
+                          &enum_data.qualname,
+                          enum_data.scope,
+                          &enum_data.value);
+
+        for variant in &enum_definition.variants {
+            let name = &get_ident(variant.node.name);
+            let mut qualname = enum_data.qualname.clone();
+            qualname.push_str("::");
+            qualname.push_str(name);
+            let val = self.span.snippet(variant.span);
+            match variant.node.kind {
+                ast::TupleVariantKind(ref args) => {
+                    // first ident in span is the variant's name
+                    self.fmt.tuple_variant_str(variant.span,
+                                               self.span.span_for_first_ident(variant.span),
+                                               variant.node.id,
+                                               name,
+                                               &qualname,
+                                               &enum_data.qualname,
+                                               &val,
+                                               enum_data.id);
+                    for arg in args {
+                        self.visit_ty(&*arg.ty);
                     }
-                    ast::StructVariantKind(ref struct_def) => {
-                        let ctor_id = match struct_def.ctor_id {
-                            Some(node_id) => node_id,
-                            None => -1,
-                        };
-                        self.fmt.struct_variant_str(variant.span,
-                                                    self.span.span_for_first_ident(variant.span),
-                                                    variant.node.id,
-                                                    ctor_id,
-                                                    &qualname,
-                                                    &enum_data.qualname,
-                                                    &val,
-                                                    enum_data.id);
-
-                        for field in &struct_def.fields {
-                            self.process_struct_field_def(field, variant.node.id);
-                            self.visit_ty(&*field.node.ty);
-                        }
+                }
+                ast::StructVariantKind(ref struct_def) => {
+                    let ctor_id = match struct_def.ctor_id {
+                        Some(node_id) => node_id,
+                        None => -1,
+                    };
+                    self.fmt.struct_variant_str(variant.span,
+                                                self.span.span_for_first_ident(variant.span),
+                                                variant.node.id,
+                                                ctor_id,
+                                                &qualname,
+                                                &enum_data.qualname,
+                                                &val,
+                                                enum_data.id);
+
+                    for field in &struct_def.fields {
+                        self.process_struct_field_def(field, variant.node.id);
+                        self.visit_ty(&*field.node.ty);
                     }
                 }
             }
-            self.process_generic_params(ty_params, item.span, &enum_data.qualname, enum_data.id);
-        } else {
-            self.sess.span_bug(item.span, "expected EnumData");
         }
+        self.process_generic_params(ty_params, item.span, &enum_data.qualname, enum_data.id);
     }
 
     fn process_impl(&mut self,
@@ -654,38 +651,35 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
                     typ: &ast::Ty,
                     impl_items: &[P<ast::ImplItem>]) {
         let impl_data = self.save_ctxt.get_item_data(item);
-        if let super::Data::ImplData(impl_data) = impl_data {
-            match impl_data.self_ref {
-                Some(ref self_ref) => {
-                    self.fmt.ref_str(recorder::TypeRef,
-                                     item.span,
-                                     Some(self_ref.span),
-                                     self_ref.ref_id,
-                                     self_ref.scope);
-                }
-                None => {
-                    self.visit_ty(&typ);
-                }
-            }
-            if let Some(ref trait_ref_data) = impl_data.trait_ref {
+        down_cast_data!(impl_data, ImplData, self, item.span);
+        match impl_data.self_ref {
+            Some(ref self_ref) => {
                 self.fmt.ref_str(recorder::TypeRef,
                                  item.span,
-                                 Some(trait_ref_data.span),
-                                 trait_ref_data.ref_id,
-                                 trait_ref_data.scope);
-                visit::walk_path(self, &trait_ref.as_ref().unwrap().path);
+                                 Some(self_ref.span),
+                                 self_ref.ref_id,
+                                 self_ref.scope);
             }
-
-            self.fmt.impl_str(item.span,
-                              Some(impl_data.span),
-                              impl_data.id,
-                              impl_data.self_ref.map(|data| data.ref_id),
-                              impl_data.trait_ref.map(|data| data.ref_id),
-                              impl_data.scope);
-        } else {
-            self.sess.span_bug(item.span, "expected ImplData");
+            None => {
+                self.visit_ty(&typ);
+            }
+        }
+        if let Some(ref trait_ref_data) = impl_data.trait_ref {
+            self.fmt.ref_str(recorder::TypeRef,
+                             item.span,
+                             Some(trait_ref_data.span),
+                             trait_ref_data.ref_id,
+                             trait_ref_data.scope);
+            visit::walk_path(self, &trait_ref.as_ref().unwrap().path);
         }
 
+        self.fmt.impl_str(item.span,
+                          Some(impl_data.span),
+                          impl_data.id,
+                          impl_data.self_ref.map(|data| data.ref_id),
+                          impl_data.trait_ref.map(|data| data.ref_id),
+                          impl_data.scope);
+
         self.process_generic_params(type_parameters, item.span, "", item.id);
         for impl_item in impl_items {
             self.visit_impl_item(impl_item);
@@ -746,16 +740,13 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
     fn process_mod(&mut self,
                    item: &ast::Item) {  // The module in question, represented as an item.
         let mod_data = self.save_ctxt.get_item_data(item);
-        if let super::Data::ModData(mod_data) = mod_data {
-            self.fmt.mod_str(item.span,
-                             Some(mod_data.span),
-                             mod_data.id,
-                             &mod_data.qualname,
-                             mod_data.scope,
-                             &mod_data.filename);
-        } else {
-            self.sess.span_bug(item.span, "expected ModData");
-        }
+        down_cast_data!(mod_data, ModData, self, item.span);
+        self.fmt.mod_str(item.span,
+                         Some(mod_data.span),
+                         mod_data.id,
+                         &mod_data.qualname,
+                         mod_data.scope,
+                         &mod_data.filename);
     }
 
     fn process_path(&mut self,
@@ -883,16 +874,13 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
         self.write_sub_paths_truncated(path, false);
 
         let struct_lit_data = self.save_ctxt.get_expr_data(ex);
-        let struct_def = if let super::Data::TypeRefData(struct_lit_data) = struct_lit_data {
-            self.fmt.ref_str(recorder::TypeRef,
-                             ex.span,
-                             Some(struct_lit_data.span),
-                             struct_lit_data.ref_id,
-                             struct_lit_data.scope);
-            struct_lit_data.ref_id
-        } else {
-            self.sess.span_bug(ex.span, "expected TypeRefData");
-        };
+        down_cast_data!(struct_lit_data, TypeRefData, self, ex.span);
+        self.fmt.ref_str(recorder::TypeRef,
+                         ex.span,
+                         Some(struct_lit_data.span),
+                         struct_lit_data.ref_id,
+                         struct_lit_data.scope);
+        let struct_def = struct_lit_data.ref_id;
 
         for field in fields {
             if generated_code(field.ident.span) {
@@ -1269,15 +1257,12 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
                 self.visit_expr(&sub_ex);
 
                 let field_data = self.save_ctxt.get_expr_data(ex);
-                if let super::Data::VariableRefData(field_data) = field_data {
-                    self.fmt.ref_str(recorder::VarRef,
-                                     ex.span,
-                                     Some(field_data.span),
-                                     field_data.ref_id,
-                                     field_data.scope);
-                } else {
-                    self.sess.span_bug(ex.span, "expected VariableRefData");
-                }
+                down_cast_data!(field_data, VariableRefData, self, ex.span);
+                self.fmt.ref_str(recorder::VarRef,
+                                 ex.span,
+                                 Some(field_data.span),
+                                 field_data.ref_id,
+                                 field_data.scope);
             },
             ast::ExprTupField(ref sub_ex, idx) => {
                 if generated_code(sub_ex.span) {
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index 5e6da42d688..0e5f8384207 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -47,6 +47,7 @@ pub struct CrateData {
 
 /// Data for any entity in the Rust language. The actual data contained varied
 /// with the kind of entity being queried. See the nested structs for details.
+#[derive(Debug)]
 pub enum Data {
     /// Data for all kinds of functions and methods.
     FunctionData(FunctionData),
@@ -67,6 +68,7 @@ pub enum Data {
 }
 
 /// Data for all kinds of functions and methods.
+#[derive(Debug)]
 pub struct FunctionData {
     pub id: NodeId,
     pub name: String,
@@ -77,6 +79,7 @@ pub struct FunctionData {
 }
 
 /// Data for local and global variables (consts and statics).
+#[derive(Debug)]
 pub struct VariableData {
     pub id: NodeId,
     pub name: String,
@@ -88,6 +91,7 @@ pub struct VariableData {
 }
 
 /// Data for modules.
+#[derive(Debug)]
 pub struct ModData {
     pub id: NodeId,
     pub name: String,
@@ -98,6 +102,7 @@ pub struct ModData {
 }
 
 /// Data for enum declarations.
+#[derive(Debug)]
 pub struct EnumData {
     pub id: NodeId,
     pub value: String,
@@ -106,6 +111,7 @@ pub struct EnumData {
     pub scope: NodeId,
 }
 
+#[derive(Debug)]
 pub struct ImplData {
     pub id: NodeId,
     pub span: Span,
@@ -119,6 +125,7 @@ pub struct ImplData {
 
 /// Data for the use of some item (e.g., the use of a local variable, which
 /// will refere to that variables declaration (by ref_id)).
+#[derive(Debug)]
 pub struct VariableRefData {
     pub name: String,
     pub span: Span,
@@ -127,6 +134,7 @@ pub struct VariableRefData {
 }
 
 /// Data for a reference to a type or trait.
+#[derive(Debug)]
 pub struct TypeRefData {
     pub span: Span,
     pub scope: NodeId,