From 0263039ca0350eb67ce11e985bd7e698de48ca0f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 10 Feb 2012 10:28:35 -0800 Subject: [PATCH] use absolute names when pretty-printing types --- Makefile.in | 7 ++++-- src/comp/metadata/decoder.rs | 10 +++++--- src/comp/metadata/tydecode.rs | 6 ++--- src/comp/metadata/tyencode.rs | 8 +++--- src/comp/middle/ty.rs | 29 +++++++++++----------- src/comp/middle/typeck.rs | 29 +++++++++++++--------- src/comp/util/ppaux.rs | 46 ++++++++++++++++++++--------------- src/etc/ctags.rust | 3 +++ 8 files changed, 79 insertions(+), 59 deletions(-) diff --git a/Makefile.in b/Makefile.in index faee8e8d863..7310c5efe53 100644 --- a/Makefile.in +++ b/Makefile.in @@ -410,9 +410,12 @@ TSREQS := \ FUZZ := $(HBIN3_H_$(CFG_HOST_TRIPLE))/fuzzer$(X) CARGO := $(HBIN3_H_$(CFG_HOST_TRIPLE))/cargo$(X) RUSTDOC := $(HBIN3_H_$(CFG_HOST_TRIPLE))/rustdoc$(X) -SERIALIZER := $(HBIN3_H_$(CFG_HOST_TRIPLE))/serializer$(X) +SERIALIZER := $(HBIN2_H_$(CFG_HOST_TRIPLE))/serializer$(X) +# ^^ Note: we use HBIN2 because that is the only stage for which +# we build a complete rustc by default, and serializer requires +# the complete rustc. -all: rustc $(GENERATED) docs $(FUZZ) $(CARGO) $(RUSTDOC) +all: rustc $(GENERATED) docs $(FUZZ) $(CARGO) $(RUSTDOC) $(SERIALIZER) endif diff --git a/src/comp/metadata/decoder.rs b/src/comp/metadata/decoder.rs index ccc0e3bfa2a..cd007e22fc4 100644 --- a/src/comp/metadata/decoder.rs +++ b/src/comp/metadata/decoder.rs @@ -112,10 +112,11 @@ fn doc_type(doc: ebml::doc, tcx: ty::ctxt, cdata: cmd) -> ty::t { }) } -fn item_type(item: ebml::doc, tcx: ty::ctxt, cdata: cmd) -> ty::t { +fn item_type(item_id: ast::def_id, item: ebml::doc, + tcx: ty::ctxt, cdata: cmd) -> ty::t { let t = doc_type(item, tcx, cdata); if family_names_type(item_family(item)) { - ty::mk_named(tcx, t, item_name(item)) + ty::mk_with_id(tcx, t, item_id) } else { t } } @@ -240,7 +241,7 @@ fn lookup_def(cnum: ast::crate_num, data: @[u8], did_: ast::def_id) -> fn get_type(cdata: cmd, id: ast::node_id, tcx: ty::ctxt) -> ty::ty_param_bounds_and_ty { let item = lookup_item(id, cdata.data); - let t = item_type(item, tcx, cdata); + let t = item_type({crate: cdata.cnum, node: id}, item, tcx, cdata); let tp_bounds = if family_has_type_params(item_family(item)) { item_ty_param_bounds(item, tcx, cdata) } else { @[] }; @@ -274,7 +275,8 @@ fn get_enum_variants(cdata: cmd, id: ast::node_id, tcx: ty::ctxt) let disr_val = 0; for did: ast::def_id in variant_ids { let item = find_item(did.node, items); - let ctor_ty = item_type(item, tcx, cdata); + let ctor_ty = item_type({crate: cdata.cnum, node: id}, item, + tcx, cdata); let name = item_name(item); let arg_tys: [ty::t] = []; alt ty::get(ctor_ty).struct { diff --git a/src/comp/metadata/tydecode.rs b/src/comp/metadata/tydecode.rs index 12cf330189e..e9cb99f3db7 100644 --- a/src/comp/metadata/tydecode.rs +++ b/src/comp/metadata/tydecode.rs @@ -293,11 +293,9 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t { ret ty::mk_constr(st.tcx, tt, tcs); } '"' { - let name = ""; - while peek(st) as char != '"' { str::push_byte(name, next(st)); } - st.pos = st.pos + 1u; + let def = parse_def(st, conv); let inner = parse_ty(st, conv); - ty::mk_named(st.tcx, inner, name) + ty::mk_with_id(st.tcx, inner, def) } 'B' { ty::mk_opaque_box(st.tcx) } c { #error("unexpected char in type string: %c", c); fail;} diff --git a/src/comp/metadata/tyencode.rs b/src/comp/metadata/tyencode.rs index 4d8042477d0..e69b3888b6c 100644 --- a/src/comp/metadata/tyencode.rs +++ b/src/comp/metadata/tyencode.rs @@ -53,11 +53,11 @@ fn enc_ty(w: io::writer, cx: @ctxt, t: ty::t) { some(a) { w.write_str(*a.s); ret; } none { let pos = w.tell(); - alt ty::type_name(t) { - some(n) { - w.write_char('"'); - w.write_str(n); + alt ty::type_def_id(t) { + some(def_id) { w.write_char('"'); + w.write_str(cx.ds(def_id)); + w.write_char('|'); } _ {} } diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 019ba856e98..7976576720f 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -42,7 +42,7 @@ export method; export method_idx; export mk_class; export mk_ctxt; -export mk_named, type_name; +export mk_with_id, type_def_id; export mt; export node_type_table; export pat_ty; @@ -151,8 +151,10 @@ type mt = {ty: t, mut: ast::mutability}; // the types of AST nodes. type creader_cache = hashmap<{cnum: int, pos: uint, len: uint}, t>; +type intern_key = {struct: sty, o_def_id: option}; + type ctxt = - @{interner: hashmap<{struct: sty, name: option}, t_box>, + @{interner: hashmap, mutable next_id: uint, sess: session::session, def_map: resolve::def_map, @@ -175,7 +177,7 @@ type t_box = @{struct: sty, id: uint, has_params: bool, has_vars: bool, - name: option}; + o_def_id: option}; // To reduce refcounting cost, we're representing types as unsafe pointers // throughout the compiler. These are simply casted t_box values. Use ty::get @@ -194,7 +196,7 @@ pure fn get(t: t) -> t_box unsafe { fn type_has_params(t: t) -> bool { get(t).has_params } fn type_has_vars(t: t) -> bool { get(t).has_vars } -fn type_name(t: t) -> option { get(t).name } +fn type_def_id(t: t) -> option { get(t).o_def_id } fn type_id(t: t) -> uint { get(t).id } enum closure_kind { @@ -308,10 +310,9 @@ fn new_ty_hash() -> map::hashmap { fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map, freevars: freevars::freevar_map) -> ctxt { - let interner = map::mk_hashmap({|&&k: {struct: sty, name: option}| - hash_type_structure(k.struct) + alt k.name { - some(s) { str::hash(s) } _ { 0u } - } + let interner = map::mk_hashmap({|&&k: intern_key| + hash_type_structure(k.struct) + + option::maybe(0u, k.o_def_id, ast_util::hash_def_id) }, {|&&a, &&b| a == b}); @{interner: interner, mutable next_id: 0u, @@ -335,12 +336,12 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map, // Type constructors -fn mk_t(cx: ctxt, st: sty) -> t { mk_t_named(cx, st, none) } +fn mk_t(cx: ctxt, st: sty) -> t { mk_t_with_id(cx, st, none) } // Interns a type/name combination, stores the resulting box in cx.interner, // and returns the box as cast to an unsafe ptr (see comments for t above). -fn mk_t_named(cx: ctxt, st: sty, name: option) -> t { - let key = {struct: st, name: name}; +fn mk_t_with_id(cx: ctxt, st: sty, o_def_id: option) -> t { + let key = {struct: st, o_def_id: o_def_id}; alt cx.interner.find(key) { some(t) { unsafe { ret unsafe::reinterpret_cast(t); } } _ {} @@ -385,7 +386,7 @@ fn mk_t_named(cx: ctxt, st: sty, name: option) -> t { id: cx.next_id, has_params: has_params, has_vars: has_vars, - name: name}; + o_def_id: o_def_id}; cx.interner.insert(key, t); cx.next_id += 1u; unsafe { unsafe::reinterpret_cast(t) } @@ -469,8 +470,8 @@ fn mk_opaque_closure_ptr(cx: ctxt, ck: closure_kind) -> t { fn mk_opaque_box(cx: ctxt) -> t { mk_t(cx, ty_opaque_box) } -fn mk_named(cx: ctxt, base: t, name: str) -> t { - mk_t_named(cx, get(base).struct, some(name)) +fn mk_with_id(cx: ctxt, base: t, def_id: ast::def_id) -> t { + mk_t_with_id(cx, get(base).struct, some(def_id)) } // Converts s to its machine type equivalent diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 3aae6075eb4..b687f3f702c 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -373,6 +373,7 @@ fn ty_of_item(tcx: ty::ctxt, mode: mode, it: @ast::item) some(tpt) { ret tpt; } _ {} } + let def_id = {crate: ast::local_crate, node: it.id}; alt it.node { ast::item_const(t, _) { let typ = ast_ty_to_ty(tcx, mode, t); @@ -390,18 +391,21 @@ fn ty_of_item(tcx: ty::ctxt, mode: mode, it: @ast::item) } // Tell ast_ty_to_ty() that we want to perform a recursive // call to resolve any named types. - let tpt = {bounds: ty_param_bounds(tcx, mode, tps), - ty: ty::mk_named(tcx, ast_ty_to_ty(tcx, mode, t), - it.ident)}; + let tpt = { + let t0 = ast_ty_to_ty(tcx, mode, t); + {bounds: ty_param_bounds(tcx, mode, tps), + ty: ty::mk_with_id(tcx, t0, def_id)} + }; tcx.tcache.insert(local_def(it.id), tpt); ret tpt; } ast::item_res(decl, tps, _, _, _) { let {bounds, params} = mk_ty_params(tcx, tps); let t_arg = ty_of_arg(tcx, mode, decl.inputs[0]); - let t = ty::mk_named(tcx, ty::mk_res(tcx, local_def(it.id), t_arg.ty, - params), - it.ident); + let t = { + let t0 = ty::mk_res(tcx, local_def(it.id), t_arg.ty, params); + ty::mk_with_id(tcx, t0, def_id) + }; let t_res = {bounds: bounds, ty: t}; tcx.tcache.insert(local_def(it.id), t_res); ret t_res; @@ -409,17 +413,20 @@ fn ty_of_item(tcx: ty::ctxt, mode: mode, it: @ast::item) ast::item_enum(_, tps) { // Create a new generic polytype. let {bounds, params} = mk_ty_params(tcx, tps); - let t = ty::mk_named(tcx, ty::mk_enum(tcx, local_def(it.id), params), - it.ident); + let t = { + let t0 = ty::mk_enum(tcx, local_def(it.id), params); + ty::mk_with_id(tcx, t0, def_id) + }; let tpt = {bounds: bounds, ty: t}; tcx.tcache.insert(local_def(it.id), tpt); ret tpt; } ast::item_iface(tps, ms) { let {bounds, params} = mk_ty_params(tcx, tps); - let t = ty::mk_named(tcx, ty::mk_iface(tcx, local_def(it.id), - params), - it.ident); + let t = { + let t0 = ty::mk_iface(tcx, local_def(it.id), params); + ty::mk_with_id(tcx, t0, def_id) + }; let tpt = {bounds: bounds, ty: t}; tcx.tcache.insert(local_def(it.id), tpt); ret tpt; diff --git a/src/comp/util/ppaux.rs b/src/comp/util/ppaux.rs index 24337878a5c..5af07e1650e 100644 --- a/src/comp/util/ppaux.rs +++ b/src/comp/util/ppaux.rs @@ -6,6 +6,7 @@ import syntax::print::pprust::{path_to_str, constr_args_to_str, proto_to_str, mode_to_str}; import syntax::{ast, ast_util}; import middle::ast_map; +import driver::session::session; fn ty_to_str(cx: ctxt, typ: t) -> str { fn fn_input_to_str(cx: ctxt, input: {mode: ast::mode, ty: t}) -> @@ -60,21 +61,28 @@ fn ty_to_str(cx: ctxt, typ: t) -> str { } ret mstr + ty_to_str(cx, m.ty); } - alt ty::type_name(typ) { - some(cs) { - alt ty::get(typ).struct { - ty_enum(_, tps) | ty_res(_, _, tps) { - if vec::len(tps) > 0u { - let strs = vec::map(tps, {|t| ty_to_str(cx, t)}); - ret cs + "<" + str::connect(strs, ",") + ">"; - } - } - _ {} + fn parameterized(cx: ctxt, base: str, tps: [ty::t]) -> str { + if vec::len(tps) > 0u { + let strs = vec::map(tps, {|t| ty_to_str(cx, t)}); + #fmt["%s<%s>", base, str::connect(strs, ",")] + } else { + base } - ret cs; - } - _ { } } + + // if there is an id, print that instead of the structural type: + alt ty::type_def_id(typ) { + some(def_id) { + let cs = ast_map::path_to_str(ty::item_path(cx, def_id)); + ret alt ty::get(typ).struct { + ty_enum(_, tps) | ty_res(_, _, tps) { parameterized(cx, cs, tps) } + _ { cs } + }; + } + none { /* fallthrough */} + } + + // pretty print the structural type representation: ret alt ty::get(typ).struct { ty_nil { "()" } ty_bot { "_|_" } @@ -110,15 +118,13 @@ fn ty_to_str(cx: ctxt, typ: t) -> str { ty_param(id, _) { "'" + str::from_bytes([('a' as u8) + (id as u8)]) } - ty_enum(did, tps) { + ty_enum(did, tps) | ty_res(did, _, tps) { + // Not sure why, but under some circumstances enum or resource types + // do not have an associated id. I didn't investigate enough to know + // if there is a good reason for this. - Niko, 2012-02-10 let path = ty::item_path(cx, did); let base = ast_map::path_to_str(path); - if vec::is_empty(tps) { - base - } else { - let tps_strs = vec::map(tps) {|t| ty_to_str(cx, t) }; - #fmt["%s<%s>", base, str::connect(tps_strs, ",")] - } + parameterized(cx, base, tps) } _ { ty_to_short_str(cx, typ) } } diff --git a/src/etc/ctags.rust b/src/etc/ctags.rust index 08f73c02aac..17712b45feb 100644 --- a/src/etc/ctags.rust +++ b/src/etc/ctags.rust @@ -6,3 +6,6 @@ --regex-rust=/[ \t]*resource[ \t]+([a-zA-Z0-9_]+)/\1/T,types/ --regex-rust=/[ \t]*mod[ \t]+([a-zA-Z0-9_]+)/\1/m,modules/ --regex-rust=/[ \t]*const[ \t]+([a-zA-Z0-9_]+)/\1/m,consts/ +--regex-rust=/[ \t]*iface[ \t]+([a-zA-Z0-9_]+)/\1/m,ifaces/ +--regex-rust=/[ \t]*impl[ \t]+([a-zA-Z0-9_]+)/\1/m,impls/ +--regex-rust=/[ \t]*impl[ \t]+of[ \t]([a-zA-Z0-9_]+)/\1/m,impls/