about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-08-22 17:58:05 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-08-22 20:32:09 -0700
commitc8ce32e7f45a020eebcd7329fbe33e8b53f832a3 (patch)
tree63b905a71ab35dd5a1690213ea54e966842baaaa /src/rustc
parentb3b1c3bf4d72b59280cea647030c9813007f7b10 (diff)
Represent "item families" in the decoder as an enum
This eliminates some match checks. Also get rid of other match checks
in metadata code.
Diffstat (limited to 'src/rustc')
-rw-r--r--src/rustc/metadata/decoder.rs190
-rw-r--r--src/rustc/metadata/encoder.rs11
-rw-r--r--src/rustc/metadata/tydecode.rs48
3 files changed, 157 insertions, 92 deletions
diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs
index 1b4fad2ca66..a1a2b7245eb 100644
--- a/src/rustc/metadata/decoder.rs
+++ b/src/rustc/metadata/decoder.rs
@@ -105,9 +105,56 @@ fn lookup_item(item_id: int, data: @~[u8]) -> ebml::doc {
     }
 }
 
-fn item_family(item: ebml::doc) -> char {
+enum Family {
+    Const,                 // c
+    Fn,                    // f
+    UnsafeFn,              // u
+    PureFn,                // p
+    StaticMethod,          // F
+    UnsafeStaticMethod,    // U
+    PureStaticMethod,      // P
+    ForeignFn,             // e
+    Type,                  // y
+    ForeignType,           // T
+    Mod,                   // m
+    ForeignMod,            // n
+    Enum,                  // t
+    Variant,               // v
+    Impl,                  // i
+    Trait,                 // I
+    Class,                 // C
+    Struct,                // S
+    PublicField,           // g
+    PrivateField,          // j
+    InheritedField         // N
+}
+
+fn item_family(item: ebml::doc) -> Family {
     let fam = ebml::get_doc(item, tag_items_data_item_family);
-    ebml::doc_as_u8(fam) as char
+    match ebml::doc_as_u8(fam) as char {
+      'c' => Const,
+      'f' => Fn,
+      'u' => UnsafeFn,
+      'p' => PureFn,
+      'F' => StaticMethod,
+      'U' => UnsafeStaticMethod,
+      'P' => PureStaticMethod,
+      'e' => ForeignFn,
+      'y' => Type,
+      'T' => ForeignType,
+      'm' => Mod,
+      'n' => ForeignMod,
+      't' => Enum,
+      'v' => Variant,
+      'i' => Impl,
+      'I' => Trait,
+      'C' => Class,
+      'S' => Struct,
+      'g' => PublicField,
+      'j' => PrivateField,
+      'N' => InheritedField,
+       c => fail (#fmt("unexpected family char: %c", c))
+    }
 }
 
 fn item_symbol(item: ebml::doc) -> ~str {
@@ -245,31 +292,34 @@ fn item_name(intr: ident_interner, item: ebml::doc) -> ast::ident {
 
 fn item_to_def_like(item: ebml::doc, did: ast::def_id, cnum: ast::crate_num)
         -> def_like {
-    let fam_ch = item_family(item);
-    match fam_ch {
-      'c' => dl_def(ast::def_const(did)),
-      'C' => dl_def(ast::def_class(did, true)),
-      'S' => dl_def(ast::def_class(did, false)),
-      'u' => dl_def(ast::def_fn(did, ast::unsafe_fn)),
-      'f' => dl_def(ast::def_fn(did, ast::impure_fn)),
-      'p' => dl_def(ast::def_fn(did, ast::pure_fn)),
-      'e' => dl_def(ast::def_fn(did, ast::extern_fn)),
-      'U' => dl_def(ast::def_static_method(did, ast::unsafe_fn)),
-      'F' => dl_def(ast::def_static_method(did, ast::impure_fn)),
-      'P' => dl_def(ast::def_static_method(did, ast::pure_fn)),
-      'y' => dl_def(ast::def_ty(did)),
-      't' => dl_def(ast::def_ty(did)),
-      'm' => dl_def(ast::def_mod(did)),
-      'n' => dl_def(ast::def_foreign_mod(did)),
-      'v' => {
-        let mut tid = option::get(item_parent_item(item));
-        tid = {crate: cnum, node: tid.node};
-        dl_def(ast::def_variant(tid, did))
+    let fam = item_family(item);
+    match fam {
+      Const     => dl_def(ast::def_const(did)),
+      Class     => dl_def(ast::def_class(did, true)),
+      Struct    => dl_def(ast::def_class(did, false)),
+      UnsafeFn  => dl_def(ast::def_fn(did, ast::unsafe_fn)),
+      Fn        => dl_def(ast::def_fn(did, ast::impure_fn)),
+      PureFn    => dl_def(ast::def_fn(did, ast::pure_fn)),
+      ForeignFn => dl_def(ast::def_fn(did, ast::extern_fn)),
+      UnsafeStaticMethod => dl_def(ast::def_static_method(did,
+                                                          ast::unsafe_fn)),
+      StaticMethod => dl_def(ast::def_static_method(did, ast::impure_fn)),
+      PureStaticMethod => dl_def(ast::def_static_method(did, ast::pure_fn)),
+      Type | ForeignType => dl_def(ast::def_ty(did)),
+      Mod => dl_def(ast::def_mod(did)),
+      ForeignMod => dl_def(ast::def_foreign_mod(did)),
+      Variant => {
+          match item_parent_item(item) {
+              some(t) => {
+                let tid = {crate: cnum, node: t.node};
+                dl_def(ast::def_variant(tid, did))
+              }
+              none => fail ~"item_to_def_like: enum item has no parent"
+          }
       }
-      'I' => dl_def(ast::def_ty(did)),
-      'i' => dl_impl(did),
-      'g' | 'j' | 'N' => dl_field,
-      ch => fail fmt!{"unexpected family code: '%c'", ch}
+      Trait | Enum => dl_def(ast::def_ty(did)),
+      Impl => dl_impl(did),
+      PublicField | PrivateField | InheritedField => dl_field,
     }
 }
 
@@ -642,12 +692,14 @@ fn get_trait_methods(intr: ident_interner, cdata: cmd, id: ast::node_id,
         let self_ty = get_self_ty(mth);
         vec::push(result, {ident: name, tps: bounds, fty: fty,
                     self_ty: self_ty,
-                    purity: match check item_family(mth) {
-                      'u' => ast::unsafe_fn,
-                      'f' => ast::impure_fn,
-                      'p' => ast::pure_fn
+                    purity: match item_family(mth) {
+                      UnsafeFn => ast::unsafe_fn,
+                      Fn => ast::impure_fn,
+                      PureFn => ast::pure_fn,
+                      _ => fail ~"bad purity"
                     }, vis: ast::public});
     }
+    #debug("get_trait_methods: }");
     @result
 }
 
@@ -659,7 +711,7 @@ fn get_method_names_if_trait(intr: ident_interner, cdata: cmd,
                           -> option<@DVec<(ast::ident, ast::self_ty_)>> {
 
     let item = lookup_item(node_id, cdata.data);
-    if item_family(item) != 'I' {
+    if item_family(item) != Trait {
         return none;
     }
 
@@ -685,7 +737,7 @@ fn get_item_attrs(cdata: cmd,
 
 // Helper function that gets either fields or methods
 fn get_class_members(intr: ident_interner, cdata: cmd, id: ast::node_id,
-                     p: fn(char) -> bool) -> ~[ty::field_ty] {
+                     p: fn(Family) -> bool) -> ~[ty::field_ty] {
     let data = cdata.data;
     let item = lookup_item(id, data);
     let mut result = ~[];
@@ -702,33 +754,31 @@ fn get_class_members(intr: ident_interner, cdata: cmd, id: ast::node_id,
     result
 }
 
-pure fn family_to_visibility(family: char) -> ast::visibility {
+pure fn family_to_visibility(family: Family) -> ast::visibility {
     match family {
-      'g' => ast::public,
-      'j' => ast::private,
-      'N' => ast::inherited,
+      PublicField => ast::public,
+      PrivateField => ast::private,
+      InheritedField => ast::inherited,
       _ => fail
     }
 }
 
-/* 'g' for public field, 'j' for private field, 'N' for inherited field */
 fn get_class_fields(intr: ident_interner, cdata: cmd, id: ast::node_id)
     -> ~[ty::field_ty] {
-    get_class_members(intr, cdata, id, |f| f == 'g' || f == 'j' || f == 'N')
+    get_class_members(intr, cdata, id, |f| f == PublicField
+                      || f == PrivateField || f == InheritedField)
 }
 
-fn family_has_type_params(fam_ch: char) -> bool {
-    match fam_ch {
-      'c' | 'T' | 'm' | 'n' | 'g' | 'h' | 'j' | 'e' | 'N' => false,
-      'f' | 'u' | 'p' | 'F' | 'U' | 'P' | 'y' | 't' | 'v' | 'i' | 'I' | 'C'
-          | 'a' | 'S'
-          => true,
-      _ => fail fmt!("'%c' is not a family", fam_ch)
+fn family_has_type_params(fam: Family) -> bool {
+    match fam {
+      Const | ForeignType | Mod | ForeignMod | PublicField | PrivateField
+      | ForeignFn => false,
+      _           => true
     }
 }
 
-fn family_names_type(fam_ch: char) -> bool {
-    match fam_ch { 'y' | 't' | 'I' => true, _ => false }
+fn family_names_type(fam: Family) -> bool {
+    match fam { Type | Mod | Trait => true, _ => false }
 }
 
 fn read_path(d: ebml::doc) -> {path: ~str, pos: uint} {
@@ -748,29 +798,29 @@ fn describe_def(items: ebml::doc, id: ast::def_id) -> ~str {
     return item_family_to_str(item_family(it));
 }
 
-fn item_family_to_str(fam: char) -> ~str {
-    match check fam {
-      'c' => return ~"const",
-      'f' => return ~"fn",
-      'u' => return ~"unsafe fn",
-      'p' => return ~"pure fn",
-      'F' => return ~"static method",
-      'U' => return ~"unsafe static method",
-      'P' => return ~"pure static method",
-      'e' => return ~"foreign fn",
-      'y' => return ~"type",
-      'T' => return ~"foreign type",
-      't' => return ~"type",
-      'm' => return ~"mod",
-      'n' => return ~"foreign mod",
-      'v' => return ~"enum",
-      'i' => return ~"impl",
-      'I' => return ~"trait",
-      'C' => return ~"class",
-      'S' => return ~"struct",
-      'g' => return ~"public field",
-      'j' => return ~"private field",
-      'N' => return ~"inherited field"
+fn item_family_to_str(fam: Family) -> ~str {
+    match fam {
+      Const => ~"const",
+      Fn => ~"fn",
+      UnsafeFn => ~"unsafe fn",
+      PureFn => ~"pure fn",
+      StaticMethod => ~"static method",
+      UnsafeStaticMethod => ~"unsafe static method",
+      PureStaticMethod => ~"pure static method",
+      ForeignFn => ~"foreign fn",
+      Type => ~"type",
+      ForeignType => ~"foreign type",
+      Mod => ~"mod",
+      ForeignMod => ~"foreign mod",
+      Enum => ~"enum",
+      Variant => ~"variant",
+      Impl => ~"impl",
+      Trait => ~"trait",
+      Class => ~"class",
+      Struct => ~"struct",
+      PublicField => ~"public field",
+      PrivateField => ~"private field",
+      InheritedField => ~"inherited field",
     }
 }
 
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index e14e64ddd0c..7b2e2b8a217 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -88,7 +88,7 @@ fn encode_region_param(ecx: @encode_ctxt, ebml_w: ebml::writer,
 fn encode_mutability(ebml_w: ebml::writer, mt: class_mutability) {
     do ebml_w.wr_tag(tag_class_mut) {
         let val = match mt {
-          class_immutable => 'i',
+          class_immutable => 'a',
           class_mutable => 'm'
         };
         ebml_w.writer.write(&[val as u8]);
@@ -472,7 +472,7 @@ fn purity_static_method_family(p: purity) -> char {
       unsafe_fn => 'U',
       pure_fn => 'P',
       impure_fn => 'F',
-      extern_fn => 'E'
+      _ => fail ~"extern fn can't be static"
     }
 }
 
@@ -813,19 +813,22 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
         visit_expr: |_e, _cx, _v| { },
         visit_item: |i, cx, v, copy ebml_w| {
             visit::visit_item(i, cx, v);
-            match check ecx.tcx.items.get(i.id) {
+            match ecx.tcx.items.get(i.id) {
               ast_map::node_item(_, pt) => {
                 encode_info_for_item(ecx, ebml_w, i, index, *pt);
               }
+              _ => fail ~"bad item"
             }
         },
         visit_foreign_item: |ni, cx, v, copy ebml_w| {
             visit::visit_foreign_item(ni, cx, v);
-            match check ecx.tcx.items.get(ni.id) {
+            match ecx.tcx.items.get(ni.id) {
               ast_map::node_foreign_item(_, abi, pt) => {
                 encode_info_for_foreign_item(ecx, ebml_w, ni,
                                              index, *pt, abi);
               }
+              // case for separate item and foreign-item tables
+              _ => fail ~"bad foreign item"
             }
         }
         with *visit::default_visitor()
diff --git a/src/rustc/metadata/tydecode.rs b/src/rustc/metadata/tydecode.rs
index 5b76e0da7f5..3677dce74d8 100644
--- a/src/rustc/metadata/tydecode.rs
+++ b/src/rustc/metadata/tydecode.rs
@@ -1,5 +1,8 @@
 // Type decoding
 
+// tjc note: Would be great to have a `match check` macro equivalent
+// for some of these
+
 import syntax::ast;
 import syntax::ast::*;
 import syntax::ast_util;
@@ -103,10 +106,11 @@ fn parse_vstore(st: @pstate) -> ty::vstore {
         return ty::vstore_fixed(n);
     }
 
-    match check next(st) {
+    match next(st) {
       '~' => ty::vstore_uniq,
       '@' => ty::vstore_box,
-      '&' => ty::vstore_slice(parse_region(st))
+      '&' => ty::vstore_slice(parse_region(st)),
+      _ => fail ~"parse_vstore: bad input"
     }
 }
 
@@ -126,7 +130,7 @@ fn parse_substs(st: @pstate, conv: conv_did) -> ty::substs {
 }
 
 fn parse_bound_region(st: @pstate) -> ty::bound_region {
-    match check next(st) {
+    match next(st) {
       's' => ty::br_self,
       'a' => {
         let id = parse_int(st) as uint;
@@ -138,12 +142,13 @@ fn parse_bound_region(st: @pstate) -> ty::bound_region {
         let id = parse_int(st);
         assert next(st) == '|';
         ty::br_cap_avoid(id, @parse_bound_region(st))
-      }
+      },
+      _ => fail ~"parse_bound_region: bad input"
     }
 }
 
 fn parse_region(st: @pstate) -> ty::region {
-    match check next(st) {
+    match next(st) {
       'b' => {
         ty::re_bound(parse_bound_region(st))
       }
@@ -163,13 +168,15 @@ fn parse_region(st: @pstate) -> ty::region {
       't' => {
         ty::re_static
       }
+      _ => fail ~"parse_region: bad input"
     }
 }
 
 fn parse_opt<T>(st: @pstate, f: fn() -> T) -> option<T> {
-    match check next(st) {
+    match next(st) {
       'n' => none,
-      's' => some(f())
+      's' => some(f()),
+      _ => fail ~"parse_opt: bad input"
     }
 }
 
@@ -183,7 +190,7 @@ fn parse_str(st: @pstate, term: char) -> ~str {
 }
 
 fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
-    match check next(st) {
+    match next(st) {
       'n' => return ty::mk_nil(st.tcx),
       'z' => return ty::mk_bot(st.tcx),
       'b' => return ty::mk_bool(st.tcx),
@@ -191,7 +198,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
       'u' => return ty::mk_uint(st.tcx),
       'l' => return ty::mk_float(st.tcx),
       'M' => {
-        match check next(st) {
+        match next(st) {
           'b' => return ty::mk_mach_uint(st.tcx, ast::ty_u8),
           'w' => return ty::mk_mach_uint(st.tcx, ast::ty_u16),
           'l' => return ty::mk_mach_uint(st.tcx, ast::ty_u32),
@@ -201,7 +208,8 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
           'L' => return ty::mk_mach_int(st.tcx, ast::ty_i32),
           'D' => return ty::mk_mach_int(st.tcx, ast::ty_i64),
           'f' => return ty::mk_mach_float(st.tcx, ast::ty_f32),
-          'F' => return ty::mk_mach_float(st.tcx, ast::ty_f64)
+          'F' => return ty::mk_mach_float(st.tcx, ast::ty_f64),
+          _ => fail ~"parse_ty: bad numeric type"
         }
       }
       'c' => return ty::mk_char(st.tcx),
@@ -270,10 +278,11 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
       }
       'Y' => return ty::mk_type(st.tcx),
       'C' => {
-        let ck = match check next(st) {
+        let ck = match next(st) {
           '&' => ty::ck_block,
           '@' => ty::ck_box,
-          '~' => ty::ck_uniq
+          '~' => ty::ck_uniq,
+          _ => fail ~"parse_ty: bad closure kind"
         };
         return ty::mk_opaque_closure_ptr(st.tcx, ck);
       }
@@ -354,11 +363,12 @@ fn parse_hex(st: @pstate) -> uint {
 }
 
 fn parse_purity(c: char) -> purity {
-    match check c {
+    match c {
       'u' => unsafe_fn,
       'p' => pure_fn,
       'i' => impure_fn,
-      'c' => extern_fn
+      'c' => extern_fn,
+      _ => fail ~"parse_purity: bad purity"
     }
 }
 
@@ -369,12 +379,13 @@ fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::fn_ty {
     assert (next(st) == '[');
     let mut inputs: ~[ty::arg] = ~[];
     while peek(st) != ']' {
-        let mode = match check peek(st) {
+        let mode = match peek(st) {
           '&' => ast::by_mutbl_ref,
           '-' => ast::by_move,
           '+' => ast::by_copy,
           '=' => ast::by_ref,
-          '#' => ast::by_val
+          '#' => ast::by_val,
+          _ => fail ~"bad mode"
         };
         st.pos += 1u;
         vec::push(inputs, {mode: ast::expl(mode), ty: parse_ty(st, conv)});
@@ -422,13 +433,14 @@ fn parse_bounds_data(data: @~[u8], start: uint,
 fn parse_bounds(st: @pstate, conv: conv_did) -> @~[ty::param_bound] {
     let mut bounds = ~[];
     loop {
-        vec::push(bounds, match check next(st) {
+        vec::push(bounds, match next(st) {
           'S' => ty::bound_send,
           'C' => ty::bound_copy,
           'K' => ty::bound_const,
           'O' => ty::bound_owned,
           'I' => ty::bound_trait(parse_ty(st, conv)),
-          '.' => break
+          '.' => break,
+          _ => fail ~"parse_bounds: bad bounds"
         });
     }
     @bounds