rustc: Parse and stub (broken) typechecking for bounded function types
This commit is contained in:
@@ -362,6 +362,7 @@ fn parse_purity(c: char) -> purity {
|
||||
fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::fn_ty {
|
||||
let proto = parse_proto(next(st));
|
||||
let purity = parse_purity(next(st));
|
||||
let bounds = parse_bounds(st, conv);
|
||||
assert (next(st) == '[');
|
||||
let mut inputs: ~[ty::arg] = ~[];
|
||||
while peek(st) != ']' {
|
||||
@@ -377,8 +378,8 @@ 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, inputs: inputs, output: ret_ty,
|
||||
ret_style: ret_style};
|
||||
return {purity: purity, proto: proto, bounds: bounds, inputs: inputs,
|
||||
output: ret_ty, ret_style: ret_style};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -337,6 +337,7 @@ fn enc_purity(w: io::writer, p: purity) {
|
||||
fn enc_ty_fn(w: io::writer, cx: @ctxt, ft: ty::fn_ty) {
|
||||
enc_proto(w, ft.proto);
|
||||
enc_purity(w, ft.purity);
|
||||
enc_bounds(w, cx, ft.bounds);
|
||||
w.write_char('[');
|
||||
for ft.inputs.each |arg| {
|
||||
enc_mode(w, cx, arg.mode);
|
||||
|
||||
@@ -1982,6 +1982,7 @@ fn normalize_for_monomorphization(tcx: ty::ctxt, ty: ty::t) -> option<ty::t> {
|
||||
ty::ty_fn(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}))
|
||||
@@ -1989,6 +1990,7 @@ fn normalize_for_monomorphization(tcx: ty::ctxt, ty: ty::t) -> option<ty::t> {
|
||||
ty::ty_trait(_, _) => {
|
||||
some(ty::mk_fn(tcx, {purity: ast::impure_fn,
|
||||
proto: ast::proto_box,
|
||||
bounds: @~[],
|
||||
inputs: ~[],
|
||||
output: ty::mk_nil(tcx),
|
||||
ret_style: ast::return_val}))
|
||||
|
||||
@@ -961,6 +961,7 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
|
||||
let fty = ty::mk_fn(bcx.tcx(), {
|
||||
purity: ast::impure_fn,
|
||||
proto: ast::proto_block,
|
||||
bounds: @~[],
|
||||
inputs: ~[{
|
||||
mode: ast::expl(ast::by_val),
|
||||
ty: ty::mk_imm_ptr(
|
||||
|
||||
@@ -316,11 +316,13 @@ enum closure_kind {
|
||||
///
|
||||
/// - `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.
|
||||
/// - `ret_style` indicates whether the function returns a value or fails.
|
||||
type fn_ty = {purity: ast::purity,
|
||||
proto: ast::proto,
|
||||
bounds: @~[param_bound],
|
||||
inputs: ~[arg],
|
||||
output: t,
|
||||
ret_style: ret_style};
|
||||
|
||||
@@ -246,7 +246,7 @@ 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: ast::proto_bare,
|
||||
ty::ty_fn({purity: ast::impure_fn, proto: ast::proto_bare, bounds,
|
||||
inputs, output, ret_style: ast::return_val}) => {
|
||||
match tcx.items.find(main_id) {
|
||||
some(ast_map::node_item(it,_)) => {
|
||||
|
||||
@@ -261,8 +261,10 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope copy owned>(
|
||||
};
|
||||
ty::mk_rec(tcx, flds)
|
||||
}
|
||||
ast::ty_fn(proto, decl) => {
|
||||
ty::mk_fn(tcx, ty_of_fn_decl(self, rscope, proto, decl, none))
|
||||
ast::ty_fn(proto, ast_bounds, decl) => {
|
||||
let bounds = collect::compute_bounds(self.ccx(), ast_bounds);
|
||||
let fn_decl = ty_of_fn_decl(self, rscope, proto, bounds, decl, none);
|
||||
ty::mk_fn(tcx, fn_decl)
|
||||
}
|
||||
ast::ty_path(path, id) => {
|
||||
let a_def = match tcx.def_map.find(id) {
|
||||
@@ -398,6 +400,7 @@ type expected_tys = option<{inputs: ~[ty::arg],
|
||||
fn ty_of_fn_decl<AC: ast_conv, RS: region_scope copy owned>(
|
||||
self: AC, rscope: RS,
|
||||
proto: ast::proto,
|
||||
bounds: @~[ty::param_bound],
|
||||
decl: ast::fn_decl,
|
||||
expected_tys: expected_tys) -> ty::fn_ty {
|
||||
|
||||
@@ -423,7 +426,7 @@ fn ty_of_fn_decl<AC: ast_conv, RS: region_scope copy owned>(
|
||||
_ => ast_ty_to_ty(self, rb, decl.output)
|
||||
};
|
||||
|
||||
{purity: decl.purity, proto: proto, inputs: input_tys,
|
||||
{purity: decl.purity, proto: proto, bounds: bounds, inputs: input_tys,
|
||||
output: output_ty, ret_style: decl.cf}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1135,7 +1135,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||
};
|
||||
|
||||
// construct the function type
|
||||
let fn_ty = astconv::ty_of_fn_decl(fcx, fcx, proto,
|
||||
let fn_ty = astconv::ty_of_fn_decl(fcx, fcx, proto, @~[],
|
||||
decl, expected_tys);
|
||||
let fty = ty::mk_fn(tcx, fn_ty);
|
||||
|
||||
@@ -2401,6 +2401,7 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
|
||||
let fty = ty::mk_fn(ccx.tcx, {
|
||||
purity: ast::impure_fn,
|
||||
proto: ast::proto_block,
|
||||
bounds: @~[],
|
||||
inputs: ~[{
|
||||
mode: ast::expl(ast::by_val),
|
||||
ty: ty::mk_imm_ptr(
|
||||
@@ -2420,6 +2421,7 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
|
||||
};
|
||||
let fty = ty::mk_fn(tcx, {purity: ast::impure_fn,
|
||||
proto: ast::proto_bare,
|
||||
bounds: @~[],
|
||||
inputs: inputs, output: output,
|
||||
ret_style: ast::return_val});
|
||||
let i_ty = ty::lookup_item_type(ccx.tcx, local_def(it.id));
|
||||
|
||||
@@ -125,6 +125,7 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
|
||||
});
|
||||
ty::mk_fn(tcx, {purity: ast::pure_fn,
|
||||
proto: ast::proto_box,
|
||||
bounds: @~[],
|
||||
inputs: args,
|
||||
output: enum_ty,
|
||||
ret_style: ast::return_val})
|
||||
@@ -396,6 +397,7 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
|
||||
let t_ctor = ty::mk_fn(
|
||||
tcx, {purity: ast::impure_fn,
|
||||
proto: ast::proto_block,
|
||||
bounds: @~[],
|
||||
inputs: t_args,
|
||||
output: t_res,
|
||||
ret_style: ast::return_val});
|
||||
@@ -410,7 +412,7 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
|
||||
// Write the dtor type
|
||||
let t_dtor = ty::mk_fn(
|
||||
tcx,
|
||||
ty_of_fn_decl(ccx, type_rscope(rp), ast::proto_block,
|
||||
ty_of_fn_decl(ccx, type_rscope(rp), ast::proto_block, @~[],
|
||||
ast_util::dtor_dec(), none));
|
||||
write_ty_to_tcx(tcx, dtor.node.id, t_dtor);
|
||||
tcx.tcache.insert(local_def(dtor.node.id),
|
||||
@@ -460,9 +462,10 @@ fn convert_foreign(ccx: @crate_ctxt, i: @ast::foreign_item) {
|
||||
fn ty_of_method(ccx: @crate_ctxt,
|
||||
m: @ast::method,
|
||||
rp: bool) -> ty::method {
|
||||
// XXX: Are the bounds correct here?
|
||||
{ident: m.ident,
|
||||
tps: ty_param_bounds(ccx, m.tps),
|
||||
fty: ty_of_fn_decl(ccx, type_rscope(rp), ast::proto_bare,
|
||||
fty: ty_of_fn_decl(ccx, type_rscope(rp), ast::proto_bare, @~[],
|
||||
m.decl, none),
|
||||
self_ty: m.self_ty.node,
|
||||
purity: m.decl.purity,
|
||||
@@ -474,8 +477,8 @@ fn ty_of_ty_method(self: @crate_ctxt,
|
||||
rp: bool) -> ty::method {
|
||||
{ident: m.ident,
|
||||
tps: ty_param_bounds(self, m.tps),
|
||||
fty: ty_of_fn_decl(self, type_rscope(rp), ast::proto_bare,
|
||||
m.decl, none),
|
||||
fty: ty_of_fn_decl(self, type_rscope(rp), ast::proto_bare, @~[], m.decl,
|
||||
none),
|
||||
// assume public, because this is only invoked on trait methods
|
||||
self_ty: m.self_ty.node,
|
||||
purity: m.decl.purity, vis: ast::public}
|
||||
@@ -528,8 +531,8 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item)
|
||||
}
|
||||
ast::item_fn(decl, tps, _) => {
|
||||
let bounds = ty_param_bounds(ccx, tps);
|
||||
let tofd = ty_of_fn_decl(ccx, empty_rscope, ast::proto_bare,
|
||||
decl, none);
|
||||
let tofd = ty_of_fn_decl(ccx, empty_rscope, ast::proto_bare, @~[],
|
||||
decl, none);
|
||||
let tpt = {bounds: bounds,
|
||||
rp: false, // functions do not have a self
|
||||
ty: ty::mk_fn(ccx.tcx, tofd)};
|
||||
@@ -599,40 +602,42 @@ fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_bounds(ccx: @crate_ctxt,
|
||||
ast_bounds: @~[ast::ty_param_bound]) -> ty::param_bounds {
|
||||
@do vec::flat_map(*ast_bounds) |b| {
|
||||
match b {
|
||||
ast::bound_send => ~[ty::bound_send],
|
||||
ast::bound_copy => ~[ty::bound_copy],
|
||||
ast::bound_const => ~[ty::bound_const],
|
||||
ast::bound_owned => ~[ty::bound_owned],
|
||||
ast::bound_trait(t) => {
|
||||
let ity = ast_ty_to_ty(ccx, empty_rscope, t);
|
||||
match ty::get(ity).struct {
|
||||
ty::ty_trait(*) => {
|
||||
~[ty::bound_trait(ity)]
|
||||
}
|
||||
_ => {
|
||||
ccx.tcx.sess.span_err(
|
||||
t.span, ~"type parameter bounds must be \
|
||||
trait types");
|
||||
~[]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn ty_param_bounds(ccx: @crate_ctxt,
|
||||
params: ~[ast::ty_param]) -> @~[ty::param_bounds] {
|
||||
|
||||
fn compute_bounds(ccx: @crate_ctxt,
|
||||
param: ast::ty_param) -> ty::param_bounds {
|
||||
@do vec::flat_map(*param.bounds) |b| {
|
||||
match b {
|
||||
ast::bound_send => ~[ty::bound_send],
|
||||
ast::bound_copy => ~[ty::bound_copy],
|
||||
ast::bound_const => ~[ty::bound_const],
|
||||
ast::bound_owned => ~[ty::bound_owned],
|
||||
ast::bound_trait(t) => {
|
||||
let ity = ast_ty_to_ty(ccx, empty_rscope, t);
|
||||
match ty::get(ity).struct {
|
||||
ty::ty_trait(*) => {
|
||||
~[ty::bound_trait(ity)]
|
||||
}
|
||||
_ => {
|
||||
ccx.tcx.sess.span_err(
|
||||
t.span, ~"type parameter bounds must be \
|
||||
trait types");
|
||||
~[]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@do params.map |param| {
|
||||
match ccx.tcx.ty_param_bounds.find(param.id) {
|
||||
some(bs) => bs,
|
||||
none => {
|
||||
let bounds = compute_bounds(ccx, param);
|
||||
let bounds = compute_bounds(ccx, param.bounds);
|
||||
ccx.tcx.ty_param_bounds.insert(param.id, bounds);
|
||||
bounds
|
||||
}
|
||||
@@ -652,6 +657,7 @@ fn ty_of_foreign_fn_decl(ccx: @crate_ctxt,
|
||||
|
||||
let t_fn = ty::mk_fn(ccx.tcx, {purity: decl.purity,
|
||||
proto: ast::proto_bare,
|
||||
bounds: @~[],
|
||||
inputs: input_tys,
|
||||
output: output_ty,
|
||||
ret_style: ast::return_val});
|
||||
|
||||
@@ -1717,6 +1717,7 @@ fn super_fns<C:combine>(
|
||||
// b_f.constraints).then {||
|
||||
ok({purity: purity,
|
||||
proto: p,
|
||||
bounds: a_f.bounds, // XXX: This is wrong!
|
||||
inputs: inputs,
|
||||
output: output,
|
||||
ret_style: rs})
|
||||
|
||||
Reference in New Issue
Block a user