Skip to content

Commit c8ce32e

Browse files
committed
Represent "item families" in the decoder as an enum
This eliminates some match checks. Also get rid of other match checks in metadata code.
1 parent b3b1c3b commit c8ce32e

File tree

3 files changed

+157
-92
lines changed

3 files changed

+157
-92
lines changed

src/rustc/metadata/decoder.rs

Lines changed: 120 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,56 @@ fn lookup_item(item_id: int, data: @~[u8]) -> ebml::doc {
105105
}
106106
}
107107

108-
fn item_family(item: ebml::doc) -> char {
108+
enum Family {
109+
Const, // c
110+
Fn, // f
111+
UnsafeFn, // u
112+
PureFn, // p
113+
StaticMethod, // F
114+
UnsafeStaticMethod, // U
115+
PureStaticMethod, // P
116+
ForeignFn, // e
117+
Type, // y
118+
ForeignType, // T
119+
Mod, // m
120+
ForeignMod, // n
121+
Enum, // t
122+
Variant, // v
123+
Impl, // i
124+
Trait, // I
125+
Class, // C
126+
Struct, // S
127+
PublicField, // g
128+
PrivateField, // j
129+
InheritedField // N
130+
}
131+
132+
fn item_family(item: ebml::doc) -> Family {
109133
let fam = ebml::get_doc(item, tag_items_data_item_family);
110-
ebml::doc_as_u8(fam) as char
134+
match ebml::doc_as_u8(fam) as char {
135+
'c' => Const,
136+
'f' => Fn,
137+
'u' => UnsafeFn,
138+
'p' => PureFn,
139+
'F' => StaticMethod,
140+
'U' => UnsafeStaticMethod,
141+
'P' => PureStaticMethod,
142+
'e' => ForeignFn,
143+
'y' => Type,
144+
'T' => ForeignType,
145+
'm' => Mod,
146+
'n' => ForeignMod,
147+
't' => Enum,
148+
'v' => Variant,
149+
'i' => Impl,
150+
'I' => Trait,
151+
'C' => Class,
152+
'S' => Struct,
153+
'g' => PublicField,
154+
'j' => PrivateField,
155+
'N' => InheritedField,
156+
c => fail (#fmt("unexpected family char: %c", c))
157+
}
111158
}
112159

113160
fn item_symbol(item: ebml::doc) -> ~str {
@@ -245,31 +292,34 @@ fn item_name(intr: ident_interner, item: ebml::doc) -> ast::ident {
245292

246293
fn item_to_def_like(item: ebml::doc, did: ast::def_id, cnum: ast::crate_num)
247294
-> def_like {
248-
let fam_ch = item_family(item);
249-
match fam_ch {
250-
'c' => dl_def(ast::def_const(did)),
251-
'C' => dl_def(ast::def_class(did, true)),
252-
'S' => dl_def(ast::def_class(did, false)),
253-
'u' => dl_def(ast::def_fn(did, ast::unsafe_fn)),
254-
'f' => dl_def(ast::def_fn(did, ast::impure_fn)),
255-
'p' => dl_def(ast::def_fn(did, ast::pure_fn)),
256-
'e' => dl_def(ast::def_fn(did, ast::extern_fn)),
257-
'U' => dl_def(ast::def_static_method(did, ast::unsafe_fn)),
258-
'F' => dl_def(ast::def_static_method(did, ast::impure_fn)),
259-
'P' => dl_def(ast::def_static_method(did, ast::pure_fn)),
260-
'y' => dl_def(ast::def_ty(did)),
261-
't' => dl_def(ast::def_ty(did)),
262-
'm' => dl_def(ast::def_mod(did)),
263-
'n' => dl_def(ast::def_foreign_mod(did)),
264-
'v' => {
265-
let mut tid = option::get(item_parent_item(item));
266-
tid = {crate: cnum, node: tid.node};
267-
dl_def(ast::def_variant(tid, did))
295+
let fam = item_family(item);
296+
match fam {
297+
Const => dl_def(ast::def_const(did)),
298+
Class => dl_def(ast::def_class(did, true)),
299+
Struct => dl_def(ast::def_class(did, false)),
300+
UnsafeFn => dl_def(ast::def_fn(did, ast::unsafe_fn)),
301+
Fn => dl_def(ast::def_fn(did, ast::impure_fn)),
302+
PureFn => dl_def(ast::def_fn(did, ast::pure_fn)),
303+
ForeignFn => dl_def(ast::def_fn(did, ast::extern_fn)),
304+
UnsafeStaticMethod => dl_def(ast::def_static_method(did,
305+
ast::unsafe_fn)),
306+
StaticMethod => dl_def(ast::def_static_method(did, ast::impure_fn)),
307+
PureStaticMethod => dl_def(ast::def_static_method(did, ast::pure_fn)),
308+
Type | ForeignType => dl_def(ast::def_ty(did)),
309+
Mod => dl_def(ast::def_mod(did)),
310+
ForeignMod => dl_def(ast::def_foreign_mod(did)),
311+
Variant => {
312+
match item_parent_item(item) {
313+
some(t) => {
314+
let tid = {crate: cnum, node: t.node};
315+
dl_def(ast::def_variant(tid, did))
316+
}
317+
none => fail ~"item_to_def_like: enum item has no parent"
318+
}
268319
}
269-
'I' => dl_def(ast::def_ty(did)),
270-
'i' => dl_impl(did),
271-
'g' | 'j' | 'N' => dl_field,
272-
ch => fail fmt!{"unexpected family code: '%c'", ch}
320+
Trait | Enum => dl_def(ast::def_ty(did)),
321+
Impl => dl_impl(did),
322+
PublicField | PrivateField | InheritedField => dl_field,
273323
}
274324
}
275325

@@ -642,12 +692,14 @@ fn get_trait_methods(intr: ident_interner, cdata: cmd, id: ast::node_id,
642692
let self_ty = get_self_ty(mth);
643693
vec::push(result, {ident: name, tps: bounds, fty: fty,
644694
self_ty: self_ty,
645-
purity: match check item_family(mth) {
646-
'u' => ast::unsafe_fn,
647-
'f' => ast::impure_fn,
648-
'p' => ast::pure_fn
695+
purity: match item_family(mth) {
696+
UnsafeFn => ast::unsafe_fn,
697+
Fn => ast::impure_fn,
698+
PureFn => ast::pure_fn,
699+
_ => fail ~"bad purity"
649700
}, vis: ast::public});
650701
}
702+
#debug("get_trait_methods: }");
651703
@result
652704
}
653705

@@ -659,7 +711,7 @@ fn get_method_names_if_trait(intr: ident_interner, cdata: cmd,
659711
-> option<@DVec<(ast::ident, ast::self_ty_)>> {
660712

661713
let item = lookup_item(node_id, cdata.data);
662-
if item_family(item) != 'I' {
714+
if item_family(item) != Trait {
663715
return none;
664716
}
665717

@@ -685,7 +737,7 @@ fn get_item_attrs(cdata: cmd,
685737

686738
// Helper function that gets either fields or methods
687739
fn get_class_members(intr: ident_interner, cdata: cmd, id: ast::node_id,
688-
p: fn(char) -> bool) -> ~[ty::field_ty] {
740+
p: fn(Family) -> bool) -> ~[ty::field_ty] {
689741
let data = cdata.data;
690742
let item = lookup_item(id, data);
691743
let mut result = ~[];
@@ -702,33 +754,31 @@ fn get_class_members(intr: ident_interner, cdata: cmd, id: ast::node_id,
702754
result
703755
}
704756

705-
pure fn family_to_visibility(family: char) -> ast::visibility {
757+
pure fn family_to_visibility(family: Family) -> ast::visibility {
706758
match family {
707-
'g' => ast::public,
708-
'j' => ast::private,
709-
'N' => ast::inherited,
759+
PublicField => ast::public,
760+
PrivateField => ast::private,
761+
InheritedField => ast::inherited,
710762
_ => fail
711763
}
712764
}
713765

714-
/* 'g' for public field, 'j' for private field, 'N' for inherited field */
715766
fn get_class_fields(intr: ident_interner, cdata: cmd, id: ast::node_id)
716767
-> ~[ty::field_ty] {
717-
get_class_members(intr, cdata, id, |f| f == 'g' || f == 'j' || f == 'N')
768+
get_class_members(intr, cdata, id, |f| f == PublicField
769+
|| f == PrivateField || f == InheritedField)
718770
}
719771

720-
fn family_has_type_params(fam_ch: char) -> bool {
721-
match fam_ch {
722-
'c' | 'T' | 'm' | 'n' | 'g' | 'h' | 'j' | 'e' | 'N' => false,
723-
'f' | 'u' | 'p' | 'F' | 'U' | 'P' | 'y' | 't' | 'v' | 'i' | 'I' | 'C'
724-
| 'a' | 'S'
725-
=> true,
726-
_ => fail fmt!("'%c' is not a family", fam_ch)
772+
fn family_has_type_params(fam: Family) -> bool {
773+
match fam {
774+
Const | ForeignType | Mod | ForeignMod | PublicField | PrivateField
775+
| ForeignFn => false,
776+
_ => true
727777
}
728778
}
729779

730-
fn family_names_type(fam_ch: char) -> bool {
731-
match fam_ch { 'y' | 't' | 'I' => true, _ => false }
780+
fn family_names_type(fam: Family) -> bool {
781+
match fam { Type | Mod | Trait => true, _ => false }
732782
}
733783

734784
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 {
748798
return item_family_to_str(item_family(it));
749799
}
750800

751-
fn item_family_to_str(fam: char) -> ~str {
752-
match check fam {
753-
'c' => return ~"const",
754-
'f' => return ~"fn",
755-
'u' => return ~"unsafe fn",
756-
'p' => return ~"pure fn",
757-
'F' => return ~"static method",
758-
'U' => return ~"unsafe static method",
759-
'P' => return ~"pure static method",
760-
'e' => return ~"foreign fn",
761-
'y' => return ~"type",
762-
'T' => return ~"foreign type",
763-
't' => return ~"type",
764-
'm' => return ~"mod",
765-
'n' => return ~"foreign mod",
766-
'v' => return ~"enum",
767-
'i' => return ~"impl",
768-
'I' => return ~"trait",
769-
'C' => return ~"class",
770-
'S' => return ~"struct",
771-
'g' => return ~"public field",
772-
'j' => return ~"private field",
773-
'N' => return ~"inherited field"
801+
fn item_family_to_str(fam: Family) -> ~str {
802+
match fam {
803+
Const => ~"const",
804+
Fn => ~"fn",
805+
UnsafeFn => ~"unsafe fn",
806+
PureFn => ~"pure fn",
807+
StaticMethod => ~"static method",
808+
UnsafeStaticMethod => ~"unsafe static method",
809+
PureStaticMethod => ~"pure static method",
810+
ForeignFn => ~"foreign fn",
811+
Type => ~"type",
812+
ForeignType => ~"foreign type",
813+
Mod => ~"mod",
814+
ForeignMod => ~"foreign mod",
815+
Enum => ~"enum",
816+
Variant => ~"variant",
817+
Impl => ~"impl",
818+
Trait => ~"trait",
819+
Class => ~"class",
820+
Struct => ~"struct",
821+
PublicField => ~"public field",
822+
PrivateField => ~"private field",
823+
InheritedField => ~"inherited field",
774824
}
775825
}
776826

src/rustc/metadata/encoder.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ fn encode_region_param(ecx: @encode_ctxt, ebml_w: ebml::writer,
8888
fn encode_mutability(ebml_w: ebml::writer, mt: class_mutability) {
8989
do ebml_w.wr_tag(tag_class_mut) {
9090
let val = match mt {
91-
class_immutable => 'i',
91+
class_immutable => 'a',
9292
class_mutable => 'm'
9393
};
9494
ebml_w.writer.write(&[val as u8]);
@@ -472,7 +472,7 @@ fn purity_static_method_family(p: purity) -> char {
472472
unsafe_fn => 'U',
473473
pure_fn => 'P',
474474
impure_fn => 'F',
475-
extern_fn => 'E'
475+
_ => fail ~"extern fn can't be static"
476476
}
477477
}
478478

@@ -813,19 +813,22 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
813813
visit_expr: |_e, _cx, _v| { },
814814
visit_item: |i, cx, v, copy ebml_w| {
815815
visit::visit_item(i, cx, v);
816-
match check ecx.tcx.items.get(i.id) {
816+
match ecx.tcx.items.get(i.id) {
817817
ast_map::node_item(_, pt) => {
818818
encode_info_for_item(ecx, ebml_w, i, index, *pt);
819819
}
820+
_ => fail ~"bad item"
820821
}
821822
},
822823
visit_foreign_item: |ni, cx, v, copy ebml_w| {
823824
visit::visit_foreign_item(ni, cx, v);
824-
match check ecx.tcx.items.get(ni.id) {
825+
match ecx.tcx.items.get(ni.id) {
825826
ast_map::node_foreign_item(_, abi, pt) => {
826827
encode_info_for_foreign_item(ecx, ebml_w, ni,
827828
index, *pt, abi);
828829
}
830+
// case for separate item and foreign-item tables
831+
_ => fail ~"bad foreign item"
829832
}
830833
}
831834
with *visit::default_visitor()

0 commit comments

Comments
 (0)