Skip to content

Commit 60f47ea

Browse files
committed
rustc: Parse and stub (broken) typechecking for bounded function types
1 parent c0f7ed6 commit 60f47ea

File tree

17 files changed

+117
-70
lines changed

17 files changed

+117
-70
lines changed

src/libsyntax/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ enum ty_ {
558558
ty_ptr(mt),
559559
ty_rptr(@region, mt),
560560
ty_rec(~[ty_field]),
561-
ty_fn(proto, fn_decl),
561+
ty_fn(proto, @~[ty_param_bound], fn_decl),
562562
ty_tup(~[@ty]),
563563
ty_path(@path, node_id),
564564
ty_fixed_length(@ty, option<uint>),

src/libsyntax/ext/auto_serialize.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,12 @@ impl helpers of ext_ctxt_helpers for ext_ctxt {
186186
};
187187

188188
@{id: self.next_id(),
189-
node: ast::ty_fn(ast::proto_block, {inputs: args,
190-
output: output,
191-
purity: ast::impure_fn,
192-
cf: ast::return_val}),
189+
node: ast::ty_fn(ast::proto_block,
190+
@~[],
191+
{inputs: args,
192+
output: output,
193+
purity: ast::impure_fn,
194+
cf: ast::return_val}),
193195
span: span}
194196
}
195197

