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] = ~[]; let mut arg_tys: ~[ty::t] = ~[];
match ty::get(ctor_ty).struct { match ty::get(ctor_ty).struct {
ty::ty_fn(f) => { 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. */ } _ => { /* 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_name(ecx, ebml_w, mty.ident);
encode_type_param_bounds(ebml_w, ecx, ty_m.tps); encode_type_param_bounds(ebml_w, ecx, ty_m.tps);
encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty)); 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); encode_self_type(ebml_w, mty.self_ty);
ebml_w.end_tag(); ebml_w.end_tag();
} }

View File

@@ -9,6 +9,7 @@ use syntax::ast_util;
use syntax::ast_util::respan; use syntax::ast_util::respan;
use middle::ty; use middle::ty;
use std::map::hashmap; use std::map::hashmap;
use ty::{FnTyBase, FnMeta, FnSig};
export parse_ty_data, parse_def_id, parse_ident; export parse_ty_data, parse_def_id, parse_ident;
export parse_bounds_data; export parse_bounds_data;
@@ -274,7 +275,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
parse_ty_rust_fn(st, conv) parse_ty_rust_fn(st, conv)
} }
'X' => { '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), 'Y' => return ty::mk_type(st.tcx),
'C' => { '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 proto = parse_proto(st);
let purity = parse_purity(next(st)); let purity = parse_purity(next(st));
let bounds = parse_bounds(st, conv); 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 ']' st.pos += 1u; // eat the ']'
let (ret_style, ret_ty) = parse_ret_ty(st, conv); let (ret_style, ret_ty) = parse_ret_ty(st, conv);
return {purity: purity, proto: proto, bounds: bounds, inputs: inputs, return FnTyBase {
output: ret_ty, ret_style: ret_style}; 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) { fn enc_ty_fn(w: io::Writer, cx: @ctxt, ft: ty::FnTy) {
enc_proto(w, cx, ft.proto); enc_proto(w, cx, ft.meta.proto);
enc_purity(w, ft.purity); enc_purity(w, ft.meta.purity);
enc_bounds(w, cx, ft.bounds); enc_bounds(w, cx, ft.meta.bounds);
w.write_char('['); w.write_char('[');
for ft.inputs.each |arg| { for ft.sig.inputs.each |arg| {
enc_mode(w, cx, arg.mode); enc_mode(w, cx, arg.mode);
enc_ty(w, cx, arg.ty); enc_ty(w, cx, arg.ty);
} }
w.write_char(']'); w.write_char(']');
match ft.ret_style { match ft.meta.ret_style {
noreturn => w.write_char('!'), 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); let callee_ty = ty::node_id_to_type(tcx, callee_id);
match ty::get(callee_ty).struct { match ty::get(callee_ty).struct {
ty::ty_fn(fn_ty) => { ty::ty_fn(fn_ty) => {
match fn_ty.purity { match fn_ty.meta.purity {
ast::pure_fn => return, // case (c) above ast::pure_fn => return, // case (c) above
ast::impure_fn | ast::unsafe_fn | ast::extern_fn => { ast::impure_fn | ast::unsafe_fn | ast::extern_fn => {
self.report_purity_error( self.report_purity_error(
pc, callee_span, pc, callee_span,
fmt!("access to %s function", 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 { match ty::get(fn_ty).struct {
ty::ty_fn(fn_ty) => { ty::ty_fn(fn_ty) => {
let mut counter = 0; 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; counter += 1;
debug!("arg %d, ty=%s, mode=%s", debug!("arg %d, ty=%s, mode=%s",
counter, counter,

View File

@@ -529,10 +529,10 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
let ccx = cx.ccx(); let ccx = cx.ccx();
let mut cx = cx; let mut cx = cx;
match ty::get(fn_ty).struct { match ty::get(fn_ty).struct {
ty::ty_fn({inputs: args, _}) => { ty::ty_fn(ref fn_ty) => {
let mut j = 0u; let mut j = 0u;
let v_id = variant.id; 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 llfldp_a = GEP_enum(cx, a_tup, tid, v_id, tps, j);
let ty_subst = ty::subst_tps(ccx.tcx, tps, a.ty); let ty_subst = ty::subst_tps(ccx.tcx, tps, a.ty);
cx = f(cx, llfldp_a, ty_subst); 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 = let main_takes_argv =
// invariant! // invariant!
match ty::get(main_node_type).struct { 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") _ => 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 { let proto = ty::ty_fn_proto(t);
ty::ty_fn({proto: ty::proto_bare, _}) | match proto {
ty::ty_fn({proto: ty::proto_vstore(ty::vstore_slice(_)), _}) => ty::proto_bare | ty::proto_vstore(ty::vstore_slice(_)) => bcx,
bcx, ty::proto_vstore(ty::vstore_uniq) => fn_env(ty::ck_uniq),
ty::ty_fn({proto: ty::proto_vstore(ty::vstore_uniq), _}) => ty::proto_vstore(ty::vstore_box) => fn_env(ty::ck_box),
fn_env(ty::ck_uniq), ty::proto_vstore(ty::vstore_fixed(_)) => {
ty::ty_fn({proto: ty::proto_vstore(ty::vstore_box), _}) => cx.sess().bug(~"Closure with fixed vstore");
fn_env(ty::ck_box), }
_ => }
fail ~"make_fn_glue invoked on non-function type"
};
} }
fn make_opaque_cbox_take_glue( fn make_opaque_cbox_take_glue(

View File

@@ -447,11 +447,12 @@ fn trans_rvalue_dps(bcx: block, expr: @ast::expr, dest: Dest) -> block {
ast::expr_fn_block(decl, body, cap_clause) => { ast::expr_fn_block(decl, body, cap_clause) => {
let expr_ty = expr_ty(bcx, expr); let expr_ty = expr_ty(bcx, expr);
match ty::get(expr_ty).struct { match ty::get(expr_ty).struct {
ty::ty_fn({proto, _}) => { ty::ty_fn(ref fn_ty) => {
debug!("translating fn_block %s with type %s", debug!("translating fn_block %s with type %s",
expr_to_str(expr, tcx.sess.intr()), expr_to_str(expr, tcx.sess.intr()),
ty_to_str(tcx, expr_ty)); ty_to_str(tcx, expr_ty));
return closure::trans_expr_fn(bcx, proto, decl, body, return closure::trans_expr_fn(
bcx, fn_ty.meta.proto, decl, body,
expr.id, cap_clause, None, expr.id, cap_clause, None,
dest); dest);
} }
@@ -463,11 +464,11 @@ fn trans_rvalue_dps(bcx: block, expr: @ast::expr, dest: Dest) -> block {
} }
ast::expr_loop_body(blk) => { ast::expr_loop_body(blk) => {
match ty::get(expr_ty(bcx, expr)).struct { match ty::get(expr_ty(bcx, expr)).struct {
ty::ty_fn({proto, _}) => { ty::ty_fn(ref fn_ty) => {
match blk.node { match blk.node {
ast::expr_fn_block(decl, body, cap) => { ast::expr_fn_block(decl, body, cap) => {
return closure::trans_expr_fn( return closure::trans_expr_fn(
bcx, proto, decl, body, blk.id, bcx, fn_ty.meta.proto, decl, body, blk.id,
cap, Some(None), dest); cap, Some(None), dest);
} }
_ => { _ => {

View File

@@ -20,6 +20,7 @@ use util::ppaux::ty_to_str;
use datum::*; use datum::*;
use callee::*; use callee::*;
use expr::{Dest, Ignore}; use expr::{Dest, Ignore};
use ty::{FnTyBase, FnMeta, FnSig};
export link_name, trans_foreign_mod, register_foreign_fn, trans_foreign_fn, export link_name, trans_foreign_mod, register_foreign_fn, trans_foreign_fn,
trans_intrinsic; trans_intrinsic;
@@ -439,10 +440,10 @@ type c_stack_tys = {
fn c_arg_and_ret_lltys(ccx: @crate_ctxt, fn c_arg_and_ret_lltys(ccx: @crate_ctxt,
id: ast::node_id) -> (~[TypeRef], TypeRef, ty::t) { id: ast::node_id) -> (~[TypeRef], TypeRef, ty::t) {
match ty::get(ty::node_id_to_type(ccx.tcx, id)).struct { match ty::get(ty::node_id_to_type(ccx.tcx, id)).struct {
ty::ty_fn({inputs: arg_tys, output: ret_ty, _}) => { ty::ty_fn(ref fn_ty) => {
let llargtys = type_of_explicit_args(ccx, arg_tys); let llargtys = type_of_explicit_args(ccx, fn_ty.sig.inputs);
let llretty = type_of::type_of(ccx, ret_ty); let llretty = type_of::type_of(ccx, fn_ty.sig.output);
(llargtys, llretty, ret_ty) (llargtys, llretty, fn_ty.sig.output)
} }
_ => ccx.sess.bug(~"c_arg_and_ret_lltys called on non-function type") _ => 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" => { ~"frame_address" => {
let frameaddress = ccx.intrinsics.get(~"llvm.frameaddress"); let frameaddress = ccx.intrinsics.get(~"llvm.frameaddress");
let frameaddress_val = Call(bcx, frameaddress, ~[C_i32(0i32)]); let frameaddress_val = Call(bcx, frameaddress, ~[C_i32(0i32)]);
let fty = ty::mk_fn(bcx.tcx(), { let star_u8 = ty::mk_imm_ptr(
purity: ast::impure_fn, 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: proto:
ty::proto_vstore(ty::vstore_slice( ty::proto_vstore(ty::vstore_slice(
ty::re_bound(ty::br_anon(0)))), ty::re_bound(ty::br_anon(0)))),
bounds: @~[], bounds: @~[],
inputs: ~[{ ret_style: ast::return_val},
mode: ast::expl(ast::by_val), sig: FnSig {inputs: ~[{mode: ast::expl(ast::by_val),
ty: ty::mk_imm_ptr( ty: star_u8}],
bcx.tcx(), output: ty::mk_nil(bcx.tcx())}
ty::mk_mach_uint(bcx.tcx(), ast::ty_u8))
}],
output: ty::mk_nil(bcx.tcx()),
ret_style: ast::return_val
}); });
let datum = Datum {val: get_param(decl, first_real_arg), let datum = Datum {val: get_param(decl, first_real_arg),
mode: ByRef, ty: fty, source: FromLvalue}; 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 syntax::parse::token::special_idents;
use type_of::type_of_fn_from_ty; use type_of::type_of_fn_from_ty;
use back::link::mangle_exported_name; use back::link::mangle_exported_name;
use middle::ty::{FnTyBase, FnMeta, FnSig};
fn monomorphic_fn(ccx: @crate_ctxt, fn monomorphic_fn(ccx: @crate_ctxt,
fn_id: ast::def_id, fn_id: ast::def_id,
@@ -202,23 +203,32 @@ fn normalize_for_monomorphization(tcx: ty::ctxt, ty: ty::t) -> Option<ty::t> {
Some(ty::mk_opaque_box(tcx)) Some(ty::mk_opaque_box(tcx))
} }
ty::ty_fn(ref fty) => { ty::ty_fn(ref fty) => {
Some(ty::mk_fn(tcx, {purity: ast::impure_fn, Some(ty::mk_fn(
proto: fty.proto, tcx,
FnTyBase {meta: FnMeta {purity: ast::impure_fn,
proto: fty.meta.proto,
bounds: @~[], bounds: @~[],
inputs: ~[], ret_style: ast::return_val},
output: ty::mk_nil(tcx), sig: FnSig {inputs: ~[],
ret_style: ast::return_val})) output: ty::mk_nil(tcx)}}))
} }
ty::ty_trait(_, _, _) => { ty::ty_trait(_, _, _) => {
Some(ty::mk_fn(tcx, {purity: ast::impure_fn, let box_proto = ty::proto_vstore(ty::vstore_box);
proto: ty::proto_vstore(ty::vstore_box), Some(ty::mk_fn(
tcx,
FnTyBase {meta: FnMeta {purity: ast::impure_fn,
proto: box_proto,
bounds: @~[], bounds: @~[],
inputs: ~[], ret_style: ast::return_val},
output: ty::mk_nil(tcx), sig: FnSig {inputs: ~[],
ret_style: ast::return_val})) output: ty::mk_nil(tcx)}}))
}
ty::ty_ptr(_) => {
Some(ty::mk_uint(tcx))
}
_ => {
None
} }
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 // FIXME (#2594): fetch constants out of intrinsic:: for the
// numbers. // numbers.
ty::ty_fn(fty) => { ty::ty_fn(ref fty) => {
let pureval = match fty.purity { let pureval = match fty.meta.purity {
ast::pure_fn => 0u, ast::pure_fn => 0u,
ast::unsafe_fn => 1u, ast::unsafe_fn => 1u,
ast::impure_fn => 2u, ast::impure_fn => 2u,
ast::extern_fn => 3u ast::extern_fn => 3u
}; };
let protoval = match fty.proto { let protoval = match fty.meta.proto {
ty::proto_bare => 0u, ty::proto_bare => 0u,
ty::proto_vstore(ty::vstore_uniq) => 2u, ty::proto_vstore(ty::vstore_uniq) => 2u,
ty::proto_vstore(ty::vstore_box) => 3u, ty::proto_vstore(ty::vstore_box) => 3u,
@@ -193,16 +193,16 @@ impl reflector {
ty::proto_vstore(ty::vstore_fixed(_)) => ty::proto_vstore(ty::vstore_fixed(_)) =>
fail ~"fixed unexpected" fail ~"fixed unexpected"
}; };
let retval = match fty.ret_style { let retval = match fty.meta.ret_style {
ast::noreturn => 0u, ast::noreturn => 0u,
ast::return_val => 1u ast::return_val => 1u
}; };
let extra = ~[self.c_uint(pureval), let extra = ~[self.c_uint(pureval),
self.c_uint(protoval), self.c_uint(protoval),
self.c_uint(vec::len(fty.inputs)), self.c_uint(vec::len(fty.sig.inputs)),
self.c_uint(retval)]; self.c_uint(retval)];
self.visit(~"enter_fn", extra); self.visit(~"enter_fn", extra);
for fty.inputs.eachi |i, arg| { for fty.sig.inputs.eachi |i, arg| {
let modeval = match arg.mode { let modeval = match arg.mode {
ast::infer(_) => 0u, ast::infer(_) => 0u,
ast::expl(e) => match e { ast::expl(e) => match e {
@@ -220,7 +220,7 @@ impl reflector {
} }
self.visit(~"fn_output", self.visit(~"fn_output",
~[self.c_uint(retval), ~[self.c_uint(retval),
self.c_tydesc(fty.output)]); self.c_tydesc(fty.sig.output)]);
self.visit(~"leave_fn", extra); self.visit(~"leave_fn", extra);
} }

View File

@@ -237,12 +237,14 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> ~[u8] {
tk_enum => ~[s_variant_enum_t(ccx.tcx)], tk_enum => ~[s_variant_enum_t(ccx.tcx)],
tk_newtype | tk_complex => { tk_newtype | tk_complex => {
let mut s = ~[shape_enum], id; let mut s = ~[shape_enum], id;
let nom_id = mk_nominal_id(ccx.tcx, did, None, substs.tps); let nom_id = mk_nominal_id(ccx.tcx, did,
None, substs.tps);
match ccx.shape_cx.tag_id_to_index.find(nom_id) { match ccx.shape_cx.tag_id_to_index.find(nom_id) {
None => { None => {
id = ccx.shape_cx.next_tag_id; id = ccx.shape_cx.next_tag_id;
ccx.shape_cx.tag_id_to_index.insert(nom_id, 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.tag_order.push({did: did,
substs: substs});
ccx.shape_cx.next_tag_id += 1u16; ccx.shape_cx.next_tag_id += 1u16;
} }
Some(existing_id) => id = existing_id, Some(existing_id) => id = existing_id,
@@ -337,7 +339,8 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> ~[u8] {
let id = ccx.shape_cx.resources.intern(ri); let id = ccx.shape_cx.resources.intern(ri);
add_u16(s, id as u16); add_u16(s, id as u16);
}; };
for ty::class_items_as_mutable_fields(ccx.tcx, did, substs).each |f| { for ty::class_items_as_mutable_fields(ccx.tcx, did,
substs).each |f| {
sub += shape_of(ccx, f.mt.ty); sub += shape_of(ccx, f.mt.ty);
} }
add_substr(s, sub); add_substr(s, sub);
@@ -351,21 +354,21 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> ~[u8] {
ty::ty_param(*) => { ty::ty_param(*) => {
ccx.tcx.sess.bug(~"non-monomorphized type parameter"); ccx.tcx.sess.bug(~"non-monomorphized type parameter");
} }
ty::ty_fn({proto: ty::proto_vstore(ty::vstore_box), _}) => ty::ty_fn(ref fn_ty) => {
~[shape_box_fn], match fn_ty.meta.proto {
ty::ty_fn({proto: ty::proto_vstore(ty::vstore_uniq), _}) => ty::proto_vstore(ty::vstore_box) => ~[shape_box_fn],
~[shape_uniq_fn], ty::proto_vstore(ty::vstore_uniq) => ~[shape_uniq_fn],
ty::ty_fn({proto: ty::proto_vstore(ty::vstore_slice(_)), _}) => ty::proto_vstore(ty::vstore_slice(_)) => ~[shape_stack_fn],
~[shape_stack_fn], ty::proto_bare => ~[shape_bare_fn],
ty::ty_fn({proto: ty::proto_vstore(ty::vstore_fixed(_)), _}) => ty::proto_vstore(ty::vstore_fixed(_)) =>
fail ~"fixed vstore is impossible", fail ~"fixed vstore is impossible",
ty::ty_fn({proto: ty::proto_bare, _}) => }
~[shape_bare_fn], }
ty::ty_opaque_closure_ptr(_) => ty::ty_opaque_closure_ptr(_) => ~[shape_opaque_closure_ptr],
~[shape_opaque_closure_ptr], ty::ty_infer(_) | ty::ty_self => {
ty::ty_infer(_) | ty::ty_self =>
ccx.sess.bug(~"shape_of: unexpected type struct found") ccx.sess.bug(~"shape_of: unexpected type struct found")
} }
}
} }
fn shape_of_variant(ccx: @crate_ctxt, v: ty::variant_info) -> ~[u8] { fn shape_of_variant(ccx: @crate_ctxt, v: ty::variant_info) -> ~[u8] {

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))}; 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 { match ty::get(ty::lookup_item_type(cx.ccx.tcx, fn_id).ty).struct {
ty::ty_fn({inputs, _}) => { ty::ty_fn(ref fn_ty) => {
for vec::each(inputs) |arg| { for vec::each(fn_ty.sig.inputs) |arg| {
if arg.mode == expl(by_val) { type_needs(cx, use_repr, arg.ty); } if arg.mode == expl(by_val) { type_needs(cx, use_repr, arg.ty); }
} }
} }

View File

@@ -946,10 +946,8 @@ fn callee_modes(fcx: fn_ctxt, callee: node_id) -> ~[mode] {
let ty = ty::type_autoderef(fcx.ccx.tcx, let ty = ty::type_autoderef(fcx.ccx.tcx,
ty::node_id_to_type(fcx.ccx.tcx, callee)); ty::node_id_to_type(fcx.ccx.tcx, callee));
match ty::get(ty).struct { match ty::get(ty).struct {
ty::ty_fn({inputs: args, _}) { ty::ty_fn(ref fn_ty) {
let mut modes = ~[]; return fn_ty.sig.inputs.map(|input| input.mode);
for args.each |arg| { vec::push(modes, arg.mode); }
return modes;
} }
_ { _ {
// Shouldn't happen; callee should be ty_fn. // Shouldn't happen; callee should be ty_fn.

View File

@@ -21,7 +21,7 @@ use util::ppaux::{ty_to_str, proto_ty_to_str, tys_to_str};
use std::serialization::{serialize_Option, use std::serialization::{serialize_Option,
deserialize_Option}; deserialize_Option};
export ty_vid, int_vid, region_vid, vid; export TyVid, IntVid, FnVid, RegionVid, vid;
export br_hashmap; export br_hashmap;
export is_instantiable; export is_instantiable;
export node_id_to_type; 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_closure_ptr, mk_opaque_closure_ptr;
export ty_opaque_box, mk_opaque_box; export ty_opaque_box, mk_opaque_box;
export ty_float, mk_float, mk_mach_float, type_is_fp; 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_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 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; 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_can_be_copied, kind_can_be_sent, kind_can_be_implicitly_copied;
export kind_is_safe_for_default_mode; export kind_is_safe_for_default_mode;
export kind_is_owned; export kind_is_owned;
export proto_kind, kind_lteq, type_kind; export meta_kind, kind_lteq, type_kind;
export operators; export operators;
export type_err, terr_vstore_kind; export type_err, terr_vstore_kind;
export type_err_to_str, note_and_explain_type_err; export type_err_to_str, note_and_explain_type_err;
@@ -203,7 +203,7 @@ type param_bounds = @~[param_bound];
type method = {ident: ast::ident, type method = {ident: ast::ident,
tps: @~[param_bounds], tps: @~[param_bounds],
fty: fn_ty, fty: FnTy,
self_ty: ast::self_ty_, self_ty: ast::self_ty_,
vis: ast::visibility}; vis: ast::visibility};
@@ -392,20 +392,42 @@ impl fn_proto : cmp::Eq {
} }
} }
/// Innards of a function type: /**
/// * Meta information about a closure.
/// - `purity` is the function's effect (pure, impure, unsafe). *
/// - `proto` is the protocol (fn@, fn~, etc). * - `purity` is the function's effect (pure, impure, unsafe).
/// - `bound` is the parameter bounds on the function's upvars. * - `proto` is the protocol (fn@, fn~, etc).
/// - `inputs` is the list of arguments and their modes. * - `bounds` is the parameter bounds on the function's upvars.
/// - `output` is the return type. * - `ret_style` indicates whether the function returns a value or fails. */
/// - `ret_style` indicates whether the function returns a value or fails. struct FnMeta {
type fn_ty = {purity: ast::purity, purity: ast::purity;
proto: fn_proto, proto: fn_proto;
bounds: @~[param_bound], bounds: @~[param_bound];
inputs: ~[arg], ret_style: ret_style;
output: t, }
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}; type param_ty = {idx: uint, def_id: def_id};
@@ -440,7 +462,7 @@ enum region {
re_static, re_static,
/// A region variable. Should not exist after typeck. /// A region variable. Should not exist after typeck.
re_var(region_vid) re_var(RegionVid)
} }
enum bound_region { enum bound_region {
@@ -505,7 +527,7 @@ enum sty {
ty_ptr(mt), ty_ptr(mt),
ty_rptr(region, mt), ty_rptr(region, mt),
ty_rec(~[field]), ty_rec(~[field]),
ty_fn(fn_ty), ty_fn(FnTy),
ty_trait(def_id, substs, vstore), ty_trait(def_id, substs, vstore),
ty_class(def_id, substs), ty_class(def_id, substs),
ty_tup(~[t]), ty_tup(~[t]),
@@ -567,13 +589,14 @@ enum param_bound {
bound_trait(t), bound_trait(t),
} }
enum ty_vid = uint; enum TyVid = uint;
enum int_vid = uint; enum IntVid = uint;
enum region_vid = uint; enum FnVid = uint;
enum RegionVid = uint;
enum InferTy { enum InferTy {
TyVar(ty_vid), TyVar(TyVid),
IntVar(int_vid) IntVar(IntVid)
} }
trait vid { trait vid {
@@ -581,17 +604,22 @@ trait vid {
pure fn to_str() -> ~str; pure fn to_str() -> ~str;
} }
impl ty_vid: vid { impl TyVid: vid {
pure fn to_uint() -> uint { *self } pure fn to_uint() -> uint { *self }
pure fn to_str() -> ~str { fmt!("<V%u>", self.to_uint()) } 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_uint() -> uint { *self }
pure fn to_str() -> ~str { fmt!("<VI%u>", self.to_uint()) } 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_uint() -> uint { *self }
pure fn to_str() -> ~str { fmt!("%?", self) } pure fn to_str() -> ~str { fmt!("%?", self) }
} }
@@ -600,14 +628,14 @@ impl InferTy {
pure fn to_hash() -> uint { pure fn to_hash() -> uint {
match self { match self {
TyVar(v) => v.to_uint() << 1, 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 { pure fn to_str() -> ~str {
match self { match self {
TyVar(v) => v.to_str(), 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_rec(flds) => for flds.each |f| { flags |= get(f.mt.ty).flags; },
ty_tup(ts) => for ts.each |tt| { flags |= get(tt).flags; }, ty_tup(ts) => for ts.each |tt| { flags |= get(tt).flags; },
ty_fn(ref f) => { ty_fn(ref f) => {
match f.proto { match f.meta.proto {
ty::proto_vstore(vstore_slice(r)) => flags |= rflags(r), ty::proto_vstore(vstore_slice(r)) => flags |= rflags(r),
ty::proto_bare | ty::proto_vstore(_) => {} ty::proto_bare | ty::proto_vstore(_) => {}
} }
for f.inputs.each |a| { flags |= get(a.ty).flags; } for f.sig.inputs.each |a| { flags |= get(a.ty).flags; }
flags |= get(f.output).flags; flags |= get(f.sig.output).flags;
} }
} }
let t = @{struct: st, id: cx.next_id, flags: flags, o_def_id: o_def_id}; 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})) 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_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)) } 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 // 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) fn mk_trait(cx: ctxt, did: ast::def_id, +substs: substs, vstore: vstore)
-> t { -> 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)) 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)) 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_tup(ts) => { for ts.each |tt| { maybe_walk_ty(tt, f); } }
ty_fn(ref ft) => { ty_fn(ref ft) => {
for ft.inputs.each |a| { maybe_walk_ty(a.ty, f); } for ft.sig.inputs.each |a| { maybe_walk_ty(a.ty, f); }
maybe_walk_ty(ft.output, f); maybe_walk_ty(ft.sig.output, f);
} }
ty_uniq(tm) => { maybe_walk_ty(tm.ty, f); } ty_uniq(tm) => { maybe_walk_ty(tm.ty, f); }
} }
@@ -1029,12 +1056,15 @@ fn fold_sty(sty: &sty, fldop: fn(t) -> t) -> sty {
ty_tup(new_ts) ty_tup(new_ts)
} }
ty_fn(ref f) => { ty_fn(ref f) => {
let new_args = vec::map(f.inputs, |a| { let new_args = f.sig.inputs.map(|a| {
let new_ty = fldop(a.ty); let new_ty = fldop(a.ty);
{mode: a.mode, ty: new_ty} {mode: a.mode, ty: new_ty}
}); });
let new_output = fldop(f.output); let new_output = fldop(f.sig.output);
ty_fn({inputs: new_args, output: new_output,.. *f}) ty_fn(FnTyBase {
meta: f.meta,
sig: FnSig {inputs: new_args, output: new_output}
})
} }
ty_rptr(r, tm) => { ty_rptr(r, tm) => {
ty_rptr(r, {ty: fldop(tm.ty), mutbl: tm.mutbl}) ty_rptr(r, {ty: fldop(tm.ty), mutbl: tm.mutbl})
@@ -1113,9 +1143,9 @@ fn fold_regions_and_ty(
ty_trait(def_id, ref substs, vst) => { ty_trait(def_id, ref substs, vst) => {
ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), vst) ty::mk_trait(cx, def_id, fold_substs(substs, fldr, fldt), vst)
} }
ty_fn(f) => { ty_fn(ref f) => {
let new_proto; let new_proto;
match f.proto { match f.meta.proto {
proto_bare => proto_bare =>
new_proto = proto_bare, new_proto = proto_bare,
proto_vstore(vstore_slice(r)) => proto_vstore(vstore_slice(r)) =>
@@ -1123,16 +1153,15 @@ fn fold_regions_and_ty(
proto_vstore(old_vstore) => proto_vstore(old_vstore) =>
new_proto = proto_vstore(old_vstore) new_proto = proto_vstore(old_vstore)
} }
let new_args = vec::map(f.sig.inputs, |a| {
let new_args = vec::map(f.inputs, |a| {
let new_ty = fldfnt(a.ty); let new_ty = fldfnt(a.ty);
{mode: a.mode, ty: new_ty} {mode: a.mode, ty: new_ty}
}); });
let new_output = fldfnt(f.output); let new_output = fldfnt(f.sig.output);
ty::mk_fn(cx, { ty::mk_fn(cx, FnTyBase {
inputs: new_args, meta: FnMeta {proto: new_proto, ..f.meta},
output: new_output, sig: FnSig {inputs: new_args,
proto: new_proto,.. f output: new_output}
}) })
} }
ref sty => { ref sty => {
@@ -1440,7 +1469,7 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
accum accum
} }
ty_fn(ref fty) => { ty_fn(ref fty) => {
match fty.proto { match fty.meta.proto {
proto_bare | proto_vstore(vstore_slice(_)) => false, proto_bare | proto_vstore(vstore_slice(_)) => false,
_ => true _ => true
} }
@@ -1667,8 +1696,8 @@ pure fn kind_is_owned(k: kind) -> bool {
*k & KIND_MASK_OWNED == KIND_MASK_OWNED *k & KIND_MASK_OWNED == KIND_MASK_OWNED
} }
fn proto_kind(p: fn_proto) -> kind { fn meta_kind(p: FnMeta) -> kind {
match p { match p.proto { // XXX consider the kind bounds!
proto_vstore(vstore_slice(_)) => proto_vstore(vstore_slice(_)) =>
kind_noncopyable() | kind_(KIND_MASK_DEFAULT_MODE), kind_noncopyable() | kind_(KIND_MASK_DEFAULT_MODE),
proto_vstore(vstore_box) => proto_vstore(vstore_box) =>
@@ -1753,7 +1782,7 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
} }
// functions depend on the protocol // 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, // Those with refcounts raise noncopyable to copyable,
// lower sendable to copyable. Therefore just set result 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) => { ty_fn(ref f) => {
let mut h = 27u; let mut h = 27u;
for vec::each(f.inputs) |a| { h = hash_subty(h, a.ty); } for vec::each(f.sig.inputs) |a| {
hash_subty(h, f.output) h = hash_subty(h, a.ty);
}
hash_subty(h, f.sig.output)
} }
ty_self => 28u, ty_self => 28u,
ty_infer(v) => hash_uint(29u, v.to_hash()), 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 // Type accessors for substructures of types
fn ty_fn_args(fty: t) -> ~[arg] { fn ty_fn_args(fty: t) -> ~[arg] {
match get(fty).struct { 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" _ => fail ~"ty_fn_args() called on non-fn type"
} }
} }
fn ty_fn_proto(fty: t) -> fn_proto { fn ty_fn_proto(fty: t) -> fn_proto {
match get(fty).struct { 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" _ => fail ~"ty_fn_proto() called on non-fn type"
} }
} }
fn ty_fn_purity(fty: t) -> ast::purity { fn ty_fn_purity(fty: t) -> ast::purity {
match get(fty).struct { 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" _ => fail ~"ty_fn_purity() called on non-fn type"
} }
} }
pure fn ty_fn_ret(fty: t) -> t { pure fn ty_fn_ret(fty: t) -> t {
match get(fty).struct { 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" _ => fail ~"ty_fn_ret() called on non-fn type"
} }
} }
fn ty_fn_ret_style(fty: t) -> ast::ret_style { fn ty_fn_ret_style(fty: t) -> ast::ret_style {
match get(fty).struct { 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" _ => 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. // Returns a vec of all the input and output types of fty.
fn tys_in_fn_ty(fty: &fn_ty) -> ~[t] { fn tys_in_fn_ty(fty: &FnTy) -> ~[t] {
vec::append_one(fty.inputs.map(|a| a.ty), fty.output) vec::append_one(fty.sig.inputs.map(|a| a.ty), fty.sig.output)
} }
// Just checks whether it's a fn that returns bool, // 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 { match get(typ).struct {
ty_infer(TyVar(vid)) => return vid, ty_infer(TyVar(vid)) => return vid,
_ => { error!("ty_var_id called on non-var ty"); fail; } _ => { 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 { match get(typ).struct {
ty_infer(IntVar(vid)) => return vid, ty_infer(IntVar(vid)) => return vid,
_ => { error!("ty_var_integral_id called on ty other than \ _ => { error!("ty_var_integral_id called on ty other than \
@@ -2765,11 +2796,11 @@ fn param_tys_in_type(ty: t) -> ~[param_ty] {
rslt 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 // Returns a vec of all the type variables occurring in `ty`. It may
// contain duplicates. (Integral type vars aren't counted.) // 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 = ~[]; let mut rslt = ~[];
do walk_ty(ty) |ty| { do walk_ty(ty) |ty| {
match get(ty).struct { 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 // This type has a region. Get rid of it
mk_rptr(cx, re_static, normalize_mt(cx, mt)), mk_rptr(cx, re_static, normalize_mt(cx, mt)),
ty_fn({purity: purity, ty_fn(ref fn_ty) => {
proto: proto_vstore(vstore), let proto = match fn_ty.meta.proto {
bounds: bounds, proto_bare => proto_bare,
inputs: inputs, proto_vstore(vstore) => proto_vstore(normalize_vstore(vstore))
output: output, };
ret_style: ret_style}) => mk_fn(cx, FnTyBase {
mk_fn(cx, { meta: FnMeta {proto: proto, ..fn_ty.meta},
purity: purity, sig: fn_ty.sig
proto: proto_vstore(normalize_vstore(vstore)), })
bounds: bounds, }
inputs: inputs,
output: output,
ret_style: ret_style
}),
ty_enum(did, r) => ty_enum(did, r) =>
match r.self_r { match r.self_r {
@@ -3708,31 +3735,48 @@ impl vstore : cmp::Eq {
} }
} }
impl fn_ty : cmp::Eq { impl FnMeta : cmp::Eq {
pure fn eq(&&other: fn_ty) -> bool { pure fn eq(&&other: FnMeta) -> bool {
self.purity == other.purity && self.purity == other.purity &&
self.proto == other.proto && self.proto == other.proto &&
self.bounds == other.bounds && self.bounds == other.bounds &&
self.inputs == other.inputs &&
self.output == other.output &&
self.ret_style == other.ret_style self.ret_style == other.ret_style
} }
} }
impl ty_vid: cmp::Eq { impl FnSig : cmp::Eq {
pure fn eq(&&other: ty_vid) -> bool { 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 *self == *other
} }
} }
impl int_vid: cmp::Eq { impl IntVid: cmp::Eq {
pure fn eq(&&other: int_vid) -> bool { pure fn eq(&&other: IntVid) -> bool {
*self == *other *self == *other
} }
} }
impl region_vid: cmp::Eq { impl FnVid: cmp::Eq {
pure fn eq(&&other: region_vid) -> bool { pure fn eq(&&other: FnVid) -> bool {
*self == *other
}
}
impl RegionVid: cmp::Eq {
pure fn eq(&&other: RegionVid) -> bool {
*self == *other *self == *other
} }
} }

View File

@@ -255,14 +255,15 @@ fn check_main_fn_ty(ccx: @crate_ctxt,
let tcx = ccx.tcx; let tcx = ccx.tcx;
let main_t = ty::node_id_to_type(tcx, main_id); let main_t = ty::node_id_to_type(tcx, main_id);
match ty::get(main_t).struct { match ty::get(main_t).struct {
ty::ty_fn({purity: ast::impure_fn, proto: ty::proto_bare, ty::ty_fn(fn_ty) => {
inputs, output, ret_style: ast::return_val, _}) => {
match tcx.items.find(main_id) { match tcx.items.find(main_id) {
Some(ast_map::node_item(it,_)) => { Some(ast_map::node_item(it,_)) => {
match it.node { match it.node {
ast::item_fn(_,_,ps,_) if vec::is_not_empty(ps) => { ast::item_fn(_,_,ps,_) if vec::is_not_empty(ps) => {
tcx.sess.span_err(main_span, tcx.sess.span_err(
~"main function is not allowed to have type parameters"); main_span,
~"main function is not allowed \
to have type parameters");
return; return;
} }
_ => () _ => ()
@@ -270,12 +271,13 @@ fn check_main_fn_ty(ccx: @crate_ctxt,
} }
_ => () _ => ()
} }
let mut ok = ty::type_is_nil(output); let mut ok = ty::type_is_nil(fn_ty.sig.output);
let num_args = vec::len(inputs); let num_args = vec::len(fn_ty.sig.inputs);
ok &= num_args == 0u || num_args == 1u && ok &= num_args == 0u || num_args == 1u &&
arg_is_argv_ty(tcx, inputs[0]); arg_is_argv_ty(tcx, fn_ty.sig.inputs[0]);
if !ok { if !ok {
tcx.sess.span_err(main_span, tcx.sess.span_err(
main_span,
fmt!("Wrong type in main function: found `%s`, \ fmt!("Wrong type in main function: found `%s`, \
expected `extern fn(~[str]) -> ()` \ expected `extern fn(~[str]) -> ()` \
or `extern fn() -> ()`", or `extern fn() -> ()`",

View File

@@ -45,6 +45,7 @@
use check::fn_ctxt; use check::fn_ctxt;
use rscope::{anon_rscope, binding_rscope, empty_rscope, in_anon_rscope}; use rscope::{anon_rscope, binding_rscope, empty_rscope, in_anon_rscope};
use rscope::{in_binding_rscope, region_scope, type_rscope}; use rscope::{in_binding_rscope, region_scope, type_rscope};
use ty::{FnTyBase, FnMeta, FnSig};
trait ast_conv { trait ast_conv {
fn tcx() -> ty::ctxt; 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], bounds: @~[ty::param_bound],
decl: ast::fn_decl, decl: ast::fn_decl,
expected_tys: expected_tys, expected_tys: expected_tys,
span: span) -> ty::fn_ty { span: span) -> ty::FnTy {
debug!("ty_of_fn_decl"); debug!("ty_of_fn_decl");
do indent { 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); let proto = ast_proto_to_proto(self, rscope, span, ast_proto);
{purity: purity, proto: proto, bounds: bounds, inputs: input_tys, FnTyBase {
output: output_ty, ret_style: decl.cf} 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_conv, ast_path_to_ty, ast_ty_to_ty};
use astconv::{ast_region_to_region}; 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 regionmanip::{replace_bound_regions_in_fn_ty};
use rscope::{anon_rscope, binding_rscope, empty_rscope, in_anon_rscope}; use rscope::{anon_rscope, binding_rscope, empty_rscope, in_anon_rscope};
use rscope::{in_binding_rscope, region_scope, type_rscope, use rscope::{in_binding_rscope, region_scope, type_rscope,
@@ -98,7 +98,7 @@ type self_info = {
/// share the inherited fields. /// share the inherited fields.
struct inherited { struct inherited {
infcx: infer::infer_ctxt; 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_types: hashmap<ast::node_id, ty::t>;
node_type_substs: hashmap<ast::node_id, ty::substs>; node_type_substs: hashmap<ast::node_id, ty::substs>;
borrowings: hashmap<ast::node_id, ty::borrow>; borrowings: hashmap<ast::node_id, ty::borrow>;
@@ -211,7 +211,7 @@ fn check_bare_fn(ccx: @crate_ctxt,
fn check_fn(ccx: @crate_ctxt, fn check_fn(ccx: @crate_ctxt,
self_info: Option<self_info>, self_info: Option<self_info>,
fn_ty: &ty::fn_ty, fn_ty: &ty::FnTy,
decl: ast::fn_decl, decl: ast::fn_decl,
body: ast::blk, body: ast::blk,
indirect_ret: bool, indirect_ret: bool,
@@ -231,8 +231,8 @@ fn check_fn(ccx: @crate_ctxt,
|br| ty::re_free(body.node.id, br)) |br| ty::re_free(body.node.id, br))
}; };
let arg_tys = fn_ty.inputs.map(|a| a.ty); let arg_tys = fn_ty.sig.inputs.map(|a| a.ty);
let ret_ty = fn_ty.output; let ret_ty = fn_ty.sig.output;
debug!("check_fn(arg_tys=%?, ret_ty=%?, self_info.self_ty=%?)", debug!("check_fn(arg_tys=%?, ret_ty=%?, self_info.self_ty=%?)",
arg_tys.map(|a| ty_to_str(tcx, a)), arg_tys.map(|a| ty_to_str(tcx, a)),
@@ -245,12 +245,12 @@ fn check_fn(ccx: @crate_ctxt,
let fcx: @fn_ctxt = { let fcx: @fn_ctxt = {
let (purity, inherited) = match old_fcx { let (purity, inherited) = match old_fcx {
None => { None => {
(fn_ty.purity, (fn_ty.meta.purity,
blank_inherited(ccx)) blank_inherited(ccx))
} }
Some(fcx) => { Some(fcx) => {
(ty::determine_inherited_purity(fcx.purity, fn_ty.purity, (ty::determine_inherited_purity(fcx.purity, fn_ty.meta.purity,
fn_ty.proto), fn_ty.meta.proto),
fcx.inh) fcx.inh)
} }
}; };
@@ -943,9 +943,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
// Grab the argument types, supplying fresh type variables // Grab the argument types, supplying fresh type variables
// if the wrong number of arguments were supplied // 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 { 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 { } else {
fcx.ccx.tcx.sess.span_err( fcx.ccx.tcx.sess.span_err(
sp, fmt!("this function takes %u parameter%s but %u \ 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. // Pull the return type out of the type of the function.
match structure_of(fcx, sp, fty) { match structure_of(fcx, sp, fty) {
ty::ty_fn(f) => { ty::ty_fn(ref f) => {
bot |= (f.ret_style == ast::noreturn); bot |= (f.meta.ret_style == ast::noreturn);
fcx.write_ty(call_expr_id, f.output); fcx.write_ty(call_expr_id, f.sig.output);
return bot; return bot;
} }
_ => fcx.ccx.tcx.sess.span_fatal(sp, ~"calling non-function") _ => 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( replace_bound_regions_in_fn_ty(
tcx, @Nil, None, fn_ty, tcx, @Nil, None, fn_ty,
|br| ty::re_bound(ty::br_cap_avoid(expr.id, @br))); |br| ty::re_bound(ty::br_cap_avoid(expr.id, @br)));
(Some({inputs:fn_ty.inputs, (Some({inputs: fn_ty.sig.inputs,
output:fn_ty.output}), output: fn_ty.sig.output}),
fn_ty.purity, fn_ty.meta.purity,
fn_ty.proto) fn_ty.meta.proto)
} }
_ => { _ => {
(None, ast::impure_fn, ty::proto_vstore(ty::vstore_box)) (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. // Patch up the function declaration, if necessary.
match ast_proto_opt { match ast_proto_opt {
None => { None => {
fn_ty.purity = expected_purity; fn_ty.meta.purity = expected_purity;
fn_ty.proto = expected_proto; fn_ty.meta.proto = expected_proto;
} }
Some(_) => { } Some(_) => { }
} }
@@ -1643,16 +1643,20 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
let inner_ty = match expected_sty { let inner_ty = match expected_sty {
Some(ty::ty_fn(fty)) => { Some(ty::ty_fn(fty)) => {
match fcx.mk_subty(false, expr.span, match fcx.mk_subty(false, expr.span,
fty.output, ty::mk_bool(tcx)) { fty.sig.output, ty::mk_bool(tcx)) {
result::Ok(_) => (), result::Ok(_) => (),
result::Err(_) => { result::Err(_) => {
tcx.sess.span_fatal( tcx.sess.span_fatal(
expr.span, fmt!("a `loop` function's last argument \ expr.span, fmt!("a `loop` function's last argument \
should return `bool`, not `%s`", 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 \ 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)); fcx, expr.span, fcx.node_ty(b.id));
match ty::get(block_ty).struct { match ty::get(block_ty).struct {
ty::ty_fn(fty) => { ty::ty_fn(fty) => {
fcx.write_ty(expr.id, ty::mk_fn(tcx, {output: ty::mk_bool(tcx), fcx.write_ty(expr.id, ty::mk_fn(tcx, FnTyBase {
.. fty})); meta: fty.meta,
sig: FnSig {output: ty::mk_bool(tcx),
..fty.sig}
}))
} }
_ => fail ~"expected fn type" _ => fail ~"expected fn type"
} }
@@ -2306,7 +2313,7 @@ fn self_ref(fcx: @fn_ctxt, id: ast::node_id) -> bool {
ast_util::is_self) 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) { match fcx.inh.locals.find(id) {
Some(x) => x, 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)) arg(ast::by_ref, visitor_trait)], ty::mk_nil(tcx))
} }
~"frame_address" => { ~"frame_address" => {
let fty = ty::mk_fn(ccx.tcx, { let fty = ty::mk_fn(ccx.tcx, FnTyBase {
purity: ast::impure_fn, meta: FnMeta {purity: ast::impure_fn,
proto: proto: ty::proto_vstore(ty::vstore_slice(
ty::proto_vstore(ty::vstore_slice(
ty::re_bound(ty::br_anon(0)))), ty::re_bound(ty::br_anon(0)))),
bounds: @~[], bounds: @~[],
inputs: ~[{ ret_style: ast::return_val},
mode: ast::expl(ast::by_val), sig: FnSig {inputs: ~[{mode: ast::expl(ast::by_val),
ty: ty::mk_imm_ptr( ty: ty::mk_imm_ptr(
ccx.tcx, ccx.tcx,
ty::mk_mach_uint(ccx.tcx, ast::ty_u8)) ty::mk_mach_uint(ccx.tcx, ast::ty_u8))
}], }],
output: ty::mk_nil(ccx.tcx), output: ty::mk_nil(ccx.tcx)}
ret_style: ast::return_val
}); });
(0u, ~[arg(ast::by_ref, fty)], ty::mk_nil(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; return;
} }
}; };
let fty = ty::mk_fn(tcx, {purity: ast::impure_fn, let fty = ty::mk_fn(tcx, FnTyBase {
meta: FnMeta {purity: ast::impure_fn,
proto: ty::proto_bare, proto: ty::proto_bare,
bounds: @~[], bounds: @~[],
inputs: inputs, output: output, ret_style: ast::return_val},
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_ty = ty::lookup_item_type(ccx.tcx, local_def(it.id));
let i_n_tps = (*i_ty.bounds).len(); let i_n_tps = (*i_ty.bounds).len();
if i_n_tps != n_tps { if i_n_tps != n_tps {

View File

@@ -2,7 +2,7 @@
use coherence::get_base_type_def_id; use coherence::get_base_type_def_id;
use middle::resolve::{Impl, MethodInfo}; 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, use syntax::ast::{def_id,
sty_static, sty_box, sty_by_ref, sty_region, sty_uniq}; sty_static, sty_box, sty_by_ref, sty_region, sty_uniq};
use syntax::ast::{sty_value, by_ref, by_copy}; 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 { fn ty_from_did(did: ast::def_id) -> ty::t {
match ty::get(ty::lookup_item_type(self.tcx(), did).ty).struct { match ty::get(ty::lookup_item_type(self.tcx(), did).ty).struct {
ty::ty_fn(fty) => { ty::ty_fn(ref fty) => {
ty::mk_fn(self.tcx(), ty::mk_fn(self.tcx(), FnTyBase {
{proto: ty::proto_vstore(ty::vstore_box),.. fty}) meta: FnMeta {proto: ty::proto_vstore(ty::vstore_box),
..fty.meta},
sig: fty.sig
})
} }
_ => fail ~"ty_from_did: not function ty" _ => 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 bit hokey, but the method unbound has a bare protocol, whereas
// a.b has a protocol like fn@() (perhaps eventually fn&()): // a.b has a protocol like fn@() (perhaps eventually fn&()):
let fty = ty::mk_fn(tcx, {proto: ty::proto_vstore(ty::vstore_box), let fty = ty::mk_fn(tcx, FnTyBase {
.. m.fty}); meta: FnMeta {proto: ty::proto_vstore(ty::vstore_box),
..m.fty.meta},
sig: m.fty.sig
});
self.candidates.push( self.candidates.push(
{self_ty: self.self_ty, {self_ty: self.self_ty,

View File

@@ -216,11 +216,14 @@ fn visit_expr(e: @ast::expr, &&rcx: @rcx, v: rvt) {
result::Err(_) => return, // Typechecking will fail anyhow. result::Err(_) => return, // Typechecking will fail anyhow.
result::Ok(function_type) => { result::Ok(function_type) => {
match ty::get(function_type).struct { match ty::get(function_type).struct {
ty::ty_fn({ ty::ty_fn(ref fn_ty) => {
proto: proto_vstore(vstore_slice(region)), _ match fn_ty.meta.proto {
}) => { proto_vstore(vstore_slice(region)) => {
constrain_free_variables(rcx, region, e); constrain_free_variables(rcx, region, e);
} }
_ => {}
}
}
_ => () _ => ()
} }
} }

View File

@@ -9,9 +9,9 @@ fn replace_bound_regions_in_fn_ty(
tcx: ty::ctxt, tcx: ty::ctxt,
isr: isr_alist, isr: isr_alist,
self_info: Option<self_info>, self_info: Option<self_info>,
fn_ty: &ty::fn_ty, fn_ty: &ty::FnTy,
mapf: fn(ty::bound_region) -> ty::region) -> 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 // Take self_info apart; the self_ty part is the only one we want
// to update here. // 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 astconv::{ast_conv, ty_of_fn_decl, ty_of_arg, ast_ty_to_ty};
use ast_util::trait_method_to_ty_method; use ast_util::trait_method_to_ty_method;
use rscope::*; use rscope::*;
use ty::{FnTyBase, FnMeta, FnSig};
fn collect_item_types(ccx: @crate_ctxt, crate: @ast::crate) { 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); let arg_ty = ccx.to_ty(rs, va.ty);
{mode: ast::expl(ast::by_copy), ty: arg_ty} {mode: ast::expl(ast::by_copy), ty: arg_ty}
}); });
result_ty = Some(ty::mk_fn(tcx, result_ty = Some(ty::mk_fn(tcx, FnTyBase {
{purity: ast::pure_fn, meta: FnMeta {purity: ast::pure_fn,
proto: ty::proto_vstore proto: ty::proto_vstore(ty::vstore_box),
(ty::vstore_box),
bounds: @~[], bounds: @~[],
inputs: args, ret_style: ast::return_val},
output: enum_ty, sig: FnSig {inputs: args,
ret_style: ast::return_val})); output: enum_ty}
}));
} }
ast::tuple_variant_kind(_) | ast::struct_variant_kind(_) => { ast::tuple_variant_kind(_) | ast::struct_variant_kind(_) => {
result_ty = Some(enum_ty); 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, trait_m: ty::method, trait_substs: ty::substs,
self_ty: ty::t) { 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( tcx.sess.span_err(
sp, fmt!("method `%s`'s purity does \ sp, fmt!("method `%s`'s purity does \
not match the trait method's \ not match the trait method's \
@@ -268,12 +269,12 @@ fn compare_impl_method(tcx: ty::ctxt, sp: span,
return; 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 \ tcx.sess.span_err(sp,fmt!("method `%s` has %u parameters \
but the trait has %u", but the trait has %u",
tcx.sess.str_of(trait_m.ident), tcx.sess.str_of(trait_m.ident),
vec::len(impl_m.fty.inputs), vec::len(impl_m.fty.sig.inputs),
vec::len(trait_m.fty.inputs))); vec::len(trait_m.fty.sig.inputs)));
return; return;
} }
@@ -488,13 +489,15 @@ fn convert_struct(ccx: @crate_ctxt,
{self_r: rscope::bound_self_region(rp), {self_r: rscope::bound_self_region(rp),
self_ty: None, self_ty: None,
tps: ty::ty_params_to_tys(tcx, tps)}); tps: ty::ty_params_to_tys(tcx, tps)});
let t_ctor = ty::mk_fn( let proto = ty::proto_vstore(ty::vstore_slice(ty::re_static));
tcx, {purity: ast::impure_fn, let t_ctor = ty::mk_fn(tcx, FnTyBase {
proto: ty::proto_vstore(ty::vstore_slice(ty::re_static)), meta: FnMeta {purity: ast::impure_fn,
proto: proto,
bounds: @~[], bounds: @~[],
inputs: t_args, ret_style: ast::return_val},
output: t_res, sig: FnSig {inputs: t_args,
ret_style: ast::return_val}); output: t_res}
});
write_ty_to_tcx(tcx, ctor.node.id, t_ctor); write_ty_to_tcx(tcx, ctor.node.id, t_ctor);
tcx.tcache.insert(local_def(ctor.node.id), tcx.tcache.insert(local_def(ctor.node.id),
{bounds: tpt.bounds, {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 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 output_ty = ast_ty_to_ty(ccx, rb, decl.output);
let t_fn = ty::mk_fn(ccx.tcx, {purity: purity, let t_fn = ty::mk_fn(ccx.tcx, FnTyBase {
meta: FnMeta {purity: purity,
proto: ty::proto_bare, proto: ty::proto_bare,
bounds: @~[], bounds: @~[],
inputs: input_tys, ret_style: ast::return_val},
output: output_ty, sig: FnSig {inputs: input_tys,
ret_style: ast::return_val}); output: output_ty}
});
let tpt = {bounds: bounds, region_param: None, ty: t_fn}; let tpt = {bounds: bounds, region_param: None, ty: t_fn};
ccx.tcx.tcache.insert(def_id, tpt); ccx.tcx.tcache.insert(def_id, tpt);
return tpt; return tpt;

View File

@@ -250,7 +250,7 @@ use std::smallintmap;
use std::smallintmap::smallintmap; use std::smallintmap::smallintmap;
use std::map::hashmap; use std::map::hashmap;
use middle::ty; 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}; ty_int, ty_uint, get, terr_fn, TyVar, IntVar};
use syntax::{ast, ast_util}; use syntax::{ast, ast_util};
use syntax::ast::{ret_style, purity}; use syntax::ast::{ret_style, purity};
@@ -312,11 +312,11 @@ enum infer_ctxt = @{
// We instantiate vals_and_bindings with bounds<ty::t> because the // We instantiate vals_and_bindings with bounds<ty::t> because the
// types that might instantiate a general type variable have an // types that might instantiate a general type variable have an
// order, represented by its upper and lower bounds. // 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 // The types that might instantiate an integral type variable are
// represented by an int_ty_set. // 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. // For region variables.
region_vars: RegionVarBindings, region_vars: RegionVarBindings,
@@ -328,11 +328,11 @@ enum infer_ctxt = @{
}; };
enum fixup_err { enum fixup_err {
unresolved_int_ty(int_vid), unresolved_int_ty(IntVid),
unresolved_ty(ty_vid), unresolved_ty(TyVid),
cyclic_ty(ty_vid), cyclic_ty(TyVid),
unresolved_region(region_vid), unresolved_region(RegionVid),
region_var_bound_by_region_var(region_vid, region_vid) region_var_bound_by_region_var(RegionVid, RegionVid)
} }
fn fixup_err_to_str(f: fixup_err) -> ~str { fn fixup_err_to_str(f: fixup_err) -> ~str {
@@ -596,12 +596,12 @@ impl infer_ctxt {
} }
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; let id = *self.ty_var_counter;
*self.ty_var_counter += 1u; *self.ty_var_counter += 1u;
self.ty_var_bindings.vals.insert(id, self.ty_var_bindings.vals.insert(id,
root({lb: None, ub: None}, 0u)); root({lb: None, ub: None}, 0u));
return ty_vid(id); return TyVid(id);
} }
fn next_ty_var() -> ty::t { fn next_ty_var() -> ty::t {
@@ -612,13 +612,13 @@ impl infer_ctxt {
vec::from_fn(n, |_i| self.next_ty_var()) 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; let id = *self.int_var_counter;
*self.int_var_counter += 1u; *self.int_var_counter += 1u;
self.int_var_bindings.vals.insert(id, self.int_var_bindings.vals.insert(id,
root(int_ty_set_all(), 0u)); root(int_ty_set_all(), 0u));
return int_vid(id); return IntVid(id);
} }
fn next_int_var() -> ty::t { fn next_int_var() -> ty::t {

View File

@@ -45,6 +45,7 @@
// now. // now.
use to_str::to_str; use to_str::to_str;
use ty::{FnTyBase, FnMeta, FnSig};
trait combine { trait combine {
fn infcx() -> infer_ctxt; 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 self_tys(a: Option<ty::t>, b: Option<ty::t>) -> cres<Option<ty::t>>;
fn substs(did: ast::def_id, as: &ty::substs, fn substs(did: ast::def_id, as: &ty::substs,
bs: &ty::substs) -> cres<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 flds(a: ty::field, b: ty::field) -> cres<ty::field>;
fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode>; fn modes(a: ast::mode, b: ast::mode) -> cres<ast::mode>;
fn args(a: ty::arg, b: ty::arg) -> cres<ty::arg>; 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>( fn super_fn_metas<C:combine>(
self: &C, a_f: &ty::fn_ty, b_f: &ty::fn_ty) -> cres<ty::fn_ty> { 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], fn argvecs<C:combine>(self: &C, a_args: ~[ty::arg],
b_args: ~[ty::arg]) -> cres<~[ty::arg]> { b_args: ~[ty::arg]) -> cres<~[ty::arg]> {
if vec::same_length(a_args, b_args) { 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 { } else {
Err(ty::terr_arg_count) 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 argvecs(self, a_f.inputs, b_f.inputs).chain |inputs| {
do self.tys(a_f.output, b_f.output).chain |output| { do self.tys(a_f.output, b_f.output).chain |output| {
do self.purities(a_f.purity, b_f.purity).chain |purity| { Ok(FnSig {inputs: inputs, output: output})
// 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})
// }
}
} }
} }
}
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) 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) 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, fn substs(did: ast::def_id,
as: &ty::substs, as: &ty::substs,
bs: &ty::substs) -> cres<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>( 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> { c_ts: fn(ty::t, ty::t) -> cres<ty::t>) -> cres<ty::t> {
// The comments in this function are written for LUB and types, // 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>( 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> { c_ts: fn(ty::t, ty::t) -> cres<ty::t>) -> cres<ty::t> {
let vb = &self.infcx().ty_var_bindings; let vb = &self.infcx().ty_var_bindings;

View File

@@ -126,10 +126,18 @@ impl Lub: combine {
super_args(&self, a, b) 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) 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, fn substs(did: ast::def_id,
as: &ty::substs, as: &ty::substs,
bs: &ty::substs) -> cres<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::cell::{Cell, empty_cell};
use std::list::{List, Nil, Cons}; 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 region::is_subregion_of;
use syntax::codemap; use syntax::codemap;
use to_str::to_str; use to_str::to_str;
@@ -324,9 +324,9 @@ export lub_regions;
export glb_regions; export glb_regions;
enum Constraint { enum Constraint {
ConstrainVarSubVar(region_vid, region_vid), ConstrainVarSubVar(RegionVid, RegionVid),
ConstrainRegSubVar(region, region_vid), ConstrainRegSubVar(region, RegionVid),
ConstrainVarSubReg(region_vid, region) ConstrainVarSubReg(RegionVid, region)
} }
impl Constraint: cmp::Eq { impl Constraint: cmp::Eq {
@@ -361,12 +361,12 @@ impl TwoRegions: cmp::Eq {
enum UndoLogEntry { enum UndoLogEntry {
Snapshot, Snapshot,
AddVar(region_vid), AddVar(RegionVid),
AddConstraint(Constraint), AddConstraint(Constraint),
AddCombination(CombineMap, TwoRegions) AddCombination(CombineMap, TwoRegions)
} }
type CombineMap = hashmap<TwoRegions, region_vid>; type CombineMap = hashmap<TwoRegions, RegionVid>;
struct RegionVarBindings { struct RegionVarBindings {
tcx: ty::ctxt; tcx: ty::ctxt;
@@ -470,10 +470,10 @@ impl RegionVarBindings {
self.var_spans.len() self.var_spans.len()
} }
fn new_region_var(span: span) -> region_vid { fn new_region_var(span: span) -> RegionVid {
let id = self.num_vars(); let id = self.num_vars();
self.var_spans.push(span); self.var_spans.push(span);
let vid = region_vid(id); let vid = RegionVid(id);
if self.in_snapshot() { if self.in_snapshot() {
self.undo_log.push(AddVar(vid)); 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); debug!("RegionVarBindings: resolve_var(%?)", rid);
if self.values.is_empty() { if self.values.is_empty() {
self.tcx.sess.span_bug( self.tcx.sess.span_bug(
@@ -857,7 +857,7 @@ impl RegionVarBindings {
return graph; return graph;
fn insert_edge(graph: &mut Graph, fn insert_edge(graph: &mut Graph,
node_id: region_vid, node_id: RegionVid,
edge_dir: Direction, edge_dir: Direction,
edge_idx: uint) { edge_idx: uint) {
let edge_dir = edge_dir as uint; let edge_dir = edge_dir as uint;
@@ -893,7 +893,7 @@ impl RegionVarBindings {
} }
fn expand_node(a_region: region, fn expand_node(a_region: region,
b_vid: region_vid, b_vid: RegionVid,
b_node: &GraphNode) -> bool { b_node: &GraphNode) -> bool {
debug!("expand_node(%?, %? == %?)", debug!("expand_node(%?, %? == %?)",
a_region, b_vid, b_node.value); 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, a_node: &GraphNode,
b_region: region) -> bool { b_region: region) -> bool {
debug!("contract_node(%? == %?/%?, %?)", debug!("contract_node(%? == %?/%?, %?)",
@@ -980,7 +980,7 @@ impl RegionVarBindings {
}; };
fn check_node(self: &RegionVarBindings, fn check_node(self: &RegionVarBindings,
a_vid: region_vid, a_vid: RegionVid,
a_node: &GraphNode, a_node: &GraphNode,
a_region: region, a_region: region,
b_region: region) -> bool { b_region: region) -> bool {
@@ -993,7 +993,7 @@ impl RegionVarBindings {
} }
fn adjust_node(self: &RegionVarBindings, fn adjust_node(self: &RegionVarBindings,
a_vid: region_vid, a_vid: RegionVid,
a_node: &GraphNode, a_node: &GraphNode,
a_region: region, a_region: region,
b_region: region) -> bool { b_region: region) -> bool {
@@ -1051,7 +1051,7 @@ impl RegionVarBindings {
} }
ErrorValue => { ErrorValue => {
let node_vid = region_vid(idx); let node_vid = RegionVid(idx);
match node.classification { match node.classification {
Expanding => { Expanding => {
self.report_error_for_expanding_node( self.report_error_for_expanding_node(
@@ -1078,7 +1078,7 @@ impl RegionVarBindings {
fn report_error_for_expanding_node(graph: &Graph, fn report_error_for_expanding_node(graph: &Graph,
dup_map: TwoRegionsMap, dup_map: TwoRegionsMap,
node_idx: region_vid) { node_idx: RegionVid) {
// Errors in expanding nodes result from a lower-bound that is // Errors in expanding nodes result from a lower-bound that is
// not contained by an upper-bound. // not contained by an upper-bound.
let lower_bounds = let lower_bounds =
@@ -1130,7 +1130,7 @@ impl RegionVarBindings {
fn report_error_for_contracting_node(graph: &Graph, fn report_error_for_contracting_node(graph: &Graph,
dup_map: TwoRegionsMap, dup_map: TwoRegionsMap,
node_idx: region_vid) { node_idx: RegionVid) {
// Errors in contracting nodes result from two upper-bounds // Errors in contracting nodes result from two upper-bounds
// that have no intersection. // that have no intersection.
let upper_bounds = self.collect_concrete_regions(graph, node_idx, let upper_bounds = self.collect_concrete_regions(graph, node_idx,
@@ -1182,7 +1182,7 @@ impl RegionVarBindings {
} }
fn collect_concrete_regions(graph: &Graph, fn collect_concrete_regions(graph: &Graph,
orig_node_idx: region_vid, orig_node_idx: RegionVid,
dir: Direction) -> ~[SpannedRegion] { dir: Direction) -> ~[SpannedRegion] {
let set = uint_hash(); let set = uint_hash();
let mut stack = ~[orig_node_idx]; let mut stack = ~[orig_node_idx];
@@ -1224,7 +1224,7 @@ impl RegionVarBindings {
} }
fn each_edge(graph: &Graph, fn each_edge(graph: &Graph,
node_idx: region_vid, node_idx: RegionVid,
dir: Direction, dir: Direction,
op: fn(edge: &GraphEdge) -> bool) { op: fn(edge: &GraphEdge) -> bool) {
let mut edge_idx = graph.nodes[*node_idx].head_edge[dir as uint]; 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, infcx: infer_ctxt,
modes: uint, modes: uint,
mut err: Option<fixup_err>, mut err: Option<fixup_err>,
mut v_seen: ~[ty_vid] mut v_seen: ~[TyVid]
}; };
enum resolve_state { 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) { if !self.should(resolve_rvar) {
return ty::re_var(rid) return ty::re_var(rid)
} }
self.infcx.region_vars.resolve_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 { match r {
ty::re_var(rid2) => { ty::re_var(rid2) => {
self.err = Some(region_var_bound_by_region_var(rid, 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) { if vec::contains(self.v_seen, vid) {
self.err = Some(cyclic_ty(vid)); self.err = Some(cyclic_ty(vid));
return ty::mk_var(self.infcx.tcx, 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) { if !self.should(resolve_ivar) {
return ty::mk_int_var(self.infcx.tcx, vid); 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` // 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 // as-is, we need to do some extra work here in order to make sure
// that function subtyping works correctly with respect to regions // that function subtyping works correctly with respect to regions
@@ -171,6 +171,14 @@ impl Sub: combine {
super_flds(&self, a, b) 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, fn vstores(vk: ty::terr_vstore_kind,
a: ty::vstore, b: ty::vstore) -> cres<ty::vstore> { a: ty::vstore, b: ty::vstore) -> cres<ty::vstore> {
super_vstores(&self, vk, a, b) 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>( fn set_var_to_merged_bounds<C: combine>(
self: &C, self: &C,
v_id: ty::ty_vid, v_id: ty::TyVid,
a: bounds<ty::t>, a: bounds<ty::t>,
b: bounds<ty::t>, b: bounds<ty::t>,
rank: uint) -> ures { 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 /// subtle and tricky process, as described in detail at the top
/// of infer.rs /// of infer.rs
fn var_sub_var<C: combine>(self: &C, fn var_sub_var<C: combine>(self: &C,
a_id: ty::ty_vid, a_id: ty::TyVid,
b_id: ty::ty_vid) -> ures { b_id: ty::TyVid) -> ures {
let vb = &self.infcx().ty_var_bindings; let vb = &self.infcx().ty_var_bindings;
// Need to make sub_id a subtype of sup_id. // 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 /// 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 vb = &self.infcx().ty_var_bindings;
let nde_a = self.infcx().get(vb, a_id); 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 /// 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 vb = &self.infcx().ty_var_bindings;
let a_bounds = {lb: Some(a), ub: None}; let a_bounds = {lb: Some(a), ub: None};
@@ -294,7 +294,7 @@ fn bnds<C: combine>(
// Integral variables // Integral variables
impl infer_ctxt { 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 vb = &self.int_var_bindings;
let nde_a = self.get(vb, a_id); let nde_a = self.get(vb, a_id);
@@ -340,7 +340,7 @@ impl infer_ctxt {
uok() 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); assert ty::type_is_integral(b);
let vb = &self.int_var_bindings; let vb = &self.int_var_bindings;
@@ -358,7 +358,7 @@ impl infer_ctxt {
uok() 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); assert ty::type_is_integral(a);
let vb = &self.int_var_bindings; 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 { fn method_to_str(cx: ctxt, m: method) -> ~str {
return fn_to_str( return fn_to_str(
cx, m.fty.purity, m.fty.proto, Some(m.ident), m.fty.inputs, cx, m.fty.meta.purity, m.fty.meta.proto, Some(m.ident),
m.fty.output, m.fty.ret_style) + ~";"; m.fty.sig.inputs, m.fty.sig.output,
m.fty.meta.ret_style) + ~";";
} }
fn field_to_str(cx: ctxt, f: field) -> ~str { fn field_to_str(cx: ctxt, f: field) -> ~str {
return cx.sess.str_of(f.ident) + ~": " + mt_to_str(cx, f.mt); 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)); } for elems.each |elem| { vec::push(strs, ty_to_str(cx, elem)); }
~"(" + str::connect(strs, ~",") + ~")" ~"(" + str::connect(strs, ~",") + ~")"
} }
ty_fn(f) => { ty_fn(ref f) => {
fn_to_str(cx, f.purity, f.proto, None, f.inputs, fn_to_str(cx, f.meta.purity, f.meta.proto, None, f.sig.inputs,
f.output, f.ret_style) f.sig.output, f.meta.ret_style)
} }
ty_infer(infer_ty) => infer_ty.to_str(), ty_infer(infer_ty) => infer_ty.to_str(),
ty_param({idx: id, _}) => { ty_param({idx: id, _}) => {