Refactor fn_ty, working towards #3320
This commit is contained in:
parent
699505899e
commit
fb8786fe52
33 changed files with 704 additions and 574 deletions
|
@ -585,7 +585,7 @@ fn get_enum_variants(intr: ident_interner, cdata: cmd, id: ast::node_id,
|
|||
let mut arg_tys: ~[ty::t] = ~[];
|
||||
match ty::get(ctor_ty).struct {
|
||||
ty::ty_fn(f) => {
|
||||
for f.inputs.each |a| { vec::push(arg_tys, a.ty); }
|
||||
for f.sig.inputs.each |a| { vec::push(arg_tys, a.ty); }
|
||||
}
|
||||
_ => { /* Nullary enum variant. */ }
|
||||
}
|
||||
|
|
|
@ -750,7 +750,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item,
|
|||
encode_name(ecx, ebml_w, mty.ident);
|
||||
encode_type_param_bounds(ebml_w, ecx, ty_m.tps);
|
||||
encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty));
|
||||
encode_family(ebml_w, purity_fn_family(mty.fty.purity));
|
||||
encode_family(ebml_w, purity_fn_family(mty.fty.meta.purity));
|
||||
encode_self_type(ebml_w, mty.self_ty);
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ use syntax::ast_util;
|
|||
use syntax::ast_util::respan;
|
||||
use middle::ty;
|
||||
use std::map::hashmap;
|
||||
use ty::{FnTyBase, FnMeta, FnSig};
|
||||
|
||||
export parse_ty_data, parse_def_id, parse_ident;
|
||||
export parse_bounds_data;
|
||||
|
@ -274,7 +275,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
|
|||
parse_ty_rust_fn(st, conv)
|
||||
}
|
||||
'X' => {
|
||||
return ty::mk_var(st.tcx, ty::ty_vid(parse_int(st) as uint));
|
||||
return ty::mk_var(st.tcx, ty::TyVid(parse_int(st) as uint));
|
||||
}
|
||||
'Y' => return ty::mk_type(st.tcx),
|
||||
'C' => {
|
||||
|
@ -372,7 +373,7 @@ fn parse_purity(c: char) -> purity {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::fn_ty {
|
||||
fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::FnTy {
|
||||
let proto = parse_proto(st);
|
||||
let purity = parse_purity(next(st));
|
||||
let bounds = parse_bounds(st, conv);
|
||||
|
@ -392,8 +393,14 @@ fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::fn_ty {
|
|||
}
|
||||
st.pos += 1u; // eat the ']'
|
||||
let (ret_style, ret_ty) = parse_ret_ty(st, conv);
|
||||
return {purity: purity, proto: proto, bounds: bounds, inputs: inputs,
|
||||
output: ret_ty, ret_style: ret_style};
|
||||
return FnTyBase {
|
||||
meta: FnMeta {purity: purity,
|
||||
proto: proto,
|
||||
bounds: bounds,
|
||||
ret_style: ret_style},
|
||||
sig: FnSig {inputs: inputs,
|
||||
output: ret_ty}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -342,19 +342,19 @@ fn enc_purity(w: io::Writer, p: purity) {
|
|||
}
|
||||
}
|
||||
|
||||
fn enc_ty_fn(w: io::Writer, cx: @ctxt, ft: ty::fn_ty) {
|
||||
enc_proto(w, cx, ft.proto);
|
||||
enc_purity(w, ft.purity);
|
||||
enc_bounds(w, cx, ft.bounds);
|
||||
fn enc_ty_fn(w: io::Writer, cx: @ctxt, ft: ty::FnTy) {
|
||||
enc_proto(w, cx, ft.meta.proto);
|
||||
enc_purity(w, ft.meta.purity);
|
||||
enc_bounds(w, cx, ft.meta.bounds);
|
||||
w.write_char('[');
|
||||
for ft.inputs.each |arg| {
|
||||
for ft.sig.inputs.each |arg| {
|
||||
enc_mode(w, cx, arg.mode);
|
||||
enc_ty(w, cx, arg.ty);
|
||||
}
|
||||
w.write_char(']');
|
||||
match ft.ret_style {
|
||||
match ft.meta.ret_style {
|
||||
noreturn => w.write_char('!'),
|
||||
_ => enc_ty(w, cx, ft.output)
|
||||
_ => enc_ty(w, cx, ft.sig.output)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -218,13 +218,13 @@ impl check_loan_ctxt {
|
|||
let callee_ty = ty::node_id_to_type(tcx, callee_id);
|
||||
match ty::get(callee_ty).struct {
|
||||
ty::ty_fn(fn_ty) => {
|
||||
match fn_ty.purity {
|
||||
match fn_ty.meta.purity {
|
||||
ast::pure_fn => return, // case (c) above
|
||||
ast::impure_fn | ast::unsafe_fn | ast::extern_fn => {
|
||||
self.report_purity_error(
|
||||
pc, callee_span,
|
||||
fmt!("access to %s function",
|
||||
pprust::purity_to_str(fn_ty.purity)));
|
||||
pprust::purity_to_str(fn_ty.meta.purity)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -659,7 +659,7 @@ fn check_fn(tcx: ty::ctxt, fk: visit::fn_kind, decl: ast::fn_decl,
|
|||
match ty::get(fn_ty).struct {
|
||||
ty::ty_fn(fn_ty) => {
|
||||
let mut counter = 0;
|
||||
do vec::iter2(fn_ty.inputs, decl.inputs) |arg_ty, arg_ast| {
|
||||
do vec::iter2(fn_ty.sig.inputs, decl.inputs) |arg_ty, arg_ast| {
|
||||
counter += 1;
|
||||
debug!("arg %d, ty=%s, mode=%s",
|
||||
counter,
|
||||
|
|
|
@ -529,10 +529,10 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
|
|||
let ccx = cx.ccx();
|
||||
let mut cx = cx;
|
||||
match ty::get(fn_ty).struct {
|
||||
ty::ty_fn({inputs: args, _}) => {
|
||||
ty::ty_fn(ref fn_ty) => {
|
||||
let mut j = 0u;
|
||||
let v_id = variant.id;
|
||||
for vec::each(args) |a| {
|
||||
for vec::each(fn_ty.sig.inputs) |a| {
|
||||
let llfldp_a = GEP_enum(cx, a_tup, tid, v_id, tps, j);
|
||||
let ty_subst = ty::subst_tps(ccx.tcx, tps, a.ty);
|
||||
cx = f(cx, llfldp_a, ty_subst);
|
||||
|
@ -1984,7 +1984,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
|
|||
let main_takes_argv =
|
||||
// invariant!
|
||||
match ty::get(main_node_type).struct {
|
||||
ty::ty_fn({inputs, _}) => inputs.len() != 0u,
|
||||
ty::ty_fn(ref fn_ty) => fn_ty.sig.inputs.len() != 0u,
|
||||
_ => ccx.sess.span_fatal(sp, ~"main has a non-function type")
|
||||
};
|
||||
|
||||
|
|
|
@ -425,17 +425,15 @@ fn make_fn_glue(
|
|||
}
|
||||
};
|
||||
|
||||
return match ty::get(t).struct {
|
||||
ty::ty_fn({proto: ty::proto_bare, _}) |
|
||||
ty::ty_fn({proto: ty::proto_vstore(ty::vstore_slice(_)), _}) =>
|
||||
bcx,
|
||||
ty::ty_fn({proto: ty::proto_vstore(ty::vstore_uniq), _}) =>
|
||||
fn_env(ty::ck_uniq),
|
||||
ty::ty_fn({proto: ty::proto_vstore(ty::vstore_box), _}) =>
|
||||
fn_env(ty::ck_box),
|
||||
_ =>
|
||||
fail ~"make_fn_glue invoked on non-function type"
|
||||
};
|
||||
let proto = ty::ty_fn_proto(t);
|
||||
match proto {
|
||||
ty::proto_bare | ty::proto_vstore(ty::vstore_slice(_)) => bcx,
|
||||
ty::proto_vstore(ty::vstore_uniq) => fn_env(ty::ck_uniq),
|
||||
ty::proto_vstore(ty::vstore_box) => fn_env(ty::ck_box),
|
||||
ty::proto_vstore(ty::vstore_fixed(_)) => {
|
||||
cx.sess().bug(~"Closure with fixed vstore");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn make_opaque_cbox_take_glue(
|
||||
|
|
|
@ -447,13 +447,14 @@ fn trans_rvalue_dps(bcx: block, expr: @ast::expr, dest: Dest) -> block {
|
|||
ast::expr_fn_block(decl, body, cap_clause) => {
|
||||
let expr_ty = expr_ty(bcx, expr);
|
||||
match ty::get(expr_ty).struct {
|
||||
ty::ty_fn({proto, _}) => {
|
||||
ty::ty_fn(ref fn_ty) => {
|
||||
debug!("translating fn_block %s with type %s",
|
||||
expr_to_str(expr, tcx.sess.intr()),
|
||||
ty_to_str(tcx, expr_ty));
|
||||
return closure::trans_expr_fn(bcx, proto, decl, body,
|
||||
expr.id, cap_clause, None,
|
||||
dest);
|
||||
return closure::trans_expr_fn(
|
||||
bcx, fn_ty.meta.proto, decl, body,
|
||||
expr.id, cap_clause, None,
|
||||
dest);
|
||||
}
|
||||
_ => {
|
||||
bcx.sess().impossible_case(
|
||||
|
@ -463,11 +464,11 @@ fn trans_rvalue_dps(bcx: block, expr: @ast::expr, dest: Dest) -> block {
|
|||
}
|
||||
ast::expr_loop_body(blk) => {
|
||||
match ty::get(expr_ty(bcx, expr)).struct {
|
||||
ty::ty_fn({proto, _}) => {
|
||||
ty::ty_fn(ref fn_ty) => {
|
||||
match blk.node {
|
||||
ast::expr_fn_block(decl, body, cap) => {
|
||||
return closure::trans_expr_fn(
|
||||
bcx, proto, decl, body, blk.id,
|
||||
bcx, fn_ty.meta.proto, decl, body, blk.id,
|
||||
cap, Some(None), dest);
|
||||
}
|
||||
_ => {
|
||||
|
|
|
@ -20,6 +20,7 @@ use util::ppaux::ty_to_str;
|
|||
use datum::*;
|
||||
use callee::*;
|
||||
use expr::{Dest, Ignore};
|
||||
use ty::{FnTyBase, FnMeta, FnSig};
|
||||
|
||||
export link_name, trans_foreign_mod, register_foreign_fn, trans_foreign_fn,
|
||||
trans_intrinsic;
|
||||
|
@ -439,12 +440,12 @@ type c_stack_tys = {
|
|||
fn c_arg_and_ret_lltys(ccx: @crate_ctxt,
|
||||
id: ast::node_id) -> (~[TypeRef], TypeRef, ty::t) {
|
||||
match ty::get(ty::node_id_to_type(ccx.tcx, id)).struct {
|
||||
ty::ty_fn({inputs: arg_tys, output: ret_ty, _}) => {
|
||||
let llargtys = type_of_explicit_args(ccx, arg_tys);
|
||||
let llretty = type_of::type_of(ccx, ret_ty);
|
||||
(llargtys, llretty, ret_ty)
|
||||
}
|
||||
_ => ccx.sess.bug(~"c_arg_and_ret_lltys called on non-function type")
|
||||
ty::ty_fn(ref fn_ty) => {
|
||||
let llargtys = type_of_explicit_args(ccx, fn_ty.sig.inputs);
|
||||
let llretty = type_of::type_of(ccx, fn_ty.sig.output);
|
||||
(llargtys, llretty, fn_ty.sig.output)
|
||||
}
|
||||
_ => ccx.sess.bug(~"c_arg_and_ret_lltys called on non-function type")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -953,20 +954,19 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
|
|||
~"frame_address" => {
|
||||
let frameaddress = ccx.intrinsics.get(~"llvm.frameaddress");
|
||||
let frameaddress_val = Call(bcx, frameaddress, ~[C_i32(0i32)]);
|
||||
let fty = ty::mk_fn(bcx.tcx(), {
|
||||
purity: ast::impure_fn,
|
||||
proto:
|
||||
ty::proto_vstore(ty::vstore_slice(
|
||||
ty::re_bound(ty::br_anon(0)))),
|
||||
bounds: @~[],
|
||||
inputs: ~[{
|
||||
mode: ast::expl(ast::by_val),
|
||||
ty: ty::mk_imm_ptr(
|
||||
bcx.tcx(),
|
||||
ty::mk_mach_uint(bcx.tcx(), ast::ty_u8))
|
||||
}],
|
||||
output: ty::mk_nil(bcx.tcx()),
|
||||
ret_style: ast::return_val
|
||||
let star_u8 = ty::mk_imm_ptr(
|
||||
bcx.tcx(),
|
||||
ty::mk_mach_uint(bcx.tcx(), ast::ty_u8));
|
||||
let fty = ty::mk_fn(bcx.tcx(), FnTyBase {
|
||||
meta: FnMeta {purity: ast::impure_fn,
|
||||
proto:
|
||||
ty::proto_vstore(ty::vstore_slice(
|
||||
ty::re_bound(ty::br_anon(0)))),
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val},
|
||||
sig: FnSig {inputs: ~[{mode: ast::expl(ast::by_val),
|
||||
ty: star_u8}],
|
||||
output: ty::mk_nil(bcx.tcx())}
|
||||
});
|
||||
let datum = Datum {val: get_param(decl, first_real_arg),
|
||||
mode: ByRef, ty: fty, source: FromLvalue};
|
||||
|
|
|
@ -10,6 +10,7 @@ use base::{trans_item, get_item_val, no_self, self_arg, trans_fn,
|
|||
use syntax::parse::token::special_idents;
|
||||
use type_of::type_of_fn_from_ty;
|
||||
use back::link::mangle_exported_name;
|
||||
use middle::ty::{FnTyBase, FnMeta, FnSig};
|
||||
|
||||
fn monomorphic_fn(ccx: @crate_ctxt,
|
||||
fn_id: ast::def_id,
|
||||
|
@ -198,27 +199,36 @@ fn monomorphic_fn(ccx: @crate_ctxt,
|
|||
fn normalize_for_monomorphization(tcx: ty::ctxt, ty: ty::t) -> Option<ty::t> {
|
||||
// FIXME[mono] could do this recursively. is that worthwhile? (#2529)
|
||||
match ty::get(ty).struct {
|
||||
ty::ty_box(*) => {
|
||||
Some(ty::mk_opaque_box(tcx))
|
||||
}
|
||||
ty::ty_fn(ref fty) => {
|
||||
Some(ty::mk_fn(tcx, {purity: ast::impure_fn,
|
||||
proto: fty.proto,
|
||||
bounds: @~[],
|
||||
inputs: ~[],
|
||||
output: ty::mk_nil(tcx),
|
||||
ret_style: ast::return_val}))
|
||||
}
|
||||
ty::ty_trait(_, _, _) => {
|
||||
Some(ty::mk_fn(tcx, {purity: ast::impure_fn,
|
||||
proto: ty::proto_vstore(ty::vstore_box),
|
||||
bounds: @~[],
|
||||
inputs: ~[],
|
||||
output: ty::mk_nil(tcx),
|
||||
ret_style: ast::return_val}))
|
||||
}
|
||||
ty::ty_ptr(_) => Some(ty::mk_uint(tcx)),
|
||||
_ => None
|
||||
ty::ty_box(*) => {
|
||||
Some(ty::mk_opaque_box(tcx))
|
||||
}
|
||||
ty::ty_fn(ref fty) => {
|
||||
Some(ty::mk_fn(
|
||||
tcx,
|
||||
FnTyBase {meta: FnMeta {purity: ast::impure_fn,
|
||||
proto: fty.meta.proto,
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val},
|
||||
sig: FnSig {inputs: ~[],
|
||||
output: ty::mk_nil(tcx)}}))
|
||||
}
|
||||
ty::ty_trait(_, _, _) => {
|
||||
let box_proto = ty::proto_vstore(ty::vstore_box);
|
||||
Some(ty::mk_fn(
|
||||
tcx,
|
||||
FnTyBase {meta: FnMeta {purity: ast::impure_fn,
|
||||
proto: box_proto,
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val},
|
||||
sig: FnSig {inputs: ~[],
|
||||
output: ty::mk_nil(tcx)}}))
|
||||
}
|
||||
ty::ty_ptr(_) => {
|
||||
Some(ty::mk_uint(tcx))
|
||||
}
|
||||
_ => {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -178,14 +178,14 @@ impl reflector {
|
|||
|
||||
// FIXME (#2594): fetch constants out of intrinsic:: for the
|
||||
// numbers.
|
||||
ty::ty_fn(fty) => {
|
||||
let pureval = match fty.purity {
|
||||
ty::ty_fn(ref fty) => {
|
||||
let pureval = match fty.meta.purity {
|
||||
ast::pure_fn => 0u,
|
||||
ast::unsafe_fn => 1u,
|
||||
ast::impure_fn => 2u,
|
||||
ast::extern_fn => 3u
|
||||
};
|
||||
let protoval = match fty.proto {
|
||||
let protoval = match fty.meta.proto {
|
||||
ty::proto_bare => 0u,
|
||||
ty::proto_vstore(ty::vstore_uniq) => 2u,
|
||||
ty::proto_vstore(ty::vstore_box) => 3u,
|
||||
|
@ -193,16 +193,16 @@ impl reflector {
|
|||
ty::proto_vstore(ty::vstore_fixed(_)) =>
|
||||
fail ~"fixed unexpected"
|
||||
};
|
||||
let retval = match fty.ret_style {
|
||||
let retval = match fty.meta.ret_style {
|
||||
ast::noreturn => 0u,
|
||||
ast::return_val => 1u
|
||||
};
|
||||
let extra = ~[self.c_uint(pureval),
|
||||
self.c_uint(protoval),
|
||||
self.c_uint(vec::len(fty.inputs)),
|
||||
self.c_uint(retval)];
|
||||
self.c_uint(protoval),
|
||||
self.c_uint(vec::len(fty.sig.inputs)),
|
||||
self.c_uint(retval)];
|
||||
self.visit(~"enter_fn", extra);
|
||||
for fty.inputs.eachi |i, arg| {
|
||||
for fty.sig.inputs.eachi |i, arg| {
|
||||
let modeval = match arg.mode {
|
||||
ast::infer(_) => 0u,
|
||||
ast::expl(e) => match e {
|
||||
|
@ -220,7 +220,7 @@ impl reflector {
|
|||
}
|
||||
self.visit(~"fn_output",
|
||||
~[self.c_uint(retval),
|
||||
self.c_tydesc(fty.output)]);
|
||||
self.c_tydesc(fty.sig.output)]);
|
||||
self.visit(~"leave_fn", extra);
|
||||
}
|
||||
|
||||
|
|
|
@ -213,158 +213,161 @@ fn add_substr(&dest: ~[u8], src: ~[u8]) {
|
|||
|
||||
fn shape_of(ccx: @crate_ctxt, t: ty::t) -> ~[u8] {
|
||||
match ty::get(t).struct {
|
||||
ty::ty_nil | ty::ty_bool | ty::ty_uint(ast::ty_u8) |
|
||||
ty::ty_bot => ~[shape_u8],
|
||||
ty::ty_int(ast::ty_i) => ~[s_int(ccx.tcx)],
|
||||
ty::ty_float(ast::ty_f) => ~[s_float(ccx.tcx)],
|
||||
ty::ty_uint(ast::ty_u) | ty::ty_ptr(_) => ~[s_uint(ccx.tcx)],
|
||||
ty::ty_type => ~[s_tydesc(ccx.tcx)],
|
||||
ty::ty_int(ast::ty_i8) => ~[shape_i8],
|
||||
ty::ty_uint(ast::ty_u16) => ~[shape_u16],
|
||||
ty::ty_int(ast::ty_i16) => ~[shape_i16],
|
||||
ty::ty_uint(ast::ty_u32) => ~[shape_u32],
|
||||
ty::ty_int(ast::ty_i32) | ty::ty_int(ast::ty_char) => ~[shape_i32],
|
||||
ty::ty_uint(ast::ty_u64) => ~[shape_u64],
|
||||
ty::ty_int(ast::ty_i64) => ~[shape_i64],
|
||||
ty::ty_float(ast::ty_f32) => ~[shape_f32],
|
||||
ty::ty_float(ast::ty_f64) => ~[shape_f64],
|
||||
ty::ty_estr(ty::vstore_uniq) => {
|
||||
shape_of(ccx, tvec::expand_boxed_vec_ty(ccx.tcx, t))
|
||||
}
|
||||
ty::ty_enum(did, substs) => {
|
||||
match enum_kind(ccx, did) {
|
||||
tk_unit => ~[s_variant_enum_t(ccx.tcx)],
|
||||
tk_enum => ~[s_variant_enum_t(ccx.tcx)],
|
||||
tk_newtype | tk_complex => {
|
||||
let mut s = ~[shape_enum], id;
|
||||
let nom_id = mk_nominal_id(ccx.tcx, did, None, substs.tps);
|
||||
match ccx.shape_cx.tag_id_to_index.find(nom_id) {
|
||||
None => {
|
||||
id = ccx.shape_cx.next_tag_id;
|
||||
ccx.shape_cx.tag_id_to_index.insert(nom_id, id);
|
||||
ccx.shape_cx.tag_order.push({did: did, substs: substs});
|
||||
ccx.shape_cx.next_tag_id += 1u16;
|
||||
}
|
||||
Some(existing_id) => id = existing_id,
|
||||
ty::ty_nil | ty::ty_bool | ty::ty_uint(ast::ty_u8) |
|
||||
ty::ty_bot => ~[shape_u8],
|
||||
ty::ty_int(ast::ty_i) => ~[s_int(ccx.tcx)],
|
||||
ty::ty_float(ast::ty_f) => ~[s_float(ccx.tcx)],
|
||||
ty::ty_uint(ast::ty_u) | ty::ty_ptr(_) => ~[s_uint(ccx.tcx)],
|
||||
ty::ty_type => ~[s_tydesc(ccx.tcx)],
|
||||
ty::ty_int(ast::ty_i8) => ~[shape_i8],
|
||||
ty::ty_uint(ast::ty_u16) => ~[shape_u16],
|
||||
ty::ty_int(ast::ty_i16) => ~[shape_i16],
|
||||
ty::ty_uint(ast::ty_u32) => ~[shape_u32],
|
||||
ty::ty_int(ast::ty_i32) | ty::ty_int(ast::ty_char) => ~[shape_i32],
|
||||
ty::ty_uint(ast::ty_u64) => ~[shape_u64],
|
||||
ty::ty_int(ast::ty_i64) => ~[shape_i64],
|
||||
ty::ty_float(ast::ty_f32) => ~[shape_f32],
|
||||
ty::ty_float(ast::ty_f64) => ~[shape_f64],
|
||||
ty::ty_estr(ty::vstore_uniq) => {
|
||||
shape_of(ccx, tvec::expand_boxed_vec_ty(ccx.tcx, t))
|
||||
}
|
||||
ty::ty_enum(did, substs) => {
|
||||
match enum_kind(ccx, did) {
|
||||
tk_unit => ~[s_variant_enum_t(ccx.tcx)],
|
||||
tk_enum => ~[s_variant_enum_t(ccx.tcx)],
|
||||
tk_newtype | tk_complex => {
|
||||
let mut s = ~[shape_enum], id;
|
||||
let nom_id = mk_nominal_id(ccx.tcx, did,
|
||||
None, substs.tps);
|
||||
match ccx.shape_cx.tag_id_to_index.find(nom_id) {
|
||||
None => {
|
||||
id = ccx.shape_cx.next_tag_id;
|
||||
ccx.shape_cx.tag_id_to_index.insert(nom_id, id);
|
||||
ccx.shape_cx.tag_order.push({did: did,
|
||||
substs: substs});
|
||||
ccx.shape_cx.next_tag_id += 1u16;
|
||||
}
|
||||
Some(existing_id) => id = existing_id,
|
||||
}
|
||||
add_u16(s, id as u16);
|
||||
|
||||
s
|
||||
}
|
||||
}
|
||||
add_u16(s, id as u16);
|
||||
|
||||
}
|
||||
ty::ty_estr(ty::vstore_box) |
|
||||
ty::ty_evec(_, ty::vstore_box) |
|
||||
ty::ty_box(_) | ty::ty_opaque_box => ~[shape_box],
|
||||
ty::ty_uniq(mt) => {
|
||||
let mut s = ~[shape_uniq];
|
||||
add_substr(s, shape_of(ccx, mt.ty));
|
||||
s
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::ty_estr(ty::vstore_box) |
|
||||
ty::ty_evec(_, ty::vstore_box) |
|
||||
ty::ty_box(_) | ty::ty_opaque_box => ~[shape_box],
|
||||
ty::ty_uniq(mt) => {
|
||||
let mut s = ~[shape_uniq];
|
||||
add_substr(s, shape_of(ccx, mt.ty));
|
||||
s
|
||||
}
|
||||
ty::ty_unboxed_vec(mt) => {
|
||||
let mut s = ~[shape_unboxed_vec];
|
||||
add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty));
|
||||
add_substr(s, shape_of(ccx, mt.ty));
|
||||
s
|
||||
}
|
||||
ty::ty_evec(_, ty::vstore_uniq) => {
|
||||
shape_of(ccx, tvec::expand_boxed_vec_ty(ccx.tcx, t))
|
||||
}
|
||||
|
||||
ty::ty_estr(ty::vstore_fixed(n)) => {
|
||||
let mut s = ~[shape_fixedvec];
|
||||
let u8_t = ty::mk_mach_uint(ccx.tcx, ast::ty_u8);
|
||||
assert (n + 1u) <= 0xffffu;
|
||||
add_u16(s, (n + 1u) as u16);
|
||||
add_bool(s, true);
|
||||
add_substr(s, shape_of(ccx, u8_t));
|
||||
s
|
||||
}
|
||||
|
||||
ty::ty_evec(mt, ty::vstore_fixed(n)) => {
|
||||
let mut s = ~[shape_fixedvec];
|
||||
assert n <= 0xffffu;
|
||||
add_u16(s, n as u16);
|
||||
add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty));
|
||||
add_substr(s, shape_of(ccx, mt.ty));
|
||||
s
|
||||
}
|
||||
|
||||
ty::ty_estr(ty::vstore_slice(_)) => {
|
||||
let mut s = ~[shape_slice];
|
||||
let u8_t = ty::mk_mach_uint(ccx.tcx, ast::ty_u8);
|
||||
add_bool(s, true); // is_pod
|
||||
add_bool(s, true); // is_str
|
||||
add_substr(s, shape_of(ccx, u8_t));
|
||||
s
|
||||
}
|
||||
|
||||
ty::ty_evec(mt, ty::vstore_slice(_)) => {
|
||||
let mut s = ~[shape_slice];
|
||||
add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty));
|
||||
add_bool(s, false); // is_str
|
||||
add_substr(s, shape_of(ccx, mt.ty));
|
||||
s
|
||||
}
|
||||
|
||||
ty::ty_rec(fields) => {
|
||||
let mut s = ~[shape_struct], sub = ~[];
|
||||
for vec::each(fields) |f| {
|
||||
sub += shape_of(ccx, f.mt.ty);
|
||||
ty::ty_unboxed_vec(mt) => {
|
||||
let mut s = ~[shape_unboxed_vec];
|
||||
add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty));
|
||||
add_substr(s, shape_of(ccx, mt.ty));
|
||||
s
|
||||
}
|
||||
add_substr(s, sub);
|
||||
s
|
||||
}
|
||||
ty::ty_tup(elts) => {
|
||||
let mut s = ~[shape_struct], sub = ~[];
|
||||
for vec::each(elts) |elt| {
|
||||
sub += shape_of(ccx, elt);
|
||||
ty::ty_evec(_, ty::vstore_uniq) => {
|
||||
shape_of(ccx, tvec::expand_boxed_vec_ty(ccx.tcx, t))
|
||||
}
|
||||
add_substr(s, sub);
|
||||
s
|
||||
}
|
||||
ty::ty_trait(_, _, _) => ~[shape_box_fn],
|
||||
ty::ty_class(did, ref substs) => {
|
||||
// same as records, unless there's a dtor
|
||||
let tps = substs.tps;
|
||||
let m_dtor_did = ty::ty_dtor(ccx.tcx, did);
|
||||
let mut s = if option::is_some(m_dtor_did) {
|
||||
~[shape_res]
|
||||
}
|
||||
else { ~[shape_struct] }, sub = ~[];
|
||||
do option::iter(m_dtor_did) |dtor_did| {
|
||||
let ri = @{did: dtor_did, parent_id: Some(did), tps: tps};
|
||||
let id = ccx.shape_cx.resources.intern(ri);
|
||||
add_u16(s, id as u16);
|
||||
};
|
||||
for ty::class_items_as_mutable_fields(ccx.tcx, did, substs).each |f| {
|
||||
sub += shape_of(ccx, f.mt.ty);
|
||||
|
||||
ty::ty_estr(ty::vstore_fixed(n)) => {
|
||||
let mut s = ~[shape_fixedvec];
|
||||
let u8_t = ty::mk_mach_uint(ccx.tcx, ast::ty_u8);
|
||||
assert (n + 1u) <= 0xffffu;
|
||||
add_u16(s, (n + 1u) as u16);
|
||||
add_bool(s, true);
|
||||
add_substr(s, shape_of(ccx, u8_t));
|
||||
s
|
||||
}
|
||||
|
||||
ty::ty_evec(mt, ty::vstore_fixed(n)) => {
|
||||
let mut s = ~[shape_fixedvec];
|
||||
assert n <= 0xffffu;
|
||||
add_u16(s, n as u16);
|
||||
add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty));
|
||||
add_substr(s, shape_of(ccx, mt.ty));
|
||||
s
|
||||
}
|
||||
|
||||
ty::ty_estr(ty::vstore_slice(_)) => {
|
||||
let mut s = ~[shape_slice];
|
||||
let u8_t = ty::mk_mach_uint(ccx.tcx, ast::ty_u8);
|
||||
add_bool(s, true); // is_pod
|
||||
add_bool(s, true); // is_str
|
||||
add_substr(s, shape_of(ccx, u8_t));
|
||||
s
|
||||
}
|
||||
|
||||
ty::ty_evec(mt, ty::vstore_slice(_)) => {
|
||||
let mut s = ~[shape_slice];
|
||||
add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty));
|
||||
add_bool(s, false); // is_str
|
||||
add_substr(s, shape_of(ccx, mt.ty));
|
||||
s
|
||||
}
|
||||
|
||||
ty::ty_rec(fields) => {
|
||||
let mut s = ~[shape_struct], sub = ~[];
|
||||
for vec::each(fields) |f| {
|
||||
sub += shape_of(ccx, f.mt.ty);
|
||||
}
|
||||
add_substr(s, sub);
|
||||
s
|
||||
}
|
||||
ty::ty_tup(elts) => {
|
||||
let mut s = ~[shape_struct], sub = ~[];
|
||||
for vec::each(elts) |elt| {
|
||||
sub += shape_of(ccx, elt);
|
||||
}
|
||||
add_substr(s, sub);
|
||||
s
|
||||
}
|
||||
ty::ty_trait(_, _, _) => ~[shape_box_fn],
|
||||
ty::ty_class(did, ref substs) => {
|
||||
// same as records, unless there's a dtor
|
||||
let tps = substs.tps;
|
||||
let m_dtor_did = ty::ty_dtor(ccx.tcx, did);
|
||||
let mut s = if option::is_some(m_dtor_did) {
|
||||
~[shape_res]
|
||||
}
|
||||
else { ~[shape_struct] }, sub = ~[];
|
||||
do option::iter(m_dtor_did) |dtor_did| {
|
||||
let ri = @{did: dtor_did, parent_id: Some(did), tps: tps};
|
||||
let id = ccx.shape_cx.resources.intern(ri);
|
||||
add_u16(s, id as u16);
|
||||
};
|
||||
for ty::class_items_as_mutable_fields(ccx.tcx, did,
|
||||
substs).each |f| {
|
||||
sub += shape_of(ccx, f.mt.ty);
|
||||
}
|
||||
add_substr(s, sub);
|
||||
s
|
||||
}
|
||||
ty::ty_rptr(_, mt) => {
|
||||
let mut s = ~[shape_rptr];
|
||||
add_substr(s, shape_of(ccx, mt.ty));
|
||||
s
|
||||
}
|
||||
ty::ty_param(*) => {
|
||||
ccx.tcx.sess.bug(~"non-monomorphized type parameter");
|
||||
}
|
||||
ty::ty_fn(ref fn_ty) => {
|
||||
match fn_ty.meta.proto {
|
||||
ty::proto_vstore(ty::vstore_box) => ~[shape_box_fn],
|
||||
ty::proto_vstore(ty::vstore_uniq) => ~[shape_uniq_fn],
|
||||
ty::proto_vstore(ty::vstore_slice(_)) => ~[shape_stack_fn],
|
||||
ty::proto_bare => ~[shape_bare_fn],
|
||||
ty::proto_vstore(ty::vstore_fixed(_)) =>
|
||||
fail ~"fixed vstore is impossible",
|
||||
}
|
||||
}
|
||||
ty::ty_opaque_closure_ptr(_) => ~[shape_opaque_closure_ptr],
|
||||
ty::ty_infer(_) | ty::ty_self => {
|
||||
ccx.sess.bug(~"shape_of: unexpected type struct found")
|
||||
}
|
||||
add_substr(s, sub);
|
||||
s
|
||||
}
|
||||
ty::ty_rptr(_, mt) => {
|
||||
let mut s = ~[shape_rptr];
|
||||
add_substr(s, shape_of(ccx, mt.ty));
|
||||
s
|
||||
}
|
||||
ty::ty_param(*) => {
|
||||
ccx.tcx.sess.bug(~"non-monomorphized type parameter");
|
||||
}
|
||||
ty::ty_fn({proto: ty::proto_vstore(ty::vstore_box), _}) =>
|
||||
~[shape_box_fn],
|
||||
ty::ty_fn({proto: ty::proto_vstore(ty::vstore_uniq), _}) =>
|
||||
~[shape_uniq_fn],
|
||||
ty::ty_fn({proto: ty::proto_vstore(ty::vstore_slice(_)), _}) =>
|
||||
~[shape_stack_fn],
|
||||
ty::ty_fn({proto: ty::proto_vstore(ty::vstore_fixed(_)), _}) =>
|
||||
fail ~"fixed vstore is impossible",
|
||||
ty::ty_fn({proto: ty::proto_bare, _}) =>
|
||||
~[shape_bare_fn],
|
||||
ty::ty_opaque_closure_ptr(_) =>
|
||||
~[shape_opaque_closure_ptr],
|
||||
ty::ty_infer(_) | ty::ty_self =>
|
||||
ccx.sess.bug(~"shape_of: unexpected type struct found")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,8 +46,8 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
|
|||
|
||||
let cx = {ccx: ccx, uses: vec::to_mut(vec::from_elem(n_tps, 0u))};
|
||||
match ty::get(ty::lookup_item_type(cx.ccx.tcx, fn_id).ty).struct {
|
||||
ty::ty_fn({inputs, _}) => {
|
||||
for vec::each(inputs) |arg| {
|
||||
ty::ty_fn(ref fn_ty) => {
|
||||
for vec::each(fn_ty.sig.inputs) |arg| {
|
||||
if arg.mode == expl(by_val) { type_needs(cx, use_repr, arg.ty); }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -946,16 +946,14 @@ fn callee_modes(fcx: fn_ctxt, callee: node_id) -> ~[mode] {
|
|||
let ty = ty::type_autoderef(fcx.ccx.tcx,
|
||||
ty::node_id_to_type(fcx.ccx.tcx, callee));
|
||||
match ty::get(ty).struct {
|
||||
ty::ty_fn({inputs: args, _}) {
|
||||
let mut modes = ~[];
|
||||
for args.each |arg| { vec::push(modes, arg.mode); }
|
||||
return modes;
|
||||
}
|
||||
_ {
|
||||
// Shouldn't happen; callee should be ty_fn.
|
||||
fcx.ccx.tcx.sess.bug(~"non-fn callee type in callee_modes: " +
|
||||
ty::ty_fn(ref fn_ty) {
|
||||
return fn_ty.sig.inputs.map(|input| input.mode);
|
||||
}
|
||||
_ {
|
||||
// Shouldn't happen; callee should be ty_fn.
|
||||
fcx.ccx.tcx.sess.bug(~"non-fn callee type in callee_modes: " +
|
||||
util::ppaux::ty_to_str(fcx.ccx.tcx, ty));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ use util::ppaux::{ty_to_str, proto_ty_to_str, tys_to_str};
|
|||
use std::serialization::{serialize_Option,
|
||||
deserialize_Option};
|
||||
|
||||
export ty_vid, int_vid, region_vid, vid;
|
||||
export TyVid, IntVid, FnVid, RegionVid, vid;
|
||||
export br_hashmap;
|
||||
export is_instantiable;
|
||||
export node_id_to_type;
|
||||
|
@ -80,7 +80,7 @@ export ty_box, mk_box, mk_imm_box, type_is_box, type_is_boxed;
|
|||
export ty_opaque_closure_ptr, mk_opaque_closure_ptr;
|
||||
export ty_opaque_box, mk_opaque_box;
|
||||
export ty_float, mk_float, mk_mach_float, type_is_fp;
|
||||
export ty_fn, fn_ty, mk_fn;
|
||||
export ty_fn, FnTy, FnTyBase, FnMeta, FnSig, mk_fn;
|
||||
export ty_fn_proto, ty_fn_purity, ty_fn_ret, ty_fn_ret_style, tys_in_fn_ty;
|
||||
export ty_int, mk_int, mk_mach_int, mk_char;
|
||||
export mk_i8, mk_u8, mk_i16, mk_u16, mk_i32, mk_u32, mk_i64, mk_u64;
|
||||
|
@ -119,7 +119,7 @@ export kind_noncopyable, kind_const;
|
|||
export kind_can_be_copied, kind_can_be_sent, kind_can_be_implicitly_copied;
|
||||
export kind_is_safe_for_default_mode;
|
||||
export kind_is_owned;
|
||||
export proto_kind, kind_lteq, type_kind;
|
||||
export meta_kind, kind_lteq, type_kind;
|
||||
export operators;
|
||||
export type_err, terr_vstore_kind;
|
||||
export type_err_to_str, note_and_explain_type_err;
|
||||
|
@ -203,7 +203,7 @@ type param_bounds = @~[param_bound];
|
|||
|
||||
type method = {ident: ast::ident,
|
||||
tps: @~[param_bounds],
|
||||
fty: fn_ty,
|
||||
fty: FnTy,
|
||||
self_ty: ast::self_ty_,
|
||||
vis: ast::visibility};
|
||||
|
||||
|
@ -392,20 +392,42 @@ impl fn_proto : cmp::Eq {
|
|||
}
|
||||
}
|
||||
|
||||
/// Innards of a function type:
|
||||
///
|
||||
/// - `purity` is the function's effect (pure, impure, unsafe).
|
||||
/// - `proto` is the protocol (fn@, fn~, etc).
|
||||
/// - `bound` is the parameter bounds on the function's upvars.
|
||||
/// - `inputs` is the list of arguments and their modes.
|
||||
/// - `output` is the return type.
|
||||
/// - `ret_style` indicates whether the function returns a value or fails.
|
||||
type fn_ty = {purity: ast::purity,
|
||||
proto: fn_proto,
|
||||
bounds: @~[param_bound],
|
||||
inputs: ~[arg],
|
||||
output: t,
|
||||
ret_style: ret_style};
|
||||
/**
|
||||
* Meta information about a closure.
|
||||
*
|
||||
* - `purity` is the function's effect (pure, impure, unsafe).
|
||||
* - `proto` is the protocol (fn@, fn~, etc).
|
||||
* - `bounds` is the parameter bounds on the function's upvars.
|
||||
* - `ret_style` indicates whether the function returns a value or fails. */
|
||||
struct FnMeta {
|
||||
purity: ast::purity;
|
||||
proto: fn_proto;
|
||||
bounds: @~[param_bound];
|
||||
ret_style: ret_style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Signature of a function type, which I have arbitrarily
|
||||
* decided to use to refer to the input/output types.
|
||||
*
|
||||
* - `inputs` is the list of arguments and their modes.
|
||||
* - `output` is the return type. */
|
||||
struct FnSig {
|
||||
inputs: ~[arg];
|
||||
output: t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function type: combines the meta information and the
|
||||
* type signature. This particular type is parameterized
|
||||
* by the meta information because, in some cases, the
|
||||
* meta information is inferred. */
|
||||
struct FnTyBase<M: cmp::Eq> {
|
||||
meta: M;
|
||||
sig: FnSig;
|
||||
}
|
||||
|
||||
type FnTy = FnTyBase<FnMeta>;
|
||||
|
||||
type param_ty = {idx: uint, def_id: def_id};
|
||||
|
||||
|
@ -440,7 +462,7 @@ enum region {
|
|||
re_static,
|
||||
|
||||
/// A region variable. Should not exist after typeck.
|
||||
re_var(region_vid)
|
||||
re_var(RegionVid)
|
||||
}
|
||||
|
||||
enum bound_region {
|
||||
|
@ -505,7 +527,7 @@ enum sty {
|
|||
ty_ptr(mt),
|
||||
ty_rptr(region, mt),
|
||||
ty_rec(~[field]),
|
||||
ty_fn(fn_ty),
|
||||
ty_fn(FnTy),
|
||||
ty_trait(def_id, substs, vstore),
|
||||
ty_class(def_id, substs),
|
||||
ty_tup(~[t]),
|
||||
|
@ -567,13 +589,14 @@ enum param_bound {
|
|||
bound_trait(t),
|
||||
}
|
||||
|
||||
enum ty_vid = uint;
|
||||
enum int_vid = uint;
|
||||
enum region_vid = uint;
|
||||
enum TyVid = uint;
|
||||
enum IntVid = uint;
|
||||
enum FnVid = uint;
|
||||
enum RegionVid = uint;
|
||||
|
||||
enum InferTy {
|
||||
TyVar(ty_vid),
|
||||
IntVar(int_vid)
|
||||
TyVar(TyVid),
|
||||
IntVar(IntVid)
|
||||
}
|
||||
|
||||
trait vid {
|
||||
|
@ -581,17 +604,22 @@ trait vid {
|
|||
pure fn to_str() -> ~str;
|
||||
}
|
||||
|
||||
impl ty_vid: vid {
|
||||
impl TyVid: vid {
|
||||
pure fn to_uint() -> uint { *self }
|
||||
pure fn to_str() -> ~str { fmt!("<V%u>", self.to_uint()) }
|
||||
}
|
||||
|
||||
impl int_vid: vid {
|
||||
impl IntVid: vid {
|
||||
pure fn to_uint() -> uint { *self }
|
||||
pure fn to_str() -> ~str { fmt!("<VI%u>", self.to_uint()) }
|
||||
}
|
||||
|
||||
impl region_vid: vid {
|
||||
impl FnVid: vid {
|
||||
pure fn to_uint() -> uint { *self }
|
||||
pure fn to_str() -> ~str { fmt!("<F%u>", self.to_uint()) }
|
||||
}
|
||||
|
||||
impl RegionVid: vid {
|
||||
pure fn to_uint() -> uint { *self }
|
||||
pure fn to_str() -> ~str { fmt!("%?", self) }
|
||||
}
|
||||
|
@ -600,14 +628,14 @@ impl InferTy {
|
|||
pure fn to_hash() -> uint {
|
||||
match self {
|
||||
TyVar(v) => v.to_uint() << 1,
|
||||
IntVar(v) => (v.to_uint() << 1) + 1
|
||||
IntVar(v) => (v.to_uint() << 1) + 1,
|
||||
}
|
||||
}
|
||||
|
||||
pure fn to_str() -> ~str {
|
||||
match self {
|
||||
TyVar(v) => v.to_str(),
|
||||
IntVar(v) => v.to_str()
|
||||
IntVar(v) => v.to_str(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -781,12 +809,12 @@ fn mk_t_with_id(cx: ctxt, +st: sty, o_def_id: Option<ast::def_id>) -> t {
|
|||
ty_rec(flds) => for flds.each |f| { flags |= get(f.mt.ty).flags; },
|
||||
ty_tup(ts) => for ts.each |tt| { flags |= get(tt).flags; },
|
||||
ty_fn(ref f) => {
|
||||
match f.proto {
|
||||
match f.meta.proto {
|
||||
ty::proto_vstore(vstore_slice(r)) => flags |= rflags(r),
|
||||
ty::proto_bare | ty::proto_vstore(_) => {}
|
||||
}
|
||||
for f.inputs.each |a| { flags |= get(a.ty).flags; }
|
||||
flags |= get(f.output).flags;
|
||||
for f.sig.inputs.each |a| { flags |= get(a.ty).flags; }
|
||||
flags |= get(f.sig.output).flags;
|
||||
}
|
||||
}
|
||||
let t = @{struct: st, id: cx.next_id, flags: flags, o_def_id: o_def_id};
|
||||
|
@ -883,13 +911,12 @@ fn mk_mut_unboxed_vec(cx: ctxt, ty: t) -> t {
|
|||
mk_t(cx, ty_unboxed_vec({ty: ty, mutbl: ast::m_imm}))
|
||||
}
|
||||
|
||||
|
||||
fn mk_rec(cx: ctxt, fs: ~[field]) -> t { mk_t(cx, ty_rec(fs)) }
|
||||
|
||||
fn mk_tup(cx: ctxt, ts: ~[t]) -> t { mk_t(cx, ty_tup(ts)) }
|
||||
|
||||
// take a copy because we want to own the various vectors inside
|
||||
fn mk_fn(cx: ctxt, +fty: fn_ty) -> t { mk_t(cx, ty_fn(fty)) }
|
||||
fn mk_fn(cx: ctxt, +fty: FnTy) -> t { mk_t(cx, ty_fn(fty)) }
|
||||
|
||||
fn mk_trait(cx: ctxt, did: ast::def_id, +substs: substs, vstore: vstore)
|
||||
-> t {
|
||||
|
@ -902,9 +929,9 @@ fn mk_class(cx: ctxt, class_id: ast::def_id, +substs: substs) -> t {
|
|||
mk_t(cx, ty_class(class_id, substs))
|
||||
}
|
||||
|
||||
fn mk_var(cx: ctxt, v: ty_vid) -> t { mk_infer(cx, TyVar(v)) }
|
||||
fn mk_var(cx: ctxt, v: TyVid) -> t { mk_infer(cx, TyVar(v)) }
|
||||
|
||||
fn mk_int_var(cx: ctxt, v: int_vid) -> t {
|
||||
fn mk_int_var(cx: ctxt, v: IntVid) -> t {
|
||||
mk_infer(cx, IntVar(v))
|
||||
}
|
||||
|
||||
|
@ -976,8 +1003,8 @@ fn maybe_walk_ty(ty: t, f: fn(t) -> bool) {
|
|||
}
|
||||
ty_tup(ts) => { for ts.each |tt| { maybe_walk_ty(tt, f); } }
|
||||
ty_fn(ref ft) => {
|
||||
for ft.inputs.each |a| { maybe_walk_ty(a.ty, f); }
|
||||
maybe_walk_ty(ft.output, f);
|
||||
for ft.sig.inputs.each |a| { maybe_walk_ty(a.ty, f); }
|
||||
maybe_walk_ty(ft.sig.output, f);
|
||||
}
|
||||
ty_uniq(tm) => { maybe_walk_ty(tm.ty, f); }
|
||||
}
|
||||
|
@ -995,58 +1022,61 @@ fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty {
|
|||
}
|
||||
|
||||
match *sty {
|
||||
ty_box(tm) => {
|
||||
ty_box({ty: fldop(tm.ty), mutbl: tm.mutbl})
|
||||
}
|
||||
ty_uniq(tm) => {
|
||||
ty_uniq({ty: fldop(tm.ty), mutbl: tm.mutbl})
|
||||
}
|
||||
ty_ptr(tm) => {
|
||||
ty_ptr({ty: fldop(tm.ty), mutbl: tm.mutbl})
|
||||
}
|
||||
ty_unboxed_vec(tm) => {
|
||||
ty_unboxed_vec({ty: fldop(tm.ty), mutbl: tm.mutbl})
|
||||
}
|
||||
ty_evec(tm, vst) => {
|
||||
ty_evec({ty: fldop(tm.ty), mutbl: tm.mutbl}, vst)
|
||||
}
|
||||
ty_enum(tid, ref substs) => {
|
||||
ty_enum(tid, fold_substs(substs, fldop))
|
||||
}
|
||||
ty_trait(did, ref substs, vst) => {
|
||||
ty_trait(did, fold_substs(substs, fldop), vst)
|
||||
}
|
||||
ty_rec(fields) => {
|
||||
let new_fields = do vec::map(fields) |fl| {
|
||||
let new_ty = fldop(fl.mt.ty);
|
||||
let new_mt = {ty: new_ty, mutbl: fl.mt.mutbl};
|
||||
{ident: fl.ident, mt: new_mt}
|
||||
};
|
||||
ty_rec(new_fields)
|
||||
}
|
||||
ty_tup(ts) => {
|
||||
let new_ts = vec::map(ts, |tt| fldop(tt));
|
||||
ty_tup(new_ts)
|
||||
}
|
||||
ty_fn(ref f) => {
|
||||
let new_args = vec::map(f.inputs, |a| {
|
||||
let new_ty = fldop(a.ty);
|
||||
{mode: a.mode, ty: new_ty}
|
||||
});
|
||||
let new_output = fldop(f.output);
|
||||
ty_fn({inputs: new_args, output: new_output,.. *f})
|
||||
}
|
||||
ty_rptr(r, tm) => {
|
||||
ty_rptr(r, {ty: fldop(tm.ty), mutbl: tm.mutbl})
|
||||
}
|
||||
ty_class(did, ref substs) => {
|
||||
ty_class(did, fold_substs(substs, fldop))
|
||||
}
|
||||
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
|
||||
ty_estr(_) | ty_type | ty_opaque_closure_ptr(_) |
|
||||
ty_opaque_box | ty_infer(_) | ty_param(*) | ty_self => {
|
||||
*sty
|
||||
}
|
||||
ty_box(tm) => {
|
||||
ty_box({ty: fldop(tm.ty), mutbl: tm.mutbl})
|
||||
}
|
||||
ty_uniq(tm) => {
|
||||
ty_uniq({ty: fldop(tm.ty), mutbl: tm.mutbl})
|
||||
}
|
||||
ty_ptr(tm) => {
|
||||
ty_ptr({ty: fldop(tm.ty), mutbl: tm.mutbl})
|
||||
}
|
||||
ty_unboxed_vec(tm) => {
|
||||
ty_unboxed_vec({ty: fldop(tm.ty), mutbl: tm.mutbl})
|
||||
}
|
||||
ty_evec(tm, vst) => {
|
||||
ty_evec({ty: fldop(tm.ty), mutbl: tm.mutbl}, vst)
|
||||
}
|
||||
ty_enum(tid, ref substs) => {
|
||||
ty_enum(tid, fold_substs(substs, fldop))
|
||||
}
|
||||
ty_trait(did, ref substs, vst) => {
|
||||
ty_trait(did, fold_substs(substs, fldop), vst)
|
||||
}
|
||||
ty_rec(fields) => {
|
||||
let new_fields = do vec::map(fields) |fl| {
|
||||
let new_ty = fldop(fl.mt.ty);
|
||||
let new_mt = {ty: new_ty, mutbl: fl.mt.mutbl};
|
||||
{ident: fl.ident, mt: new_mt}
|
||||
};
|
||||
ty_rec(new_fields)
|
||||
}
|
||||
ty_tup(ts) => {
|
||||
let new_ts = vec::map(ts, |tt| fldop(tt));
|
||||
ty_tup(new_ts)
|
||||
}
|
||||
ty_fn(ref f) => {
|
||||
let new_args = f.sig.inputs.map(|a| {
|
||||
let new_ty = fldop(a.ty);
|
||||
{mode: a.mode, ty: new_ty}
|
||||
});
|
||||
let new_output = fldop(f.sig.output);
|
||||
ty_fn(FnTyBase {
|
||||
meta: f.meta,
|
||||
sig: FnSig {inputs: new_args, output: new_output}
|
||||
})
|
||||
}
|
||||
ty_rptr(r, tm) => {
|
||||
ty_rptr(r, {ty: fldop(tm.ty), mutbl: tm.mutbl})
|
||||
}
|
||||
ty_class(did, ref substs) => {
|
||||
ty_class(did, fold_substs(substs, fldop))
|
||||
}
|
||||
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
|
||||
ty_estr(_) | ty_type | ty_opaque_closure_ptr(_) |
|
||||
ty_opaque_box | ty_infer(_) | ty_param(*) | ty_self => {
|
||||
*sty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1113,9 +1143,9 @@ fn fold_regions_and_ty(
|
|||
ty_trait(def_id, ref substs, vst) => {
|
||||
ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), vst)
|
||||
}
|
||||
ty_fn(f) => {
|
||||
ty_fn(ref f) => {
|
||||
let new_proto;
|
||||
match f.proto {
|
||||
match f.meta.proto {
|
||||
proto_bare =>
|
||||
new_proto = proto_bare,
|
||||
proto_vstore(vstore_slice(r)) =>
|
||||
|
@ -1123,16 +1153,15 @@ fn fold_regions_and_ty(
|
|||
proto_vstore(old_vstore) =>
|
||||
new_proto = proto_vstore(old_vstore)
|
||||
}
|
||||
|
||||
let new_args = vec::map(f.inputs, |a| {
|
||||
let new_args = vec::map(f.sig.inputs, |a| {
|
||||
let new_ty = fldfnt(a.ty);
|
||||
{mode: a.mode, ty: new_ty}
|
||||
});
|
||||
let new_output = fldfnt(f.output);
|
||||
ty::mk_fn(cx, {
|
||||
inputs: new_args,
|
||||
output: new_output,
|
||||
proto: new_proto,.. f
|
||||
let new_output = fldfnt(f.sig.output);
|
||||
ty::mk_fn(cx, FnTyBase {
|
||||
meta: FnMeta {proto: new_proto, ..f.meta},
|
||||
sig: FnSig {inputs: new_args,
|
||||
output: new_output}
|
||||
})
|
||||
}
|
||||
ref sty => {
|
||||
|
@ -1440,7 +1469,7 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
|
|||
accum
|
||||
}
|
||||
ty_fn(ref fty) => {
|
||||
match fty.proto {
|
||||
match fty.meta.proto {
|
||||
proto_bare | proto_vstore(vstore_slice(_)) => false,
|
||||
_ => true
|
||||
}
|
||||
|
@ -1667,8 +1696,8 @@ pure fn kind_is_owned(k: kind) -> bool {
|
|||
*k & KIND_MASK_OWNED == KIND_MASK_OWNED
|
||||
}
|
||||
|
||||
fn proto_kind(p: fn_proto) -> kind {
|
||||
match p {
|
||||
fn meta_kind(p: FnMeta) -> kind {
|
||||
match p.proto { // XXX consider the kind bounds!
|
||||
proto_vstore(vstore_slice(_)) =>
|
||||
kind_noncopyable() | kind_(KIND_MASK_DEFAULT_MODE),
|
||||
proto_vstore(vstore_box) =>
|
||||
|
@ -1753,7 +1782,7 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
|
|||
}
|
||||
|
||||
// functions depend on the protocol
|
||||
ty_fn(ref f) => proto_kind(f.proto),
|
||||
ty_fn(ref f) => meta_kind(f.meta),
|
||||
|
||||
// Those with refcounts raise noncopyable to copyable,
|
||||
// lower sendable to copyable. Therefore just set result to copyable.
|
||||
|
@ -2361,8 +2390,10 @@ pure fn hash_type_structure(st: &sty) -> uint {
|
|||
}
|
||||
ty_fn(ref f) => {
|
||||
let mut h = 27u;
|
||||
for vec::each(f.inputs) |a| { h = hash_subty(h, a.ty); }
|
||||
hash_subty(h, f.output)
|
||||
for vec::each(f.sig.inputs) |a| {
|
||||
h = hash_subty(h, a.ty);
|
||||
}
|
||||
hash_subty(h, f.sig.output)
|
||||
}
|
||||
ty_self => 28u,
|
||||
ty_infer(v) => hash_uint(29u, v.to_hash()),
|
||||
|
@ -2415,35 +2446,35 @@ fn node_id_has_type_params(cx: ctxt, id: ast::node_id) -> bool {
|
|||
// Type accessors for substructures of types
|
||||
fn ty_fn_args(fty: t) -> ~[arg] {
|
||||
match get(fty).struct {
|
||||
ty_fn(ref f) => f.inputs,
|
||||
ty_fn(ref f) => f.sig.inputs,
|
||||
_ => fail ~"ty_fn_args() called on non-fn type"
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_fn_proto(fty: t) -> fn_proto {
|
||||
match get(fty).struct {
|
||||
ty_fn(ref f) => f.proto,
|
||||
ty_fn(ref f) => f.meta.proto,
|
||||
_ => fail ~"ty_fn_proto() called on non-fn type"
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_fn_purity(fty: t) -> ast::purity {
|
||||
match get(fty).struct {
|
||||
ty_fn(ref f) => f.purity,
|
||||
ty_fn(ref f) => f.meta.purity,
|
||||
_ => fail ~"ty_fn_purity() called on non-fn type"
|
||||
}
|
||||
}
|
||||
|
||||
pure fn ty_fn_ret(fty: t) -> t {
|
||||
match get(fty).struct {
|
||||
ty_fn(ref f) => f.output,
|
||||
ty_fn(ref f) => f.sig.output,
|
||||
_ => fail ~"ty_fn_ret() called on non-fn type"
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_fn_ret_style(fty: t) -> ast::ret_style {
|
||||
match get(fty).struct {
|
||||
ty_fn(ref f) => f.ret_style,
|
||||
ty_fn(ref f) => f.meta.ret_style,
|
||||
_ => fail ~"ty_fn_ret_style() called on non-fn type"
|
||||
}
|
||||
}
|
||||
|
@ -2463,8 +2494,8 @@ fn ty_region(ty: t) -> region {
|
|||
}
|
||||
|
||||
// Returns a vec of all the input and output types of fty.
|
||||
fn tys_in_fn_ty(fty: &fn_ty) -> ~[t] {
|
||||
vec::append_one(fty.inputs.map(|a| a.ty), fty.output)
|
||||
fn tys_in_fn_ty(fty: &FnTy) -> ~[t] {
|
||||
vec::append_one(fty.sig.inputs.map(|a| a.ty), fty.sig.output)
|
||||
}
|
||||
|
||||
// Just checks whether it's a fn that returns bool,
|
||||
|
@ -2474,14 +2505,14 @@ fn is_pred_ty(fty: t) -> bool {
|
|||
}
|
||||
|
||||
/*
|
||||
fn ty_var_id(typ: t) -> ty_vid {
|
||||
fn ty_var_id(typ: t) -> TyVid {
|
||||
match get(typ).struct {
|
||||
ty_infer(TyVar(vid)) => return vid,
|
||||
_ => { error!("ty_var_id called on non-var ty"); fail; }
|
||||
}
|
||||
}
|
||||
|
||||
fn int_var_id(typ: t) -> int_vid {
|
||||
fn int_var_id(typ: t) -> IntVid {
|
||||
match get(typ).struct {
|
||||
ty_infer(IntVar(vid)) => return vid,
|
||||
_ => { error!("ty_var_integral_id called on ty other than \
|
||||
|
@ -2765,11 +2796,11 @@ fn param_tys_in_type(ty: t) -> ~[param_ty] {
|
|||
rslt
|
||||
}
|
||||
|
||||
fn occurs_check(tcx: ctxt, sp: span, vid: ty_vid, rt: t) {
|
||||
fn occurs_check(tcx: ctxt, sp: span, vid: TyVid, rt: t) {
|
||||
|
||||
// Returns a vec of all the type variables occurring in `ty`. It may
|
||||
// contain duplicates. (Integral type vars aren't counted.)
|
||||
fn vars_in_type(ty: t) -> ~[ty_vid] {
|
||||
fn vars_in_type(ty: t) -> ~[TyVid] {
|
||||
let mut rslt = ~[];
|
||||
do walk_ty(ty) |ty| {
|
||||
match get(ty).struct {
|
||||
|
@ -3561,20 +3592,16 @@ fn normalize_ty(cx: ctxt, t: t) -> t {
|
|||
// This type has a region. Get rid of it
|
||||
mk_rptr(cx, re_static, normalize_mt(cx, mt)),
|
||||
|
||||
ty_fn({purity: purity,
|
||||
proto: proto_vstore(vstore),
|
||||
bounds: bounds,
|
||||
inputs: inputs,
|
||||
output: output,
|
||||
ret_style: ret_style}) =>
|
||||
mk_fn(cx, {
|
||||
purity: purity,
|
||||
proto: proto_vstore(normalize_vstore(vstore)),
|
||||
bounds: bounds,
|
||||
inputs: inputs,
|
||||
output: output,
|
||||
ret_style: ret_style
|
||||
}),
|
||||
ty_fn(ref fn_ty) => {
|
||||
let proto = match fn_ty.meta.proto {
|
||||
proto_bare => proto_bare,
|
||||
proto_vstore(vstore) => proto_vstore(normalize_vstore(vstore))
|
||||
};
|
||||
mk_fn(cx, FnTyBase {
|
||||
meta: FnMeta {proto: proto, ..fn_ty.meta},
|
||||
sig: fn_ty.sig
|
||||
})
|
||||
}
|
||||
|
||||
ty_enum(did, r) =>
|
||||
match r.self_r {
|
||||
|
@ -3708,31 +3735,48 @@ impl vstore : cmp::Eq {
|
|||
}
|
||||
}
|
||||
|
||||
impl fn_ty : cmp::Eq {
|
||||
pure fn eq(&&other: fn_ty) -> bool {
|
||||
impl FnMeta : cmp::Eq {
|
||||
pure fn eq(&&other: FnMeta) -> bool {
|
||||
self.purity == other.purity &&
|
||||
self.proto == other.proto &&
|
||||
self.bounds == other.bounds &&
|
||||
self.inputs == other.inputs &&
|
||||
self.output == other.output &&
|
||||
self.ret_style == other.ret_style
|
||||
}
|
||||
}
|
||||
|
||||
impl ty_vid: cmp::Eq {
|
||||
pure fn eq(&&other: ty_vid) -> bool {
|
||||
impl FnSig : cmp::Eq {
|
||||
pure fn eq(&&other: FnSig) -> bool {
|
||||
self.inputs == other.inputs &&
|
||||
self.output == other.output
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: cmp::Eq> FnTyBase<M> : cmp::Eq {
|
||||
pure fn eq(&&other: FnTyBase<M>) -> bool {
|
||||
self.meta == other.meta && self.sig == other.sig
|
||||
}
|
||||
}
|
||||
|
||||
impl TyVid: cmp::Eq {
|
||||
pure fn eq(&&other: TyVid) -> bool {
|
||||
*self == *other
|
||||
}
|
||||
}
|
||||
|
||||
impl int_vid: cmp::Eq {
|
||||
pure fn eq(&&other: int_vid) -> bool {
|
||||
impl IntVid: cmp::Eq {
|
||||
pure fn eq(&&other: IntVid) -> bool {
|
||||
*self == *other
|
||||
}
|
||||
}
|
||||
|
||||
impl region_vid: cmp::Eq {
|
||||
pure fn eq(&&other: region_vid) -> bool {
|
||||
impl FnVid: cmp::Eq {
|
||||
pure fn eq(&&other: FnVid) -> bool {
|
||||
*self == *other
|
||||
}
|
||||
}
|
||||
|
||||
impl RegionVid: cmp::Eq {
|
||||
pure fn eq(&&other: RegionVid) -> bool {
|
||||
*self == *other
|
||||
}
|
||||
}
|
||||
|
|
|
@ -255,38 +255,40 @@ fn check_main_fn_ty(ccx: @crate_ctxt,
|
|||
let tcx = ccx.tcx;
|
||||
let main_t = ty::node_id_to_type(tcx, main_id);
|
||||
match ty::get(main_t).struct {
|
||||
ty::ty_fn({purity: ast::impure_fn, proto: ty::proto_bare,
|
||||
inputs, output, ret_style: ast::return_val, _}) => {
|
||||
match tcx.items.find(main_id) {
|
||||
Some(ast_map::node_item(it,_)) => {
|
||||
match it.node {
|
||||
ast::item_fn(_,_,ps,_) if vec::is_not_empty(ps) => {
|
||||
tcx.sess.span_err(main_span,
|
||||
~"main function is not allowed to have type parameters");
|
||||
return;
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
let mut ok = ty::type_is_nil(output);
|
||||
let num_args = vec::len(inputs);
|
||||
ok &= num_args == 0u || num_args == 1u &&
|
||||
arg_is_argv_ty(tcx, inputs[0]);
|
||||
if !ok {
|
||||
tcx.sess.span_err(main_span,
|
||||
fmt!("Wrong type in main function: found `%s`, \
|
||||
expected `extern fn(~[str]) -> ()` \
|
||||
or `extern fn() -> ()`",
|
||||
ty::ty_fn(fn_ty) => {
|
||||
match tcx.items.find(main_id) {
|
||||
Some(ast_map::node_item(it,_)) => {
|
||||
match it.node {
|
||||
ast::item_fn(_,_,ps,_) if vec::is_not_empty(ps) => {
|
||||
tcx.sess.span_err(
|
||||
main_span,
|
||||
~"main function is not allowed \
|
||||
to have type parameters");
|
||||
return;
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
let mut ok = ty::type_is_nil(fn_ty.sig.output);
|
||||
let num_args = vec::len(fn_ty.sig.inputs);
|
||||
ok &= num_args == 0u || num_args == 1u &&
|
||||
arg_is_argv_ty(tcx, fn_ty.sig.inputs[0]);
|
||||
if !ok {
|
||||
tcx.sess.span_err(
|
||||
main_span,
|
||||
fmt!("Wrong type in main function: found `%s`, \
|
||||
expected `extern fn(~[str]) -> ()` \
|
||||
or `extern fn() -> ()`",
|
||||
ty_to_str(tcx, main_t)));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.span_bug(main_span,
|
||||
~"main has a non-function type: found `" +
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.span_bug(main_span,
|
||||
~"main has a non-function type: found `" +
|
||||
ty_to_str(tcx, main_t) + ~"`");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
use check::fn_ctxt;
|
||||
use rscope::{anon_rscope, binding_rscope, empty_rscope, in_anon_rscope};
|
||||
use rscope::{in_binding_rscope, region_scope, type_rscope};
|
||||
use ty::{FnTyBase, FnMeta, FnSig};
|
||||
|
||||
trait ast_conv {
|
||||
fn tcx() -> ty::ctxt;
|
||||
|
@ -471,7 +472,7 @@ fn ty_of_fn_decl<AC: ast_conv, RS: region_scope copy owned>(
|
|||
bounds: @~[ty::param_bound],
|
||||
decl: ast::fn_decl,
|
||||
expected_tys: expected_tys,
|
||||
span: span) -> ty::fn_ty {
|
||||
span: span) -> ty::FnTy {
|
||||
|
||||
debug!("ty_of_fn_decl");
|
||||
do indent {
|
||||
|
@ -497,8 +498,14 @@ fn ty_of_fn_decl<AC: ast_conv, RS: region_scope copy owned>(
|
|||
|
||||
let proto = ast_proto_to_proto(self, rscope, span, ast_proto);
|
||||
|
||||
{purity: purity, proto: proto, bounds: bounds, inputs: input_tys,
|
||||
output: output_ty, ret_style: decl.cf}
|
||||
FnTyBase {
|
||||
meta: FnMeta {purity: purity,
|
||||
proto: proto,
|
||||
bounds: bounds,
|
||||
ret_style: decl.cf},
|
||||
sig: FnSig {inputs: input_tys,
|
||||
output: output_ty}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ type parameter).
|
|||
|
||||
use astconv::{ast_conv, ast_path_to_ty, ast_ty_to_ty};
|
||||
use astconv::{ast_region_to_region};
|
||||
use middle::ty::{ty_vid, vid};
|
||||
use middle::ty::{TyVid, vid, FnTyBase, FnMeta, FnSig};
|
||||
use regionmanip::{replace_bound_regions_in_fn_ty};
|
||||
use rscope::{anon_rscope, binding_rscope, empty_rscope, in_anon_rscope};
|
||||
use rscope::{in_binding_rscope, region_scope, type_rscope,
|
||||
|
@ -98,7 +98,7 @@ type self_info = {
|
|||
/// share the inherited fields.
|
||||
struct inherited {
|
||||
infcx: infer::infer_ctxt;
|
||||
locals: hashmap<ast::node_id, ty_vid>;
|
||||
locals: hashmap<ast::node_id, TyVid>;
|
||||
node_types: hashmap<ast::node_id, ty::t>;
|
||||
node_type_substs: hashmap<ast::node_id, ty::substs>;
|
||||
borrowings: hashmap<ast::node_id, ty::borrow>;
|
||||
|
@ -211,7 +211,7 @@ fn check_bare_fn(ccx: @crate_ctxt,
|
|||
|
||||
fn check_fn(ccx: @crate_ctxt,
|
||||
self_info: Option<self_info>,
|
||||
fn_ty: &ty::fn_ty,
|
||||
fn_ty: &ty::FnTy,
|
||||
decl: ast::fn_decl,
|
||||
body: ast::blk,
|
||||
indirect_ret: bool,
|
||||
|
@ -231,8 +231,8 @@ fn check_fn(ccx: @crate_ctxt,
|
|||
|br| ty::re_free(body.node.id, br))
|
||||
};
|
||||
|
||||
let arg_tys = fn_ty.inputs.map(|a| a.ty);
|
||||
let ret_ty = fn_ty.output;
|
||||
let arg_tys = fn_ty.sig.inputs.map(|a| a.ty);
|
||||
let ret_ty = fn_ty.sig.output;
|
||||
|
||||
debug!("check_fn(arg_tys=%?, ret_ty=%?, self_info.self_ty=%?)",
|
||||
arg_tys.map(|a| ty_to_str(tcx, a)),
|
||||
|
@ -245,12 +245,12 @@ fn check_fn(ccx: @crate_ctxt,
|
|||
let fcx: @fn_ctxt = {
|
||||
let (purity, inherited) = match old_fcx {
|
||||
None => {
|
||||
(fn_ty.purity,
|
||||
(fn_ty.meta.purity,
|
||||
blank_inherited(ccx))
|
||||
}
|
||||
Some(fcx) => {
|
||||
(ty::determine_inherited_purity(fcx.purity, fn_ty.purity,
|
||||
fn_ty.proto),
|
||||
(ty::determine_inherited_purity(fcx.purity, fn_ty.meta.purity,
|
||||
fn_ty.meta.proto),
|
||||
fcx.inh)
|
||||
}
|
||||
};
|
||||
|
@ -943,9 +943,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
|||
|
||||
// Grab the argument types, supplying fresh type variables
|
||||
// if the wrong number of arguments were supplied
|
||||
let expected_arg_count = vec::len(fn_ty.inputs);
|
||||
let expected_arg_count = vec::len(fn_ty.sig.inputs);
|
||||
let arg_tys = if expected_arg_count == supplied_arg_count {
|
||||
fn_ty.inputs.map(|a| a.ty)
|
||||
fn_ty.sig.inputs.map(|a| a.ty)
|
||||
} else {
|
||||
fcx.ccx.tcx.sess.span_err(
|
||||
sp, fmt!("this function takes %u parameter%s but %u \
|
||||
|
@ -1031,9 +1031,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
|||
|
||||
// Pull the return type out of the type of the function.
|
||||
match structure_of(fcx, sp, fty) {
|
||||
ty::ty_fn(f) => {
|
||||
bot |= (f.ret_style == ast::noreturn);
|
||||
fcx.write_ty(call_expr_id, f.output);
|
||||
ty::ty_fn(ref f) => {
|
||||
bot |= (f.meta.ret_style == ast::noreturn);
|
||||
fcx.write_ty(call_expr_id, f.sig.output);
|
||||
return bot;
|
||||
}
|
||||
_ => fcx.ccx.tcx.sess.span_fatal(sp, ~"calling non-function")
|
||||
|
@ -1242,10 +1242,10 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
|||
replace_bound_regions_in_fn_ty(
|
||||
tcx, @Nil, None, fn_ty,
|
||||
|br| ty::re_bound(ty::br_cap_avoid(expr.id, @br)));
|
||||
(Some({inputs:fn_ty.inputs,
|
||||
output:fn_ty.output}),
|
||||
fn_ty.purity,
|
||||
fn_ty.proto)
|
||||
(Some({inputs: fn_ty.sig.inputs,
|
||||
output: fn_ty.sig.output}),
|
||||
fn_ty.meta.purity,
|
||||
fn_ty.meta.proto)
|
||||
}
|
||||
_ => {
|
||||
(None, ast::impure_fn, ty::proto_vstore(ty::vstore_box))
|
||||
|
@ -1268,8 +1268,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
|||
// Patch up the function declaration, if necessary.
|
||||
match ast_proto_opt {
|
||||
None => {
|
||||
fn_ty.purity = expected_purity;
|
||||
fn_ty.proto = expected_proto;
|
||||
fn_ty.meta.purity = expected_purity;
|
||||
fn_ty.meta.proto = expected_proto;
|
||||
}
|
||||
Some(_) => { }
|
||||
}
|
||||
|
@ -1643,16 +1643,20 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
|||
let inner_ty = match expected_sty {
|
||||
Some(ty::ty_fn(fty)) => {
|
||||
match fcx.mk_subty(false, expr.span,
|
||||
fty.output, ty::mk_bool(tcx)) {
|
||||
fty.sig.output, ty::mk_bool(tcx)) {
|
||||
result::Ok(_) => (),
|
||||
result::Err(_) => {
|
||||
tcx.sess.span_fatal(
|
||||
expr.span, fmt!("a `loop` function's last argument \
|
||||
should return `bool`, not `%s`",
|
||||
fcx.infcx().ty_to_str(fty.output)));
|
||||
fcx.infcx().ty_to_str(fty.sig.output)));
|
||||
}
|
||||
}
|
||||
ty::mk_fn(tcx, {output: ty::mk_nil(tcx),.. fty})
|
||||
ty::mk_fn(tcx, FnTyBase {
|
||||
meta: fty.meta,
|
||||
sig: FnSig {output: ty::mk_nil(tcx),
|
||||
..fty.sig}
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.span_fatal(expr.span, ~"a `loop` function's last \
|
||||
|
@ -1675,8 +1679,11 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
|||
fcx, expr.span, fcx.node_ty(b.id));
|
||||
match ty::get(block_ty).struct {
|
||||
ty::ty_fn(fty) => {
|
||||
fcx.write_ty(expr.id, ty::mk_fn(tcx, {output: ty::mk_bool(tcx),
|
||||
.. fty}));
|
||||
fcx.write_ty(expr.id, ty::mk_fn(tcx, FnTyBase {
|
||||
meta: fty.meta,
|
||||
sig: FnSig {output: ty::mk_bool(tcx),
|
||||
..fty.sig}
|
||||
}))
|
||||
}
|
||||
_ => fail ~"expected fn type"
|
||||
}
|
||||
|
@ -2306,7 +2313,7 @@ fn self_ref(fcx: @fn_ctxt, id: ast::node_id) -> bool {
|
|||
ast_util::is_self)
|
||||
}
|
||||
|
||||
fn lookup_local(fcx: @fn_ctxt, sp: span, id: ast::node_id) -> ty_vid {
|
||||
fn lookup_local(fcx: @fn_ctxt, sp: span, id: ast::node_id) -> TyVid {
|
||||
match fcx.inh.locals.find(id) {
|
||||
Some(x) => x,
|
||||
_ => {
|
||||
|
@ -2571,20 +2578,18 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
|
|||
arg(ast::by_ref, visitor_trait)], ty::mk_nil(tcx))
|
||||
}
|
||||
~"frame_address" => {
|
||||
let fty = ty::mk_fn(ccx.tcx, {
|
||||
purity: ast::impure_fn,
|
||||
proto:
|
||||
ty::proto_vstore(ty::vstore_slice(
|
||||
ty::re_bound(ty::br_anon(0)))),
|
||||
bounds: @~[],
|
||||
inputs: ~[{
|
||||
mode: ast::expl(ast::by_val),
|
||||
ty: ty::mk_imm_ptr(
|
||||
ccx.tcx,
|
||||
ty::mk_mach_uint(ccx.tcx, ast::ty_u8))
|
||||
}],
|
||||
output: ty::mk_nil(ccx.tcx),
|
||||
ret_style: ast::return_val
|
||||
let fty = ty::mk_fn(ccx.tcx, FnTyBase {
|
||||
meta: FnMeta {purity: ast::impure_fn,
|
||||
proto: ty::proto_vstore(ty::vstore_slice(
|
||||
ty::re_bound(ty::br_anon(0)))),
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val},
|
||||
sig: FnSig {inputs: ~[{mode: ast::expl(ast::by_val),
|
||||
ty: ty::mk_imm_ptr(
|
||||
ccx.tcx,
|
||||
ty::mk_mach_uint(ccx.tcx, ast::ty_u8))
|
||||
}],
|
||||
output: ty::mk_nil(ccx.tcx)}
|
||||
});
|
||||
(0u, ~[arg(ast::by_ref, fty)], ty::mk_nil(tcx))
|
||||
}
|
||||
|
@ -2597,11 +2602,14 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
|
|||
return;
|
||||
}
|
||||
};
|
||||
let fty = ty::mk_fn(tcx, {purity: ast::impure_fn,
|
||||
proto: ty::proto_bare,
|
||||
bounds: @~[],
|
||||
inputs: inputs, output: output,
|
||||
ret_style: ast::return_val});
|
||||
let fty = ty::mk_fn(tcx, FnTyBase {
|
||||
meta: FnMeta {purity: ast::impure_fn,
|
||||
proto: ty::proto_bare,
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val},
|
||||
sig: FnSig {inputs: inputs,
|
||||
output: output}
|
||||
});
|
||||
let i_ty = ty::lookup_item_type(ccx.tcx, local_def(it.id));
|
||||
let i_n_tps = (*i_ty.bounds).len();
|
||||
if i_n_tps != n_tps {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use coherence::get_base_type_def_id;
|
||||
use middle::resolve::{Impl, MethodInfo};
|
||||
use middle::ty::{mk_box, mk_rptr, mk_uniq};
|
||||
use middle::ty::{mk_box, mk_rptr, mk_uniq, FnTyBase, FnMeta, FnSig};
|
||||
use syntax::ast::{def_id,
|
||||
sty_static, sty_box, sty_by_ref, sty_region, sty_uniq};
|
||||
use syntax::ast::{sty_value, by_ref, by_copy};
|
||||
|
@ -411,9 +411,12 @@ struct lookup {
|
|||
|
||||
fn ty_from_did(did: ast::def_id) -> ty::t {
|
||||
match ty::get(ty::lookup_item_type(self.tcx(), did).ty).struct {
|
||||
ty::ty_fn(fty) => {
|
||||
ty::mk_fn(self.tcx(),
|
||||
{proto: ty::proto_vstore(ty::vstore_box),.. fty})
|
||||
ty::ty_fn(ref fty) => {
|
||||
ty::mk_fn(self.tcx(), FnTyBase {
|
||||
meta: FnMeta {proto: ty::proto_vstore(ty::vstore_box),
|
||||
..fty.meta},
|
||||
sig: fty.sig
|
||||
})
|
||||
}
|
||||
_ => fail ~"ty_from_did: not function ty"
|
||||
}
|
||||
|
@ -553,8 +556,11 @@ struct lookup {
|
|||
|
||||
// a bit hokey, but the method unbound has a bare protocol, whereas
|
||||
// a.b has a protocol like fn@() (perhaps eventually fn&()):
|
||||
let fty = ty::mk_fn(tcx, {proto: ty::proto_vstore(ty::vstore_box),
|
||||
.. m.fty});
|
||||
let fty = ty::mk_fn(tcx, FnTyBase {
|
||||
meta: FnMeta {proto: ty::proto_vstore(ty::vstore_box),
|
||||
..m.fty.meta},
|
||||
sig: m.fty.sig
|
||||
});
|
||||
|
||||
self.candidates.push(
|
||||
{self_ty: self.self_ty,
|
||||
|
|
|
@ -216,10 +216,13 @@ fn visit_expr(e: @ast::expr, &&rcx: @rcx, v: rvt) {
|
|||
result::Err(_) => return, // Typechecking will fail anyhow.
|
||||
result::Ok(function_type) => {
|
||||
match ty::get(function_type).struct {
|
||||
ty::ty_fn({
|
||||
proto: proto_vstore(vstore_slice(region)), _
|
||||
}) => {
|
||||
constrain_free_variables(rcx, region, e);
|
||||
ty::ty_fn(ref fn_ty) => {
|
||||
match fn_ty.meta.proto {
|
||||
proto_vstore(vstore_slice(region)) => {
|
||||
constrain_free_variables(rcx, region, e);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@ fn replace_bound_regions_in_fn_ty(
|
|||
tcx: ty::ctxt,
|
||||
isr: isr_alist,
|
||||
self_info: Option<self_info>,
|
||||
fn_ty: &ty::fn_ty,
|
||||
fn_ty: &ty::FnTy,
|
||||
mapf: fn(ty::bound_region) -> ty::region) ->
|
||||
{isr: isr_alist, self_info: Option<self_info>, fn_ty: ty::fn_ty} {
|
||||
{isr: isr_alist, self_info: Option<self_info>, fn_ty: ty::FnTy} {
|
||||
|
||||
// Take self_info apart; the self_ty part is the only one we want
|
||||
// to update here.
|
||||
|
|
|
@ -23,6 +23,7 @@ are represented as `ty_param()` instances.
|
|||
use astconv::{ast_conv, ty_of_fn_decl, ty_of_arg, ast_ty_to_ty};
|
||||
use ast_util::trait_method_to_ty_method;
|
||||
use rscope::*;
|
||||
use ty::{FnTyBase, FnMeta, FnSig};
|
||||
|
||||
fn collect_item_types(ccx: @crate_ctxt, crate: @ast::crate) {
|
||||
|
||||
|
@ -127,14 +128,14 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
|
|||
let arg_ty = ccx.to_ty(rs, va.ty);
|
||||
{mode: ast::expl(ast::by_copy), ty: arg_ty}
|
||||
});
|
||||
result_ty = Some(ty::mk_fn(tcx,
|
||||
{purity: ast::pure_fn,
|
||||
proto: ty::proto_vstore
|
||||
(ty::vstore_box),
|
||||
bounds: @~[],
|
||||
inputs: args,
|
||||
output: enum_ty,
|
||||
ret_style: ast::return_val}));
|
||||
result_ty = Some(ty::mk_fn(tcx, FnTyBase {
|
||||
meta: FnMeta {purity: ast::pure_fn,
|
||||
proto: ty::proto_vstore(ty::vstore_box),
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val},
|
||||
sig: FnSig {inputs: args,
|
||||
output: enum_ty}
|
||||
}));
|
||||
}
|
||||
ast::tuple_variant_kind(_) | ast::struct_variant_kind(_) => {
|
||||
result_ty = Some(enum_ty);
|
||||
|
@ -247,7 +248,7 @@ fn compare_impl_method(tcx: ty::ctxt, sp: span,
|
|||
trait_m: ty::method, trait_substs: ty::substs,
|
||||
self_ty: ty::t) {
|
||||
|
||||
if impl_m.fty.purity != trait_m.fty.purity {
|
||||
if impl_m.fty.meta.purity != trait_m.fty.meta.purity {
|
||||
tcx.sess.span_err(
|
||||
sp, fmt!("method `%s`'s purity does \
|
||||
not match the trait method's \
|
||||
|
@ -268,12 +269,12 @@ fn compare_impl_method(tcx: ty::ctxt, sp: span,
|
|||
return;
|
||||
}
|
||||
|
||||
if vec::len(impl_m.fty.inputs) != vec::len(trait_m.fty.inputs) {
|
||||
if vec::len(impl_m.fty.sig.inputs) != vec::len(trait_m.fty.sig.inputs) {
|
||||
tcx.sess.span_err(sp,fmt!("method `%s` has %u parameters \
|
||||
but the trait has %u",
|
||||
tcx.sess.str_of(trait_m.ident),
|
||||
vec::len(impl_m.fty.inputs),
|
||||
vec::len(trait_m.fty.inputs)));
|
||||
vec::len(impl_m.fty.sig.inputs),
|
||||
vec::len(trait_m.fty.sig.inputs)));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -488,13 +489,15 @@ fn convert_struct(ccx: @crate_ctxt,
|
|||
{self_r: rscope::bound_self_region(rp),
|
||||
self_ty: None,
|
||||
tps: ty::ty_params_to_tys(tcx, tps)});
|
||||
let t_ctor = ty::mk_fn(
|
||||
tcx, {purity: ast::impure_fn,
|
||||
proto: ty::proto_vstore(ty::vstore_slice(ty::re_static)),
|
||||
bounds: @~[],
|
||||
inputs: t_args,
|
||||
output: t_res,
|
||||
ret_style: ast::return_val});
|
||||
let proto = ty::proto_vstore(ty::vstore_slice(ty::re_static));
|
||||
let t_ctor = ty::mk_fn(tcx, FnTyBase {
|
||||
meta: FnMeta {purity: ast::impure_fn,
|
||||
proto: proto,
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val},
|
||||
sig: FnSig {inputs: t_args,
|
||||
output: t_res}
|
||||
});
|
||||
write_ty_to_tcx(tcx, ctor.node.id, t_ctor);
|
||||
tcx.tcache.insert(local_def(ctor.node.id),
|
||||
{bounds: tpt.bounds,
|
||||
|
@ -755,12 +758,14 @@ fn ty_of_foreign_fn_decl(ccx: @crate_ctxt,
|
|||
let input_tys = decl.inputs.map(|a| ty_of_arg(ccx, rb, a, None) );
|
||||
let output_ty = ast_ty_to_ty(ccx, rb, decl.output);
|
||||
|
||||
let t_fn = ty::mk_fn(ccx.tcx, {purity: purity,
|
||||
proto: ty::proto_bare,
|
||||
bounds: @~[],
|
||||
inputs: input_tys,
|
||||
output: output_ty,
|
||||
ret_style: ast::return_val});
|
||||
let t_fn = ty::mk_fn(ccx.tcx, FnTyBase {
|
||||
meta: FnMeta {purity: purity,
|
||||
proto: ty::proto_bare,
|
||||
bounds: @~[],
|
||||
ret_style: ast::return_val},
|
||||
sig: FnSig {inputs: input_tys,
|
||||
output: output_ty}
|
||||
});
|
||||
let tpt = {bounds: bounds, region_param: None, ty: t_fn};
|
||||
ccx.tcx.tcache.insert(def_id, tpt);
|
||||
return tpt;
|
||||
|
|
|
@ -250,7 +250,7 @@ use std::smallintmap;
|
|||
use std::smallintmap::smallintmap;
|
||||
use std::map::hashmap;
|
||||
use middle::ty;
|
||||
use middle::ty::{ty_vid, int_vid, region_vid, vid,
|
||||
use middle::ty::{TyVid, IntVid, RegionVid, vid,
|
||||
ty_int, ty_uint, get, terr_fn, TyVar, IntVar};
|
||||
use syntax::{ast, ast_util};
|
||||
use syntax::ast::{ret_style, purity};
|
||||
|
@ -312,11 +312,11 @@ enum infer_ctxt = @{
|
|||
// We instantiate vals_and_bindings with bounds<ty::t> because the
|
||||
// types that might instantiate a general type variable have an
|
||||
// order, represented by its upper and lower bounds.
|
||||
ty_var_bindings: vals_and_bindings<ty::ty_vid, bounds<ty::t>>,
|
||||
ty_var_bindings: vals_and_bindings<ty::TyVid, bounds<ty::t>>,
|
||||
|
||||
// The types that might instantiate an integral type variable are
|
||||
// represented by an int_ty_set.
|
||||
int_var_bindings: vals_and_bindings<ty::int_vid, int_ty_set>,
|
||||
int_var_bindings: vals_and_bindings<ty::IntVid, int_ty_set>,
|
||||
|
||||
// For region variables.
|
||||
region_vars: RegionVarBindings,
|
||||
|
@ -328,11 +328,11 @@ enum infer_ctxt = @{
|
|||
};
|
||||
|
||||
enum fixup_err {
|
||||
unresolved_int_ty(int_vid),
|
||||
unresolved_ty(ty_vid),
|
||||
cyclic_ty(ty_vid),
|
||||
unresolved_region(region_vid),
|
||||
region_var_bound_by_region_var(region_vid, region_vid)
|
||||
unresolved_int_ty(IntVid),
|
||||
unresolved_ty(TyVid),
|
||||
cyclic_ty(TyVid),
|
||||
unresolved_region(RegionVid),
|
||||
region_var_bound_by_region_var(RegionVid, RegionVid)
|
||||
}
|
||||
|
||||
fn fixup_err_to_str(f: fixup_err) -> ~str {
|
||||
|
@ -596,12 +596,12 @@ impl infer_ctxt {
|
|||
}
|
||||
|
||||
impl infer_ctxt {
|
||||
fn next_ty_var_id() -> ty_vid {
|
||||
fn next_ty_var_id() -> TyVid {
|
||||
let id = *self.ty_var_counter;
|
||||
*self.ty_var_counter += 1u;
|
||||
self.ty_var_bindings.vals.insert(id,
|
||||
root({lb: None, ub: None}, 0u));
|
||||
return ty_vid(id);
|
||||
return TyVid(id);
|
||||
}
|
||||
|
||||
fn next_ty_var() -> ty::t {
|
||||
|
@ -612,13 +612,13 @@ impl infer_ctxt {
|
|||
vec::from_fn(n, |_i| self.next_ty_var())
|
||||
}
|
||||
|
||||
fn next_int_var_id() -> int_vid {
|
||||
fn next_int_var_id() -> IntVid {
|
||||
let id = *self.int_var_counter;
|
||||
*self.int_var_counter += 1u;
|
||||
|
||||
self.int_var_bindings.vals.insert(id,
|
||||
root(int_ty_set_all(), 0u));
|
||||
return int_vid(id);
|
||||
return IntVid(id);
|
||||
}
|
||||
|
||||
fn next_int_var() -> ty::t {
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
// now.
|
||||
|
||||
use to_str::to_str;
|
||||
use ty::{FnTyBase, FnMeta, FnSig};
|
||||
|
||||
trait combine {
|
||||
fn infcx() -> infer_ctxt;
|
||||
|
@ -62,7 +63,9 @@ trait combine {
|
|||
fn self_tys(a: Option<ty::t>, b: Option<ty::t>) -> cres<Option<ty::t>>;
|
||||
fn substs(did: ast::def_id, as: &ty::substs,
|
||||
bs: &ty::substs) -> cres<ty::substs>;
|
||||
fn fns(a: &ty::fn_ty, b: &ty::fn_ty) -> cres<ty::fn_ty>;
|
||||
fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres<ty::FnTy>;
|
||||
fn fn_sigs(a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig>;
|
||||
fn fn_metas(a: &ty::FnMeta, b: &ty::FnMeta) -> cres<ty::FnMeta>;
|
||||
fn flds(a: ty::field, b: ty::field) -> cres<ty::field>;
|
||||
fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode>;
|
||||
fn args(a: ty::arg, b: ty::arg) -> cres<ty::arg>;
|
||||
|
@ -302,37 +305,47 @@ fn super_vstores<C:combine>(
|
|||
}
|
||||
}
|
||||
|
||||
fn super_fns<C:combine>(
|
||||
self: &C, a_f: &ty::fn_ty, b_f: &ty::fn_ty) -> cres<ty::fn_ty> {
|
||||
fn super_fn_metas<C:combine>(
|
||||
self: &C, a_f: &ty::FnMeta, b_f: &ty::FnMeta) -> cres<ty::FnMeta>
|
||||
{
|
||||
do self.protos(a_f.proto, b_f.proto).chain |p| {
|
||||
do self.ret_styles(a_f.ret_style, b_f.ret_style).chain |rs| {
|
||||
do self.purities(a_f.purity, b_f.purity).chain |purity| {
|
||||
Ok(FnMeta {purity: purity,
|
||||
proto: p,
|
||||
bounds: a_f.bounds, // XXX: This is wrong!
|
||||
ret_style: rs})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn super_fn_sigs<C:combine>(
|
||||
self: &C, a_f: &ty::FnSig, b_f: &ty::FnSig) -> cres<ty::FnSig>
|
||||
{
|
||||
fn argvecs<C:combine>(self: &C, a_args: ~[ty::arg],
|
||||
b_args: ~[ty::arg]) -> cres<~[ty::arg]> {
|
||||
|
||||
if vec::same_length(a_args, b_args) {
|
||||
map_vec2(a_args, b_args, |a, b| self.args(a, b) )
|
||||
map_vec2(a_args, b_args, |a, b| self.args(a, b))
|
||||
} else {
|
||||
Err(ty::terr_arg_count)
|
||||
}
|
||||
}
|
||||
|
||||
do self.protos(a_f.proto, b_f.proto).chain |p| {
|
||||
do self.ret_styles(a_f.ret_style, b_f.ret_style).chain |rs| {
|
||||
do argvecs(self, a_f.inputs, b_f.inputs).chain |inputs| {
|
||||
do self.tys(a_f.output, b_f.output).chain |output| {
|
||||
do self.purities(a_f.purity, b_f.purity).chain |purity| {
|
||||
// FIXME: uncomment if #2588 doesn't get accepted:
|
||||
// self.infcx().constrvecs(a_f.constraints,
|
||||
// b_f.constraints).then {||
|
||||
Ok({purity: purity,
|
||||
proto: p,
|
||||
bounds: a_f.bounds, // XXX: This is wrong!
|
||||
inputs: inputs,
|
||||
output: output,
|
||||
ret_style: rs})
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
do argvecs(self, a_f.inputs, b_f.inputs).chain |inputs| {
|
||||
do self.tys(a_f.output, b_f.output).chain |output| {
|
||||
Ok(FnSig {inputs: inputs, output: output})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn super_fns<C:combine>(
|
||||
self: &C, a_f: &ty::FnTy, b_f: &ty::FnTy) -> cres<ty::FnTy>
|
||||
{
|
||||
do self.fn_metas(&a_f.meta, &b_f.meta).chain |m| {
|
||||
do self.fn_sigs(&a_f.sig, &b_f.sig).chain |s| {
|
||||
Ok(FnTyBase {meta: m, sig: s})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,10 +147,18 @@ impl Glb: combine {
|
|||
super_args(&self, a, b)
|
||||
}
|
||||
|
||||
fn fns(a: &ty::fn_ty, b: &ty::fn_ty) -> cres<ty::fn_ty> {
|
||||
fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres<ty::FnTy> {
|
||||
super_fns(&self, a, b)
|
||||
}
|
||||
|
||||
fn fn_metas(a: &ty::FnMeta, b: &ty::FnMeta) -> cres<ty::FnMeta> {
|
||||
super_fn_metas(&self, a, b)
|
||||
}
|
||||
|
||||
fn fn_sigs(a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
|
||||
super_fn_sigs(&self, a, b)
|
||||
}
|
||||
|
||||
fn substs(did: ast::def_id,
|
||||
as: &ty::substs,
|
||||
bs: &ty::substs) -> cres<ty::substs> {
|
||||
|
|
|
@ -68,7 +68,7 @@ fn lattice_tys<L:lattice_ops combine>(
|
|||
}
|
||||
|
||||
fn lattice_vars<L:lattice_ops combine>(
|
||||
self: &L, +a_t: ty::t, +a_vid: ty::ty_vid, +b_vid: ty::ty_vid,
|
||||
self: &L, +a_t: ty::t, +a_vid: ty::TyVid, +b_vid: ty::TyVid,
|
||||
c_ts: fn(ty::t, ty::t) -> cres<ty::t>) -> cres<ty::t> {
|
||||
|
||||
// The comments in this function are written for LUB and types,
|
||||
|
@ -112,7 +112,7 @@ fn lattice_vars<L:lattice_ops combine>(
|
|||
}
|
||||
|
||||
fn lattice_var_and_t<L:lattice_ops combine>(
|
||||
self: &L, a_id: ty::ty_vid, b: ty::t,
|
||||
self: &L, a_id: ty::TyVid, b: ty::t,
|
||||
c_ts: fn(ty::t, ty::t) -> cres<ty::t>) -> cres<ty::t> {
|
||||
|
||||
let vb = &self.infcx().ty_var_bindings;
|
||||
|
|
|
@ -126,10 +126,18 @@ impl Lub: combine {
|
|||
super_args(&self, a, b)
|
||||
}
|
||||
|
||||
fn fns(a: &ty::fn_ty, b: &ty::fn_ty) -> cres<ty::fn_ty> {
|
||||
fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres<ty::FnTy> {
|
||||
super_fns(&self, a, b)
|
||||
}
|
||||
|
||||
fn fn_metas(a: &ty::FnMeta, b: &ty::FnMeta) -> cres<ty::FnMeta> {
|
||||
super_fn_metas(&self, a, b)
|
||||
}
|
||||
|
||||
fn fn_sigs(a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
|
||||
super_fn_sigs(&self, a, b)
|
||||
}
|
||||
|
||||
fn substs(did: ast::def_id,
|
||||
as: &ty::substs,
|
||||
bs: &ty::substs) -> cres<ty::substs> {
|
||||
|
|
|
@ -312,7 +312,7 @@ use std::map::{hashmap, uint_hash};
|
|||
use std::cell::{Cell, empty_cell};
|
||||
use std::list::{List, Nil, Cons};
|
||||
|
||||
use ty::{region, region_vid, hash_region};
|
||||
use ty::{region, RegionVid, hash_region};
|
||||
use region::is_subregion_of;
|
||||
use syntax::codemap;
|
||||
use to_str::to_str;
|
||||
|
@ -324,9 +324,9 @@ export lub_regions;
|
|||
export glb_regions;
|
||||
|
||||
enum Constraint {
|
||||
ConstrainVarSubVar(region_vid, region_vid),
|
||||
ConstrainRegSubVar(region, region_vid),
|
||||
ConstrainVarSubReg(region_vid, region)
|
||||
ConstrainVarSubVar(RegionVid, RegionVid),
|
||||
ConstrainRegSubVar(region, RegionVid),
|
||||
ConstrainVarSubReg(RegionVid, region)
|
||||
}
|
||||
|
||||
impl Constraint: cmp::Eq {
|
||||
|
@ -361,12 +361,12 @@ impl TwoRegions: cmp::Eq {
|
|||
|
||||
enum UndoLogEntry {
|
||||
Snapshot,
|
||||
AddVar(region_vid),
|
||||
AddVar(RegionVid),
|
||||
AddConstraint(Constraint),
|
||||
AddCombination(CombineMap, TwoRegions)
|
||||
}
|
||||
|
||||
type CombineMap = hashmap<TwoRegions, region_vid>;
|
||||
type CombineMap = hashmap<TwoRegions, RegionVid>;
|
||||
|
||||
struct RegionVarBindings {
|
||||
tcx: ty::ctxt;
|
||||
|
@ -470,10 +470,10 @@ impl RegionVarBindings {
|
|||
self.var_spans.len()
|
||||
}
|
||||
|
||||
fn new_region_var(span: span) -> region_vid {
|
||||
fn new_region_var(span: span) -> RegionVid {
|
||||
let id = self.num_vars();
|
||||
self.var_spans.push(span);
|
||||
let vid = region_vid(id);
|
||||
let vid = RegionVid(id);
|
||||
if self.in_snapshot() {
|
||||
self.undo_log.push(AddVar(vid));
|
||||
}
|
||||
|
@ -568,7 +568,7 @@ impl RegionVarBindings {
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_var(rid: region_vid) -> ty::region {
|
||||
fn resolve_var(rid: RegionVid) -> ty::region {
|
||||
debug!("RegionVarBindings: resolve_var(%?)", rid);
|
||||
if self.values.is_empty() {
|
||||
self.tcx.sess.span_bug(
|
||||
|
@ -857,7 +857,7 @@ impl RegionVarBindings {
|
|||
return graph;
|
||||
|
||||
fn insert_edge(graph: &mut Graph,
|
||||
node_id: region_vid,
|
||||
node_id: RegionVid,
|
||||
edge_dir: Direction,
|
||||
edge_idx: uint) {
|
||||
let edge_dir = edge_dir as uint;
|
||||
|
@ -893,7 +893,7 @@ impl RegionVarBindings {
|
|||
}
|
||||
|
||||
fn expand_node(a_region: region,
|
||||
b_vid: region_vid,
|
||||
b_vid: RegionVid,
|
||||
b_node: &GraphNode) -> bool {
|
||||
debug!("expand_node(%?, %? == %?)",
|
||||
a_region, b_vid, b_node.value);
|
||||
|
@ -950,7 +950,7 @@ impl RegionVarBindings {
|
|||
}
|
||||
}
|
||||
|
||||
fn contract_node(a_vid: region_vid,
|
||||
fn contract_node(a_vid: RegionVid,
|
||||
a_node: &GraphNode,
|
||||
b_region: region) -> bool {
|
||||
debug!("contract_node(%? == %?/%?, %?)",
|
||||
|
@ -980,7 +980,7 @@ impl RegionVarBindings {
|
|||
};
|
||||
|
||||
fn check_node(self: &RegionVarBindings,
|
||||
a_vid: region_vid,
|
||||
a_vid: RegionVid,
|
||||
a_node: &GraphNode,
|
||||
a_region: region,
|
||||
b_region: region) -> bool {
|
||||
|
@ -993,7 +993,7 @@ impl RegionVarBindings {
|
|||
}
|
||||
|
||||
fn adjust_node(self: &RegionVarBindings,
|
||||
a_vid: region_vid,
|
||||
a_vid: RegionVid,
|
||||
a_node: &GraphNode,
|
||||
a_region: region,
|
||||
b_region: region) -> bool {
|
||||
|
@ -1051,7 +1051,7 @@ impl RegionVarBindings {
|
|||
}
|
||||
|
||||
ErrorValue => {
|
||||
let node_vid = region_vid(idx);
|
||||
let node_vid = RegionVid(idx);
|
||||
match node.classification {
|
||||
Expanding => {
|
||||
self.report_error_for_expanding_node(
|
||||
|
@ -1078,7 +1078,7 @@ impl RegionVarBindings {
|
|||
|
||||
fn report_error_for_expanding_node(graph: &Graph,
|
||||
dup_map: TwoRegionsMap,
|
||||
node_idx: region_vid) {
|
||||
node_idx: RegionVid) {
|
||||
// Errors in expanding nodes result from a lower-bound that is
|
||||
// not contained by an upper-bound.
|
||||
let lower_bounds =
|
||||
|
@ -1130,7 +1130,7 @@ impl RegionVarBindings {
|
|||
|
||||
fn report_error_for_contracting_node(graph: &Graph,
|
||||
dup_map: TwoRegionsMap,
|
||||
node_idx: region_vid) {
|
||||
node_idx: RegionVid) {
|
||||
// Errors in contracting nodes result from two upper-bounds
|
||||
// that have no intersection.
|
||||
let upper_bounds = self.collect_concrete_regions(graph, node_idx,
|
||||
|
@ -1182,7 +1182,7 @@ impl RegionVarBindings {
|
|||
}
|
||||
|
||||
fn collect_concrete_regions(graph: &Graph,
|
||||
orig_node_idx: region_vid,
|
||||
orig_node_idx: RegionVid,
|
||||
dir: Direction) -> ~[SpannedRegion] {
|
||||
let set = uint_hash();
|
||||
let mut stack = ~[orig_node_idx];
|
||||
|
@ -1224,7 +1224,7 @@ impl RegionVarBindings {
|
|||
}
|
||||
|
||||
fn each_edge(graph: &Graph,
|
||||
node_idx: region_vid,
|
||||
node_idx: RegionVid,
|
||||
dir: Direction,
|
||||
op: fn(edge: &GraphEdge) -> bool) {
|
||||
let mut edge_idx = graph.nodes[*node_idx].head_edge[dir as uint];
|
||||
|
|
|
@ -55,7 +55,7 @@ type resolve_state_ = {
|
|||
infcx: infer_ctxt,
|
||||
modes: uint,
|
||||
mut err: Option<fixup_err>,
|
||||
mut v_seen: ~[ty_vid]
|
||||
mut v_seen: ~[TyVid]
|
||||
};
|
||||
|
||||
enum resolve_state {
|
||||
|
@ -153,14 +153,14 @@ impl resolve_state {
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_region_var(rid: region_vid) -> ty::region {
|
||||
fn resolve_region_var(rid: RegionVid) -> ty::region {
|
||||
if !self.should(resolve_rvar) {
|
||||
return ty::re_var(rid)
|
||||
}
|
||||
self.infcx.region_vars.resolve_var(rid)
|
||||
}
|
||||
|
||||
fn assert_not_rvar(rid: region_vid, r: ty::region) {
|
||||
fn assert_not_rvar(rid: RegionVid, r: ty::region) {
|
||||
match r {
|
||||
ty::re_var(rid2) => {
|
||||
self.err = Some(region_var_bound_by_region_var(rid, rid2));
|
||||
|
@ -169,7 +169,7 @@ impl resolve_state {
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_ty_var(vid: ty_vid) -> ty::t {
|
||||
fn resolve_ty_var(vid: TyVid) -> ty::t {
|
||||
if vec::contains(self.v_seen, vid) {
|
||||
self.err = Some(cyclic_ty(vid));
|
||||
return ty::mk_var(self.infcx.tcx, vid);
|
||||
|
@ -202,7 +202,7 @@ impl resolve_state {
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_int_var(vid: int_vid) -> ty::t {
|
||||
fn resolve_int_var(vid: IntVid) -> ty::t {
|
||||
if !self.should(resolve_ivar) {
|
||||
return ty::mk_int_var(self.infcx.tcx, vid);
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ impl Sub: combine {
|
|||
}
|
||||
}
|
||||
|
||||
fn fns(a: &ty::fn_ty, b: &ty::fn_ty) -> cres<ty::fn_ty> {
|
||||
fn fns(a: &ty::FnTy, b: &ty::FnTy) -> cres<ty::FnTy> {
|
||||
// Rather than checking the subtype relationship between `a` and `b`
|
||||
// as-is, we need to do some extra work here in order to make sure
|
||||
// that function subtyping works correctly with respect to regions
|
||||
|
@ -171,6 +171,14 @@ impl Sub: combine {
|
|||
super_flds(&self, a, b)
|
||||
}
|
||||
|
||||
fn fn_metas(a: &ty::FnMeta, b: &ty::FnMeta) -> cres<ty::FnMeta> {
|
||||
super_fn_metas(&self, a, b)
|
||||
}
|
||||
|
||||
fn fn_sigs(a: &ty::FnSig, b: &ty::FnSig) -> cres<ty::FnSig> {
|
||||
super_fn_sigs(&self, a, b)
|
||||
}
|
||||
|
||||
fn vstores(vk: ty::terr_vstore_kind,
|
||||
a: ty::vstore, b: ty::vstore) -> cres<ty::vstore> {
|
||||
super_vstores(&self, vk, a, b)
|
||||
|
|
|
@ -113,7 +113,7 @@ fn merge_bnds<C: combine>(
|
|||
|
||||
fn set_var_to_merged_bounds<C: combine>(
|
||||
self: &C,
|
||||
v_id: ty::ty_vid,
|
||||
v_id: ty::TyVid,
|
||||
a: bounds<ty::t>,
|
||||
b: bounds<ty::t>,
|
||||
rank: uint) -> ures {
|
||||
|
@ -175,8 +175,8 @@ fn set_var_to_merged_bounds<C: combine>(
|
|||
/// subtle and tricky process, as described in detail at the top
|
||||
/// of infer.rs
|
||||
fn var_sub_var<C: combine>(self: &C,
|
||||
a_id: ty::ty_vid,
|
||||
b_id: ty::ty_vid) -> ures {
|
||||
a_id: ty::TyVid,
|
||||
b_id: ty::TyVid) -> ures {
|
||||
let vb = &self.infcx().ty_var_bindings;
|
||||
|
||||
// Need to make sub_id a subtype of sup_id.
|
||||
|
@ -241,7 +241,7 @@ fn var_sub_var<C: combine>(self: &C,
|
|||
}
|
||||
|
||||
/// make variable a subtype of T
|
||||
fn var_sub_t<C: combine>(self: &C, a_id: ty::ty_vid, b: ty::t) -> ures {
|
||||
fn var_sub_t<C: combine>(self: &C, a_id: ty::TyVid, b: ty::t) -> ures {
|
||||
|
||||
let vb = &self.infcx().ty_var_bindings;
|
||||
let nde_a = self.infcx().get(vb, a_id);
|
||||
|
@ -257,7 +257,7 @@ fn var_sub_t<C: combine>(self: &C, a_id: ty::ty_vid, b: ty::t) -> ures {
|
|||
}
|
||||
|
||||
/// make T a subtype of variable
|
||||
fn t_sub_var<C: combine>(self: &C, a: ty::t, b_id: ty::ty_vid) -> ures {
|
||||
fn t_sub_var<C: combine>(self: &C, a: ty::t, b_id: ty::TyVid) -> ures {
|
||||
|
||||
let vb = &self.infcx().ty_var_bindings;
|
||||
let a_bounds = {lb: Some(a), ub: None};
|
||||
|
@ -294,7 +294,7 @@ fn bnds<C: combine>(
|
|||
// Integral variables
|
||||
|
||||
impl infer_ctxt {
|
||||
fn int_vars(a_id: ty::int_vid, b_id: ty::int_vid) -> ures {
|
||||
fn int_vars(a_id: ty::IntVid, b_id: ty::IntVid) -> ures {
|
||||
let vb = &self.int_var_bindings;
|
||||
|
||||
let nde_a = self.get(vb, a_id);
|
||||
|
@ -340,7 +340,7 @@ impl infer_ctxt {
|
|||
uok()
|
||||
}
|
||||
|
||||
fn int_var_sub_t(a_id: ty::int_vid, b: ty::t) -> ures {
|
||||
fn int_var_sub_t(a_id: ty::IntVid, b: ty::t) -> ures {
|
||||
assert ty::type_is_integral(b);
|
||||
|
||||
let vb = &self.int_var_bindings;
|
||||
|
@ -358,7 +358,7 @@ impl infer_ctxt {
|
|||
uok()
|
||||
}
|
||||
|
||||
fn t_sub_int_var(a: ty::t, b_id: ty::int_vid) -> ures {
|
||||
fn t_sub_int_var(a: ty::t, b_id: ty::IntVid) -> ures {
|
||||
assert ty::type_is_integral(a);
|
||||
let vb = &self.int_var_bindings;
|
||||
|
||||
|
|
|
@ -283,8 +283,9 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str {
|
|||
}
|
||||
fn method_to_str(cx: ctxt, m: method) -> ~str {
|
||||
return fn_to_str(
|
||||
cx, m.fty.purity, m.fty.proto, Some(m.ident), m.fty.inputs,
|
||||
m.fty.output, m.fty.ret_style) + ~";";
|
||||
cx, m.fty.meta.purity, m.fty.meta.proto, Some(m.ident),
|
||||
m.fty.sig.inputs, m.fty.sig.output,
|
||||
m.fty.meta.ret_style) + ~";";
|
||||
}
|
||||
fn field_to_str(cx: ctxt, f: field) -> ~str {
|
||||
return cx.sess.str_of(f.ident) + ~": " + mt_to_str(cx, f.mt);
|
||||
|
@ -331,9 +332,9 @@ fn ty_to_str(cx: ctxt, typ: t) -> ~str {
|
|||
for elems.each |elem| { vec::push(strs, ty_to_str(cx, elem)); }
|
||||
~"(" + str::connect(strs, ~",") + ~")"
|
||||
}
|
||||
ty_fn(f) => {
|
||||
fn_to_str(cx, f.purity, f.proto, None, f.inputs,
|
||||
f.output, f.ret_style)
|
||||
ty_fn(ref f) => {
|
||||
fn_to_str(cx, f.meta.purity, f.meta.proto, None, f.sig.inputs,
|
||||
f.sig.output, f.meta.ret_style)
|
||||
}
|
||||
ty_infer(infer_ty) => infer_ty.to_str(),
|
||||
ty_param({idx: id, _}) => {
|
||||
|
|
Loading…
Reference in a new issue