@@ -441,7 +443,7 @@ fn ser_ty(cx: ext_ctxt, tps: ser_tps_map,
441443
~[#ast[stmt]{$(s).emit_rec($(fld_lambda));}]
442444
}
443445

444-
ast::ty_fn(_, _) => {
446+
ast::ty_fn(*) => {
445447
cx.span_err(ty.span, ~"cannot serialize function types");
446448
~[]
447449
}
@@ -681,7 +683,7 @@ fn deser_ty(cx: ext_ctxt, tps: deser_tps_map,
681683
#ast{ $(d).read_rec($(fld_lambda)) }
682684
}
683685

684-
ast::ty_fn(_, _) => {
686+
ast::ty_fn(*) => {
685687
#ast{ fail }
686688
}
687689

src/libsyntax/fold.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,10 @@ fn noop_fold_ty(t: ty_, fld: ast_fold) -> ty_ {
514514
ty_ptr(mt) => ty_ptr(fold_mt(mt, fld)),
515515
ty_rptr(region, mt) => ty_rptr(region, fold_mt(mt, fld)),
516516
ty_rec(fields) => ty_rec(vec::map(fields, |f| fold_field(f, fld))),
517-
ty_fn(proto, decl) => ty_fn(proto, fold_fn_decl(decl, fld)),
517+
ty_fn(proto, bounds, decl) =>
518+
ty_fn(proto, @vec::map(*bounds,
519+
|x| fold_ty_param_bound(x, fld)),
520+
fold_fn_decl(decl, fld)),
518521
ty_tup(tys) => ty_tup(vec::map(tys, |ty| fld.fold_ty(ty))),
519522
ty_path(path, id) => ty_path(fld.fold_path(path), fld.new_id(id)),
520523
ty_fixed_length(t, vs) => ty_fixed_length(fld.fold_ty(t), vs),

src/libsyntax/parse/parser.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
5050
stmt_semi, subtract, sty_box, sty_by_ref, sty_region, sty_uniq,
5151
sty_value, token_tree, trait_method, trait_ref, tt_delim, tt_seq,
5252
tt_tok, tt_nonterminal, ty, ty_, ty_bot, ty_box, ty_field, ty_fn,
53-
ty_infer, ty_mac, ty_method, ty_nil, ty_param, ty_path, ty_ptr,
54-
ty_rec, ty_rptr, ty_tup, ty_u32, ty_uniq, ty_vec,
55-
ty_fixed_length, unchecked_blk, uniq, unsafe_blk, unsafe_fn,
56-
variant, view_item, view_item_, view_item_export,
53+
ty_infer, ty_mac, ty_method, ty_nil, ty_param, ty_param_bound,
54+
ty_path, ty_ptr, ty_rec, ty_rptr, ty_tup, ty_u32, ty_uniq,
55+
ty_vec, ty_fixed_length, unchecked_blk, uniq, unsafe_blk,
56+
unsafe_fn, variant, view_item, view_item_, view_item_export,
5757
view_item_import, view_item_use, view_path, view_path_glob,
5858
view_path_list, view_path_simple, visibility, vstore, vstore_box,
5959
vstore_fixed, vstore_slice, vstore_uniq};
@@ -240,14 +240,17 @@ class parser {
240240
fn get_id() -> node_id { next_node_id(self.sess) }
241241

242242
fn parse_ty_fn(purity: ast::purity) -> ty_ {
243-
let proto = if self.eat_keyword(~"extern") {
243+
let proto, bounds;
244+
if self.eat_keyword(~"extern") {
244245
self.expect_keyword(~"fn");
245-
ast::proto_bare
246+
proto = ast::proto_bare;
247+
bounds = @~[];
246248
} else {
247249
self.expect_keyword(~"fn");
248-
self.parse_fn_ty_proto()
250+
proto = self.parse_fn_ty_proto();
251+
bounds = self.parse_optional_ty_param_bounds();
249252
};
250-
ty_fn(proto, self.parse_ty_fn_decl(purity))
253+
ty_fn(proto, bounds, self.parse_ty_fn_decl(purity))
251254
}
252255

253256
fn parse_ty_fn_decl(purity: ast::purity) -> fn_decl {
@@ -467,7 +470,7 @@ class parser {
467470
self.parse_ty_fn(ast::impure_fn)
468471
} else if self.eat_keyword(~"extern") {
469472
self.expect_keyword(~"fn");
470-
ty_fn(proto_bare, self.parse_ty_fn_decl(ast::impure_fn))
473+
ty_fn(proto_bare, @~[], self.parse_ty_fn_decl(ast::impure_fn))
471474
} else if self.token == token::MOD_SEP || is_ident(self.token) {
472475
let path = self.parse_path_with_tps(colons_before_params);
473476
ty_path(path, self.get_id())
@@ -2125,11 +2128,10 @@ class parser {
21252128
return spanned(lo, hi, bloc);
21262129
}
21272130

2128-
fn parse_ty_param() -> ty_param {
2131+
fn parse_optional_ty_param_bounds() -> @~[ty_param_bound] {
21292132
let mut bounds = ~[];
2130-
let ident = self.parse_ident();
21312133
if self.eat(token::COLON) {
2132-
while self.token != token::COMMA && self.token != token::GT {
2134+
while is_ident(self.token) {
21332135
if self.eat_keyword(~"send") {
21342136
push(bounds, bound_send); }
21352137
else if self.eat_keyword(~"copy") {
@@ -2139,10 +2141,17 @@ class parser {
21392141
} else if self.eat_keyword(~"owned") {
21402142
push(bounds, bound_owned);
21412143
} else {
2142-
push(bounds, bound_trait(self.parse_ty(false))); }
2144+
push(bounds, bound_trait(self.parse_ty(false)));
2145+
}
21432146
}
21442147
}
2145-
return {ident: ident, id: self.get_id(), bounds: @bounds};
2148+
return @move bounds;
2149+
}
2150+
2151+
fn parse_ty_param() -> ty_param {
2152+
let ident = self.parse_ident();
2153+
let bounds = self.parse_optional_ty_param_bounds();
2154+
return {ident: ident, id: self.get_id(), bounds: bounds};
21462155
}
21472156

21482157
fn parse_ty_params() -> ~[ty_param] {

src/libsyntax/print/pprust.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,8 @@ fn print_type_ex(s: ps, &&ty: @ast::ty, print_colons: bool) {
399399
commasep(s, inconsistent, elts, print_type);
400400
pclose(s);
401401
}
402-
ast::ty_fn(proto, d) => {
403-
print_ty_fn(s, some(proto), d, none, none);
402+
ast::ty_fn(proto, bounds, d) => {
403+
print_ty_fn(s, some(proto), bounds, d, none, none);
404404
}
405405
ast::ty_path(path, _) => print_path(s, path, print_colons),
406406
ast::ty_fixed_length(t, v) => {
@@ -702,7 +702,7 @@ fn print_ty_method(s: ps, m: ast::ty_method) {
702702
hardbreak_if_not_bol(s);
703703
maybe_print_comment(s, m.span.lo);
704704
print_outer_attributes(s, m.attrs);
705-
print_ty_fn(s, none, m.decl, some(m.ident), some(m.tps));
705+
print_ty_fn(s, none, @~[], m.decl, some(m.ident), some(m.tps));
706706
word(s.s, ~";");
707707
}
708708
@@ -1645,10 +1645,12 @@ fn print_arg(s: ps, input: ast::arg) {
16451645
}
16461646

16471647
fn print_ty_fn(s: ps, opt_proto: option<ast::proto>,
1648+
bounds: @~[ast::ty_param_bound],
16481649
decl: ast::fn_decl, id: option<ast::ident>,
16491650
tps: option<~[ast::ty_param]>) {
16501651
ibox(s, indent_unit);
16511652
word(s.s, opt_proto_to_str(opt_proto));
1653+
print_bounds(s, bounds);
16521654
match id { some(id) => { word(s.s, ~" "); word(s.s, *id); } _ => () }
16531655
match tps { some(tps) => print_type_params(s, tps), _ => () }
16541656
zerobreak(s.s);

src/libsyntax/visit.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,9 @@ fn visit_ty<E>(t: @ty, e: E, v: vt<E>) {
195195
ty_tup(ts) => for ts.each |tt| {
196196
v.visit_ty(tt, e, v);
197197
}
198-
ty_fn(_, decl) => {
198+
ty_fn(_, bounds, decl) => {
199199
for decl.inputs.each |a| { v.visit_ty(a.ty, e, v); }
200+
visit_ty_param_bounds(bounds, e, v);
200201
v.visit_ty(decl.output, e, v);
201202
}
202203
ty_path(p, _) => visit_path(p, e, v),
@@ -251,14 +252,18 @@ fn visit_foreign_item<E>(ni: @foreign_item, e: E, v: vt<E>) {
251252
}
252253
}
253254

255+
fn visit_ty_param_bounds<E>(bounds: @~[ty_param_bound], e: E, v: vt<E>) {
256+
for vec::each(*bounds) |bound| {
257+
match bound {
258+
bound_trait(t) => v.visit_ty(t, e, v),
259+
bound_copy | bound_send | bound_const | bound_owned => ()
260+
}
261+
}
262+
}
263+
254264
fn visit_ty_params<E>(tps: ~[ty_param], e: E, v: vt<E>) {
255265
for tps.each |tp| {
256-
for vec::each(*tp.bounds) |bound| {
257-
match bound {
258-
bound_trait(t) => v.visit_ty(t, e, v),
259-
bound_copy | bound_send | bound_const | bound_owned => ()
260-
}
261-
}
266+
visit_ty_param_bounds(tp.bounds, e, v);
262267
}
263268
}
264269

src/rustc/metadata/tydecode.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ fn parse_purity(c: char) -> purity {
362362
fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::fn_ty {
363363
let proto = parse_proto(next(st));
364364
let purity = parse_purity(next(st));
365+
let bounds = parse_bounds(st, conv);
365366
assert (next(st) == '[');
366367
let mut inputs: ~[ty::arg] = ~[];
367368
while peek(st) != ']' {
@@ -377,8 +378,8 @@ fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::fn_ty {
377378
}
378379
st.pos += 1u; // eat the ']'
379380
let (ret_style, ret_ty) = parse_ret_ty(st, conv);
380-
return {purity: purity, proto: proto, inputs: inputs, output: ret_ty,
381-
ret_style: ret_style};
381+
return {purity: purity, proto: proto, bounds: bounds, inputs: inputs,
382+
output: ret_ty, ret_style: ret_style};
382383
}
383384

384385

src/rustc/metadata/tyencode.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ fn enc_purity(w: io::writer, p: purity) {
337337
fn enc_ty_fn(w: io::writer, cx: @ctxt, ft: ty::fn_ty) {
338338
enc_proto(w, ft.proto);
339339
enc_purity(w, ft.purity);
340+
enc_bounds(w, cx, ft.bounds);
340341
w.write_char('[');
341342
for ft.inputs.each |arg| {
342343
enc_mode(w, cx, arg.mode);

src/rustc/middle/trans/base.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1982,13 +1982,15 @@ fn normalize_for_monomorphization(tcx: ty::ctxt, ty: ty::t) -> option<ty::t> {
19821982
ty::ty_fn(fty) => {
19831983
some(ty::mk_fn(tcx, {purity: ast::impure_fn,
19841984
proto: fty.proto,
1985+
bounds: @~[],
19851986
inputs: ~[],
19861987
output: ty::mk_nil(tcx),
19871988
ret_style: ast::return_val}))
19881989
}
19891990
ty::ty_trait(_, _) => {
19901991
some(ty::mk_fn(tcx, {purity: ast::impure_fn,
19911992
proto: ast::proto_box,
1993+
bounds: @~[],
19921994
inputs: ~[],
19931995
output: ty::mk_nil(tcx),
19941996
ret_style: ast::return_val}))

src/rustc/middle/trans/foreign.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,7 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
961961
let fty = ty::mk_fn(bcx.tcx(), {
962962
purity: ast::impure_fn,
963963
proto: ast::proto_block,
964+
bounds: @~[],
964965
inputs: ~[{
965966
mode: ast::expl(ast::by_val),
966967
ty: ty::mk_imm_ptr(

src/rustc/middle/ty.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,11 +316,13 @@ enum closure_kind {
316316
///
317317
/// - `purity` is the function's effect (pure, impure, unsafe).
318318
/// - `proto` is the protocol (fn@, fn~, etc).
319+
/// - `bound` is the parameter bounds on the function's upvars.
319320
/// - `inputs` is the list of arguments and their modes.
320321
/// - `output` is the return type.
321-
/// - `ret_style`indicates whether the function returns a value or fails.
322+
/// - `ret_style` indicates whether the function returns a value or fails.
322323
type fn_ty = {purity: ast::purity,
323324
proto: ast::proto,
325+
bounds: @~[param_bound],
324326
inputs: ~[arg],
325327
output: t,
326328
ret_style: ret_style};

src/rustc/middle/typeck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ fn check_main_fn_ty(ccx: @crate_ctxt,
246246
let tcx = ccx.tcx;
247247
let main_t = ty::node_id_to_type(tcx, main_id);
248248
match ty::get(main_t).struct {
249-
ty::ty_fn({purity: ast::impure_fn, proto: ast::proto_bare,
249+
ty::ty_fn({purity: ast::impure_fn, proto: ast::proto_bare, bounds,
250250
inputs, output, ret_style: ast::return_val}) => {
251251
match tcx.items.find(main_id) {
252252
some(ast_map::node_item(it,_)) => {

src/rustc/middle/typeck/astconv.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,10 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope copy owned>(
261261
};
262262
ty::mk_rec(tcx, flds)
263263
}
264-
ast::ty_fn(proto, decl) => {
265-
ty::mk_fn(tcx, ty_of_fn_decl(self, rscope, proto, decl, none))
264+
ast::ty_fn(proto, ast_bounds, decl) => {
265+
let bounds = collect::compute_bounds(self.ccx(), ast_bounds);
266+
let fn_decl = ty_of_fn_decl(self, rscope, proto, bounds, decl, none);
267+
ty::mk_fn(tcx, fn_decl)
266268
}
267269
ast::ty_path(path, id) => {
268270
let a_def = match tcx.def_map.find(id) {
@@ -398,6 +400,7 @@ type expected_tys = option<{inputs: ~[ty::arg],
398400
fn ty_of_fn_decl<AC: ast_conv, RS: region_scope copy owned>(
399401
self: AC, rscope: RS,
400402
proto: ast::proto,
403+
bounds: @~[ty::param_bound],
401404
decl: ast::fn_decl,
402405
expected_tys: expected_tys) -> ty::fn_ty {
403406

@@ -423,7 +426,7 @@ fn ty_of_fn_decl<AC: ast_conv, RS: region_scope copy owned>(
423426
_ => ast_ty_to_ty(self, rb, decl.output)
424427
};
425428

426-
{purity: decl.purity, proto: proto, inputs: input_tys,
429+
{purity: decl.purity, proto: proto, bounds: bounds, inputs: input_tys,
427430
output: output_ty, ret_style: decl.cf}
428431
}
429432
}

src/rustc/middle/typeck/check.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1135,7 +1135,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
11351135
};
11361136

11371137
// construct the function type
1138-
let fn_ty = astconv::ty_of_fn_decl(fcx, fcx, proto,
1138+
let fn_ty = astconv::ty_of_fn_decl(fcx, fcx, proto, @~[],
11391139
decl, expected_tys);
11401140
let fty = ty::mk_fn(tcx, fn_ty);
11411141

@@ -2401,6 +2401,7 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
24012401
let fty = ty::mk_fn(ccx.tcx, {
24022402
purity: ast::impure_fn,
24032403
proto: ast::proto_block,
2404+
bounds: @~[],
24042405
inputs: ~[{
24052406
mode: ast::expl(ast::by_val),
24062407
ty: ty::mk_imm_ptr(
@@ -2420,6 +2421,7 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
24202421
};
24212422
let fty = ty::mk_fn(tcx, {purity: ast::impure_fn,
24222423
proto: ast::proto_bare,
2424+
bounds: @~[],
24232425
inputs: inputs, output: output,
24242426
ret_style: ast::return_val});
24252427
let i_ty = ty::lookup_item_type(ccx.tcx, local_def(it.id));

0 commit comments

Comments
 (0)