Refactor fn_ty, working towards #3320

This commit is contained in:
Niko Matsakis 2012-09-07 07:37:19 -07:00
parent 699505899e
commit fb8786fe52
33 changed files with 704 additions and 574 deletions

View file

@ -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. */ }
}

View file

@ -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();
}

View file

@ -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}
};
}

View file

@ -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)
}
}

View file

@ -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)));
}
}
}

View file

@ -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,

View file

@ -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")
};

View file

@ -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(

View file

@ -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);
}
_ => {

View file

@ -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};

View file

@ -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
}
}
}

View file

@ -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);
}

View file

@ -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")
}
}

View file

@ -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); }
}
}

View file

@ -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));
}
}
}
}

View file

@ -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
}
}

View file

@ -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) + ~"`");
}
}
}
}

View file

@ -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}
}
}
}

View file

@ -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 {

View file

@ -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,

View file

@ -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);
}
_ => {}
}
}
_ => ()
}

View file

@ -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.

View file

@ -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;

View file

@ -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 {

View file

@ -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})
}
}
}

View file

@ -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> {

View file

@ -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;

View file

@ -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> {

View file

@ -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];

View file

@ -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);
}

View file

@ -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)

View file

@ -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;

View file

@ -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, _}) => {