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)
downloadrust-c8ce32e7f45a020eebcd7329fbe33e8b53f832a3.tar.gz
rust-c8ce32e7f45a020eebcd7329fbe33e8b53f832a3.zip
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