mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 23:34:48 +00:00
make nominal types optionally parameterized by a self region.
Issue #2201.
This commit is contained in:
parent
f3f34bf09b
commit
3c995fb8f3
@ -645,21 +645,29 @@ type iface_ref = {path: @path, id: node_id};
|
||||
type item = {ident: ident, attrs: [attribute],
|
||||
id: node_id, node: item_, span: span};
|
||||
|
||||
#[auto_serialize]
|
||||
enum region_param {
|
||||
rp_none,
|
||||
rp_self
|
||||
}
|
||||
|
||||
#[auto_serialize]
|
||||
enum item_ {
|
||||
item_const(@ty, @expr),
|
||||
item_fn(fn_decl, [ty_param], blk),
|
||||
item_mod(_mod),
|
||||
item_native_mod(native_mod),
|
||||
item_ty(@ty, [ty_param]),
|
||||
item_enum([variant], [ty_param]),
|
||||
item_ty(@ty, [ty_param], region_param),
|
||||
item_enum([variant], [ty_param], region_param),
|
||||
item_res(fn_decl /* dtor */, [ty_param], blk /* dtor body */,
|
||||
node_id /* dtor id */, node_id /* ctor id */),
|
||||
node_id /* dtor id */, node_id /* ctor id */,
|
||||
region_param),
|
||||
item_class([ty_param], /* ty params for class */
|
||||
[iface_ref], /* ifaces this class implements */
|
||||
[@class_member], /* methods, etc. */
|
||||
/* (not including ctor) */
|
||||
class_ctor
|
||||
class_ctor,
|
||||
region_param
|
||||
),
|
||||
item_iface([ty_param], [ty_method]),
|
||||
item_impl([ty_param], option<@ty> /* iface */,
|
||||
|
@ -149,7 +149,7 @@ fn is_exported(i: ident, m: _mod) -> bool {
|
||||
for m.items.each {|it|
|
||||
if it.ident == i { local = true; }
|
||||
alt it.node {
|
||||
item_enum(variants, _) {
|
||||
item_enum(variants, _, _) {
|
||||
for variants.each {|v|
|
||||
if v.node.name == i {
|
||||
local = true;
|
||||
|
@ -102,11 +102,11 @@ fn expand(cx: ext_ctxt,
|
||||
|
||||
vec::flat_map(in_items) {|in_item|
|
||||
alt in_item.node {
|
||||
ast::item_ty(ty, tps) {
|
||||
ast::item_ty(ty, tps, _) {
|
||||
[filter_attrs(in_item)] + ty_fns(cx, in_item.ident, ty, tps)
|
||||
}
|
||||
|
||||
ast::item_enum(variants, tps) {
|
||||
ast::item_enum(variants, tps, _) {
|
||||
[filter_attrs(in_item)] + enum_fns(cx, in_item.ident,
|
||||
in_item.span, variants, tps)
|
||||
}
|
||||
|
@ -265,36 +265,42 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
|
||||
}
|
||||
item_mod(m) { item_mod(fld.fold_mod(m)) }
|
||||
item_native_mod(nm) { item_native_mod(fld.fold_native_mod(nm)) }
|
||||
item_ty(t, typms) { item_ty(fld.fold_ty(t),
|
||||
fold_ty_params(typms, fld)) }
|
||||
item_enum(variants, typms) {
|
||||
item_ty(t, typms, rp) { item_ty(fld.fold_ty(t),
|
||||
fold_ty_params(typms, fld),
|
||||
rp) }
|
||||
item_enum(variants, typms, r) {
|
||||
item_enum(vec::map(variants, fld.fold_variant),
|
||||
fold_ty_params(typms, fld))
|
||||
fold_ty_params(typms, fld),
|
||||
r)
|
||||
}
|
||||
item_class(typms, ifaces, items, ctor) {
|
||||
item_class(typms, ifaces, items, ctor, rp) {
|
||||
let ctor_body = fld.fold_block(ctor.node.body);
|
||||
let ctor_decl = fold_fn_decl(ctor.node.dec, fld);
|
||||
let ctor_id = fld.new_id(ctor.node.id);
|
||||
item_class(typms, vec::map(ifaces, {|p|
|
||||
{path: fld.fold_path(p.path),
|
||||
id: fld.new_id(p.id)}}),
|
||||
vec::map(items, fld.fold_class_item),
|
||||
{node: {body: ctor_body,
|
||||
dec: ctor_decl,
|
||||
id: ctor_id with ctor.node}
|
||||
with ctor})
|
||||
item_class(
|
||||
typms,
|
||||
vec::map(ifaces, {|p|
|
||||
{path: fld.fold_path(p.path),
|
||||
id: fld.new_id(p.id)}}),
|
||||
vec::map(items, fld.fold_class_item),
|
||||
{node: {body: ctor_body,
|
||||
dec: ctor_decl,
|
||||
id: ctor_id with ctor.node}
|
||||
with ctor},
|
||||
rp)
|
||||
}
|
||||
item_impl(tps, ifce, ty, methods) {
|
||||
item_impl(tps, option::map(ifce, fld.fold_ty), fld.fold_ty(ty),
|
||||
vec::map(methods, fld.fold_method))
|
||||
}
|
||||
item_iface(tps, methods) { item_iface(tps, methods) }
|
||||
item_res(decl, typms, body, did, cid) {
|
||||
item_res(decl, typms, body, did, cid, rp) {
|
||||
item_res(fold_fn_decl(decl, fld),
|
||||
fold_ty_params(typms, fld),
|
||||
fld.fold_block(body),
|
||||
fld.new_id(did),
|
||||
fld.new_id(cid))
|
||||
fld.new_id(cid),
|
||||
rp)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1992,6 +1992,7 @@ fn parse_item_impl(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
||||
fn parse_item_res(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
||||
let lo = p.last_span.lo;
|
||||
let ident = parse_value_ident(p);
|
||||
let rp = parse_region_param(p);
|
||||
let ty_params = parse_ty_params(p);
|
||||
expect(p, token::LPAREN);
|
||||
let arg_ident = parse_value_ident(p);
|
||||
@ -2010,7 +2011,8 @@ fn parse_item_res(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
||||
cf: ast::return_val,
|
||||
constraints: []};
|
||||
ret mk_item(p, lo, dtor.span.hi, ident,
|
||||
ast::item_res(decl, ty_params, dtor, p.get_id(), p.get_id()),
|
||||
ast::item_res(decl, ty_params, dtor,
|
||||
p.get_id(), p.get_id(), rp),
|
||||
attrs);
|
||||
}
|
||||
|
||||
@ -2035,6 +2037,7 @@ fn parse_iface_ref_list(p:parser) -> [ast::iface_ref] {
|
||||
fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
||||
let lo = p.last_span.lo;
|
||||
let class_name = parse_value_ident(p);
|
||||
let rp = parse_region_param(p);
|
||||
let ty_params = parse_ty_params(p);
|
||||
let class_path = ident_to_path_tys(p, class_name, ty_params);
|
||||
let ifaces : [ast::iface_ref] = if eat_word(p, "implements")
|
||||
@ -2057,11 +2060,11 @@ fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
||||
some((ct_d, ct_b, ct_s)) {
|
||||
ret mk_item(p, lo, p.last_span.hi, class_name,
|
||||
ast::item_class(ty_params, ifaces, ms,
|
||||
{node: {id: ctor_id,
|
||||
self_id: p.get_id(),
|
||||
dec: ct_d,
|
||||
body: ct_b},
|
||||
span: ct_s}), attrs); }
|
||||
{node: {id: ctor_id,
|
||||
self_id: p.get_id(),
|
||||
dec: ct_d,
|
||||
body: ct_b},
|
||||
span: ct_s}, rp), attrs); }
|
||||
/*
|
||||
Is it strange for the parser to check this?
|
||||
*/
|
||||
@ -2236,17 +2239,23 @@ fn parse_type_decl(p: parser) -> {lo: uint, ident: ast::ident} {
|
||||
|
||||
fn parse_item_type(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
||||
let t = parse_type_decl(p);
|
||||
let rp = parse_region_param(p);
|
||||
let tps = parse_ty_params(p);
|
||||
expect(p, token::EQ);
|
||||
let ty = parse_ty(p, false);
|
||||
let mut hi = p.span.hi;
|
||||
expect(p, token::SEMI);
|
||||
ret mk_item(p, t.lo, hi, t.ident, ast::item_ty(ty, tps), attrs);
|
||||
ret mk_item(p, t.lo, hi, t.ident, ast::item_ty(ty, tps, rp), attrs);
|
||||
}
|
||||
|
||||
fn parse_region_param(p: parser) -> ast::region_param {
|
||||
if eat(p, token::BINOP(token::AND)) {ast::rp_self} else {ast::rp_none}
|
||||
}
|
||||
|
||||
fn parse_item_enum(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
||||
let lo = p.last_span.lo;
|
||||
let id = parse_ident(p);
|
||||
let rp = parse_region_param(p);
|
||||
let ty_params = parse_ty_params(p);
|
||||
let mut variants: [ast::variant] = [];
|
||||
// Newtype syntax
|
||||
@ -2265,7 +2274,7 @@ fn parse_item_enum(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
||||
id: p.get_id(),
|
||||
disr_expr: none});
|
||||
ret mk_item(p, lo, ty.span.hi, id,
|
||||
ast::item_enum([variant], ty_params), attrs);
|
||||
ast::item_enum([variant], ty_params, rp), attrs);
|
||||
}
|
||||
expect(p, token::LBRACE);
|
||||
|
||||
@ -2301,7 +2310,7 @@ fn parse_item_enum(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
||||
p.fatal("discriminator values can only be used with a c-like enum");
|
||||
}
|
||||
ret mk_item(p, lo, p.last_span.hi, id,
|
||||
ast::item_enum(variants, ty_params), attrs);
|
||||
ast::item_enum(variants, ty_params, rp), attrs);
|
||||
}
|
||||
|
||||
fn parse_fn_ty_proto(p: parser) -> ast::proto {
|
||||
|
@ -125,10 +125,10 @@ fn test_fun_to_str() {
|
||||
}
|
||||
|
||||
fn res_to_str(decl: ast::fn_decl, name: ast::ident,
|
||||
params: [ast::ty_param]) -> str {
|
||||
params: [ast::ty_param], rp: ast::region_param) -> str {
|
||||
let buffer = io::mem_buffer();
|
||||
let s = rust_printer(io::mem_buffer_writer(buffer));
|
||||
print_res(s, decl, name, params);
|
||||
print_res(s, decl, name, params, rp);
|
||||
end(s); // Close the head box
|
||||
end(s); // Close the outer box
|
||||
eof(s.s);
|
||||
@ -454,11 +454,12 @@ fn print_item(s: ps, &&item: @ast::item) {
|
||||
print_native_mod(s, nmod, item.attrs);
|
||||
bclose(s, item.span);
|
||||
}
|
||||
ast::item_ty(ty, params) {
|
||||
ast::item_ty(ty, params, rp) {
|
||||
ibox(s, indent_unit);
|
||||
ibox(s, 0u);
|
||||
word_nbsp(s, "type");
|
||||
word(s.s, item.ident);
|
||||
print_region_param(s, rp);
|
||||
print_type_params(s, params);
|
||||
end(s); // end the inner ibox
|
||||
|
||||
@ -468,7 +469,7 @@ fn print_item(s: ps, &&item: @ast::item) {
|
||||
word(s.s, ";");
|
||||
end(s); // end the outer ibox
|
||||
}
|
||||
ast::item_enum(variants, params) {
|
||||
ast::item_enum(variants, params, rp) {
|
||||
let newtype =
|
||||
vec::len(variants) == 1u &&
|
||||
str::eq(item.ident, variants[0].node.name) &&
|
||||
@ -478,6 +479,7 @@ fn print_item(s: ps, &&item: @ast::item) {
|
||||
word_space(s, "enum");
|
||||
} else { head(s, "enum"); }
|
||||
word(s.s, item.ident);
|
||||
print_region_param(s, rp);
|
||||
print_type_params(s, params);
|
||||
space(s.s);
|
||||
if newtype {
|
||||
@ -500,9 +502,10 @@ fn print_item(s: ps, &&item: @ast::item) {
|
||||
bclose(s, item.span);
|
||||
}
|
||||
}
|
||||
ast::item_class(tps,ifaces,items,ctor) {
|
||||
ast::item_class(tps,ifaces,items,ctor, rp) {
|
||||
head(s, "class");
|
||||
word_nbsp(s, item.ident);
|
||||
print_region_param(s, rp);
|
||||
print_type_params(s, tps);
|
||||
word_space(s, "implements");
|
||||
commasep(s, inconsistent, ifaces, {|s, p|
|
||||
@ -584,8 +587,8 @@ fn print_item(s: ps, &&item: @ast::item) {
|
||||
for methods.each {|meth| print_ty_method(s, meth); }
|
||||
bclose(s, item.span);
|
||||
}
|
||||
ast::item_res(decl, tps, body, dt_id, ct_id) {
|
||||
print_res(s, decl, item.ident, tps);
|
||||
ast::item_res(decl, tps, body, dt_id, ct_id, rp) {
|
||||
print_res(s, decl, item.ident, tps, rp);
|
||||
print_block(s, body);
|
||||
}
|
||||
}
|
||||
@ -593,9 +596,10 @@ fn print_item(s: ps, &&item: @ast::item) {
|
||||
}
|
||||
|
||||
fn print_res(s: ps, decl: ast::fn_decl, name: ast::ident,
|
||||
typarams: [ast::ty_param]) {
|
||||
typarams: [ast::ty_param], rp: ast::region_param) {
|
||||
head(s, "resource");
|
||||
word(s.s, name);
|
||||
print_region_param(s, rp);
|
||||
print_type_params(s, typarams);
|
||||
popen(s);
|
||||
word_space(s, decl.inputs[0].ident + ":");
|
||||
@ -1401,6 +1405,13 @@ fn print_bounds(s: ps, bounds: @[ast::ty_param_bound]) {
|
||||
}
|
||||
}
|
||||
|
||||
fn print_region_param(s: ps, rp: ast::region_param) {
|
||||
alt rp {
|
||||
ast::rp_self { word(s.s, "&") }
|
||||
ast::rp_none { }
|
||||
}
|
||||
}
|
||||
|
||||
fn print_type_params(s: ps, &¶ms: [ast::ty_param]) {
|
||||
if vec::len(params) > 0u {
|
||||
word(s.s, "<");
|
||||
|
@ -15,7 +15,7 @@ enum vt<E> { mk_vt(visitor<E>), }
|
||||
enum fn_kind {
|
||||
fk_item_fn(ident, [ty_param]), //< an item declared with fn()
|
||||
fk_method(ident, [ty_param], @method),
|
||||
fk_res(ident, [ty_param]),
|
||||
fk_res(ident, [ty_param], region_param),
|
||||
fk_anon(proto), //< an anonymous function like fn@(...)
|
||||
fk_fn_block, //< a block {||...}
|
||||
fk_ctor(ident, [ty_param], node_id /* self id */,
|
||||
@ -24,7 +24,7 @@ enum fn_kind {
|
||||
|
||||
fn name_of_fn(fk: fn_kind) -> ident {
|
||||
alt fk {
|
||||
fk_item_fn(name, _) | fk_method(name, _, _) | fk_res(name, _)
|
||||
fk_item_fn(name, _) | fk_method(name, _, _) | fk_res(name, _, _)
|
||||
| fk_ctor(name, _, _, _) { name }
|
||||
fk_anon(_) | fk_fn_block { "anon" }
|
||||
}
|
||||
@ -32,7 +32,7 @@ fn name_of_fn(fk: fn_kind) -> ident {
|
||||
|
||||
fn tps_of_fn(fk: fn_kind) -> [ty_param] {
|
||||
alt fk {
|
||||
fk_item_fn(_, tps) | fk_method(_, tps, _) | fk_res(_, tps)
|
||||
fk_item_fn(_, tps) | fk_method(_, tps, _) | fk_res(_, tps, _)
|
||||
| fk_ctor(_, tps, _, _) { tps }
|
||||
fk_anon(_) | fk_fn_block { [] }
|
||||
}
|
||||
@ -118,12 +118,15 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
|
||||
for nm.view_items.each {|vi| v.visit_view_item(vi, e, v); }
|
||||
for nm.items.each {|ni| v.visit_native_item(ni, e, v); }
|
||||
}
|
||||
item_ty(t, tps) { v.visit_ty(t, e, v); v.visit_ty_params(tps, e, v); }
|
||||
item_res(decl, tps, body, dtor_id, _) {
|
||||
v.visit_fn(fk_res(i.ident, tps), decl, body, i.span,
|
||||
item_ty(t, tps, rp) {
|
||||
v.visit_ty(t, e, v);
|
||||
v.visit_ty_params(tps, e, v);
|
||||
}
|
||||
item_res(decl, tps, body, dtor_id, _, rp) {
|
||||
v.visit_fn(fk_res(i.ident, tps, rp), decl, body, i.span,
|
||||
dtor_id, e, v);
|
||||
}
|
||||
item_enum(variants, tps) {
|
||||
item_enum(variants, tps, _) {
|
||||
v.visit_ty_params(tps, e, v);
|
||||
for variants.each {|vr|
|
||||
for vr.node.args.each {|va| v.visit_ty(va.ty, e, v); }
|
||||
@ -137,7 +140,7 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
|
||||
visit_method_helper(m, e, v)
|
||||
}
|
||||
}
|
||||
item_class(tps, ifaces, members, ctor) {
|
||||
item_class(tps, ifaces, members, ctor, _) {
|
||||
v.visit_ty_params(tps, e, v);
|
||||
for members.each {|m|
|
||||
v.visit_class_item(m, e, v);
|
||||
|
@ -143,8 +143,8 @@ fn visit_ids(item: ast::inlined_item, vfn: fn@(ast::node_id)) {
|
||||
visit_item: fn@(i: @ast::item) {
|
||||
vfn(i.id);
|
||||
alt i.node {
|
||||
ast::item_res(_, _, _, d_id, c_id) { vfn(d_id); vfn(c_id); }
|
||||
ast::item_enum(vs, _) { for vs.each {|v| vfn(v.node.id); } }
|
||||
ast::item_res(_, _, _, d_id, c_id, _) { vfn(d_id); vfn(c_id); }
|
||||
ast::item_enum(vs, _, _) { for vs.each {|v| vfn(v.node.id); } }
|
||||
_ {}
|
||||
}
|
||||
},
|
||||
@ -209,7 +209,7 @@ fn visit_ids(item: ast::inlined_item, vfn: fn@(ast::node_id)) {
|
||||
vfn(parent_id.node);
|
||||
}
|
||||
visit::fk_item_fn(_, tps) |
|
||||
visit::fk_res(_, tps) {
|
||||
visit::fk_res(_, tps, _) {
|
||||
vec::iter(tps) {|tp| vfn(tp.id)}
|
||||
}
|
||||
visit::fk_method(_, tps, m) {
|
||||
@ -679,7 +679,10 @@ impl helpers for ebml::writer {
|
||||
self.emit_bounds(ecx, bs)
|
||||
}
|
||||
}
|
||||
self.emit_rec_field("ty", 0u) {||
|
||||
self.emit_rec_field("rp", 1u) {||
|
||||
ast::serialize_region_param(self, tpbt.rp)
|
||||
}
|
||||
self.emit_rec_field("ty", 2u) {||
|
||||
self.emit_ty(ecx, tpbt.ty);
|
||||
}
|
||||
}
|
||||
@ -848,6 +851,11 @@ impl decoder for ebml::doc {
|
||||
|
||||
impl decoder for ebml::ebml_deserializer {
|
||||
fn read_ty(xcx: extended_decode_ctxt) -> ty::t {
|
||||
// Note: regions types embed local node ids. In principle, we
|
||||
// should translate these node ids into the new decode
|
||||
// context. However, we do not bother, because region types
|
||||
// are not used during trans.
|
||||
|
||||
tydecode::parse_ty_data(
|
||||
self.parent.data, xcx.dcx.cdata.cnum, self.pos, xcx.dcx.tcx,
|
||||
xcx.tr_def_id(_))
|
||||
@ -870,7 +878,10 @@ impl decoder for ebml::ebml_deserializer {
|
||||
bounds: self.read_rec_field("bounds", 0u) {||
|
||||
@self.read_to_vec {|| self.read_bounds(xcx) }
|
||||
},
|
||||
ty: self.read_rec_field("ty", 1u) {||
|
||||
rp: self.read_rec_field("rp", 1u) {||
|
||||
ast::deserialize_region_param(self)
|
||||
},
|
||||
ty: self.read_rec_field("ty", 2u) {||
|
||||
self.read_ty(xcx)
|
||||
}
|
||||
}
|
||||
|
@ -84,6 +84,8 @@ const tag_path_elt_name: uint = 0x43u;
|
||||
const tag_item_field: uint = 0x44u;
|
||||
const tag_class_mut: uint = 0x45u;
|
||||
|
||||
const tag_region_param: uint = 0x46u;
|
||||
|
||||
// used to encode crate_ctxt side tables
|
||||
enum astencode_tag { // Reserves 0x50 -- 0x6f
|
||||
tag_ast = 0x50,
|
||||
|
@ -157,7 +157,7 @@ fn get_field_type(tcx: ty::ctxt, class_id: ast::def_id,
|
||||
class_id, def)});
|
||||
#debug("got field data %?", the_field);
|
||||
let ty = decoder::item_type(def, the_field, tcx, cdata);
|
||||
ret {bounds: @[], ty: ty};
|
||||
ret {bounds: @[], rp: ast::rp_none, ty: ty};
|
||||
}
|
||||
|
||||
fn get_impl_iface(tcx: ty::ctxt, def: ast::def_id)
|
||||
|
@ -15,6 +15,7 @@ import syntax::print::pprust;
|
||||
import cmd=cstore::crate_metadata;
|
||||
import middle::trans::common::maps;
|
||||
import util::ppaux::ty_to_str;
|
||||
import ebml::deserializer;
|
||||
|
||||
export get_class_fields;
|
||||
export get_symbol;
|
||||
@ -176,6 +177,18 @@ fn item_ty_param_bounds(item: ebml::doc, tcx: ty::ctxt, cdata: cmd)
|
||||
@bounds
|
||||
}
|
||||
|
||||
fn item_ty_region_param(item: ebml::doc) -> ast::region_param {
|
||||
alt ebml::maybe_get_doc(item, tag_region_param) {
|
||||
some(rp_doc) {
|
||||
let dsr = ebml::ebml_deserializer(rp_doc);
|
||||
ast::deserialize_region_param(dsr)
|
||||
}
|
||||
none { // not all families of items have region params
|
||||
ast::rp_none
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn item_ty_param_count(item: ebml::doc) -> uint {
|
||||
let mut n = 0u;
|
||||
ebml::tagged_docs(item, tag_items_data_item_ty_param_bounds,
|
||||
@ -272,12 +285,14 @@ 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({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 { @[] };
|
||||
ret {bounds: tp_bounds, ty: t};
|
||||
let rp = item_ty_region_param(item);
|
||||
ret {bounds: tp_bounds, rp: rp, ty: t};
|
||||
}
|
||||
|
||||
fn get_type_param_count(data: @[u8], id: ast::node_id) -> uint {
|
||||
|
@ -16,6 +16,7 @@ import middle::ast_map;
|
||||
import syntax::attr;
|
||||
import driver::session::session;
|
||||
import std::serialization::serializer;
|
||||
import std::ebml::serializer;
|
||||
|
||||
export encode_metadata;
|
||||
export encoded_ty;
|
||||
@ -40,6 +41,12 @@ fn encode_def_id(ebml_w: ebml::writer, id: def_id) {
|
||||
ebml_w.wr_tagged_str(tag_def_id, def_to_str(id));
|
||||
}
|
||||
|
||||
fn encode_region_param(ebml_w: ebml::writer, rp: region_param) {
|
||||
ebml_w.wr_tag(tag_region_param) {||
|
||||
serialize_region_param(ebml_w, rp)
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_named_def_id(ebml_w: ebml::writer, name: str, id: def_id) {
|
||||
ebml_w.wr_tag(tag_paths_data_item) {||
|
||||
encode_name(ebml_w, name);
|
||||
@ -132,14 +139,14 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
|
||||
index);
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
item_ty(_, tps) {
|
||||
item_ty(_, tps, _) {
|
||||
add_to_index(ebml_w, path, index, it.ident);
|
||||
ebml_w.start_tag(tag_paths_data_item);
|
||||
encode_name(ebml_w, it.ident);
|
||||
encode_def_id(ebml_w, local_def(it.id));
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
item_res(_, tps, _, _, ctor_id) {
|
||||
item_res(_, tps, _, _, ctor_id, _) {
|
||||
add_to_index(ebml_w, path, index, it.ident);
|
||||
ebml_w.start_tag(tag_paths_data_item);
|
||||
encode_name(ebml_w, it.ident);
|
||||
@ -151,7 +158,7 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
|
||||
encode_def_id(ebml_w, local_def(it.id));
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
item_class(_, _, items, ctor) {
|
||||
item_class(_, _, items, ctor, _) {
|
||||
add_to_index(ebml_w, path, index, it.ident);
|
||||
ebml_w.start_tag(tag_paths_data_item);
|
||||
encode_name(ebml_w, it.ident);
|
||||
@ -165,7 +172,7 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
|
||||
index);
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
item_enum(variants, tps) {
|
||||
item_enum(variants, _, _) {
|
||||
add_to_index(ebml_w, path, index, it.ident);
|
||||
ebml_w.start_tag(tag_paths_data_item);
|
||||
encode_name(ebml_w, it.ident);
|
||||
@ -480,7 +487,8 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||
index: @mut [entry<int>], path: ast_map::path) {
|
||||
|
||||
let tcx = ecx.ccx.tcx;
|
||||
let must_write = alt item.node { item_enum(_, _) { true } _ { false } };
|
||||
let must_write =
|
||||
alt item.node { item_enum(_, _, _) { true } _ { false } };
|
||||
if !must_write && !ecx.ccx.reachable.contains_key(item.id) { ret; }
|
||||
|
||||
fn add_to_index_(item: @item, ebml_w: ebml::writer,
|
||||
@ -528,7 +536,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||
encode_path(ebml_w, path, ast_map::path_name(item.ident));
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
item_ty(_, tps) {
|
||||
item_ty(_, tps, rp) {
|
||||
add_to_index();
|
||||
ebml_w.start_tag(tag_items_data_item);
|
||||
encode_def_id(ebml_w, local_def(item.id));
|
||||
@ -537,26 +545,28 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
||||
encode_name(ebml_w, item.ident);
|
||||
encode_path(ebml_w, path, ast_map::path_name(item.ident));
|
||||
encode_region_param(ebml_w, rp);
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
item_enum(variants, tps) {
|
||||
item_enum(variants, tps, rp) {
|
||||
add_to_index();
|
||||
ebml_w.start_tag(tag_items_data_item);
|
||||
encode_def_id(ebml_w, local_def(item.id));
|
||||
encode_family(ebml_w, 't');
|
||||
encode_type_param_bounds(ebml_w, ecx, tps);
|
||||
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
||||
encode_name(ebml_w, item.ident);
|
||||
for variants.each {|v|
|
||||
encode_variant_id(ebml_w, local_def(v.node.id));
|
||||
ebml_w.wr_tag(tag_items_data_item) {||
|
||||
encode_def_id(ebml_w, local_def(item.id));
|
||||
encode_family(ebml_w, 't');
|
||||
encode_type_param_bounds(ebml_w, ecx, tps);
|
||||
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
||||
encode_name(ebml_w, item.ident);
|
||||
for variants.each {|v|
|
||||
encode_variant_id(ebml_w, local_def(v.node.id));
|
||||
}
|
||||
astencode::encode_inlined_item(ecx, ebml_w, path, ii_item(item));
|
||||
encode_path(ebml_w, path, ast_map::path_name(item.ident));
|
||||
encode_region_param(ebml_w, rp);
|
||||
}
|
||||
astencode::encode_inlined_item(ecx, ebml_w, path, ii_item(item));
|
||||
encode_path(ebml_w, path, ast_map::path_name(item.ident));
|
||||
ebml_w.end_tag();
|
||||
encode_enum_variant_info(ecx, ebml_w, item.id, variants,
|
||||
path, index, tps);
|
||||
}
|
||||
item_class(tps, _ifaces, items,ctor) {
|
||||
item_class(tps, _ifaces, items, ctor, rp) {
|
||||
/* First, encode the fields and methods
|
||||
These come first because we need to write them to make
|
||||
the index, and the index needs to be in the item for the
|
||||
@ -573,6 +583,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
||||
encode_name(ebml_w, item.ident);
|
||||
encode_path(ebml_w, path, ast_map::path_name(item.ident));
|
||||
encode_region_param(ebml_w, rp);
|
||||
/* FIXME: encode ifaces */
|
||||
/* Encode def_ids for each field and method
|
||||
for methods, write all the stuff get_iface_method
|
||||
@ -605,7 +616,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||
encode_index(ebml_w, bkts, write_int);
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
item_res(_, tps, _, _, ctor_id) {
|
||||
item_res(_, tps, _, _, ctor_id, rp) {
|
||||
add_to_index();
|
||||
let fn_ty = node_id_to_type(tcx, ctor_id);
|
||||
|
||||
@ -620,6 +631,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
||||
encode_symbol(ecx, ebml_w, item.id);
|
||||
}
|
||||
encode_path(ebml_w, path, ast_map::path_name(item.ident));
|
||||
encode_region_param(ebml_w, rp);
|
||||
ebml_w.end_tag();
|
||||
|
||||
*index += [{val: ctor_id, pos: ebml_w.writer.tell()}];
|
||||
@ -732,7 +744,7 @@ fn encode_info_for_items(ecx: @encode_ctxt, ebml_w: ebml::writer,
|
||||
encode_info_for_item(ecx, ebml_w, i, index, *pt);
|
||||
/* encode ctor, then encode items */
|
||||
alt i.node {
|
||||
item_class(tps,_,_,ctor) {
|
||||
item_class(tps, _, _, ctor, _) {
|
||||
/* this is assuming that ctors aren't inlined...
|
||||
probably shouldn't assume that */
|
||||
#debug("encoding info for ctor %s %d", i.ident,
|
||||
|
@ -182,6 +182,65 @@ fn parse_vstore(st: @pstate) -> ty::vstore {
|
||||
st.tcx.sess.unimpl("tydecode::parse_vstore");
|
||||
}
|
||||
|
||||
fn parse_substs(st: @pstate, conv: conv_did) -> ty::substs {
|
||||
let self_r = parse_opt(st) {|| parse_region(st) };
|
||||
|
||||
assert next(st) == '[';
|
||||
let mut params: [ty::t] = [];
|
||||
while peek(st) != ']' { params += [parse_ty(st, conv)]; }
|
||||
st.pos = st.pos + 1u;
|
||||
|
||||
ret {self_r: self_r, tps: params};
|
||||
}
|
||||
|
||||
fn parse_bound_region(st: @pstate) -> ty::bound_region {
|
||||
alt check next(st) {
|
||||
's' { ty::br_self }
|
||||
'a' { ty::br_anon }
|
||||
'[' { ty::br_named(parse_str(st, ']')) }
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_region(st: @pstate) -> ty::region {
|
||||
alt check next(st) {
|
||||
'b' {
|
||||
ty::re_bound(parse_bound_region(st))
|
||||
}
|
||||
'f' {
|
||||
assert next(st) == '[';
|
||||
let id = parse_int(st);
|
||||
assert next(st) == '|';
|
||||
let br = parse_bound_region(st);
|
||||
assert next(st) == ']';
|
||||
ty::re_free(id, br)
|
||||
}
|
||||
's' {
|
||||
let id = parse_int(st);
|
||||
assert next(st) == '|';
|
||||
ty::re_scope(id)
|
||||
}
|
||||
't' {
|
||||
ty::re_static
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_opt<T>(st: @pstate, f: fn() -> T) -> option<T> {
|
||||
alt check next(st) {
|
||||
'n' { none }
|
||||
's' { some(f()) }
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_str(st: @pstate, term: char) -> str {
|
||||
let mut result = "";
|
||||
while peek(st) != term {
|
||||
result += str::from_byte(next_byte(st));
|
||||
}
|
||||
next(st);
|
||||
ret result;
|
||||
}
|
||||
|
||||
fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
|
||||
alt check next(st) {
|
||||
'n' { ret ty::mk_nil(st.tcx); }
|
||||
@ -209,10 +268,9 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
|
||||
't' {
|
||||
assert (next(st) == '[');
|
||||
let def = parse_def(st, conv);
|
||||
let mut params: [ty::t] = [];
|
||||
while peek(st) != ']' { params += [parse_ty(st, conv)]; }
|
||||
st.pos = st.pos + 1u;
|
||||
ret ty::mk_enum(st.tcx, def, params);
|
||||
let substs = parse_substs(st, conv);
|
||||
assert next(st) == ']';
|
||||
ret ty::mk_enum(st.tcx, def, substs);
|
||||
}
|
||||
'x' {
|
||||
assert (next(st) == '[');
|
||||
@ -250,11 +308,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
|
||||
assert (next(st) == '[');
|
||||
let mut fields: [ty::field] = [];
|
||||
while peek(st) != ']' {
|
||||
let mut name = "";
|
||||
while peek(st) != '=' {
|
||||
name += str::from_byte(next_byte(st));
|
||||
}
|
||||
st.pos = st.pos + 1u;
|
||||
let name = parse_str(st, '=');
|
||||
fields += [{ident: name, mt: parse_mt(st, conv)}];
|
||||
}
|
||||
st.pos = st.pos + 1u;
|
||||
@ -275,10 +329,9 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
|
||||
assert (next(st) == '[');
|
||||
let def = parse_def(st, conv);
|
||||
let inner = parse_ty(st, conv);
|
||||
let mut params: [ty::t] = [];
|
||||
while peek(st) != ']' { params += [parse_ty(st, conv)]; }
|
||||
st.pos = st.pos + 1u;
|
||||
ret ty::mk_res(st.tcx, def, inner, params);
|
||||
let substs = parse_substs(st, conv);
|
||||
assert next(st) == ']';
|
||||
ret ty::mk_res(st.tcx, def, inner, substs);
|
||||
}
|
||||
'X' {
|
||||
ret ty::mk_var(st.tcx, ty::ty_vid(parse_int(st) as uint));
|
||||
@ -326,10 +379,9 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
|
||||
#debug("saw a [");
|
||||
let did = parse_def(st, conv);
|
||||
#debug("parsed a def_id %?", did);
|
||||
let mut params: [ty::t] = [];
|
||||
while peek(st) != ']' { params += [parse_ty(st, conv)]; }
|
||||
let substs = parse_substs(st, conv);
|
||||
assert (next(st) == ']');
|
||||
ret ty::mk_class(st.tcx, did, params);
|
||||
ret ty::mk_class(st.tcx, did, substs);
|
||||
}
|
||||
c { #error("unexpected char in type string: %c", c); fail;}
|
||||
}
|
||||
|
@ -100,18 +100,25 @@ fn enc_mt(w: io::writer, cx: @ctxt, mt: ty::mt) {
|
||||
}
|
||||
enc_ty(w, cx, mt.ty);
|
||||
}
|
||||
fn enc_bound_region(w: io::writer, br: ty::bound_region) {
|
||||
alt br {
|
||||
ty::br_self { w.write_char('s') }
|
||||
ty::br_anon { w.write_char('a') }
|
||||
ty::br_named(s) {
|
||||
w.write_char('[');
|
||||
w.write_str(s);
|
||||
w.write_char(']')
|
||||
|
||||
fn enc_opt<T>(w: io::writer, t: option<T>, enc_f: fn(T)) {
|
||||
alt t {
|
||||
none { w.write_char('n') }
|
||||
some(v) {
|
||||
w.write_char('s');
|
||||
enc_f(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
fn enc_region(w: io::writer, r: ty::region) {
|
||||
|
||||
fn enc_substs(w: io::writer, cx: @ctxt, substs: ty::substs) {
|
||||
enc_opt(w, substs.self_r) { |r| enc_region(w, cx, r) }
|
||||
w.write_char('[');
|
||||
for substs.tps.each { |t| enc_ty(w, cx, t); }
|
||||
w.write_char(']');
|
||||
}
|
||||
|
||||
fn enc_region(w: io::writer, cx: @ctxt, r: ty::region) {
|
||||
alt r {
|
||||
ty::re_bound(br) {
|
||||
w.write_char('b');
|
||||
@ -130,18 +137,29 @@ fn enc_region(w: io::writer, r: ty::region) {
|
||||
w.write_int(nid);
|
||||
w.write_char('|');
|
||||
}
|
||||
ty::re_var(id) {
|
||||
w.write_char('v');
|
||||
w.write_uint(id.to_uint());
|
||||
w.write_char('|');
|
||||
}
|
||||
ty::re_static {
|
||||
w.write_char('t');
|
||||
}
|
||||
ty::re_var(_) {
|
||||
// these should not crop up after typeck
|
||||
cx.tcx.sess.bug("Cannot encode region variables");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn enc_vstore(w: io::writer, v: ty::vstore) {
|
||||
fn enc_bound_region(w: io::writer, br: ty::bound_region) {
|
||||
alt br {
|
||||
ty::br_self { w.write_char('s') }
|
||||
ty::br_anon { w.write_char('a') }
|
||||
ty::br_named(s) {
|
||||
w.write_char('[');
|
||||
w.write_str(s);
|
||||
w.write_char(']')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn enc_vstore(w: io::writer, cx: @ctxt, v: ty::vstore) {
|
||||
w.write_char('/');
|
||||
alt v {
|
||||
ty::vstore_fixed(u) {
|
||||
@ -156,7 +174,7 @@ fn enc_vstore(w: io::writer, v: ty::vstore) {
|
||||
}
|
||||
ty::vstore_slice(r) {
|
||||
w.write_char('&');
|
||||
enc_region(w, r);
|
||||
enc_region(w, cx, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -193,11 +211,11 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
|
||||
}
|
||||
}
|
||||
ty::ty_str { w.write_char('S'); }
|
||||
ty::ty_enum(def, tys) {
|
||||
ty::ty_enum(def, substs) {
|
||||
w.write_str("t[");
|
||||
w.write_str(cx.ds(def));
|
||||
w.write_char('|');
|
||||
for tys.each {|t| enc_ty(w, cx, t); }
|
||||
enc_substs(w, cx, substs);
|
||||
w.write_char(']');
|
||||
}
|
||||
ty::ty_iface(def, tys) {
|
||||
@ -217,17 +235,17 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
|
||||
ty::ty_ptr(mt) { w.write_char('*'); enc_mt(w, cx, mt); }
|
||||
ty::ty_rptr(r, mt) {
|
||||
w.write_char('&');
|
||||
enc_region(w, r);
|
||||
enc_region(w, cx, r);
|
||||
enc_mt(w, cx, mt);
|
||||
}
|
||||
ty::ty_evec(mt, v) {
|
||||
w.write_char('V');
|
||||
enc_mt(w, cx, mt);
|
||||
enc_vstore(w, v);
|
||||
enc_vstore(w, cx, v);
|
||||
}
|
||||
ty::ty_estr(v) {
|
||||
w.write_char('v');
|
||||
enc_vstore(w, v);
|
||||
enc_vstore(w, cx, v);
|
||||
}
|
||||
ty::ty_vec(mt) { w.write_char('I'); enc_mt(w, cx, mt); }
|
||||
ty::ty_rec(fields) {
|
||||
@ -243,12 +261,12 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
|
||||
enc_proto(w, f.proto);
|
||||
enc_ty_fn(w, cx, f);
|
||||
}
|
||||
ty::ty_res(def, ty, tps) {
|
||||
ty::ty_res(def, ty, substs) {
|
||||
w.write_str("r[");
|
||||
w.write_str(cx.ds(def));
|
||||
w.write_char('|');
|
||||
enc_ty(w, cx, ty);
|
||||
for tps.each {|t| enc_ty(w, cx, t); }
|
||||
enc_substs(w, cx, substs);
|
||||
w.write_char(']');
|
||||
}
|
||||
ty::ty_var(id) {
|
||||
@ -277,7 +295,7 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
|
||||
w.write_char(']');
|
||||
}
|
||||
ty::ty_opaque_box { w.write_char('B'); }
|
||||
ty::ty_class(def, tys) {
|
||||
ty::ty_class(def, substs) {
|
||||
#debug("~~~~ %s", "a[");
|
||||
w.write_str("a[");
|
||||
let s = cx.ds(def);
|
||||
@ -285,7 +303,7 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
|
||||
w.write_str(s);
|
||||
#debug("~~~~ %s", "|");
|
||||
w.write_str("|");
|
||||
for tys.each {|t| enc_ty(w, cx, t); }
|
||||
enc_substs(w, cx, substs);
|
||||
#debug("~~~~ %s", "]");
|
||||
w.write_char(']');
|
||||
}
|
||||
|
@ -503,7 +503,7 @@ fn ty_can_unsafely_include(cx: ctx, needle: unsafe_ty, haystack: ty::t,
|
||||
} { ret true; }
|
||||
alt ty::get(haystack).struct {
|
||||
ty::ty_enum(_, ts) {
|
||||
for ts.each {|t|
|
||||
for ts.tps.each {|t|
|
||||
if helper(tcx, needle, t, mutbl) { ret true; }
|
||||
}
|
||||
ret false;
|
||||
@ -565,10 +565,11 @@ fn copy_is_expensive(tcx: ty::ctxt, ty: ty::t) -> bool {
|
||||
ty::ty_fn(_) { 4u }
|
||||
ty::ty_str | ty::ty_vec(_) | ty::ty_param(_, _) { 50u }
|
||||
ty::ty_uniq(mt) { 1u + score_ty(tcx, mt.ty) }
|
||||
ty::ty_enum(_, ts) | ty::ty_tup(ts) {
|
||||
let mut sum = 0u;
|
||||
for ts.each {|t| sum += score_ty(tcx, t); }
|
||||
sum
|
||||
ty::ty_enum(_, substs) {
|
||||
substs.tps.foldl(0u) { |sum, t| sum + score_ty(tcx, t) }
|
||||
}
|
||||
ty::ty_tup(ts) {
|
||||
ts.foldl(0u) { |sum, t| sum + score_ty(tcx, t) }
|
||||
}
|
||||
ty::ty_rec(fs) {
|
||||
let mut sum = 0u;
|
||||
|
@ -183,13 +183,13 @@ fn map_item(i: @item, cx: ctx, v: vt) {
|
||||
map_method(impl_did, extend(cx, i.ident), m, cx);
|
||||
}
|
||||
}
|
||||
item_res(decl, tps, _, dtor_id, ctor_id) {
|
||||
item_res(decl, tps, _, dtor_id, ctor_id, _) {
|
||||
cx.map.insert(ctor_id, node_ctor(i.ident, tps,
|
||||
res_ctor(decl, ctor_id, i.span),
|
||||
item_path));
|
||||
cx.map.insert(dtor_id, node_item(i, item_path));
|
||||
}
|
||||
item_enum(vs, _) {
|
||||
item_enum(vs, _, _) {
|
||||
for vs.each {|v|
|
||||
cx.map.insert(v.node.id, node_variant(
|
||||
v, i, extend(cx, i.ident)));
|
||||
@ -204,7 +204,7 @@ fn map_item(i: @item, cx: ctx, v: vt) {
|
||||
cx.map.insert(nitem.id, node_native_item(nitem, abi, @cx.path));
|
||||
}
|
||||
}
|
||||
item_class(_, _, items, ctor) {
|
||||
item_class(_, _, items, ctor, _) {
|
||||
let d_id = ast_util::local_def(i.id);
|
||||
let p = extend(cx, i.ident);
|
||||
for items.each {|ci|
|
||||
|
@ -22,7 +22,7 @@ fn check_item(sess: session, ast_map: ast_map::map, def_map: resolve::def_map,
|
||||
v.visit_expr(ex, true, v);
|
||||
check_item_recursion(sess, ast_map, def_map, it);
|
||||
}
|
||||
item_enum(vs, _) {
|
||||
item_enum(vs, _, _) {
|
||||
for vs.each {|var|
|
||||
option::iter(var.node.disr_expr) {|ex|
|
||||
v.visit_expr(ex, true, v);
|
||||
|
@ -538,11 +538,21 @@ impl unify_methods for infer_ctxt {
|
||||
sub(self).tys(a, b).chain {|_t| ok(()) }
|
||||
}
|
||||
|
||||
fn sub_regions(a: ty::region, b: ty::region) -> ures {
|
||||
sub(self).regions(a, b).chain {|_t| ok(()) }
|
||||
}
|
||||
|
||||
fn eq_tys(a: ty::t, b: ty::t) -> ures {
|
||||
self.sub_tys(a, b).then {||
|
||||
self.sub_tys(b, a)
|
||||
}
|
||||
}
|
||||
|
||||
fn eq_regions(a: ty::region, b: ty::region) -> ures {
|
||||
self.sub_regions(a, b).then {||
|
||||
self.sub_regions(b, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl resolve_methods for infer_ctxt {
|
||||
@ -905,6 +915,7 @@ iface combine {
|
||||
fn contratys(a: ty::t, b: ty::t) -> cres<ty::t>;
|
||||
fn tys(a: ty::t, b: ty::t) -> cres<ty::t>;
|
||||
fn tps(as: [ty::t], bs: [ty::t]) -> cres<[ty::t]>;
|
||||
fn substs(as: ty::substs, bs: ty::substs) -> cres<ty::substs>;
|
||||
fn fns(a: ty::fn_ty, b: ty::fn_ty) -> cres<ty::fn_ty>;
|
||||
fn flds(a: ty::field, b: ty::field) -> cres<ty::field>;
|
||||
fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode>;
|
||||
@ -921,6 +932,41 @@ enum sub = infer_ctxt; // "subtype", "subregion" etc
|
||||
enum lub = infer_ctxt; // "least upper bound" (common supertype)
|
||||
enum glb = infer_ctxt; // "greatest lower bound" (common subtype)
|
||||
|
||||
fn super_substs<C:combine>(
|
||||
self: C, a: ty::substs, b: ty::substs) -> cres<ty::substs> {
|
||||
|
||||
fn eq_opt_regions(infcx: infer_ctxt,
|
||||
a: option<ty::region>,
|
||||
b: option<ty::region>) -> cres<option<ty::region>> {
|
||||
alt (a, b) {
|
||||
(none, none) {
|
||||
ok(none)
|
||||
}
|
||||
(some(a), some(b)) {
|
||||
infcx.eq_regions(a, b);
|
||||
ok(some(a))
|
||||
}
|
||||
(_, _) {
|
||||
// If these two substitutions are for the same type (and
|
||||
// they should be), then the type should either
|
||||
// consistenly have a region parameter or not have a
|
||||
// region parameter.
|
||||
infcx.tcx.sess.bug(
|
||||
#fmt["substitution a had opt_region %s and \
|
||||
b had opt_region %s",
|
||||
a.to_str(infcx),
|
||||
b.to_str(infcx)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.tps(a.tps, b.tps).chain { |tps|
|
||||
eq_opt_regions(self.infcx(), a.self_r, b.self_r).chain { |self_r|
|
||||
ok({self_r: self_r, tps: tps})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn super_tps<C:combine>(
|
||||
self: C, as: [ty::t], bs: [ty::t]) -> cres<[ty::t]> {
|
||||
|
||||
@ -1057,9 +1103,9 @@ fn super_tys<C:combine>(
|
||||
ok(a)
|
||||
}
|
||||
|
||||
(ty::ty_enum(a_id, a_tps), ty::ty_enum(b_id, b_tps))
|
||||
(ty::ty_enum(a_id, a_substs), ty::ty_enum(b_id, b_substs))
|
||||
if a_id == b_id {
|
||||
self.tps(a_tps, b_tps).chain {|tps|
|
||||
self.substs(a_substs, b_substs).chain {|tps|
|
||||
ok(ty::mk_enum(tcx, a_id, tps))
|
||||
}
|
||||
}
|
||||
@ -1071,10 +1117,10 @@ fn super_tys<C:combine>(
|
||||
}
|
||||
}
|
||||
|
||||
(ty::ty_class(a_id, a_tps), ty::ty_class(b_id, b_tps))
|
||||
(ty::ty_class(a_id, a_substs), ty::ty_class(b_id, b_substs))
|
||||
if a_id == b_id {
|
||||
self.tps(a_tps, b_tps).chain {|tps|
|
||||
ok(ty::mk_class(tcx, a_id, tps))
|
||||
self.substs(a_substs, b_substs).chain {|substs|
|
||||
ok(ty::mk_class(tcx, a_id, substs))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1124,11 +1170,12 @@ fn super_tys<C:combine>(
|
||||
}
|
||||
}
|
||||
|
||||
(ty::ty_res(a_id, a_t, a_tps), ty::ty_res(b_id, b_t, b_tps))
|
||||
(ty::ty_res(a_id, a_t, a_substs),
|
||||
ty::ty_res(b_id, b_t, b_substs))
|
||||
if a_id == b_id {
|
||||
self.tys(a_t, b_t).chain {|t|
|
||||
self.tps(a_tps, b_tps).chain {|tps|
|
||||
ok(ty::mk_res(tcx, a_id, t, tps))
|
||||
self.substs(a_substs, b_substs).chain {|substs|
|
||||
ok(ty::mk_res(tcx, a_id, t, substs))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1299,6 +1346,10 @@ impl of combine for sub {
|
||||
super_fns(self, a, b)
|
||||
}
|
||||
|
||||
fn substs(as: ty::substs, bs: ty::substs) -> cres<ty::substs> {
|
||||
super_substs(self, as, bs)
|
||||
}
|
||||
|
||||
fn tps(as: [ty::t], bs: [ty::t]) -> cres<[ty::t]> {
|
||||
super_tps(self, as, bs)
|
||||
}
|
||||
@ -1470,6 +1521,10 @@ impl of combine for lub {
|
||||
super_fns(self, a, b)
|
||||
}
|
||||
|
||||
fn substs(as: ty::substs, bs: ty::substs) -> cres<ty::substs> {
|
||||
super_substs(self, as, bs)
|
||||
}
|
||||
|
||||
fn tps(as: [ty::t], bs: [ty::t]) -> cres<[ty::t]> {
|
||||
super_tps(self, as, bs)
|
||||
}
|
||||
@ -1656,6 +1711,10 @@ impl of combine for glb {
|
||||
super_fns(self, a, b)
|
||||
}
|
||||
|
||||
fn substs(as: ty::substs, bs: ty::substs) -> cres<ty::substs> {
|
||||
super_substs(self, as, bs)
|
||||
}
|
||||
|
||||
fn tps(as: [ty::t], bs: [ty::t]) -> cres<[ty::t]> {
|
||||
super_tps(self, as, bs)
|
||||
}
|
||||
|
@ -30,18 +30,18 @@ fn expr_root_(tcx: ty::ctxt, ctor_self: option<node_id>,
|
||||
outer_t: t}];
|
||||
t = mt.ty;
|
||||
}
|
||||
ty::ty_res(_, inner, tps) {
|
||||
ty::ty_res(_, inner, substs) {
|
||||
ds += [@{mutbl: false, kind: unbox(false), outer_t: t}];
|
||||
t = ty::substitute_type_params(tcx, tps, inner);
|
||||
t = ty::subst(tcx, substs, inner);
|
||||
}
|
||||
ty::ty_enum(did, tps) {
|
||||
ty::ty_enum(did, substs) {
|
||||
let variants = ty::enum_variants(tcx, did);
|
||||
if vec::len(*variants) != 1u ||
|
||||
vec::len(variants[0].args) != 1u {
|
||||
break;
|
||||
}
|
||||
ds += [@{mutbl: false, kind: unbox(false), outer_t: t}];
|
||||
t = ty::substitute_type_params(tcx, tps, variants[0].args[0]);
|
||||
t = ty::subst(tcx, substs, variants[0].args[0]);
|
||||
}
|
||||
_ { break; }
|
||||
}
|
||||
@ -216,7 +216,7 @@ fn visit_expr(ex: @expr, &&cx: @ctx, v: visit::vt<@ctx>) {
|
||||
|
||||
fn visit_item(item: @item, &&cx: @ctx, v: visit::vt<@ctx>) {
|
||||
alt item.node {
|
||||
item_class(tps, _, items, ctor) {
|
||||
item_class(tps, _, items, ctor, _) {
|
||||
v.visit_ty_params(tps, cx, v);
|
||||
vec::map::<@class_member, ()>(items,
|
||||
{|i| v.visit_class_item(i, cx, v); });
|
||||
|
@ -143,16 +143,7 @@ import std::list::list;
|
||||
import std::map;
|
||||
import std::map::hashmap;
|
||||
|
||||
/* Represents the type of the most immediate parent node. */
|
||||
enum parent {
|
||||
pa_fn_item(ast::node_id),
|
||||
pa_block(ast::node_id),
|
||||
pa_nested_fn(ast::node_id),
|
||||
pa_item(ast::node_id),
|
||||
pa_call(ast::node_id),
|
||||
pa_alt(ast::node_id),
|
||||
pa_crate
|
||||
}
|
||||
type parent = option<ast::node_id>;
|
||||
|
||||
/* Records the parameter ID of a region name. */
|
||||
type binding = {node_id: ast::node_id,
|
||||
@ -167,43 +158,11 @@ type region_map = {
|
||||
local_blocks: hashmap<ast::node_id,ast::node_id>
|
||||
};
|
||||
|
||||
type region_scope = @{
|
||||
node_id: ast::node_id,
|
||||
kind: region_scope_kind
|
||||
};
|
||||
|
||||
enum region_scope_kind {
|
||||
rsk_root,
|
||||
rsk_body(region_scope),
|
||||
rsk_self(region_scope),
|
||||
rsk_binding(region_scope, @mut [binding])
|
||||
}
|
||||
|
||||
fn root_scope(node_id: ast::node_id) -> region_scope {
|
||||
@{node_id: node_id, kind: rsk_root}
|
||||
}
|
||||
|
||||
impl methods for region_scope {
|
||||
fn body_subscope(node_id: ast::node_id) -> region_scope {
|
||||
@{node_id: node_id, kind: rsk_body(self)}
|
||||
}
|
||||
|
||||
fn binding_subscope(node_id: ast::node_id) -> region_scope {
|
||||
@{node_id: node_id, kind: rsk_binding(self, @mut [])}
|
||||
}
|
||||
|
||||
fn self_subscope(node_id: ast::node_id) -> region_scope {
|
||||
@{node_id: node_id, kind: rsk_self(self)}
|
||||
}
|
||||
}
|
||||
|
||||
type ctxt = {
|
||||
sess: session,
|
||||
def_map: resolve::def_map,
|
||||
region_map: @region_map,
|
||||
|
||||
scope: region_scope,
|
||||
|
||||
parent: parent
|
||||
};
|
||||
|
||||
@ -269,40 +228,8 @@ fn nearest_common_ancestor(region_map: @region_map, scope_a: ast::node_id,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_inferred_region(cx: ctxt, sp: syntax::codemap::span) -> ty::region {
|
||||
// We infer to the caller region if we're at item scope
|
||||
// and to the block region if we're at block scope.
|
||||
//
|
||||
// TODO: What do we do if we're in an alt?
|
||||
|
||||
ret alt cx.parent {
|
||||
pa_fn_item(_) | pa_nested_fn(_) { ty::re_bound(ty::br_anon) }
|
||||
pa_block(node_id) | pa_call(node_id) | pa_alt(node_id) {
|
||||
ty::re_scope(node_id)
|
||||
}
|
||||
pa_item(_) { ty::re_bound(ty::br_anon) }
|
||||
pa_crate { cx.sess.span_bug(sp, "inferred region at crate level?!"); }
|
||||
}
|
||||
}
|
||||
|
||||
fn opt_parent_id(cx: ctxt) -> option<ast::node_id> {
|
||||
alt cx.parent {
|
||||
pa_fn_item(parent_id) |
|
||||
pa_item(parent_id) |
|
||||
pa_block(parent_id) |
|
||||
pa_alt(parent_id) |
|
||||
pa_call(parent_id) |
|
||||
pa_nested_fn(parent_id) {
|
||||
some(parent_id)
|
||||
}
|
||||
pa_crate {
|
||||
none
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parent_id(cx: ctxt, span: span) -> ast::node_id {
|
||||
alt opt_parent_id(cx) {
|
||||
alt cx.parent {
|
||||
none {
|
||||
cx.sess.span_bug(span, "crate should not be parent here");
|
||||
}
|
||||
@ -313,7 +240,7 @@ fn parent_id(cx: ctxt, span: span) -> ast::node_id {
|
||||
}
|
||||
|
||||
fn record_parent(cx: ctxt, child_id: ast::node_id) {
|
||||
alt opt_parent_id(cx) {
|
||||
alt cx.parent {
|
||||
none { /* no-op */ }
|
||||
some(parent_id) {
|
||||
cx.region_map.parents.insert(child_id, parent_id);
|
||||
@ -326,8 +253,7 @@ fn resolve_block(blk: ast::blk, cx: ctxt, visitor: visit::vt<ctxt>) {
|
||||
record_parent(cx, blk.node.id);
|
||||
|
||||
// Descend.
|
||||
let new_cx: ctxt = {parent: pa_block(blk.node.id),
|
||||
scope: cx.scope.body_subscope(blk.node.id)
|
||||
let new_cx: ctxt = {parent: some(blk.node.id)
|
||||
with cx};
|
||||
visit::visit_block(blk, new_cx, visitor);
|
||||
}
|
||||
@ -361,21 +287,15 @@ fn resolve_expr(expr: @ast::expr, cx: ctxt, visitor: visit::vt<ctxt>) {
|
||||
record_parent(cx, expr.id);
|
||||
alt expr.node {
|
||||
ast::expr_fn(_, _, _, _) | ast::expr_fn_block(_, _) {
|
||||
let new_cx = {parent: pa_nested_fn(expr.id),
|
||||
scope: cx.scope.binding_subscope(expr.id)
|
||||
with cx};
|
||||
let new_cx = {parent: some(expr.id) with cx};
|
||||
visit::visit_expr(expr, new_cx, visitor);
|
||||
}
|
||||
ast::expr_call(_, _, _) {
|
||||
let new_cx = {parent: pa_call(expr.id),
|
||||
scope: cx.scope.binding_subscope(expr.id)
|
||||
with cx};
|
||||
let new_cx = {parent: some(expr.id) with cx};
|
||||
visit::visit_expr(expr, new_cx, visitor);
|
||||
}
|
||||
ast::expr_alt(subexpr, _, _) {
|
||||
let new_cx = {parent: pa_alt(expr.id),
|
||||
scope: cx.scope.binding_subscope(expr.id)
|
||||
with cx};
|
||||
let new_cx = {parent: some(expr.id) with cx};
|
||||
visit::visit_expr(expr, new_cx, visitor);
|
||||
}
|
||||
_ {
|
||||
@ -392,27 +312,7 @@ fn resolve_local(local: @ast::local, cx: ctxt, visitor: visit::vt<ctxt>) {
|
||||
|
||||
fn resolve_item(item: @ast::item, cx: ctxt, visitor: visit::vt<ctxt>) {
|
||||
// Items create a new outer block scope as far as we're concerned.
|
||||
let {parent, scope} = {
|
||||
alt item.node {
|
||||
ast::item_fn(_, _, _) | ast::item_enum(_, _) {
|
||||
{parent: pa_fn_item(item.id),
|
||||
scope: cx.scope.binding_subscope(item.id)}
|
||||
}
|
||||
ast::item_impl(_, _, _, _) | ast::item_class(_, _, _, _) {
|
||||
{parent: pa_item(item.id),
|
||||
scope: cx.scope.self_subscope(item.id)}
|
||||
}
|
||||
_ {
|
||||
{parent: pa_item(item.id),
|
||||
scope: root_scope(item.id)}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let new_cx: ctxt = {parent: parent,
|
||||
scope: scope
|
||||
with cx};
|
||||
|
||||
let new_cx: ctxt = {parent: some(item.id) with cx};
|
||||
visit::visit_item(item, new_cx, visitor);
|
||||
}
|
||||
|
||||
@ -422,8 +322,7 @@ fn resolve_crate(sess: session, def_map: resolve::def_map, crate: @ast::crate)
|
||||
def_map: def_map,
|
||||
region_map: @{parents: map::int_hash(),
|
||||
local_blocks: map::int_hash()},
|
||||
scope: root_scope(0),
|
||||
parent: pa_crate};
|
||||
parent: none};
|
||||
let visitor = visit::mk_vt(@{
|
||||
visit_block: resolve_block,
|
||||
visit_item: resolve_item,
|
||||
|
@ -434,7 +434,7 @@ fn resolve_names(e: @env, c: @ast::crate) {
|
||||
non-class items
|
||||
*/
|
||||
alt i.node {
|
||||
ast::item_class(_, ifaces, _, _) {
|
||||
ast::item_class(_, ifaces, _, _, _) {
|
||||
/* visit the iface paths... */
|
||||
for ifaces.each {|p|
|
||||
maybe_insert(e, p.id,
|
||||
@ -559,7 +559,7 @@ fn visit_item_with_scope(e: @env, i: @ast::item, sc: scopes, v: vt<scopes>) {
|
||||
v.visit_ty(m.decl.output, msc, v);
|
||||
}
|
||||
}
|
||||
ast::item_class(tps, ifaces, members, ctor) {
|
||||
ast::item_class(tps, ifaces, members, ctor, _) {
|
||||
visit::visit_ty_params(tps, sc, v);
|
||||
// Can maybe skip this now that we require self on class fields
|
||||
let class_scope = cons(scope_item(i), @sc);
|
||||
@ -613,7 +613,7 @@ fn visit_fn_with_scope(e: @env, fk: visit::fn_kind, decl: ast::fn_decl,
|
||||
// for f's constrs in the table.
|
||||
for decl.constraints.each {|c| resolve_constr(e, c, sc, v); }
|
||||
let scope = alt fk {
|
||||
visit::fk_item_fn(_, tps) | visit::fk_res(_, tps) |
|
||||
visit::fk_item_fn(_, tps) | visit::fk_res(_, tps, _) |
|
||||
visit::fk_method(_, tps, _) | visit::fk_ctor(_, tps, _, _)
|
||||
{ scope_bare_fn(decl, id, tps) }
|
||||
visit::fk_anon(ast::proto_bare) { scope_bare_fn(decl, id, []) }
|
||||
@ -1019,7 +1019,7 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace,
|
||||
ast::item_impl(tps, _, _, _) {
|
||||
if ns == ns_type { ret lookup_in_ty_params(e, name, tps); }
|
||||
}
|
||||
ast::item_enum(_, tps) | ast::item_ty(_, tps) {
|
||||
ast::item_enum(_, tps, _) | ast::item_ty(_, tps, _) {
|
||||
if ns == ns_type { ret lookup_in_ty_params(e, name, tps); }
|
||||
}
|
||||
ast::item_iface(tps, _) {
|
||||
@ -1036,7 +1036,7 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace,
|
||||
ast::item_native_mod(m) {
|
||||
ret lookup_in_local_native_mod(e, it.id, sp, name, ns);
|
||||
}
|
||||
ast::item_class(tps, _, members, ctor) {
|
||||
ast::item_class(tps, _, members, ctor, _) {
|
||||
if ns == ns_type {
|
||||
ret lookup_in_ty_params(e, name, tps);
|
||||
}
|
||||
@ -1210,7 +1210,7 @@ fn lookup_in_block(e: env, name: ident, sp: span, b: ast::blk_, pos: uint,
|
||||
}
|
||||
ast::decl_item(it) {
|
||||
alt it.node {
|
||||
ast::item_enum(variants, _) {
|
||||
ast::item_enum(variants, _, _) {
|
||||
if ns == ns_type {
|
||||
if str::eq(it.ident, name) {
|
||||
ret some(ast::def_ty(local_def(it.id)));
|
||||
@ -1309,10 +1309,10 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option<def> {
|
||||
ast::item_native_mod(_) {
|
||||
if ns == ns_module { ret some(ast::def_native_mod(local_def(i.id))); }
|
||||
}
|
||||
ast::item_ty(_, _) | item_iface(_, _) | item_enum(_, _) {
|
||||
ast::item_ty(_, _, _) | item_iface(_, _) | item_enum(_, _, _) {
|
||||
if ns == ns_type { ret some(ast::def_ty(local_def(i.id))); }
|
||||
}
|
||||
ast::item_res(_, _, _, _, ctor_id) {
|
||||
ast::item_res(_, _, _, _, ctor_id, _) {
|
||||
alt ns {
|
||||
ns_val {
|
||||
ret some(ast::def_fn(local_def(ctor_id), ast::impure_fn));
|
||||
@ -1321,7 +1321,7 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option<def> {
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
ast::item_class(_, _, _, _) {
|
||||
ast::item_class(_, _, _, _, _) {
|
||||
if ns == ns_type {
|
||||
ret some(ast::def_class(local_def(i.id)));
|
||||
}
|
||||
@ -1614,12 +1614,12 @@ fn index_mod(md: ast::_mod) -> mod_index {
|
||||
for md.items.each {|it|
|
||||
alt it.node {
|
||||
ast::item_const(_, _) | ast::item_fn(_, _, _) | ast::item_mod(_) |
|
||||
ast::item_native_mod(_) | ast::item_ty(_, _) |
|
||||
ast::item_res(_, _, _, _, _) |
|
||||
ast::item_native_mod(_) | ast::item_ty(_, _, _) |
|
||||
ast::item_res(_, _, _, _, _, _) |
|
||||
ast::item_impl(_, _, _, _) | ast::item_iface(_, _) {
|
||||
add_to_index(index, it.ident, mie_item(it));
|
||||
}
|
||||
ast::item_enum(variants, _) {
|
||||
ast::item_enum(variants, _, _) {
|
||||
add_to_index(index, it.ident, mie_item(it));
|
||||
let mut variant_idx: uint = 0u;
|
||||
for variants.each {|v|
|
||||
@ -1629,7 +1629,7 @@ fn index_mod(md: ast::_mod) -> mod_index {
|
||||
variant_idx += 1u;
|
||||
}
|
||||
}
|
||||
ast::item_class(tps, _, items, ctor) {
|
||||
ast::item_class(tps, _, items, ctor, _) {
|
||||
// add the class name itself
|
||||
add_to_index(index, it.ident, mie_item(it));
|
||||
// add the constructor decl
|
||||
@ -1763,7 +1763,7 @@ fn check_item(e: @env, i: @ast::item, &&x: (), v: vt<()>) {
|
||||
ensure_unique(*e, i.span, ty_params, {|tp| tp.ident},
|
||||
"type parameter");
|
||||
}
|
||||
ast::item_enum(_, ty_params) {
|
||||
ast::item_enum(_, ty_params, _) {
|
||||
ensure_unique(*e, i.span, ty_params, {|tp| tp.ident},
|
||||
"type parameter");
|
||||
}
|
||||
@ -1837,7 +1837,7 @@ fn check_block(e: @env, b: ast::blk, &&x: (), v: vt<()>) {
|
||||
}
|
||||
ast::decl_item(it) {
|
||||
alt it.node {
|
||||
ast::item_enum(variants, _) {
|
||||
ast::item_enum(variants, _, _) {
|
||||
add_name(types, it.span, it.ident);
|
||||
for variants.each {|v|
|
||||
add_name(values, v.span, v.node.name);
|
||||
@ -1849,10 +1849,10 @@ fn check_block(e: @env, b: ast::blk, &&x: (), v: vt<()>) {
|
||||
ast::item_const(_, _) | ast::item_fn(_, _, _) {
|
||||
add_name(values, it.span, it.ident);
|
||||
}
|
||||
ast::item_ty(_, _) | ast::item_iface(_, _) {
|
||||
ast::item_ty(_, _, _) | ast::item_iface(_, _) {
|
||||
add_name(types, it.span, it.ident);
|
||||
}
|
||||
ast::item_res(_, _, _, _, _) {
|
||||
ast::item_res(_, _, _, _, _, _) {
|
||||
add_name(types, it.span, it.ident);
|
||||
add_name(values, it.span, it.ident);
|
||||
}
|
||||
@ -2030,7 +2030,7 @@ fn check_exports(e: @env) {
|
||||
some(ms) {
|
||||
let maybe_id = list_search(ms) {|m|
|
||||
alt m {
|
||||
mie_item(@{node: item_enum(_, _), id, _}) { some(id) }
|
||||
mie_item(@{node: item_enum(_, _, _), id, _}) { some(id) }
|
||||
_ { none }
|
||||
}
|
||||
};
|
||||
|
@ -263,11 +263,10 @@ fn extract_variant_args(bcx: block, pat_id: ast::node_id,
|
||||
let _icx = bcx.insn_ctxt("alt::extract_variant_args");
|
||||
let ccx = bcx.fcx.ccx;
|
||||
let enum_ty_substs = alt check ty::get(node_id_type(bcx, pat_id)).struct {
|
||||
ty::ty_enum(id, tps) { assert id == vdefs.enm; tps }
|
||||
ty::ty_enum(id, substs) { assert id == vdefs.enm; substs.tps }
|
||||
};
|
||||
let mut blobptr = val;
|
||||
let variants = ty::enum_variants(ccx.tcx, vdefs.enm);
|
||||
let mut args = [];
|
||||
let size = ty::enum_variant_with_id(ccx.tcx, vdefs.enm,
|
||||
vdefs.var).args.len();
|
||||
if size > 0u && (*variants).len() != 1u {
|
||||
@ -275,14 +274,12 @@ fn extract_variant_args(bcx: block, pat_id: ast::node_id,
|
||||
PointerCast(bcx, val, T_opaque_enum_ptr(ccx));
|
||||
blobptr = GEPi(bcx, enumptr, [0, 1]);
|
||||
}
|
||||
let mut i = 0u;
|
||||
let vdefs_tg = vdefs.enm;
|
||||
let vdefs_var = vdefs.var;
|
||||
while i < size {
|
||||
args += [GEP_enum(bcx, blobptr, vdefs_tg, vdefs_var,
|
||||
enum_ty_substs, i)];
|
||||
i += 1u;
|
||||
}
|
||||
let args = vec::from_fn(size) { |i|
|
||||
GEP_enum(bcx, blobptr, vdefs_tg, vdefs_var,
|
||||
enum_ty_substs, i)
|
||||
};
|
||||
ret {vals: args, bcx: bcx};
|
||||
}
|
||||
|
||||
|
@ -297,7 +297,7 @@ fn GEP_enum(bcx: block, llblobptr: ValueRef, enum_id: ast::def_id,
|
||||
assert ix < variant.args.len();
|
||||
|
||||
let arg_lltys = vec::map(variant.args, {|aty|
|
||||
type_of(ccx, ty::substitute_type_params(ccx.tcx, ty_substs, aty))
|
||||
type_of(ccx, ty::subst_tps(ccx.tcx, ty_substs, aty))
|
||||
});
|
||||
let typed_blobptr = PointerCast(bcx, llblobptr,
|
||||
T_ptr(T_struct(arg_lltys)));
|
||||
@ -686,8 +686,8 @@ fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
|
||||
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) {
|
||||
free_ty(bcx, Load(bcx, v0), t)
|
||||
}
|
||||
ty::ty_res(did, inner, tps) {
|
||||
trans_res_drop(bcx, v0, did, inner, tps)
|
||||
ty::ty_res(did, inner, substs) {
|
||||
trans_res_drop(bcx, v0, did, inner, substs.tps)
|
||||
}
|
||||
ty::ty_fn(_) {
|
||||
closure::make_fn_glue(bcx, v0, t, drop_ty)
|
||||
@ -735,7 +735,7 @@ fn trans_res_drop(bcx: block, rs: ValueRef, did: ast::def_id,
|
||||
inner_t: ty::t, tps: [ty::t]) -> block {
|
||||
let _icx = bcx.insn_ctxt("trans_res_drop");
|
||||
let ccx = bcx.ccx();
|
||||
let inner_t_s = ty::substitute_type_params(ccx.tcx, tps, inner_t);
|
||||
let inner_t_s = ty::subst_tps(ccx.tcx, tps, inner_t);
|
||||
|
||||
let drop_flag = GEPi(bcx, rs, [0, 0]);
|
||||
with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag))) {|bcx|
|
||||
@ -911,7 +911,7 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
|
||||
let v_id = variant.id;
|
||||
for vec::each(args) {|a|
|
||||
let llfldp_a = GEP_enum(cx, a_tup, tid, v_id, tps, j);
|
||||
let ty_subst = ty::substitute_type_params(ccx.tcx, tps, a.ty);
|
||||
let ty_subst = ty::subst_tps(ccx.tcx, tps, a.ty);
|
||||
cx = f(cx, llfldp_a, ty_subst);
|
||||
j += 1u;
|
||||
}
|
||||
@ -943,19 +943,20 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
|
||||
cx = f(cx, llfld_a, arg);
|
||||
}
|
||||
}
|
||||
ty::ty_res(_, inner, tps) {
|
||||
ty::ty_res(_, inner, substs) {
|
||||
let tcx = cx.tcx();
|
||||
let inner1 = ty::substitute_type_params(tcx, tps, inner);
|
||||
let inner1 = ty::subst(tcx, substs, inner);
|
||||
let llfld_a = GEPi(cx, av, [0, 1]);
|
||||
ret f(cx, llfld_a, inner1);
|
||||
}
|
||||
ty::ty_enum(tid, tps) {
|
||||
ty::ty_enum(tid, substs) {
|
||||
let variants = ty::enum_variants(cx.tcx(), tid);
|
||||
let n_variants = (*variants).len();
|
||||
|
||||
// Cast the enums to types we can GEP into.
|
||||
if n_variants == 1u {
|
||||
ret iter_variant(cx, av, variants[0], tps, tid, f);
|
||||
ret iter_variant(cx, av, variants[0],
|
||||
substs.tps, tid, f);
|
||||
}
|
||||
|
||||
let ccx = cx.ccx();
|
||||
@ -979,15 +980,16 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
|
||||
int::to_str(variant.disr_val, 10u));
|
||||
AddCase(llswitch, C_int(ccx, variant.disr_val), variant_cx.llbb);
|
||||
let variant_cx =
|
||||
iter_variant(variant_cx, llunion_a_ptr, variant, tps, tid, f);
|
||||
iter_variant(variant_cx, llunion_a_ptr, variant,
|
||||
substs.tps, tid, f);
|
||||
Br(variant_cx, next_cx.llbb);
|
||||
}
|
||||
ret next_cx;
|
||||
}
|
||||
ty::ty_class(did, tps) {
|
||||
ty::ty_class(did, substs) {
|
||||
// a class is like a record type
|
||||
let mut i: int = 0;
|
||||
for vec::each(ty::class_items_as_fields(cx.tcx(), did, tps)) {|fld|
|
||||
for vec::each(ty::class_items_as_fields(cx.tcx(), did, substs)) {|fld|
|
||||
let llfld_a = GEPi(cx, av, [0, i]);
|
||||
cx = f(cx, llfld_a, fld.mt.ty);
|
||||
i += 1;
|
||||
@ -1617,17 +1619,17 @@ fn autoderef(cx: block, v: ValueRef, t: ty::t) -> result_t {
|
||||
t1 = mt.ty;
|
||||
v1 = v;
|
||||
}
|
||||
ty::ty_res(did, inner, tps) {
|
||||
t1 = ty::substitute_type_params(ccx.tcx, tps, inner);
|
||||
ty::ty_res(did, inner, substs) {
|
||||
t1 = ty::subst(ccx.tcx, substs, inner);
|
||||
v1 = GEPi(cx, v1, [0, 1]);
|
||||
}
|
||||
ty::ty_enum(did, tps) {
|
||||
ty::ty_enum(did, substs) {
|
||||
let variants = ty::enum_variants(ccx.tcx, did);
|
||||
if (*variants).len() != 1u || variants[0].args.len() != 1u {
|
||||
break;
|
||||
}
|
||||
t1 =
|
||||
ty::substitute_type_params(ccx.tcx, tps, variants[0].args[0]);
|
||||
ty::subst(ccx.tcx, substs, variants[0].args[0]);
|
||||
v1 = PointerCast(cx, v1, T_ptr(type_of(ccx, t1)));
|
||||
}
|
||||
_ { break; }
|
||||
@ -1939,7 +1941,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, real_substs: [ty::t],
|
||||
let (pt, name) = alt map_node {
|
||||
ast_map::node_item(i, pt) {
|
||||
alt i.node {
|
||||
ast::item_res(_, _, _, dtor_id, _) {
|
||||
ast::item_res(_, _, _, dtor_id, _, _) {
|
||||
item_ty = ty::node_id_to_type(ccx.tcx, dtor_id);
|
||||
}
|
||||
_ {}
|
||||
@ -1958,7 +1960,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, real_substs: [ty::t],
|
||||
ast_map::node_ctor(nm, _, _, pt) { (pt, nm) }
|
||||
_ { fail "unexpected node type"; }
|
||||
};
|
||||
let mono_ty = ty::substitute_type_params(ccx.tcx, substs, item_ty);
|
||||
let mono_ty = ty::subst_tps(ccx.tcx, substs, item_ty);
|
||||
let llfty = type_of_fn_from_ty(ccx, mono_ty);
|
||||
|
||||
let pt = *pt + [path_name(ccx.names(name))];
|
||||
@ -1972,7 +1974,8 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, real_substs: [ty::t],
|
||||
set_inline_hint_if_appr(i.attrs, lldecl);
|
||||
trans_fn(ccx, pt, decl, body, lldecl, no_self, psubsts, fn_id.node);
|
||||
}
|
||||
ast_map::node_item(@{node: ast::item_res(d, _, body, d_id, _), _}, _) {
|
||||
ast_map::node_item(
|
||||
@{node: ast::item_res(d, _, body, d_id, _, _), _}, _) {
|
||||
trans_fn(ccx, pt, d, body, lldecl, no_self, psubsts, d_id);
|
||||
}
|
||||
ast_map::node_native_item(i, _, _) {
|
||||
@ -1990,7 +1993,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, real_substs: [ty::t],
|
||||
ast_map::node_method(mth, impl_def_id, _) {
|
||||
set_inline_hint_if_appr(mth.attrs, lldecl);
|
||||
let selfty = ty::node_id_to_type(ccx.tcx, mth.self_id);
|
||||
let selfty = ty::substitute_type_params(ccx.tcx, substs, selfty);
|
||||
let selfty = ty::subst_tps(ccx.tcx, substs, selfty);
|
||||
trans_fn(ccx, pt, mth.decl, mth.body, lldecl,
|
||||
impl_self(selfty), psubsts, fn_id.node);
|
||||
}
|
||||
@ -2048,7 +2051,7 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
|
||||
ccx.external.insert(parent_id, some(item.id));
|
||||
let mut my_id = 0;
|
||||
alt check item.node {
|
||||
ast::item_enum(_, _) {
|
||||
ast::item_enum(_, _, _) {
|
||||
let vs_here = ty::enum_variants(ccx.tcx, local_def(item.id));
|
||||
let vs_there = ty::enum_variants(ccx.tcx, parent_id);
|
||||
vec::iter2(*vs_here, *vs_there) {|here, there|
|
||||
@ -2056,14 +2059,16 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
|
||||
ccx.external.insert(there.id, some(here.id.node));
|
||||
}
|
||||
}
|
||||
ast::item_res(_, _, _, _, ctor_id) { my_id = ctor_id; }
|
||||
ast::item_res(_, _, _, _, ctor_id, _) {
|
||||
my_id = ctor_id;
|
||||
}
|
||||
}
|
||||
trans_item(ccx, *item);
|
||||
local_def(my_id)
|
||||
}
|
||||
csearch::found(ast::ii_method(impl_did, mth)) {
|
||||
ccx.external.insert(fn_id, some(mth.id));
|
||||
let {bounds: impl_bnds, ty: impl_ty} =
|
||||
let {bounds: impl_bnds, rp: _, ty: impl_ty} =
|
||||
ty::lookup_item_type(ccx.tcx, impl_did);
|
||||
if (*impl_bnds).len() + mth.tps.len() == 0u {
|
||||
let llfn = get_item_val(ccx, mth.id);
|
||||
@ -2264,8 +2269,8 @@ fn trans_rec_field_inner(bcx: block, val: ValueRef, ty: ty::t,
|
||||
field: ast::ident, sp: span) -> lval_result {
|
||||
let fields = alt ty::get(ty).struct {
|
||||
ty::ty_rec(fs) { fs }
|
||||
ty::ty_class(did,ts) {
|
||||
ty::class_items_as_fields(bcx.tcx(), did, ts) }
|
||||
ty::ty_class(did, substs) {
|
||||
ty::class_items_as_fields(bcx.tcx(), did, substs) }
|
||||
// Constraint?
|
||||
_ { bcx.tcx().sess.span_bug(sp, "trans_rec_field:\
|
||||
base expr has non-record type"); }
|
||||
@ -4379,7 +4384,9 @@ fn trans_class_ctor(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
|
||||
// kludgy -- this wouldn't be necessary if the typechecker
|
||||
// special-cased constructors, then we could just look up
|
||||
// the ctor's return type.
|
||||
let rslt_ty = ty::mk_class(ccx.tcx, parent_id, psubsts.tys);
|
||||
let rslt_ty = ty::mk_class(ccx.tcx, parent_id,
|
||||
dummy_substs(psubsts.tys));
|
||||
|
||||
// Make the fn context
|
||||
let fcx = new_fn_ctxt_w_id(ccx, path, llctor_decl, ctor_id,
|
||||
some(psubsts), some(sp));
|
||||
@ -4397,7 +4404,7 @@ fn trans_class_ctor(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
|
||||
let selfptr = alloc_ty(bcx_top, rslt_ty);
|
||||
// initialize fields to zero
|
||||
let fields = ty::class_items_as_fields(bcx_top.tcx(), parent_id,
|
||||
psubsts.tys);
|
||||
dummy_substs(psubsts.tys));
|
||||
let mut bcx = bcx_top;
|
||||
// Initialize fields to zero so init assignments can validly
|
||||
// drop their LHS
|
||||
@ -4450,7 +4457,7 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
|
||||
ast::item_impl(tps, _, _, ms) {
|
||||
impl::trans_impl(ccx, *path, item.ident, ms, tps);
|
||||
}
|
||||
ast::item_res(decl, tps, body, dtor_id, ctor_id) {
|
||||
ast::item_res(decl, tps, body, dtor_id, ctor_id, _) {
|
||||
if tps.len() == 0u {
|
||||
let llctor_decl = get_item_val(ccx, ctor_id);
|
||||
trans_res_ctor(ccx, *path, decl, ctor_id, none, llctor_decl);
|
||||
@ -4463,7 +4470,7 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
|
||||
ast::item_mod(m) {
|
||||
trans_mod(ccx, m);
|
||||
}
|
||||
ast::item_enum(variants, tps) {
|
||||
ast::item_enum(variants, tps, _) {
|
||||
if tps.len() == 0u {
|
||||
let degen = variants.len() == 1u;
|
||||
let vi = ty::enum_variants(ccx.tcx, local_def(item.id));
|
||||
@ -4487,7 +4494,7 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
|
||||
};
|
||||
native::trans_native_mod(ccx, native_mod, abi);
|
||||
}
|
||||
ast::item_class(tps, _ifaces, items, ctor) {
|
||||
ast::item_class(tps, _ifaces, items, ctor, _) {
|
||||
if tps.len() == 0u {
|
||||
let psubsts = {tys: ty::ty_params_to_tys(ccx.tcx, tps),
|
||||
// FIXME: vtables have to get filled in depending
|
||||
@ -4495,7 +4502,7 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
|
||||
vtables: none,
|
||||
bounds: @[]};
|
||||
trans_class_ctor(ccx, *path, ctor.node.dec, ctor.node.body,
|
||||
get_item_val(ccx, ctor.node.id), psubsts,
|
||||
get_item_val(ccx, ctor.node.id), psubsts,
|
||||
ctor.node.id, local_def(item.id), ctor.span);
|
||||
}
|
||||
// If there are ty params, the ctor will get monomorphized
|
||||
@ -4684,7 +4691,7 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
|
||||
set_inline_hint_if_appr(i.attrs, llfn);
|
||||
llfn
|
||||
}
|
||||
ast::item_res(_, _, _, dtor_id, _) {
|
||||
ast::item_res(_, _, _, dtor_id, _, _) {
|
||||
// Note that the destructor is associated with the item's id,
|
||||
// not the dtor_id. This is a bit counter-intuitive, but
|
||||
// simplifies ty_res, which would have to carry around two
|
||||
@ -4726,7 +4733,7 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
|
||||
assert v.node.args.len() != 0u;
|
||||
let pth = *pth + [path_name(enm.ident), path_name(v.node.name)];
|
||||
let llfn = alt check enm.node {
|
||||
ast::item_enum(_, _) {
|
||||
ast::item_enum(_, _, _) {
|
||||
register_fn(ccx, v.span, pth, id)
|
||||
}
|
||||
};
|
||||
@ -4747,7 +4754,7 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
|
||||
fn trans_constant(ccx: @crate_ctxt, it: @ast::item) {
|
||||
let _icx = ccx.insn_ctxt("trans_constant");
|
||||
alt it.node {
|
||||
ast::item_enum(variants, _) {
|
||||
ast::item_enum(variants, _, _) {
|
||||
let vi = ty::enum_variants(ccx.tcx, {crate: ast::local_crate,
|
||||
node: it.id});
|
||||
let mut i = 0;
|
||||
|
@ -882,7 +882,7 @@ fn node_id_type(bcx: block, id: ast::node_id) -> ty::t {
|
||||
let tcx = bcx.tcx();
|
||||
let t = ty::node_id_to_type(tcx, id);
|
||||
alt bcx.fcx.param_substs {
|
||||
some(substs) { ty::substitute_type_params(tcx, substs.tys, t) }
|
||||
some(substs) { ty::subst_tps(tcx, substs.tys, t) }
|
||||
_ { assert !ty::type_has_params(t); t }
|
||||
}
|
||||
}
|
||||
@ -894,7 +894,7 @@ fn node_id_type_params(bcx: block, id: ast::node_id) -> [ty::t] {
|
||||
let params = ty::node_id_to_type_params(tcx, id);
|
||||
alt bcx.fcx.param_substs {
|
||||
some(substs) {
|
||||
vec::map(params) {|t| ty::substitute_type_params(tcx, substs.tys, t) }
|
||||
vec::map(params) {|t| ty::subst_tps(tcx, substs.tys, t) }
|
||||
}
|
||||
_ { params }
|
||||
}
|
||||
@ -910,6 +910,10 @@ fn field_idx_strict(cx: ty::ctxt, sp: span, ident: ast::ident,
|
||||
}
|
||||
}
|
||||
|
||||
fn dummy_substs(tps: [ty::t]) -> ty::substs {
|
||||
{self_r: some(ty::re_bound(ty::br_self)), tps: tps}
|
||||
}
|
||||
|
||||
//
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
|
@ -747,7 +747,7 @@ fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> {
|
||||
let (ident, ret_ty, id) = alt cx.tcx.items.get(fcx.id) {
|
||||
ast_map::node_item(item, _) {
|
||||
alt item.node {
|
||||
ast::item_fn(decl, _, _) | ast::item_res(decl, _, _, _, _) {
|
||||
ast::item_fn(decl, _, _) | ast::item_res(decl, _, _, _, _, _) {
|
||||
(item.ident, decl.output, item.id)
|
||||
}
|
||||
_ { fcx.ccx.sess.span_bug(item.span, "create_function: item \
|
||||
|
@ -178,7 +178,7 @@ fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: typeck::vtable_origin)
|
||||
let tys = alt fcx.param_substs {
|
||||
some(substs) {
|
||||
vec::map(tys, {|t|
|
||||
ty::substitute_type_params(fcx.ccx.tcx, substs.tys, t)
|
||||
ty::subst_tps(fcx.ccx.tcx, substs.tys, t)
|
||||
})
|
||||
}
|
||||
_ { tys }
|
||||
@ -244,7 +244,7 @@ fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: [ty::t],
|
||||
let ifce_id = ty::ty_to_def_id(option::get(ty::impl_iface(tcx, impl_id)));
|
||||
let has_tps = (*ty::lookup_item_type(ccx.tcx, impl_id).bounds).len() > 0u;
|
||||
make_vtable(ccx, vec::map(*ty::iface_methods(tcx, ifce_id), {|im|
|
||||
let fty = ty::substitute_type_params(tcx, substs,
|
||||
let fty = ty::subst_tps(tcx, substs,
|
||||
ty::mk_fn(tcx, im.fty));
|
||||
if (*im.tps).len() > 0u || ty::type_has_vars(fty) {
|
||||
C_null(T_ptr(T_nil()))
|
||||
|
@ -84,7 +84,7 @@ fn traverse_public_item(cx: ctx, item: @item) {
|
||||
for vec::each(nm.items) {|item| cx.rmap.insert(item.id, ()); }
|
||||
}
|
||||
}
|
||||
item_res(_, tps, blk, _, _) {
|
||||
item_res(_, tps, blk, _, _, _) {
|
||||
// resources seem to be unconditionally inlined
|
||||
traverse_inline_body(cx, blk);
|
||||
}
|
||||
@ -102,7 +102,7 @@ fn traverse_public_item(cx: ctx, item: @item) {
|
||||
}
|
||||
}
|
||||
}
|
||||
item_class(tps, _ifaces, items, ctor) {
|
||||
item_class(tps, _ifaces, items, ctor, _) {
|
||||
cx.rmap.insert(ctor.node.id, ());
|
||||
for vec::each(items) {|item|
|
||||
alt item.node {
|
||||
@ -117,7 +117,8 @@ fn traverse_public_item(cx: ctx, item: @item) {
|
||||
}
|
||||
}
|
||||
}
|
||||
item_const(_, _) | item_ty(_, _) | item_enum(_, _) | item_iface(_, _) {}
|
||||
item_const(_, _) | item_ty(_, _, _) |
|
||||
item_enum(_, _, _) | item_iface(_, _) {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,7 +153,9 @@ fn traverse_all_resources(cx: ctx, crate_mod: _mod) {
|
||||
visit_item: {|i, cx, v|
|
||||
visit::visit_item(i, cx, v);
|
||||
alt i.node {
|
||||
item_res(_, _, _, _, _) { traverse_public_item(cx, i); }
|
||||
item_res(_, _, _, _, _, _) {
|
||||
traverse_public_item(cx, i);
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
|
@ -315,7 +315,9 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
|
||||
add_substr(s, shape_of(ccx, unit_ty, ty_param_map));
|
||||
s
|
||||
}
|
||||
ty::ty_enum(did, tps) {
|
||||
ty::ty_enum(did, substs) {
|
||||
let tps = substs.tps;
|
||||
|
||||
alt enum_kind(ccx, did) {
|
||||
// FIXME: For now we do this.
|
||||
tk_unit { [s_variant_enum_t(ccx.tcx)] }
|
||||
@ -437,8 +439,9 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
|
||||
add_substr(s, shape_of(ccx, tm.ty, ty_param_map));
|
||||
s
|
||||
}
|
||||
ty::ty_res(did, raw_subt, tps) {
|
||||
let subt = ty::substitute_type_params(ccx.tcx, tps, raw_subt);
|
||||
ty::ty_res(did, raw_subt, substs) {
|
||||
let subt = ty::subst(ccx.tcx, substs, raw_subt);
|
||||
let tps = substs.tps;
|
||||
let ri = {did: did, tps: tps};
|
||||
let id = interner::intern(ccx.shape_cx.resources, ri);
|
||||
|
||||
@ -651,7 +654,7 @@ fn llalign_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef {
|
||||
fn static_size_of_enum(cx: @crate_ctxt, t: ty::t) -> uint {
|
||||
if cx.enum_sizes.contains_key(t) { ret cx.enum_sizes.get(t); }
|
||||
alt ty::get(t).struct {
|
||||
ty::ty_enum(tid, subtys) {
|
||||
ty::ty_enum(tid, substs) {
|
||||
// Compute max(variant sizes).
|
||||
let mut max_size = 0u;
|
||||
let variants = ty::enum_variants(cx.tcx, tid);
|
||||
@ -659,7 +662,7 @@ fn static_size_of_enum(cx: @crate_ctxt, t: ty::t) -> uint {
|
||||
let tup_ty = simplify_type(cx.tcx,
|
||||
ty::mk_tup(cx.tcx, variant.args));
|
||||
// Perform any type parameter substitutions.
|
||||
let tup_ty = ty::substitute_type_params(cx.tcx, subtys, tup_ty);
|
||||
let tup_ty = ty::subst(cx.tcx, substs, tup_ty);
|
||||
// Here we possibly do a recursive call.
|
||||
let this_size =
|
||||
llsize_of_real(cx, type_of::type_of(cx, tup_ty));
|
||||
@ -690,8 +693,8 @@ fn simplify_type(tcx: ty::ctxt, typ: ty::t) -> ty::t {
|
||||
ty::ty_estr(ty::vstore_uniq) | ty::ty_estr(ty::vstore_box) |
|
||||
ty::ty_ptr(_) | ty::ty_rptr(_,_) { nilptr(tcx) }
|
||||
ty::ty_fn(_) { ty::mk_tup(tcx, [nilptr(tcx), nilptr(tcx)]) }
|
||||
ty::ty_res(_, sub, tps) {
|
||||
let sub1 = ty::substitute_type_params(tcx, tps, sub);
|
||||
ty::ty_res(_, sub, substs) {
|
||||
let sub1 = ty::subst(tcx, substs, sub);
|
||||
ty::mk_tup(tcx, [ty::mk_int(tcx), simplify_type(tcx, sub1)])
|
||||
}
|
||||
ty::ty_evec(_, ty::vstore_slice(_)) |
|
||||
|
@ -89,8 +89,8 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
|
||||
}
|
||||
ty::ty_fn(_) { T_fn_pair(cx, type_of_fn_from_ty(cx, t)) }
|
||||
ty::ty_iface(_, _) { T_opaque_iface(cx) }
|
||||
ty::ty_res(_, sub, tps) {
|
||||
let sub1 = ty::substitute_type_params(cx.tcx, tps, sub);
|
||||
ty::ty_res(_, sub, substs) {
|
||||
let sub1 = ty::subst(cx.tcx, substs, sub);
|
||||
ret T_struct([T_i8(), type_of(cx, sub1)]);
|
||||
}
|
||||
ty::ty_param(_, _) { T_typaram(cx.tn) }
|
||||
|
@ -65,7 +65,7 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
|
||||
};
|
||||
alt check map_node {
|
||||
ast_map::node_item(@{node: item_fn(_, _, body), _}, _) |
|
||||
ast_map::node_item(@{node: item_res(_, _, body, _, _), _}, _) |
|
||||
ast_map::node_item(@{node: item_res(_, _, body, _, _, _), _}, _) |
|
||||
ast_map::node_method(@{body, _}, _, _) {
|
||||
handle_body(cx, body);
|
||||
}
|
||||
@ -107,13 +107,12 @@ fn type_needs_inner(cx: ctx, use: uint, ty: ty::t,
|
||||
alt ty::get(ty).struct {
|
||||
ty::ty_fn(_) | ty::ty_ptr(_) | ty::ty_rptr(_, _) |
|
||||
ty::ty_box(_) | ty::ty_iface(_, _) { false }
|
||||
ty::ty_enum(did, tps) {
|
||||
ty::ty_enum(did, substs) {
|
||||
if option::is_none(list::find(enums_seen, {|id| id == did})) {
|
||||
let seen = list::cons(did, @enums_seen);
|
||||
for vec::each(*ty::enum_variants(cx.ccx.tcx, did)) {|v|
|
||||
for vec::each(v.args) {|aty|
|
||||
let t = ty::substitute_type_params(cx.ccx.tcx,
|
||||
tps, aty);
|
||||
let t = ty::subst(cx.ccx.tcx, substs, aty);
|
||||
type_needs_inner(cx, use, t, seen);
|
||||
}
|
||||
}
|
||||
@ -153,7 +152,7 @@ fn mark_for_expr(cx: ctx, e: @expr) {
|
||||
}
|
||||
}
|
||||
expr_path(_) {
|
||||
option::iter(cx.ccx.tcx.node_type_substs.find(e.id)) {|ts|
|
||||
cx.ccx.tcx.node_type_substs.find(e.id).iter {|ts|
|
||||
let id = ast_util::def_id_of_def(cx.ccx.tcx.def_map.get(e.id));
|
||||
vec::iter2(type_uses_for(cx.ccx, id, ts.len()), ts) {|uses, subst|
|
||||
type_needs(cx, uses, subst)
|
||||
|
@ -48,8 +48,8 @@ fn find_pre_post_item(ccx: crate_ctxt, i: item) {
|
||||
}
|
||||
item_mod(m) { find_pre_post_mod(m); }
|
||||
item_native_mod(nm) { find_pre_post_native_mod(nm); }
|
||||
item_ty(_, _) | item_enum(_, _) | item_iface(_, _) { ret; }
|
||||
item_res(_, _, body, dtor_id, _) {
|
||||
item_ty(_, _, _) | item_enum(_, _, _) | item_iface(_, _) { ret; }
|
||||
item_res(_, _, body, dtor_id, _, _) {
|
||||
let fcx =
|
||||
{enclosing: ccx.fm.get(dtor_id),
|
||||
id: dtor_id,
|
||||
@ -57,7 +57,7 @@ fn find_pre_post_item(ccx: crate_ctxt, i: item) {
|
||||
ccx: ccx};
|
||||
find_pre_post_fn(fcx, body);
|
||||
}
|
||||
item_class(_,_,_,_) {
|
||||
item_class(_,_,_,_,_) {
|
||||
fail "find_pre_post_item: shouldn't be called on item_class";
|
||||
}
|
||||
item_impl(_, _, _, ms) {
|
||||
|
@ -61,7 +61,7 @@ export sequence_element_type;
|
||||
export sort_methods;
|
||||
export stmt_node_id;
|
||||
export sty;
|
||||
export substitute_type_params;
|
||||
export subst, subst_tps, substs_is_noop, substs;
|
||||
export t;
|
||||
export new_ty_hash;
|
||||
export enum_variants, substd_enum_variants;
|
||||
@ -281,6 +281,23 @@ enum bound_region {
|
||||
br_named(str) // A named region parameter.
|
||||
}
|
||||
|
||||
type opt_region = option<region>;
|
||||
|
||||
// The type substs represents the kinds of things that can be substituted into
|
||||
// a type. There may be at most one region parameter (self_r), along with
|
||||
// some number of type parameters (tps).
|
||||
//
|
||||
// The region parameter is present on nominative types (enums, resources,
|
||||
// classes) that are declared as having a region parameter. If the type is
|
||||
// declared as `enum foo&`, then self_r should always be non-none. If the
|
||||
// type is declared as `enum foo`, then self_r will always be none. In the
|
||||
// latter case, typeck::ast_ty_to_ty() will reject any references to `&T` or
|
||||
// `&self.T` within the type and report an error.
|
||||
type substs = {
|
||||
self_r: opt_region,
|
||||
tps: [t]
|
||||
};
|
||||
|
||||
// NB: If you change this, you'll probably want to change the corresponding
|
||||
// AST structure in front/ast::rs as well.
|
||||
enum sty {
|
||||
@ -292,7 +309,7 @@ enum sty {
|
||||
ty_float(ast::float_ty),
|
||||
ty_str,
|
||||
ty_estr(vstore),
|
||||
ty_enum(def_id, [t]),
|
||||
ty_enum(def_id, substs),
|
||||
ty_box(mt),
|
||||
ty_uniq(mt),
|
||||
ty_vec(mt),
|
||||
@ -302,8 +319,8 @@ enum sty {
|
||||
ty_rec([field]),
|
||||
ty_fn(fn_ty),
|
||||
ty_iface(def_id, [t]),
|
||||
ty_class(def_id, [t]),
|
||||
ty_res(def_id, t, [t]),
|
||||
ty_class(def_id, substs),
|
||||
ty_res(def_id, t, substs),
|
||||
ty_tup([t]),
|
||||
|
||||
ty_var(ty_vid), // type variable during typechecking
|
||||
@ -389,7 +406,9 @@ fn param_bounds_to_kind(bounds: param_bounds) -> kind {
|
||||
kind
|
||||
}
|
||||
|
||||
type ty_param_bounds_and_ty = {bounds: @[param_bounds], ty: t};
|
||||
type ty_param_bounds_and_ty = {bounds: @[param_bounds],
|
||||
rp: ast::region_param,
|
||||
ty: t};
|
||||
|
||||
type type_cache = hashmap<ast::def_id, ty_param_bounds_and_ty>;
|
||||
|
||||
@ -475,7 +494,13 @@ fn mk_t_with_id(cx: ctxt, st: sty, o_def_id: option<ast::def_id>) -> t {
|
||||
ty_opaque_box {}
|
||||
ty_param(_, _) { has_params = true; }
|
||||
ty_var(_) | ty_self(_) { has_vars = true; }
|
||||
ty_enum(_, tys) | ty_iface(_, tys) | ty_class(_, tys) {
|
||||
ty_enum(_, substs) | ty_class(_, substs) {
|
||||
for substs.tps.each {|tt|
|
||||
derive_flags(has_params, has_vars, has_regions, tt);
|
||||
}
|
||||
substs.self_r.iter { |_i| has_regions = true; }
|
||||
}
|
||||
ty_iface(_, tys) {
|
||||
for tys.each {|tt|
|
||||
derive_flags(has_params, has_vars, has_regions, tt);
|
||||
}
|
||||
@ -506,9 +531,9 @@ fn mk_t_with_id(cx: ctxt, st: sty, o_def_id: option<ast::def_id>) -> t {
|
||||
}
|
||||
derive_flags(has_params, has_vars, has_regions, f.output);
|
||||
}
|
||||
ty_res(_, tt, tps) {
|
||||
ty_res(_, tt, substs) {
|
||||
derive_flags(has_params, has_vars, has_regions, tt);
|
||||
for tps.each {|tt|
|
||||
for substs.tps.each {|tt|
|
||||
derive_flags(has_params, has_vars, has_regions, tt);
|
||||
}
|
||||
}
|
||||
@ -553,8 +578,8 @@ fn mk_estr(cx: ctxt, t: vstore) -> t {
|
||||
mk_t(cx, ty_estr(t))
|
||||
}
|
||||
|
||||
fn mk_enum(cx: ctxt, did: ast::def_id, tys: [t]) -> t {
|
||||
mk_t(cx, ty_enum(did, tys))
|
||||
fn mk_enum(cx: ctxt, did: ast::def_id, substs: substs) -> t {
|
||||
mk_t(cx, ty_enum(did, substs))
|
||||
}
|
||||
|
||||
fn mk_box(cx: ctxt, tm: mt) -> t { mk_t(cx, ty_box(tm)) }
|
||||
@ -602,12 +627,13 @@ fn mk_iface(cx: ctxt, did: ast::def_id, tys: [t]) -> t {
|
||||
mk_t(cx, ty_iface(did, tys))
|
||||
}
|
||||
|
||||
fn mk_class(cx: ctxt, class_id: ast::def_id, tys: [t]) -> t {
|
||||
mk_t(cx, ty_class(class_id, tys))
|
||||
fn mk_class(cx: ctxt, class_id: ast::def_id, substs: substs) -> t {
|
||||
mk_t(cx, ty_class(class_id, substs))
|
||||
}
|
||||
|
||||
fn mk_res(cx: ctxt, did: ast::def_id, inner: t, tps: [t]) -> t {
|
||||
mk_t(cx, ty_res(did, inner, tps))
|
||||
fn mk_res(cx: ctxt, did: ast::def_id,
|
||||
inner: t, substs: substs) -> t {
|
||||
mk_t(cx, ty_res(did, inner, substs))
|
||||
}
|
||||
|
||||
fn mk_var(cx: ctxt, v: ty_vid) -> t { mk_t(cx, ty_var(v)) }
|
||||
@ -657,8 +683,10 @@ fn maybe_walk_ty(ty: t, f: fn(t) -> bool) {
|
||||
ty_ptr(tm) | ty_rptr(_, tm) {
|
||||
maybe_walk_ty(tm.ty, f);
|
||||
}
|
||||
ty_enum(_, subtys) | ty_iface(_, subtys) | ty_class(_, subtys)
|
||||
| ty_self(subtys) {
|
||||
ty_enum(_, substs) | ty_class(_, substs) {
|
||||
for substs.tps.each {|subty| maybe_walk_ty(subty, f); }
|
||||
}
|
||||
ty_iface(_, subtys) |ty_self(subtys) {
|
||||
for subtys.each {|subty| maybe_walk_ty(subty, f); }
|
||||
}
|
||||
ty_rec(fields) {
|
||||
@ -669,9 +697,9 @@ fn maybe_walk_ty(ty: t, f: fn(t) -> bool) {
|
||||
for ft.inputs.each {|a| maybe_walk_ty(a.ty, f); }
|
||||
maybe_walk_ty(ft.output, f);
|
||||
}
|
||||
ty_res(_, sub, tps) {
|
||||
ty_res(_, sub, substs) {
|
||||
maybe_walk_ty(sub, f);
|
||||
for tps.each {|tp| maybe_walk_ty(tp, f); }
|
||||
for substs.tps.each {|tp| maybe_walk_ty(tp, f); }
|
||||
}
|
||||
ty_constr(sub, _) { maybe_walk_ty(sub, f); }
|
||||
ty_uniq(tm) { maybe_walk_ty(tm.ty, f); }
|
||||
@ -683,6 +711,11 @@ fn fold_sty_to_ty(tcx: ty::ctxt, sty: sty, foldop: fn(t) -> t) -> t {
|
||||
}
|
||||
|
||||
fn fold_sty(sty: sty, fldop: fn(t) -> t) -> sty {
|
||||
fn fold_substs(substs: substs, fldop: fn(t) -> t) -> substs {
|
||||
{self_r: substs.self_r,
|
||||
tps: substs.tps.map { |t| fldop(t) }}
|
||||
}
|
||||
|
||||
alt sty {
|
||||
ty_box(tm) {
|
||||
ty_box({ty: fldop(tm.ty), mutbl: tm.mutbl})
|
||||
@ -699,8 +732,8 @@ fn fold_sty(sty: sty, fldop: fn(t) -> t) -> sty {
|
||||
ty_evec(tm, vst) {
|
||||
ty_evec({ty: fldop(tm.ty), mutbl: tm.mutbl}, vst)
|
||||
}
|
||||
ty_enum(tid, subtys) {
|
||||
ty_enum(tid, vec::map(subtys) {|t| fldop(t) })
|
||||
ty_enum(tid, substs) {
|
||||
ty_enum(tid, fold_substs(substs, fldop))
|
||||
}
|
||||
ty_iface(did, subtys) {
|
||||
ty_iface(did, vec::map(subtys) {|t| fldop(t) })
|
||||
@ -728,9 +761,9 @@ fn fold_sty(sty: sty, fldop: fn(t) -> t) -> sty {
|
||||
let new_output = fldop(f.output);
|
||||
ty_fn({inputs: new_args, output: new_output with f})
|
||||
}
|
||||
ty_res(did, subty, tps) {
|
||||
let new_tps = vec::map(tps) {|ty| fldop(ty) };
|
||||
ty_res(did, fldop(subty), new_tps)
|
||||
ty_res(did, subty, substs) {
|
||||
ty_res(did, fldop(subty),
|
||||
fold_substs(substs, fldop))
|
||||
}
|
||||
ty_rptr(r, tm) {
|
||||
ty_rptr(r, {ty: fldop(tm.ty), mutbl: tm.mutbl})
|
||||
@ -738,9 +771,8 @@ fn fold_sty(sty: sty, fldop: fn(t) -> t) -> sty {
|
||||
ty_constr(subty, cs) {
|
||||
ty_constr(fldop(subty), cs)
|
||||
}
|
||||
ty_class(did, tps) {
|
||||
let new_tps = vec::map(tps) {|ty| fldop(ty) };
|
||||
ty_class(did, new_tps)
|
||||
ty_class(did, substs) {
|
||||
ty_class(did, fold_substs(substs, fldop))
|
||||
}
|
||||
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
|
||||
ty_str | ty_estr(_) | ty_type | ty_opaque_closure_ptr(_) |
|
||||
@ -765,6 +797,61 @@ fn fold_ty_var(cx: ctxt, t0: t, fldop: fn(ty_vid) -> t) -> t {
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_regions_and_ty(
|
||||
cx: ctxt,
|
||||
ty: t,
|
||||
fldr: fn(r: region) -> region,
|
||||
fldfnt: fn(t: t) -> t,
|
||||
fldt: fn(t: t) -> t) -> t {
|
||||
|
||||
fn fold_substs(
|
||||
substs: substs,
|
||||
fldr: fn(r: region) -> region,
|
||||
fldt: fn(t: t) -> t) -> substs {
|
||||
|
||||
{self_r: substs.self_r.map { |r| fldr(r) },
|
||||
tps: substs.tps.map { |t| fldt(t) }}
|
||||
}
|
||||
|
||||
let tb = ty::get(ty);
|
||||
alt tb.struct {
|
||||
ty::ty_rptr(r, mt) {
|
||||
let m_r = fldr(r);
|
||||
let m_t = fldt(mt.ty);
|
||||
ty::mk_rptr(cx, m_r, {ty: m_t, mutbl: mt.mutbl})
|
||||
}
|
||||
ty_estr(vstore_slice(r)) {
|
||||
let m_r = fldr(r);
|
||||
ty::mk_estr(cx, vstore_slice(m_r))
|
||||
}
|
||||
ty_evec(mt, vstore_slice(r)) {
|
||||
let m_r = fldr(r);
|
||||
let m_t = fldt(mt.ty);
|
||||
ty::mk_evec(cx, {ty: m_t, mutbl: mt.mutbl}, vstore_slice(m_r))
|
||||
}
|
||||
ty_enum(def_id, substs) {
|
||||
ty::mk_enum(cx, def_id, fold_substs(substs, fldr, fldt))
|
||||
}
|
||||
ty_class(def_id, substs) {
|
||||
ty::mk_class(cx, def_id, fold_substs(substs, fldr, fldt))
|
||||
}
|
||||
ty_res(def_id, t, substs) {
|
||||
ty::mk_res(cx, def_id, fldt(t),
|
||||
fold_substs(substs, fldr, fldt))
|
||||
}
|
||||
sty @ ty_fn(_) {
|
||||
fold_sty_to_ty(cx, sty) {|t|
|
||||
fldfnt(t)
|
||||
}
|
||||
}
|
||||
sty {
|
||||
fold_sty_to_ty(cx, sty) {|t|
|
||||
fldt(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// n.b. this function is intended to eventually replace fold_region() below,
|
||||
// that is why its name is so similar.
|
||||
fn fold_regions(
|
||||
@ -774,36 +861,13 @@ fn fold_regions(
|
||||
|
||||
fn do_fold(cx: ctxt, ty: t, in_fn: bool,
|
||||
fldr: fn(region, bool) -> region) -> t {
|
||||
let tb = ty::get(ty);
|
||||
if !tb.has_regions { ret ty; }
|
||||
alt tb.struct {
|
||||
ty::ty_rptr(r, mt) {
|
||||
let m_r = fldr(r, in_fn);
|
||||
let m_t = do_fold(cx, mt.ty, in_fn, fldr);
|
||||
ty::mk_rptr(cx, m_r, {ty: m_t, mutbl: mt.mutbl})
|
||||
}
|
||||
ty_estr(vstore_slice(r)) {
|
||||
let m_r = fldr(r, in_fn);
|
||||
ty::mk_estr(cx, vstore_slice(m_r))
|
||||
}
|
||||
ty_evec(mt, vstore_slice(r)) {
|
||||
let m_r = fldr(r, in_fn);
|
||||
let m_t = do_fold(cx, mt.ty, in_fn, fldr);
|
||||
ty::mk_evec(cx, {ty: m_t, mutbl: mt.mutbl}, vstore_slice(m_r))
|
||||
}
|
||||
sty @ ty_fn(_) {
|
||||
fold_sty_to_ty(cx, sty) {|t|
|
||||
do_fold(cx, t, true, fldr)
|
||||
}
|
||||
}
|
||||
sty {
|
||||
fold_sty_to_ty(cx, sty) {|t|
|
||||
do_fold(cx, t, in_fn, fldr)
|
||||
}
|
||||
}
|
||||
}
|
||||
if !type_has_regions(ty) { ret ty; }
|
||||
fold_regions_and_ty(
|
||||
cx, ty,
|
||||
{ |r| fldr(r, in_fn) },
|
||||
{ |t| do_fold(cx, t, true, fldr) },
|
||||
{ |t| do_fold(cx, t, in_fn, fldr) })
|
||||
}
|
||||
|
||||
do_fold(cx, ty, false, fldr)
|
||||
}
|
||||
|
||||
@ -842,13 +906,63 @@ fn fold_region(cx: ctxt, t0: t, fldop: fn(region, bool) -> region) -> t {
|
||||
do_fold(cx, t0, false, fldop)
|
||||
}
|
||||
|
||||
fn substitute_type_params(cx: ctxt, substs: [ty::t], typ: t) -> t {
|
||||
if substs.len() == 0u { ret typ; }
|
||||
let tb = get(typ);
|
||||
// Substitute *only* type parameters. Used in trans where regions are erased.
|
||||
fn subst_tps(cx: ctxt, tps: [t], typ: t) -> t {
|
||||
if tps.len() == 0u { ret typ; }
|
||||
let tb = ty::get(typ);
|
||||
if !tb.has_params { ret typ; }
|
||||
alt tb.struct {
|
||||
ty_param(idx, _) { substs[idx] }
|
||||
s { mk_t(cx, fold_sty(s) {|t| substitute_type_params(cx, substs, t)}) }
|
||||
ty_param(idx, _) { tps[idx] }
|
||||
sty { fold_sty_to_ty(cx, sty) {|t| subst_tps(cx, tps, t) } }
|
||||
}
|
||||
}
|
||||
|
||||
fn substs_is_noop(substs: substs) -> bool {
|
||||
substs.tps.len() == 0u && substs.self_r.is_none()
|
||||
}
|
||||
|
||||
fn substs_to_str(cx: ctxt, substs: substs) -> str {
|
||||
#fmt["substs(self_r=%s, tps=%?)",
|
||||
substs.self_r.map_default("none", { |r| region_to_str(cx, r) }),
|
||||
substs.tps.map { |t| ty_to_str(cx, t) }]
|
||||
}
|
||||
|
||||
fn subst(cx: ctxt,
|
||||
substs: substs,
|
||||
typ: t) -> t {
|
||||
|
||||
if substs_is_noop(substs) { ret typ; }
|
||||
#debug["subst(substs=%s, typ=%s)",
|
||||
substs_to_str(cx, substs),
|
||||
ty_to_str(cx, typ)];
|
||||
let r = do_subst(cx, substs, typ);
|
||||
#debug[" r = %s", ty_to_str(cx, r)];
|
||||
ret r;
|
||||
|
||||
fn do_subst(cx: ctxt,
|
||||
substs: substs,
|
||||
typ: t) -> t {
|
||||
let tb = get(typ);
|
||||
if !tb.has_params && !tb.has_regions { ret typ; }
|
||||
alt tb.struct {
|
||||
ty_param(idx, _) { substs.tps[idx] }
|
||||
_ {
|
||||
fold_regions_and_ty(
|
||||
cx, typ,
|
||||
{ |r|
|
||||
alt r {
|
||||
re_bound(br_self) {
|
||||
option::get(substs.self_r)
|
||||
}
|
||||
_ {
|
||||
r
|
||||
}
|
||||
}
|
||||
},
|
||||
{ |t| do_subst(cx, substs, t) },
|
||||
{ |t| do_subst(cx, substs, t) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -862,7 +976,7 @@ fn type_is_bool(ty: t) -> bool { get(ty).struct == ty_bool }
|
||||
|
||||
fn type_is_structural(ty: t) -> bool {
|
||||
alt get(ty).struct {
|
||||
ty_rec(_) | ty_class(_,_) | ty_tup(_) | ty_enum(_, _) | ty_fn(_) |
|
||||
ty_rec(_) | ty_class(_, _) | ty_tup(_) | ty_enum(_, _) | ty_fn(_) |
|
||||
ty_iface(_, _) | ty_res(_, _, _) | ty_evec(_, vstore_fixed(_))
|
||||
| ty_estr(vstore_fixed(_)) { true }
|
||||
_ { false }
|
||||
@ -994,8 +1108,8 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
|
||||
for flds.each {|f| if type_needs_drop(cx, f.mt.ty) { accum = true; } }
|
||||
accum
|
||||
}
|
||||
ty_class(did, ts) {
|
||||
for vec::each(ty::class_items_as_fields(cx, did, ts)) {|f|
|
||||
ty_class(did, substs) {
|
||||
for vec::each(ty::class_items_as_fields(cx, did, substs)) {|f|
|
||||
if type_needs_drop(cx, f.mt.ty) { accum = true; }
|
||||
}
|
||||
accum
|
||||
@ -1005,12 +1119,12 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
|
||||
for elts.each {|m| if type_needs_drop(cx, m) { accum = true; } }
|
||||
accum
|
||||
}
|
||||
ty_enum(did, tps) {
|
||||
ty_enum(did, substs) {
|
||||
let variants = enum_variants(cx, did);
|
||||
for vec::each(*variants) {|variant|
|
||||
for variant.args.each {|aty|
|
||||
// Perform any type parameter substitutions.
|
||||
let arg_ty = substitute_type_params(cx, tps, aty);
|
||||
let arg_ty = subst(cx, substs, aty);
|
||||
if type_needs_drop(cx, arg_ty) { accum = true; }
|
||||
}
|
||||
if accum { break; }
|
||||
@ -1064,10 +1178,10 @@ fn type_needs_unwind_cleanup_(cx: ctxt, ty: t,
|
||||
ty_rec(_) | ty_tup(_) | ty_ptr(_) {
|
||||
true
|
||||
}
|
||||
ty_enum(did, tps) {
|
||||
ty_enum(did, substs) {
|
||||
for vec::each(*enum_variants(cx, did)) {|v|
|
||||
for v.args.each {|aty|
|
||||
let t = substitute_type_params(cx, tps, aty);
|
||||
let t = subst(cx, substs, aty);
|
||||
needs_unwind_cleanup |=
|
||||
type_needs_unwind_cleanup_(cx, t, tycache,
|
||||
encountered_box);
|
||||
@ -1211,7 +1325,7 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
|
||||
lowest
|
||||
}
|
||||
// Enums lower to the lowest of their variants.
|
||||
ty_enum(did, tps) {
|
||||
ty_enum(did, substs) {
|
||||
let mut lowest = kind_sendable;
|
||||
let variants = enum_variants(cx, did);
|
||||
if vec::len(*variants) == 0u {
|
||||
@ -1220,7 +1334,7 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
|
||||
for vec::each(*variants) {|variant|
|
||||
for variant.args.each {|aty|
|
||||
// Perform any type parameter substitutions.
|
||||
let arg_ty = substitute_type_params(cx, tps, aty);
|
||||
let arg_ty = subst(cx, substs, aty);
|
||||
lowest = lower_kind(lowest, type_kind(cx, arg_ty));
|
||||
if lowest == kind_noncopyable { break; }
|
||||
}
|
||||
@ -1316,11 +1430,11 @@ fn is_instantiable(cx: ctxt, r_ty: t) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
ty_class(did, tps) {
|
||||
ty_class(did, substs) {
|
||||
vec::push(*seen, did);
|
||||
let r = vec::any(lookup_class_fields(cx, did)) {|f|
|
||||
let fty = ty::lookup_item_type(cx, f.id);
|
||||
let sty = substitute_type_params(cx, tps, fty.ty);
|
||||
let sty = subst(cx, substs, fty.ty);
|
||||
type_requires(cx, seen, r_ty, sty)
|
||||
};
|
||||
vec::pop(*seen);
|
||||
@ -1331,9 +1445,9 @@ fn is_instantiable(cx: ctxt, r_ty: t) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
ty_res(did, sub, tps) {
|
||||
ty_res(did, sub, substs) {
|
||||
vec::push(*seen, did);
|
||||
let sty = substitute_type_params(cx, tps, sub);
|
||||
let sty = subst(cx, substs, sub);
|
||||
let r = type_requires(cx, seen, r_ty, sty);
|
||||
vec::pop(*seen);
|
||||
r
|
||||
@ -1349,12 +1463,12 @@ fn is_instantiable(cx: ctxt, r_ty: t) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
ty_enum(did, tps) {
|
||||
ty_enum(did, substs) {
|
||||
vec::push(*seen, did);
|
||||
let vs = enum_variants(cx, did);
|
||||
let r = vec::len(*vs) > 0u && vec::all(*vs) {|variant|
|
||||
vec::any(variant.args) {|aty|
|
||||
let sty = substitute_type_params(cx, tps, aty);
|
||||
let sty = subst(cx, substs, aty);
|
||||
type_requires(cx, seen, r_ty, sty)
|
||||
}
|
||||
};
|
||||
@ -1380,10 +1494,10 @@ fn type_structurally_contains(cx: ctxt, ty: t, test: fn(sty) -> bool) ->
|
||||
let sty = get(ty).struct;
|
||||
if test(sty) { ret true; }
|
||||
alt sty {
|
||||
ty_enum(did, tps) {
|
||||
ty_enum(did, substs) {
|
||||
for vec::each(*enum_variants(cx, did)) {|variant|
|
||||
for variant.args.each {|aty|
|
||||
let sty = substitute_type_params(cx, tps, aty);
|
||||
let sty = subst(cx, substs, aty);
|
||||
if type_structurally_contains(cx, sty, test) { ret true; }
|
||||
}
|
||||
}
|
||||
@ -1401,8 +1515,8 @@ fn type_structurally_contains(cx: ctxt, ty: t, test: fn(sty) -> bool) ->
|
||||
}
|
||||
ret false;
|
||||
}
|
||||
ty_res(_, sub, tps) {
|
||||
let sty = substitute_type_params(cx, tps, sub);
|
||||
ty_res(_, sub, substs) {
|
||||
let sty = subst(cx, substs, sub);
|
||||
ret type_structurally_contains(cx, sty, test);
|
||||
}
|
||||
ty_evec(mt, vstore_fixed(_)) {
|
||||
@ -1485,13 +1599,13 @@ fn type_is_pod(cx: ctxt, ty: t) -> bool {
|
||||
ty_str | ty_box(_) | ty_uniq(_) | ty_vec(_) | ty_fn(_) |
|
||||
ty_iface(_, _) | ty_rptr(_,_) | ty_opaque_box { result = false; }
|
||||
// Structural types
|
||||
ty_enum(did, tps) {
|
||||
ty_enum(did, substs) {
|
||||
let variants = enum_variants(cx, did);
|
||||
for vec::each(*variants) {|variant|
|
||||
let tup_ty = mk_tup(cx, variant.args);
|
||||
|
||||
// Perform any type parameter substitutions.
|
||||
let tup_ty = substitute_type_params(cx, tps, tup_ty);
|
||||
let tup_ty = subst(cx, substs, tup_ty);
|
||||
if !type_is_pod(cx, tup_ty) { result = false; }
|
||||
}
|
||||
}
|
||||
@ -1507,8 +1621,8 @@ fn type_is_pod(cx: ctxt, ty: t) -> bool {
|
||||
ty_evec(mt, vstore_fixed(_)) {
|
||||
result = type_is_pod(cx, mt.ty);
|
||||
}
|
||||
ty_res(_, inner, tps) {
|
||||
result = type_is_pod(cx, substitute_type_params(cx, tps, inner));
|
||||
ty_res(_, inner, substs) {
|
||||
result = type_is_pod(cx, subst(cx, substs, inner));
|
||||
}
|
||||
ty_constr(subt, _) { result = type_is_pod(cx, subt); }
|
||||
ty_param(_, _) { result = false; }
|
||||
@ -1530,7 +1644,7 @@ fn type_is_enum(ty: t) -> bool {
|
||||
// constructors
|
||||
fn type_is_c_like_enum(cx: ctxt, ty: t) -> bool {
|
||||
alt get(ty).struct {
|
||||
ty_enum(did, tps) {
|
||||
ty_enum(did, substs) {
|
||||
let variants = enum_variants(cx, did);
|
||||
let some_n_ary = vec::any(*variants, {|v| vec::len(v.args) > 0u});
|
||||
ret !some_n_ary;
|
||||
@ -1562,15 +1676,15 @@ fn type_autoderef(cx: ctxt, t: t) -> t {
|
||||
loop {
|
||||
alt get(t1).struct {
|
||||
ty_box(mt) | ty_uniq(mt) | ty::ty_rptr(_, mt) { t1 = mt.ty; }
|
||||
ty_res(_, inner, tps) {
|
||||
t1 = substitute_type_params(cx, tps, inner);
|
||||
ty_res(_, inner, substs) {
|
||||
t1 = subst(cx, substs, inner);
|
||||
}
|
||||
ty_enum(did, tps) {
|
||||
ty_enum(did, substs) {
|
||||
let variants = enum_variants(cx, did);
|
||||
if vec::len(*variants) != 1u || vec::len(variants[0].args) != 1u {
|
||||
break;
|
||||
}
|
||||
t1 = substitute_type_params(cx, tps, variants[0].args[0]);
|
||||
t1 = subst(cx, substs, variants[0].args[0]);
|
||||
}
|
||||
_ { break; }
|
||||
}
|
||||
@ -1627,6 +1741,10 @@ fn hash_type_structure(st: sty) -> uint {
|
||||
re_bot { 4u }
|
||||
}
|
||||
}
|
||||
fn hash_substs(h: uint, substs: substs) -> uint {
|
||||
let h = hash_subtys(h, substs.tps);
|
||||
h + substs.self_r.map_default(0u, hash_region)
|
||||
}
|
||||
alt st {
|
||||
ty_nil { 0u } ty_bool { 1u }
|
||||
ty_int(t) {
|
||||
@ -1646,10 +1764,9 @@ fn hash_type_structure(st: sty) -> uint {
|
||||
}
|
||||
ty_estr(_) { 16u }
|
||||
ty_str { 17u }
|
||||
ty_enum(did, tys) {
|
||||
ty_enum(did, substs) {
|
||||
let mut h = hash_def(18u, did);
|
||||
for tys.each {|typ| h = hash_subty(h, typ); }
|
||||
h
|
||||
hash_substs(h, substs)
|
||||
}
|
||||
ty_box(mt) { hash_subty(19u, mt.ty) }
|
||||
ty_evec(mt, _) { hash_subty(20u, mt.ty) }
|
||||
@ -1679,9 +1796,9 @@ fn hash_type_structure(st: sty) -> uint {
|
||||
let mut h = (46u << 2u) + hash_region(region);
|
||||
hash_subty(h, mt.ty)
|
||||
}
|
||||
ty_res(did, sub, tps) {
|
||||
ty_res(did, sub, substs) {
|
||||
let mut h = hash_subty(hash_def(18u, did), sub);
|
||||
hash_subtys(h, tps)
|
||||
hash_substs(h, substs)
|
||||
}
|
||||
ty_constr(t, cs) {
|
||||
let mut h = hash_subty(36u, t);
|
||||
@ -1698,10 +1815,9 @@ fn hash_type_structure(st: sty) -> uint {
|
||||
ty_opaque_closure_ptr(ck_box) { 42u }
|
||||
ty_opaque_closure_ptr(ck_uniq) { 43u }
|
||||
ty_opaque_box { 44u }
|
||||
ty_class(did, tys) {
|
||||
let mut h = hash_def(45u, did);
|
||||
for tys.each {|typ| h = hash_subty(h, typ); }
|
||||
h
|
||||
ty_class(did, substs) {
|
||||
let mut h = hash_def(45u, did);
|
||||
hash_substs(h, substs)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1997,7 +2113,7 @@ fn ty_sort_str(cx: ctxt, t: t) -> str {
|
||||
ty_to_str(cx, t)
|
||||
}
|
||||
|
||||
ty_enum(_, _) { "enum" }
|
||||
ty_enum(id, _) { #fmt["enum %s", item_path_str(cx, id)] }
|
||||
ty_box(_) { "@-ptr" }
|
||||
ty_uniq(_) { "~-ptr" }
|
||||
ty_evec(_, _) | ty_vec(_) { "vector" }
|
||||
@ -2005,9 +2121,9 @@ fn ty_sort_str(cx: ctxt, t: t) -> str {
|
||||
ty_rptr(_, _) { "&-ptr" }
|
||||
ty_rec(_) { "record" }
|
||||
ty_fn(_) { "fn" }
|
||||
ty_iface(_, _) { "iface" }
|
||||
ty_class(_, _) { "class" }
|
||||
ty_res(_, _, _) { "resource" }
|
||||
ty_iface(id, _) { #fmt["iface %s", item_path_str(cx, id)] }
|
||||
ty_class(id, _) { #fmt["class %s", item_path_str(cx, id)] }
|
||||
ty_res(id, _, _) { #fmt["resource %s", item_path_str(cx, id)] }
|
||||
ty_tup(_) { "tuple" }
|
||||
ty_var(_) { "variable" }
|
||||
ty_param(_, _) { "type parameter" }
|
||||
@ -2148,15 +2264,15 @@ fn ty_to_def_id(ty: t) -> ast::def_id {
|
||||
type variant_info = @{args: [t], ctor_ty: t, name: str,
|
||||
id: ast::def_id, disr_val: int};
|
||||
|
||||
fn substd_enum_variants(cx: ctxt, id: ast::def_id, tps: [ty::t])
|
||||
-> [variant_info] {
|
||||
fn substd_enum_variants(cx: ctxt,
|
||||
id: ast::def_id,
|
||||
substs: substs) -> [variant_info] {
|
||||
vec::map(*enum_variants(cx, id)) { |variant_info|
|
||||
let substd_args = vec::map(variant_info.args) {|aty|
|
||||
substitute_type_params(cx, tps, aty)
|
||||
subst(cx, substs, aty)
|
||||
};
|
||||
|
||||
let substd_ctor_ty =
|
||||
substitute_type_params(cx, tps, variant_info.ctor_ty);
|
||||
let substd_ctor_ty = subst(cx, substs, variant_info.ctor_ty);
|
||||
|
||||
@{args: substd_args, ctor_ty: substd_ctor_ty with *variant_info}
|
||||
}
|
||||
@ -2214,6 +2330,7 @@ fn enum_variants(cx: ctxt, id: ast::def_id) -> @[variant_info] {
|
||||
some(variants) { ret variants; }
|
||||
_ { /* fallthrough */ }
|
||||
}
|
||||
|
||||
let result = if ast::local_crate != id.crate {
|
||||
@csearch::get_enum_variants(cx, id)
|
||||
} else {
|
||||
@ -2221,13 +2338,15 @@ fn enum_variants(cx: ctxt, id: ast::def_id) -> @[variant_info] {
|
||||
// check the disr_expr if it exists), this code should likely be
|
||||
// moved there to avoid having to call eval_const_expr twice.
|
||||
alt cx.items.get(id.node) {
|
||||
ast_map::node_item(@{node: ast::item_enum(variants, _), _}, _) {
|
||||
ast_map::node_item(@{node: ast::item_enum(variants, _, _), _}, _) {
|
||||
let mut disr_val = -1;
|
||||
@vec::map(variants, {|variant|
|
||||
let ctor_ty = node_id_to_type(cx, variant.node.id);
|
||||
let arg_tys = if vec::len(variant.node.args) > 0u {
|
||||
vec::map(ty_fn_args(ctor_ty), {|a| a.ty})
|
||||
} else { [] };
|
||||
let arg_tys = {
|
||||
if vec::len(variant.node.args) > 0u {
|
||||
ty_fn_args(ctor_ty).map { |a| a.ty }
|
||||
} else { [] }
|
||||
};
|
||||
alt variant.node.disr_expr {
|
||||
some (ex) {
|
||||
// FIXME: issue #1417
|
||||
@ -2287,7 +2406,8 @@ fn lookup_item_type(cx: ctxt, did: ast::def_id) -> ty_param_bounds_and_ty {
|
||||
// Look up a field ID, whether or not it's local
|
||||
// Takes a list of type substs in case the class is generic
|
||||
fn lookup_field_type(tcx: ctxt, class_id: def_id, id: def_id,
|
||||
substs: [ty::t]) -> ty::t {
|
||||
substs: substs) -> ty::t {
|
||||
|
||||
let t = if id.crate == ast::local_crate {
|
||||
node_id_to_type(tcx, id.node)
|
||||
}
|
||||
@ -2304,7 +2424,7 @@ fn lookup_field_type(tcx: ctxt, class_id: def_id, id: def_id,
|
||||
}
|
||||
}
|
||||
};
|
||||
substitute_type_params(tcx, substs, t)
|
||||
subst(tcx, substs, t)
|
||||
}
|
||||
|
||||
// Look up the list of field names and IDs for a given class
|
||||
@ -2314,7 +2434,7 @@ fn lookup_class_fields(cx: ctxt, did: ast::def_id) -> [field_ty] {
|
||||
alt cx.items.find(did.node) {
|
||||
some(ast_map::node_item(i,_)) {
|
||||
alt i.node {
|
||||
ast::item_class(_, _, items, _) {
|
||||
ast::item_class(_, _, items, _, _) {
|
||||
class_field_tys(items)
|
||||
}
|
||||
_ { cx.sess.bug("class ID bound to non-class"); }
|
||||
@ -2356,7 +2476,7 @@ pure fn is_public(f: field_ty) -> bool {
|
||||
fn lookup_class_method_ids(cx: ctxt, did: ast::def_id)
|
||||
: is_local(did) -> [{name: ident, id: node_id, privacy: privacy}] {
|
||||
alt cx.items.find(did.node) {
|
||||
some(ast_map::node_item(@{node: item_class(_,_,items,_), _}, _)) {
|
||||
some(ast_map::node_item(@{node: item_class(_,_,items,_,_), _}, _)) {
|
||||
let (_,ms) = split_class_items(items);
|
||||
vec::map(ms, {|m| {name: m.ident, id: m.id,
|
||||
privacy: m.privacy}})
|
||||
@ -2406,8 +2526,8 @@ fn class_field_tys(items: [@class_member]) -> [field_ty] {
|
||||
// Return a list of fields corresponding to the class's items
|
||||
// (as if the class was a record). trans uses this
|
||||
// Takes a list of substs with which to instantiate field types
|
||||
fn class_items_as_fields(cx:ctxt, did: ast::def_id, substs: [ty::t])
|
||||
-> [field] {
|
||||
fn class_items_as_fields(cx:ctxt, did: ast::def_id,
|
||||
substs: substs) -> [field] {
|
||||
let mut rslt = [];
|
||||
for lookup_class_fields(cx, did).each {|f|
|
||||
// consider all instance vars mut, because the
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -10,11 +10,12 @@ import syntax::{ast, ast_util};
|
||||
import middle::ast_map;
|
||||
import driver::session::session;
|
||||
|
||||
fn bound_region_to_str(_cx: ctxt, br: bound_region) -> str {
|
||||
fn bound_region_to_str(cx: ctxt, br: bound_region) -> str {
|
||||
alt br {
|
||||
br_anon { "&" }
|
||||
br_named(str) { #fmt["&%s", str] }
|
||||
br_self { "&self" }
|
||||
br_anon { "&" }
|
||||
br_named(str) { #fmt["&%s", str] }
|
||||
br_self if cx.sess.opts.debug_rustc { "&<self>" }
|
||||
br_self { "&self" }
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,12 +128,23 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
|
||||
fn field_to_str(cx: ctxt, f: field) -> str {
|
||||
ret f.ident + ": " + mt_to_str(cx, f.mt);
|
||||
}
|
||||
fn parameterized(cx: ctxt, base: str, tps: [ty::t]) -> str {
|
||||
fn parameterized(cx: ctxt,
|
||||
base: str,
|
||||
self_r: option<ty::region>,
|
||||
tps: [ty::t]) -> str {
|
||||
|
||||
let r_str = alt self_r {
|
||||
none { "" }
|
||||
some(r) {
|
||||
#fmt["/%s", region_to_str(cx, r)]
|
||||
}
|
||||
};
|
||||
|
||||
if vec::len(tps) > 0u {
|
||||
let strs = vec::map(tps, {|t| ty_to_str(cx, t)});
|
||||
#fmt["%s<%s>", base, str::connect(strs, ",")]
|
||||
#fmt["%s%s<%s>", base, r_str, str::connect(strs, ",")]
|
||||
} else {
|
||||
base
|
||||
#fmt["%s%s", base, r_str]
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,9 +153,11 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
|
||||
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) | ty_iface(_, tps) |
|
||||
ty_class(_, tps) {
|
||||
parameterized(cx, cs, tps)
|
||||
ty_enum(_, substs) | ty_res(_, _, substs) | ty_class(_, substs) {
|
||||
parameterized(cx, cs, substs.self_r, substs.tps)
|
||||
}
|
||||
ty_iface(_, tps) {
|
||||
parameterized(cx, cs, none, tps)
|
||||
}
|
||||
_ { cs }
|
||||
};
|
||||
@ -164,7 +178,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
|
||||
ty_float(ast::ty_f) { "float" }
|
||||
ty_float(t) { ast_util::float_ty_to_str(t) }
|
||||
ty_str { "str" }
|
||||
ty_self(ts) { parameterized(cx, "self", ts) }
|
||||
ty_self(ts) { parameterized(cx, "self", none, ts) }
|
||||
ty_box(tm) { "@" + mt_to_str(cx, tm) }
|
||||
ty_uniq(tm) { "~" + mt_to_str(cx, tm) }
|
||||
ty_ptr(tm) { "*" + mt_to_str(cx, tm) }
|
||||
@ -196,11 +210,15 @@ 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_res(did, _, tps) | ty_iface(did, tps) |
|
||||
ty_class(did, tps) {
|
||||
ty_enum(did, substs) | ty_res(did, _, substs) | ty_class(did, substs) {
|
||||
let path = ty::item_path(cx, did);
|
||||
let base = ast_map::path_to_str(path);
|
||||
parameterized(cx, base, tps)
|
||||
parameterized(cx, base, substs.self_r, substs.tps)
|
||||
}
|
||||
ty_iface(did, tps) {
|
||||
let path = ty::item_path(cx, did);
|
||||
let base = ast_map::path_to_str(path);
|
||||
parameterized(cx, base, none, tps)
|
||||
}
|
||||
ty_evec(mt, vs) {
|
||||
#fmt["[%s]/%s", mt_to_str(cx, mt),
|
||||
|
@ -147,7 +147,7 @@ fn fold_enum(
|
||||
let desc = astsrv::exec(srv) {|ctxt|
|
||||
alt check ctxt.ast_map.get(doc_id) {
|
||||
ast_map::node_item(@{
|
||||
node: ast::item_enum(ast_variants, _), _
|
||||
node: ast::item_enum(ast_variants, _, _), _
|
||||
}, _) {
|
||||
let ast_variant = option::get(
|
||||
vec::find(ast_variants) {|v|
|
||||
|
@ -78,12 +78,12 @@ fn moddoc_from_mod(
|
||||
constdoc_from_const(itemdoc)
|
||||
))
|
||||
}
|
||||
ast::item_enum(variants, _) {
|
||||
ast::item_enum(variants, _, _) {
|
||||
some(doc::enumtag(
|
||||
enumdoc_from_enum(itemdoc, variants)
|
||||
))
|
||||
}
|
||||
ast::item_res(_, _, _, _, _) {
|
||||
ast::item_res(_, _, _, _, _, _) {
|
||||
some(doc::restag(
|
||||
resdoc_from_resource(itemdoc)
|
||||
))
|
||||
@ -98,7 +98,7 @@ fn moddoc_from_mod(
|
||||
impldoc_from_impl(itemdoc, methods)
|
||||
))
|
||||
}
|
||||
ast::item_ty(_, _) {
|
||||
ast::item_ty(_, _, _) {
|
||||
some(doc::tytag(
|
||||
tydoc_from_ty(itemdoc)
|
||||
))
|
||||
|
@ -112,7 +112,7 @@ fn fold_enum(
|
||||
let sig = astsrv::exec(srv) {|ctxt|
|
||||
alt check ctxt.ast_map.get(doc_id) {
|
||||
ast_map::node_item(@{
|
||||
node: ast::item_enum(ast_variants, _), _
|
||||
node: ast::item_enum(ast_variants, _, _), _
|
||||
}, _) {
|
||||
let ast_variant = option::get(
|
||||
vec::find(ast_variants) {|v|
|
||||
@ -149,9 +149,9 @@ fn fold_res(
|
||||
sig: some(astsrv::exec(srv) {|ctxt|
|
||||
alt check ctxt.ast_map.get(doc.id()) {
|
||||
ast_map::node_item(@{
|
||||
node: ast::item_res(decl, tys, _, _, _), _
|
||||
node: ast::item_res(decl, tys, _, _, _, rp), _
|
||||
}, _) {
|
||||
pprust::res_to_str(decl, doc.name(), tys)
|
||||
pprust::res_to_str(decl, doc.name(), tys, rp)
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -303,7 +303,7 @@ fn fold_type(
|
||||
alt ctxt.ast_map.get(doc.id()) {
|
||||
ast_map::node_item(@{
|
||||
ident: ident,
|
||||
node: ast::item_ty(ty, params), _
|
||||
node: ast::item_ty(ty, params, ast::rp_none), _
|
||||
}, _) {
|
||||
some(#fmt(
|
||||
"type %s%s = %s",
|
||||
|
@ -2,7 +2,7 @@ use std;
|
||||
import std::arena;
|
||||
import std::arena::arena;
|
||||
|
||||
enum tree { nil, node(&tree, &tree, int), }
|
||||
enum tree& { nil, node(&tree, &tree, int), }
|
||||
|
||||
fn item_check(t: &tree) -> int {
|
||||
alt *t {
|
||||
|
33
src/test/compile-fail/regions-creating-enums.rs
Normal file
33
src/test/compile-fail/regions-creating-enums.rs
Normal file
@ -0,0 +1,33 @@
|
||||
enum ast& {
|
||||
num(uint),
|
||||
add(&ast, &ast)
|
||||
}
|
||||
|
||||
fn build() {
|
||||
let x = num(3u);
|
||||
let y = num(4u);
|
||||
let z = add(&x, &y);
|
||||
compute(&z);
|
||||
}
|
||||
|
||||
fn compute(x: &ast) -> uint {
|
||||
alt *x {
|
||||
num(x) { x }
|
||||
add(x, y) { compute(x) + compute(y) }
|
||||
}
|
||||
}
|
||||
|
||||
fn map_nums(x: &ast, f: fn(uint) -> uint) -> &ast {
|
||||
alt *x {
|
||||
num(x) {
|
||||
ret &num(f(x)); //! ERROR mismatched types: expected `&ast/&` but found
|
||||
}
|
||||
add(x, y) {
|
||||
let m_x = map_nums(x, f);
|
||||
let m_y = map_nums(y, f);
|
||||
ret &add(m_x, m_y); //! ERROR mismatched types: expected `&ast/&` but found
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
25
src/test/compile-fail/regions-in-enums.rs
Normal file
25
src/test/compile-fail/regions-in-enums.rs
Normal file
@ -0,0 +1,25 @@
|
||||
enum no0 {
|
||||
x0(&uint) //! ERROR to use region types here, the containing type must be declared with a region bound
|
||||
}
|
||||
|
||||
enum no1 {
|
||||
x1(&self.uint) //! ERROR to use region types here, the containing type must be declared with a region bound
|
||||
}
|
||||
|
||||
enum no2 {
|
||||
x2(&foo.uint) //! ERROR named regions other than `self` are not allowed as part of a type declaration
|
||||
}
|
||||
|
||||
enum yes0& {
|
||||
x3(&uint)
|
||||
}
|
||||
|
||||
enum yes1& {
|
||||
x4(&self.uint)
|
||||
}
|
||||
|
||||
enum yes2& {
|
||||
x5(&foo.uint) //! ERROR named regions other than `self` are not allowed as part of a type declaration
|
||||
}
|
||||
|
||||
fn main() {}
|
19
src/test/compile-fail/regions-in-rsrcs.rs
Normal file
19
src/test/compile-fail/regions-in-rsrcs.rs
Normal file
@ -0,0 +1,19 @@
|
||||
resource no0(x: &uint) { //! ERROR to use region types here, the containing type must be declared with a region bound
|
||||
}
|
||||
|
||||
resource no1(x: &self.uint) { //! ERROR to use region types here, the containing type must be declared with a region bound
|
||||
}
|
||||
|
||||
resource no2(x: &foo.uint) { //! ERROR named regions other than `self` are not allowed as part of a type declaration
|
||||
}
|
||||
|
||||
resource yes0&(x: &uint) {
|
||||
}
|
||||
|
||||
resource yes1&(x: &self.uint) {
|
||||
}
|
||||
|
||||
resource yes2&(x: &foo.uint) { //! ERROR named regions other than `self` are not allowed as part of a type declaration
|
||||
}
|
||||
|
||||
fn main() {}
|
25
src/test/compile-fail/regions-in-type-items.rs
Normal file
25
src/test/compile-fail/regions-in-type-items.rs
Normal file
@ -0,0 +1,25 @@
|
||||
type item_ty_no0 = {
|
||||
x: &uint //! ERROR to use region types here, the containing type must be declared with a region bound
|
||||
};
|
||||
|
||||
type item_ty_no1 = {
|
||||
x: &self.uint //! ERROR to use region types here, the containing type must be declared with a region bound
|
||||
};
|
||||
|
||||
type item_ty_no2 = {
|
||||
x: &foo.uint //! ERROR named regions other than `self` are not allowed as part of a type declaration
|
||||
};
|
||||
|
||||
type item_ty_yes0& = {
|
||||
x: &uint
|
||||
};
|
||||
|
||||
type item_ty_yes1& = {
|
||||
x: &self.uint
|
||||
};
|
||||
|
||||
type item_ty_yes2& = {
|
||||
x: &foo.uint //! ERROR named regions other than `self` are not allowed as part of a type declaration
|
||||
};
|
||||
|
||||
fn main() {}
|
@ -2,8 +2,7 @@ use std;
|
||||
fn main() {
|
||||
iface seq { }
|
||||
|
||||
impl <T> of seq<T> for [T] {
|
||||
//!^ ERROR wrong number of type arguments for a polymorphic type
|
||||
impl <T> of seq<T> for [T] { //! ERROR wrong number of type arguments
|
||||
/* ... */
|
||||
}
|
||||
impl of seq<bool> for u32 {
|
||||
|
@ -2,11 +2,11 @@ import libc, sys, unsafe;
|
||||
|
||||
enum arena = ();
|
||||
|
||||
type bcx = {
|
||||
type bcx& = {
|
||||
fcx: &fcx
|
||||
};
|
||||
|
||||
type fcx = {
|
||||
type fcx& = {
|
||||
arena: &arena,
|
||||
ccx: &ccx
|
||||
};
|
||||
|
@ -2,11 +2,11 @@ import libc, sys, unsafe;
|
||||
|
||||
enum arena = ();
|
||||
|
||||
type bcx = {
|
||||
type bcx& = {
|
||||
fcx: &fcx
|
||||
};
|
||||
|
||||
type fcx = {
|
||||
type fcx& = {
|
||||
arena: &arena,
|
||||
ccx: &ccx
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user