diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2012-08-06 18:54:20 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2012-08-06 18:55:24 -0700 |
| commit | 60f47eabe2ef2730b98713dee2b5fd59513e8c6c (patch) | |
| tree | cf491427dd1bfac38de4fd93d934702db9669fda /src/rustc | |
| parent | c0f7ed68e235b61a2e9710864a2283f554bb470d (diff) | |
rustc: Parse and stub (broken) typechecking for bounded function types
Diffstat (limited to 'src/rustc')
| -rw-r--r-- | src/rustc/metadata/tydecode.rs | 5 | ||||
| -rw-r--r-- | src/rustc/metadata/tyencode.rs | 1 | ||||
| -rw-r--r-- | src/rustc/middle/trans/base.rs | 2 | ||||
| -rw-r--r-- | src/rustc/middle/trans/foreign.rs | 1 | ||||
| -rw-r--r-- | src/rustc/middle/ty.rs | 4 | ||||
| -rw-r--r-- | src/rustc/middle/typeck.rs | 2 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/astconv.rs | 9 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/check.rs | 4 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/collect.rs | 66 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/infer.rs | 1 |
10 files changed, 57 insertions, 38 deletions
diff --git a/src/rustc/metadata/tydecode.rs b/src/rustc/metadata/tydecode.rs index a834147af96..e66d0cef71b 100644 --- a/src/rustc/metadata/tydecode.rs +++ b/src/rustc/metadata/tydecode.rs @@ -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}; } diff --git a/src/rustc/metadata/tyencode.rs b/src/rustc/metadata/tyencode.rs index 458dc149802..9e67157b181 100644 --- a/src/rustc/metadata/tyencode.rs +++ b/src/rustc/metadata/tyencode.rs @@ -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); diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 2f090cdab7c..16c08641e17 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -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})) diff --git a/src/rustc/middle/trans/foreign.rs b/src/rustc/middle/trans/foreign.rs index 1555f2df89a..27f7c8c0183 100644 --- a/src/rustc/middle/trans/foreign.rs +++ b/src/rustc/middle/trans/foreign.rs @@ -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( diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index 814e0cc2f15..91eb030ec03 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -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}; diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index e96fe4e8679..c91607bc9d1 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -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,_)) => { diff --git a/src/rustc/middle/typeck/astconv.rs b/src/rustc/middle/typeck/astconv.rs index fffc70e9525..c9008bc1389 100644 --- a/src/rustc/middle/typeck/astconv.rs +++ b/src/rustc/middle/typeck/astconv.rs @@ -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} } } diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index efe728f9e12..2c6be53601c 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -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)); diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs index c1211d79a7e..ce41330d25d 100644 --- a/src/rustc/middle/typeck/collect.rs +++ b/src/rustc/middle/typeck/collect.rs @@ -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 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"); - ~[] - } - } +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] { + @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}); diff --git a/src/rustc/middle/typeck/infer.rs b/src/rustc/middle/typeck/infer.rs index 8c9cbc07598..42291ea30c7 100644 --- a/src/rustc/middle/typeck/infer.rs +++ b/src/rustc/middle/typeck/infer.rs @@ -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}) |
