diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 19b7e532bc2..b921fbf5a28 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -531,7 +531,7 @@ type ty_field_ = {ident: ident, mt: mt}; type ty_field = spanned<ty_field_>; #[auto_serialize] -type ty_method = {ident: ident, attrs: ~[attribute], +type ty_method = {ident: ident, attrs: ~[attribute], purity: purity, decl: fn_decl, tps: ~[ty_param], self_ty: self_ty, id: node_id, span: span}; @@ -582,7 +582,7 @@ enum ty_ { ty_ptr(mt), ty_rptr(@region, mt), ty_rec(~[ty_field]), - ty_fn(proto, @~[ty_param_bound], fn_decl), + ty_fn(proto, purity, @~[ty_param_bound], fn_decl), ty_tup(~[@ty]), ty_path(@path, node_id), ty_fixed_length(@ty, option<uint>), @@ -600,7 +600,6 @@ type arg = {mode: mode, ty: @ty, ident: ident, id: node_id}; type fn_decl = {inputs: ~[arg], output: @ty, - purity: purity, cf: ret_style}; #[auto_serialize] @@ -633,7 +632,8 @@ type self_ty = spanned<self_ty_>; #[auto_serialize] type method = {ident: ident, attrs: ~[attribute], - tps: ~[ty_param], self_ty: self_ty, decl: fn_decl, body: blk, + tps: ~[ty_param], self_ty: self_ty, + purity: purity, decl: fn_decl, body: blk, id: node_id, span: span, self_id: node_id, vis: visibility}; // always public, unless it's a // class method @@ -775,7 +775,7 @@ type item = {ident: ident, attrs: ~[attribute], #[auto_serialize] enum item_ { item_const(@ty, @expr), - item_fn(fn_decl, ~[ty_param], blk), + item_fn(fn_decl, purity, ~[ty_param], blk), item_mod(_mod), item_foreign_mod(foreign_mod), item_ty(@ty, ~[ty_param]), @@ -821,7 +821,7 @@ type foreign_item = #[auto_serialize] enum foreign_item_ { - foreign_item_fn(fn_decl, ~[ty_param]), + foreign_item_fn(fn_decl, purity, ~[ty_param]), } // The data we save and restore about an inlined item or method. This is not diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index fe1924d1dbe..9ea9cf000f9 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -311,7 +311,8 @@ fn trait_method_to_ty_method(method: trait_method) -> ty_method { required(m) => m, provided(m) => { {ident: m.ident, attrs: m.attrs, - decl: m.decl, tps: m.tps, self_ty: m.self_ty, + purity: m.purity, decl: m.decl, + tps: m.tps, self_ty: m.self_ty, id: m.id, span: m.span} } } @@ -411,7 +412,7 @@ fn dtor_dec() -> fn_decl { {inputs: ~[{mode: ast::expl(ast::by_ref), ty: nil_t, ident: parse::token::special_idents::underscore, id: 0}], - output: nil_t, purity: impure_fn, cf: return_val} + output: nil_t, cf: return_val} } // ______________________________________________________________________ @@ -515,7 +516,7 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> { vfn(self_id); vfn(parent_id.node); } - visit::fk_item_fn(_, tps) => { + visit::fk_item_fn(_, tps, _) => { vec::iter(tps, |tp| vfn(tp.id)); } visit::fk_method(_, tps, m) => { diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs index d094bfe6f01..beb255d2cb6 100644 --- a/src/libsyntax/ext/auto_serialize.rs +++ b/src/libsyntax/ext/auto_serialize.rs @@ -191,10 +191,10 @@ impl ext_ctxt: ext_ctxt_helpers { @{id: self.next_id(), node: ast::ty_fn(ast::proto_block, + ast::impure_fn, @~[], {inputs: args, output: output, - purity: ast::impure_fn, cf: ast::return_val}), span: span} } @@ -604,8 +604,8 @@ fn mk_ser_fn(cx: ext_ctxt, span: span, name: ast::ident, id: cx.next_id(), node: ast::item_fn({inputs: ser_inputs, output: ser_output, - purity: ast::impure_fn, cf: ast::return_val}, + ast::impure_fn, ser_tps, ser_blk), vis: ast::public, @@ -810,8 +810,8 @@ fn mk_deser_fn(cx: ext_ctxt, span: span, id: cx.next_id(), node: ast::item_fn({inputs: deser_inputs, output: v_ty, - purity: ast::impure_fn, cf: ast::return_val}, + ast::impure_fn, deser_tps, deser_blk), vis: ast::public, diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index 45873f81dea..8b134239fc1 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -203,7 +203,6 @@ impl ext_ctxt: ext_ctxt_ast_builder { output: @ast::ty) -> ast::fn_decl { {inputs: inputs, output: output, - purity: ast::impure_fn, cf: ast::return_val} } @@ -226,6 +225,7 @@ impl ext_ctxt: ext_ctxt_ast_builder { self.item(name, self.empty_span(), ast::item_fn(self.fn_decl(inputs, output), + ast::impure_fn, ty_params, body)) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 05191c677a0..3c06edb443b 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -127,7 +127,6 @@ fn fold_mac_(m: mac, fld: ast_fold) -> mac { fn fold_fn_decl(decl: ast::fn_decl, fld: ast_fold) -> ast::fn_decl { return {inputs: vec::map(decl.inputs, |x| fold_arg_(x, fld) ), output: fld.fold_ty(decl.output), - purity: decl.purity, cf: decl.cf} } @@ -190,12 +189,12 @@ fn noop_fold_foreign_item(&&ni: @foreign_item, fld: ast_fold) attrs: vec::map(ni.attrs, fold_attribute), node: match ni.node { - foreign_item_fn(fdec, typms) => { + foreign_item_fn(fdec, purity, typms) => { foreign_item_fn({inputs: vec::map(fdec.inputs, fold_arg), - output: fld.fold_ty(fdec.output), - purity: fdec.purity, - cf: fdec.cf}, - fold_ty_params(typms, fld)) + output: fld.fold_ty(fdec.output), + cf: fdec.cf}, + purity, + fold_ty_params(typms, fld)) } }, id: fld.new_id(ni.id), @@ -224,8 +223,9 @@ fn noop_fold_struct_field(&&sf: @struct_field, fld: ast_fold) fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { return match i { item_const(t, e) => item_const(fld.fold_ty(t), fld.fold_expr(e)), - item_fn(decl, typms, body) => { + item_fn(decl, purity, typms, body) => { item_fn(fold_fn_decl(decl, fld), + purity, fold_ty_params(typms, fld), fld.fold_block(body)) } @@ -314,6 +314,7 @@ fn noop_fold_method(&&m: @method, fld: ast_fold) -> @method { attrs: /* FIXME (#2543) */ copy m.attrs, tps: fold_ty_params(m.tps, fld), self_ty: m.self_ty, + purity: m.purity, decl: fold_fn_decl(m.decl, fld), body: fld.fold_block(m.body), id: fld.new_id(m.id), @@ -531,10 +532,11 @@ fn noop_fold_ty(t: ty_, fld: ast_fold) -> ty_ { ty_ptr(mt) => ty_ptr(fold_mt(mt, fld)), ty_rptr(region, mt) => ty_rptr(region, fold_mt(mt, fld)), ty_rec(fields) => ty_rec(vec::map(fields, |f| fold_field(f, fld))), - ty_fn(proto, bounds, decl) => - ty_fn(proto, @vec::map(*bounds, - |x| fold_ty_param_bound(x, fld)), - fold_fn_decl(decl, fld)), + ty_fn(proto, purity, bounds, decl) => + ty_fn(proto, purity, + @vec::map(*bounds, + |x| fold_ty_param_bound(x, fld)), + fold_fn_decl(decl, fld)), ty_tup(tys) => ty_tup(vec::map(tys, |ty| fld.fold_ty(ty))), ty_path(path, id) => ty_path(fld.fold_path(path), fld.new_id(id)), ty_fixed_length(t, vs) => ty_fixed_length(fld.fold_ty(t), vs), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3ee86bcae77..ff06c14c4fb 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -285,10 +285,10 @@ struct parser { proto = self.parse_fn_ty_proto(); bounds = self.parse_optional_ty_param_bounds(); }; - ty_fn(proto, bounds, self.parse_ty_fn_decl(purity)) + ty_fn(proto, purity, bounds, self.parse_ty_fn_decl()) } - fn parse_ty_fn_decl(purity: ast::purity) -> fn_decl { + fn parse_ty_fn_decl() -> fn_decl { let inputs = do self.parse_unspanned_seq( token::LPAREN, token::RPAREN, seq_sep_trailing_disallowed(token::COMMA)) |p| { @@ -297,7 +297,7 @@ struct parser { }; let (ret_style, ret_ty) = self.parse_ret_ty(); return {inputs: inputs, output: ret_ty, - purity: purity, cf: ret_style}; + cf: ret_style}; } fn parse_trait_methods() -> ~[trait_method] { @@ -316,7 +316,7 @@ struct parser { let tps = p.parse_ty_params(); - let (self_ty, d, _) = do self.parse_fn_decl_with_self(pur) |p| { + let (self_ty, d, _) = do self.parse_fn_decl_with_self() |p| { // This is somewhat dubious; We don't want to allow argument // names to be left off if there is a definition... either::Left(p.parse_arg_general(false)) @@ -335,7 +335,7 @@ struct parser { // NB: at the moment, visibility annotations on required // methods are ignored; this could change. required({ident: ident, attrs: attrs, - decl: {purity: pur with d}, tps: tps, + purity: pur, decl: d, tps: tps, self_ty: self_ty, id: p.get_id(), span: mk_sp(lo, hi)}) } @@ -348,6 +348,7 @@ struct parser { attrs: attrs, tps: tps, self_ty: self_ty, + purity: pur, decl: d, body: body, id: p.get_id(), @@ -518,7 +519,7 @@ struct parser { self.parse_ty_fn(ast::impure_fn) } else if self.eat_keyword(~"extern") { self.expect_keyword(~"fn"); - ty_fn(proto_bare, @~[], self.parse_ty_fn_decl(ast::impure_fn)) + ty_fn(proto_bare, ast::impure_fn, @~[], self.parse_ty_fn_decl()) } else if self.token == token::MOD_SEP || is_ident(self.token) { let path = self.parse_path_with_tps(colons_before_params); ty_path(path, self.get_id()) @@ -1492,8 +1493,7 @@ struct parser { // if we want to allow fn expression argument types to be inferred in // the future, just have to change parse_arg to parse_fn_block_arg. let (decl, capture_clause) = - self.parse_fn_decl(impure_fn, - |p| p.parse_arg_or_capture_item()); + self.parse_fn_decl(|p| p.parse_arg_or_capture_item()); let body = self.parse_block(); return self.mk_expr(lo, body.span.hi, @@ -1518,7 +1518,6 @@ struct parser { node: ty_infer, span: self.span }, - purity: impure_fn, cf: return_val } }, @@ -2281,8 +2280,7 @@ struct parser { } else { ~[] } } - fn parse_fn_decl(purity: purity, - parse_arg_fn: fn(parser) -> arg_or_capture_item) + fn parse_fn_decl(parse_arg_fn: fn(parser) -> arg_or_capture_item) -> (fn_decl, capture_clause) { let args_or_capture_items: ~[arg_or_capture_item] = @@ -2295,9 +2293,8 @@ struct parser { let (ret_style, ret_ty) = self.parse_ret_ty(); return ({inputs: inputs, - output: ret_ty, - purity: purity, - cf: ret_style}, capture_clause); + output: ret_ty, + cf: ret_style}, capture_clause); } fn is_self_ident() -> bool { @@ -2316,8 +2313,7 @@ struct parser { self.bump(); } - fn parse_fn_decl_with_self(purity: purity, - parse_arg_fn: + fn parse_fn_decl_with_self(parse_arg_fn: fn(parser) -> arg_or_capture_item) -> (self_ty, fn_decl, capture_clause) { @@ -2401,7 +2397,6 @@ struct parser { let fn_decl = { inputs: inputs, output: ret_ty, - purity: purity, cf: ret_style }; @@ -2425,10 +2420,9 @@ struct parser { @{id: self.get_id(), node: ty_infer, span: self.span} }; return ({inputs: either::lefts(inputs_captures), - output: output, - purity: impure_fn, - cf: return_val}, - @either::rights(inputs_captures)); + output: output, + cf: return_val}, + @either::rights(inputs_captures)); } fn parse_fn_header() -> {ident: ident, tps: ~[ty_param]} { @@ -2450,9 +2444,9 @@ struct parser { fn parse_item_fn(purity: purity) -> item_info { let t = self.parse_fn_header(); - let (decl, _) = self.parse_fn_decl(purity, |p| p.parse_arg()); + let (decl, _) = self.parse_fn_decl(|p| p.parse_arg()); let (inner_attrs, body) = self.parse_inner_attrs_and_block(true); - (t.ident, item_fn(decl, t.tps, body), some(inner_attrs)) + (t.ident, item_fn(decl, purity, t.tps, body), some(inner_attrs)) } fn parse_method_name() -> ident { @@ -2469,7 +2463,7 @@ struct parser { let pur = self.parse_fn_purity(); let ident = self.parse_method_name(); let tps = self.parse_ty_params(); - let (self_ty, decl, _) = do self.parse_fn_decl_with_self(pur) |p| { + let (self_ty, decl, _) = do self.parse_fn_decl_with_self() |p| { p.parse_arg() }; // XXX: interaction between staticness, self_ty is broken now @@ -2478,7 +2472,7 @@ struct parser { let (inner_attrs, body) = self.parse_inner_attrs_and_block(true); let attrs = vec::append(attrs, inner_attrs); @{ident: ident, attrs: attrs, - tps: tps, self_ty: self_ty, decl: decl, + tps: tps, self_ty: self_ty, purity: pur, decl: decl, body: body, id: self.get_id(), span: mk_sp(lo, body.span.hi), self_id: self.get_id(), vis: pr} } @@ -2717,7 +2711,7 @@ struct parser { fn parse_ctor(attrs: ~[attribute], result_ty: ast::ty_) -> class_contents { let lo = self.last_span.lo; - let (decl_, _) = self.parse_fn_decl(impure_fn, |p| p.parse_arg()); + let (decl_, _) = self.parse_fn_decl(|p| p.parse_arg()); let decl = {output: @{id: self.get_id(), node: result_ty, span: decl_.output.span} with decl_}; @@ -2837,18 +2831,18 @@ struct parser { (id, item_mod(m), some(inner_attrs.inner)) } - fn parse_item_foreign_fn(+attrs: ~[attribute], - purity: purity) -> @foreign_item { - let lo = self.last_span.lo; + fn parse_item_foreign_fn(+attrs: ~[attribute]) -> @foreign_item { + let lo = self.span.lo; + let purity = self.parse_fn_purity(); let t = self.parse_fn_header(); - let (decl, _) = self.parse_fn_decl(purity, |p| p.parse_arg()); + let (decl, _) = self.parse_fn_decl(|p| p.parse_arg()); let mut hi = self.span.hi; self.expect(token::SEMI); return @{ident: t.ident, - attrs: attrs, - node: foreign_item_fn(decl, t.tps), - id: self.get_id(), - span: mk_sp(lo, hi)}; + attrs: attrs, + node: foreign_item_fn(decl, purity, t.tps), + id: self.get_id(), + span: mk_sp(lo, hi)}; } fn parse_fn_purity() -> purity { @@ -2865,7 +2859,7 @@ struct parser { fn parse_foreign_item(+attrs: ~[attribute]) -> @foreign_item { - self.parse_item_foreign_fn(attrs, self.parse_fn_purity()) + self.parse_item_foreign_fn(attrs) } fn parse_foreign_mod_items(+first_item_attrs: ~[attribute]) -> diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index ca958acb10b..53458fd8756 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -129,7 +129,7 @@ fn fun_to_str(decl: ast::fn_decl, name: ast::ident, params: ~[ast::ty_param], intr: ident_interner) -> ~str { let buffer = io::mem_buffer(); let s = rust_printer(io::mem_buffer_writer(buffer), intr); - print_fn(s, decl, name, params, none); + print_fn(s, decl, none, name, params, none); end(s); // Close the head box end(s); // Close the outer box eof(s.s); @@ -390,8 +390,8 @@ fn print_type_ex(s: ps, &&ty: @ast::ty, print_colons: bool) { commasep(s, inconsistent, elts, print_type); pclose(s); } - ast::ty_fn(proto, bounds, d) => { - print_ty_fn(s, some(proto), bounds, d, none, none, none); + ast::ty_fn(proto, purity, bounds, d) => { + print_ty_fn(s, some(proto), purity, bounds, d, none, none, none); } ast::ty_path(path, _) => print_path(s, path, print_colons), ast::ty_fixed_length(t, v) => { @@ -415,8 +415,8 @@ fn print_foreign_item(s: ps, item: @ast::foreign_item) { maybe_print_comment(s, item.span.lo); print_outer_attributes(s, item.attrs); match item.node { - ast::foreign_item_fn(decl, typarams) => { - print_fn(s, decl, item.ident, typarams, none); + ast::foreign_item_fn(decl, purity, typarams) => { + print_fn(s, decl, some(purity), item.ident, typarams, none); end(s); // end head-ibox word(s.s, ~";"); end(s); // end the outer fn box @@ -445,8 +445,8 @@ fn print_item(s: ps, &&item: @ast::item) { end(s); // end the outer cbox } - ast::item_fn(decl, typarams, body) => { - print_fn(s, decl, item.ident, typarams, none); + ast::item_fn(decl, purity, typarams, body) => { + print_fn(s, decl, some(purity), item.ident, typarams, none); word(s.s, ~" "); print_block_with_attrs(s, body, item.attrs); } @@ -722,7 +722,8 @@ fn print_ty_method(s: ps, m: ast::ty_method) { hardbreak_if_not_bol(s); maybe_print_comment(s, m.span.lo); print_outer_attributes(s, m.attrs); - print_ty_fn(s, none, @~[], m.decl, some(m.ident), some(m.tps), + print_ty_fn(s, none, m.purity, + @~[], m.decl, some(m.ident), some(m.tps), some(m.self_ty.node)); word(s.s, ~";"); } @@ -738,7 +739,8 @@ fn print_method(s: ps, meth: @ast::method) { hardbreak_if_not_bol(s); maybe_print_comment(s, meth.span.lo); print_outer_attributes(s, meth.attrs); - print_fn(s, meth.decl, meth.ident, meth.tps, some(meth.self_ty.node)); + print_fn(s, meth.decl, some(meth.purity), + meth.ident, meth.tps, some(meth.self_ty.node)); word(s.s, ~" "); print_block_with_attrs(s, meth.body, meth.attrs); } @@ -1188,7 +1190,7 @@ fn print_expr(s: ps, &&expr: @ast::expr) { cbox(s, indent_unit); // head-box, will be closed by print-block at start ibox(s, 0u); - word(s.s, fn_header_info_to_str(none, decl.purity, some(proto))); + word(s.s, fn_header_info_to_str(none, none, some(proto))); print_fn_args_and_ret(s, decl, *cap_clause, none); space(s.s); print_block(s, body); @@ -1542,10 +1544,11 @@ fn print_self_ty(s: ps, self_ty: ast::self_ty_) -> bool { return true; } -fn print_fn(s: ps, decl: ast::fn_decl, name: ast::ident, +fn print_fn(s: ps, decl: ast::fn_decl, purity: option<ast::purity>, + name: ast::ident, typarams: ~[ast::ty_param], opt_self_ty: option<ast::self_ty_>) { - head(s, fn_header_info_to_str(opt_self_ty, decl.purity, none)); + head(s, fn_header_info_to_str(opt_self_ty, purity, none)); print_ident(s, name); print_type_params(s, typarams); print_fn_args_and_ret(s, decl, ~[], opt_self_ty); @@ -1767,13 +1770,13 @@ fn print_arg(s: ps, input: ast::arg) { end(s); } -fn print_ty_fn(s: ps, opt_proto: option<ast::proto>, +fn print_ty_fn(s: ps, opt_proto: option<ast::proto>, purity: ast::purity, bounds: @~[ast::ty_param_bound], decl: ast::fn_decl, id: option<ast::ident>, tps: option<~[ast::ty_param]>, opt_self_ty: option<ast::self_ty_>) { ibox(s, indent_unit); - word(s.s, fn_header_info_to_str(opt_self_ty, decl.purity, opt_proto)); + word(s.s, fn_header_info_to_str(opt_self_ty, some(purity), opt_proto)); print_bounds(s, bounds); match id { some(id) => { word(s.s, ~" "); print_ident(s, id); } _ => () } match tps { some(tps) => print_type_params(s, tps), _ => () } @@ -1990,19 +1993,20 @@ fn next_comment(s: ps) -> option<comments::cmnt> { } fn fn_header_info_to_str(opt_sty: option<ast::self_ty_>, - purity: ast::purity, + opt_purity: option<ast::purity>, opt_p: option<ast::proto>) -> ~str { let mut s = match opt_sty { some(ast::sty_static) => ~"static ", _ => ~ "" }; - match purity { - ast::impure_fn => { } - _ => { + match opt_purity { + some(ast::impure_fn) => { } + some(purity) => { str::push_str(s, purity_to_str(purity)); str::push_char(s, ' '); } + none => {} } str::push_str(s, opt_proto_to_str(opt_p)); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 51104e97119..a5f86dee1cc 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -13,7 +13,7 @@ import codemap::span; enum vt<E> { mk_vt(visitor<E>), } enum fn_kind { - fk_item_fn(ident, ~[ty_param]), //< an item declared with fn() + fk_item_fn(ident, ~[ty_param], purity), //< an item declared with fn() fk_method(ident, ~[ty_param], @method), fk_anon(proto, capture_clause), //< an anonymous function like fn@(...) fk_fn_block(capture_clause), //< a block {||...} @@ -26,7 +26,7 @@ enum fn_kind { fn name_of_fn(fk: fn_kind) -> ident { match fk { - fk_item_fn(name, _) | fk_method(name, _, _) + fk_item_fn(name, _, _) | fk_method(name, _, _) | fk_ctor(name, _, _, _, _) => /* FIXME (#2543) */ copy name, fk_anon(*) | fk_fn_block(*) => parse::token::special_idents::anon, fk_dtor(*) => parse::token::special_idents::dtor @@ -35,7 +35,7 @@ fn name_of_fn(fk: fn_kind) -> ident { fn tps_of_fn(fk: fn_kind) -> ~[ty_param] { match fk { - fk_item_fn(_, tps) | fk_method(_, tps, _) + fk_item_fn(_, tps, _) | fk_method(_, tps, _) | fk_ctor(_, _, tps, _, _) | fk_dtor(tps, _, _, _) => { /* FIXME (#2543) */ copy tps } @@ -124,9 +124,10 @@ fn visit_local<E>(loc: @local, e: E, v: vt<E>) { fn visit_item<E>(i: @item, e: E, v: vt<E>) { match i.node { item_const(t, ex) => { v.visit_ty(t, e, v); v.visit_expr(ex, e, v); } - item_fn(decl, tp, body) => { + item_fn(decl, purity, tp, body) => { v.visit_fn(fk_item_fn(/* FIXME (#2543) */ copy i.ident, - /* FIXME (#2543) */ copy tp), decl, body, + /* FIXME (#2543) */ copy tp, + purity), decl, body, i.span, i.id, e, v); } item_mod(m) => v.visit_mod(m, i.span, i.id, e, v), @@ -199,7 +200,7 @@ fn visit_ty<E>(t: @ty, e: E, v: vt<E>) { ty_tup(ts) => for ts.each |tt| { v.visit_ty(tt, e, v); }, - ty_fn(_, bounds, decl) => { + ty_fn(_, _, bounds, decl) => { for decl.inputs.each |a| { v.visit_ty(a.ty, e, v); } visit_ty_param_bounds(bounds, e, v); v.visit_ty(decl.output, e, v); @@ -249,7 +250,7 @@ fn visit_pat<E>(p: @pat, e: E, v: vt<E>) { fn visit_foreign_item<E>(ni: @foreign_item, e: E, v: vt<E>) { match ni.node { - foreign_item_fn(fd, tps) => { + foreign_item_fn(fd, purity, tps) => { v.visit_ty_params(tps, e, v); visit_fn_decl(fd, e, v); } diff --git a/src/rustc/front/test.rs b/src/rustc/front/test.rs index cba7e89dcbb..d2abe360f67 100644 --- a/src/rustc/front/test.rs +++ b/src/rustc/front/test.rs @@ -71,7 +71,7 @@ fn fold_mod(cx: test_ctxt, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod { // indicate to the translation pass which function we want to be main. fn nomain(cx: test_ctxt, item: @ast::item) -> option<@ast::item> { match item.node { - ast::item_fn(_, _, _) => { + ast::item_fn(*) => { if item.ident == cx.sess.ident_of(~"main") { option::none } else { option::some(item) } @@ -105,7 +105,7 @@ fn fold_item(cx: test_ctxt, &&i: @ast::item, fld: fold::ast_fold) -> if is_test_fn(i) { match i.node { - ast::item_fn(decl, _, _) if decl.purity == ast::unsafe_fn => { + ast::item_fn(decl, purity, _, _) if purity == ast::unsafe_fn => { cx.sess.span_fatal( i.span, ~"unsafe functions cannot be used for tests"); @@ -132,7 +132,7 @@ fn is_test_fn(i: @ast::item) -> bool { fn has_test_signature(i: @ast::item) -> bool { match i.node { - ast::item_fn(decl, tps, _) => { + ast::item_fn(decl, _, tps, _) => { let input_cnt = vec::len(decl.inputs); let no_output = decl.output.node == ast::ty_nil; let tparm_cnt = vec::len(tps); @@ -223,7 +223,6 @@ fn mk_tests(cx: test_ctxt) -> @ast::item { let decl: ast::fn_decl = {inputs: ~[], output: ret_ty, - purity: ast::impure_fn, cf: ast::return_val}; // The vector of test_descs for this crate @@ -233,7 +232,7 @@ fn mk_tests(cx: test_ctxt) -> @ast::item { default_block(~[], option::some(test_descs), cx.sess.next_node_id()); let body = nospan(body_); - let item_ = ast::item_fn(decl, ~[], body); + let item_ = ast::item_fn(decl, ast::impure_fn, ~[], body); let item: ast::item = {ident: cx.sess.ident_of(~"tests"), attrs: ~[], @@ -389,7 +388,6 @@ fn mk_test_wrapper(cx: test_ctxt, let wrapper_decl: ast::fn_decl = { inputs: ~[], output: @{id: cx.sess.next_node_id(), node: ast::ty_nil, span: span}, - purity: ast::impure_fn, cf: ast::return_val }; @@ -442,7 +440,6 @@ fn mk_main(cx: test_ctxt) -> @ast::item { let decl: ast::fn_decl = {inputs: ~[args_arg], output: @ret_ty, - purity: ast::impure_fn, cf: ast::return_val}; let test_main_call_expr = mk_test_main_call(cx); @@ -452,7 +449,7 @@ fn mk_main(cx: test_ctxt) -> @ast::item { cx.sess.next_node_id()); let body = {node: body_, span: dummy_sp()}; - let item_ = ast::item_fn(decl, ~[], body); + let item_ = ast::item_fn(decl, ast::impure_fn, ~[], body); let item: ast::item = {ident: cx.sess.ident_of(~"main"), attrs: ~[], diff --git a/src/rustc/metadata/decoder.rs b/src/rustc/metadata/decoder.rs index 37f00be40ff..05457a710ea 100644 --- a/src/rustc/metadata/decoder.rs +++ b/src/rustc/metadata/decoder.rs @@ -695,13 +695,8 @@ fn get_trait_methods(intr: ident_interner, cdata: cmd, id: ast::node_id, } }; let self_ty = get_self_ty(mth); vec::push(result, {ident: name, tps: bounds, fty: fty, - self_ty: self_ty, - purity: match item_family(mth) { - UnsafeFn => ast::unsafe_fn, - Fn => ast::impure_fn, - PureFn => ast::pure_fn, - _ => fail ~"bad purity" - }, vis: ast::public}); + self_ty: self_ty, + vis: ast::public}); } #debug("get_trait_methods: }"); @result diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index 4e584fb167f..66d74c377ca 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -414,14 +414,14 @@ fn encode_info_for_class(ecx: @encode_ctxt, ebml_w: ebml::writer, *index } -fn encode_info_for_fn(ecx: @encode_ctxt, ebml_w: ebml::writer, - id: node_id, ident: ident, path: ast_map::path, - item: option<inlined_item>, tps: ~[ty_param], - decl: fn_decl) { +// This is for encoding info for ctors and dtors +fn encode_info_for_ctor(ecx: @encode_ctxt, ebml_w: ebml::writer, + id: node_id, ident: ident, path: ast_map::path, + item: option<inlined_item>, tps: ~[ty_param]) { ebml_w.start_tag(tag_items_data_item); encode_name(ecx, ebml_w, ident); encode_def_id(ebml_w, local_def(id)); - encode_family(ebml_w, purity_fn_family(decl.purity)); + encode_family(ebml_w, purity_fn_family(ast::impure_fn)); encode_type_param_bounds(ebml_w, ecx, tps); let its_ty = node_id_to_type(ecx.tcx, id); debug!("fn name = %s ty = %s its node id = %d", @@ -448,7 +448,7 @@ fn encode_info_for_method(ecx: @encode_ctxt, ebml_w: ebml::writer, ecx.tcx.sess.str_of(m.ident), all_tps.len()); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(m.id)); - encode_family(ebml_w, purity_fn_family(m.decl.purity)); + encode_family(ebml_w, purity_fn_family(m.purity)); encode_type_param_bounds(ebml_w, ecx, all_tps); encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, m.id)); encode_name(ecx, ebml_w, m.ident); @@ -519,11 +519,11 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); ebml_w.end_tag(); } - item_fn(decl, tps, _) => { + item_fn(decl, purity, tps, _) => { add_to_index(); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); - encode_family(ebml_w, purity_fn_family(decl.purity)); + encode_family(ebml_w, purity_fn_family(purity)); encode_type_param_bounds(ebml_w, ecx, tps); encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident)); @@ -588,13 +588,14 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, /* Encode the dtor */ do option::iter(struct_def.dtor) |dtor| { vec::push(*index, {val: dtor.node.id, pos: ebml_w.writer.tell()}); - encode_info_for_fn(ecx, ebml_w, dtor.node.id, - ecx.tcx.sess.ident_of( - ecx.tcx.sess.str_of(item.ident) + ~"_dtor"), - path, if tps.len() > 0u { - some(ii_dtor(dtor, item.ident, tps, - local_def(item.id))) } - else { none }, tps, ast_util::dtor_dec()); + encode_info_for_ctor(ecx, ebml_w, dtor.node.id, + ecx.tcx.sess.ident_of( + ecx.tcx.sess.str_of(item.ident) + + ~"_dtor"), + path, if tps.len() > 0u { + some(ii_dtor(dtor, item.ident, tps, + local_def(item.id))) } + else { none }, tps); } /* Index the class*/ @@ -647,7 +648,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, /* Write the info that's needed when viewing this class as a trait */ ebml_w.start_tag(tag_item_trait_method); - encode_family(ebml_w, purity_fn_family(m.decl.purity)); + encode_family(ebml_w, purity_fn_family(m.purity)); encode_name(ecx, ebml_w, m.ident); encode_type_param_bounds(ebml_w, ecx, m.tps); encode_type(ecx, ebml_w, node_id_to_type(tcx, m.id)); @@ -675,11 +676,11 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, val: ctor.node.id, pos: ebml_w.writer.tell() }); - encode_info_for_fn(ecx, ebml_w, ctor.node.id, item.ident, - path, if tps.len() > 0u { - some(ii_ctor(ctor, item.ident, tps, - local_def(item.id))) } - else { none }, tps, ctor.node.dec); + encode_info_for_ctor(ecx, ebml_w, ctor.node.id, item.ident, + path, if tps.len() > 0u { + some(ii_ctor(ctor, item.ident, tps, + local_def(item.id))) } + else { none }, tps); } } item_impl(tps, traits, _, methods) => { @@ -734,7 +735,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_name(ecx, ebml_w, mty.ident); encode_type_param_bounds(ebml_w, ecx, ty_m.tps); encode_type(ecx, ebml_w, ty::mk_fn(tcx, mty.fty)); - encode_family(ebml_w, purity_fn_family(mty.purity)); + encode_family(ebml_w, purity_fn_family(mty.fty.purity)); encode_self_type(ebml_w, mty.self_ty); ebml_w.end_tag(); } @@ -766,7 +767,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_def_id(ebml_w, local_def(ty_m.id)); encode_name(ecx, ebml_w, ty_m.ident); encode_family(ebml_w, - purity_static_method_family(ty_m.decl.purity)); + purity_static_method_family(ty_m.purity)); let polyty = ecx.tcx.tcache.get(local_def(ty_m.id)); encode_ty_type_param_bounds(ebml_w, ecx, polyty.bounds); encode_type(ecx, ebml_w, polyty.ty); @@ -789,9 +790,9 @@ fn encode_info_for_foreign_item(ecx: @encode_ctxt, ebml_w: ebml::writer, ebml_w.start_tag(tag_items_data_item); match nitem.node { - foreign_item_fn(fn_decl, tps) => { + foreign_item_fn(fn_decl, purity, tps) => { encode_def_id(ebml_w, local_def(nitem.id)); - encode_family(ebml_w, purity_fn_family(fn_decl.purity)); + encode_family(ebml_w, purity_fn_family(purity)); encode_type_param_bounds(ebml_w, ecx, tps); encode_type(ecx, ebml_w, node_id_to_type(ecx.tcx, nitem.id)); if abi == foreign_abi_rust_intrinsic { diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs index 6db7297618b..7c18133ae02 100644 --- a/src/rustc/middle/borrowck/check_loans.rs +++ b/src/rustc/middle/borrowck/check_loans.rs @@ -521,6 +521,8 @@ fn check_loans_in_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk, do save_and_restore(self.declared_purity) { do save_and_restore(self.fn_args) { let is_stack_closure = self.is_stack_closure(id); + let purity = + ty::ty_fn_purity(ty::node_id_to_type(self.tcx(), id)); // In principle, we could consider fk_anon(*) or // fk_fn_block(*) to be in a ctor, I suppose, but the @@ -531,7 +533,7 @@ fn check_loans_in_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk, match fk { visit::fk_ctor(*) => { self.in_ctor = true; - self.declared_purity = decl.purity; + self.declared_purity = purity; self.fn_args = @decl.inputs.map(|i| i.id ); } visit::fk_anon(*) | @@ -543,7 +545,7 @@ fn check_loans_in_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk, visit::fk_method(*) | visit::fk_item_fn(*) | visit::fk_dtor(*) => { self.in_ctor = false; - self.declared_purity = decl.purity; + self.declared_purity = purity; self.fn_args = @decl.inputs.map(|i| i.id ); } } diff --git a/src/rustc/middle/lint.rs b/src/rustc/middle/lint.rs index 1137ec47cdd..7b7e163d38c 100644 --- a/src/rustc/middle/lint.rs +++ b/src/rustc/middle/lint.rs @@ -401,7 +401,7 @@ fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) { either::Right(ast::foreign_abi_rust_intrinsic) => { for nmod.items.each |ni| { match ni.node { - ast::foreign_item_fn(decl, tps) => { + ast::foreign_item_fn(decl, _, tps) => { check_foreign_fn(cx, it.id, decl); } } diff --git a/src/rustc/middle/region.rs b/src/rustc/middle/region.rs index 17d4eaa5984..5b6a64ccd73 100644 --- a/src/rustc/middle/region.rs +++ b/src/rustc/middle/region.rs @@ -613,8 +613,8 @@ fn determine_rp_in_ty(ty: @ast::ty, } } - ast::ty_fn(ast::proto_bare, _, _) | - ast::ty_fn(ast::proto_block, _, _) if cx.anon_implies_rp => { + ast::ty_fn(ast::proto_bare, _, _, _) | + ast::ty_fn(ast::proto_block, _, _, _) if cx.anon_implies_rp => { debug!("referenced bare fn type with regions %s", pprust::ty_to_str(ty, cx.sess.intr())); cx.add_rp(cx.item_id, cx.add_variance(rv_contravariant)); @@ -661,8 +661,8 @@ fn determine_rp_in_ty(ty: @ast::ty, match ty.node { ast::ty_box(mt) | ast::ty_uniq(mt) => { match mt.ty.node { - ast::ty_fn(ast::proto_bare, _, _) | - ast::ty_fn(ast::proto_block, _, _) => { + ast::ty_fn(ast::proto_bare, _, _, _) | + ast::ty_fn(ast::proto_block, _, _, _) => { do cx.with(cx.item_id, false) { visit_mt(mt, cx, visitor); } @@ -695,7 +695,7 @@ fn determine_rp_in_ty(ty: @ast::ty, } } - ast::ty_fn(_, bounds, decl) => { + ast::ty_fn(_, _, bounds, decl) => { // fn() binds the & region, so do not consider &T types that // appear *inside* a fn() type to affect the enclosing item: do cx.with(cx.item_id, false) { diff --git a/src/rustc/middle/resolve3.rs b/src/rustc/middle/resolve3.rs index da6b0b5087b..66b7818d880 100644 --- a/src/rustc/middle/resolve3.rs +++ b/src/rustc/middle/resolve3.rs @@ -891,11 +891,11 @@ struct Resolver { def_const(local_def(item.id)), sp); } - item_fn(decl, _, _) => { + item_fn(decl, purity, _, _) => { let (name_bindings, new_parent) = self.add_child(atom, parent, ~[ValueNS], sp); - let def = def_fn(local_def(item.id), decl.purity); + let def = def_fn(local_def(item.id), purity); (*name_bindings).define_value (self.visibility_to_privacy(item.vis), def, sp); visit_item(item, new_parent, visitor); @@ -954,7 +954,7 @@ struct Resolver { (*name_bindings).define_type (privacy, def_ty(local_def(item.id)), sp); - let purity = ctor.node.dec.purity; + let purity = impure_fn; let ctor_def = def_fn(local_def(ctor.node.id), purity); (*name_bindings).define_value(privacy, ctor_def, sp); @@ -992,7 +992,7 @@ struct Resolver { self.add_child(atom, new_parent, ~[ValueNS], ty_m.span); let def = def_static_method(local_def(ty_m.id), - ty_m.decl.purity); + ty_m.purity); (*method_name_bindings).define_value (Public, def, ty_m.span); } @@ -1215,11 +1215,11 @@ struct Resolver { let name = foreign_item.ident; match foreign_item.node { - foreign_item_fn(fn_decl, type_parameters) => { + foreign_item_fn(fn_decl, purity, type_parameters) => { let (name_bindings, new_parent) = self.add_child(name, parent, ~[ValueNS], foreign_item.span); - let def = def_fn(local_def(foreign_item.id), fn_decl.purity); + let def = def_fn(local_def(foreign_item.id), purity); (*name_bindings).define_value(Public, def, foreign_item.span); do self.with_type_parameter_rib @@ -2944,7 +2944,7 @@ struct Resolver { do self.with_scope(some(item.ident)) { for foreign_module.items.each |foreign_item| { match foreign_item.node { - foreign_item_fn(_, type_parameters) => { + foreign_item_fn(_, _, type_parameters) => { do self.with_type_parameter_rib (HasTypeParameters(&type_parameters, foreign_item.id, @@ -2961,7 +2961,7 @@ struct Resolver { } } - item_fn(fn_decl, ty_params, block) => { + item_fn(fn_decl, _, ty_params, block) => { // If this is the main function, we must record it in the // session. // diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 60a57540fa9..13988ad8861 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -2214,7 +2214,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, let psubsts = some({tys: substs, vtables: vtables, bounds: tpt.bounds}); let lldecl = match map_node { - ast_map::node_item(i@@{node: ast::item_fn(decl, _, body), _}, _) => { + ast_map::node_item(i@@{node: ast::item_fn(decl, _, _, body), _}, _) => { let d = mk_lldecl(); set_inline_hint_if_appr(i.attrs, d); trans_fn(ccx, pt, decl, body, d, no_self, psubsts, fn_id.node); @@ -5010,8 +5010,8 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) { ast_map::node_item(_, p) => p }; match item.node { - ast::item_fn(decl, tps, body) => { - if decl.purity == ast::extern_fn { + ast::item_fn(decl, purity, tps, body) => { + if purity == ast::extern_fn { let llfndecl = get_item_val(ccx, item.id); foreign::trans_foreign_fn(ccx, vec::append( @@ -5304,8 +5304,8 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef { ccx.item_symbols.insert(i.id, s); g } - ast::item_fn(decl, _, _) => { - let llfn = if decl.purity != ast::extern_fn { + ast::item_fn(decl, purity, _, _) => { + let llfn = if purity != ast::extern_fn { register_fn(ccx, i.span, my_path, i.id) } else { foreign::register_foreign_fn(ccx, i.span, my_path, i.id) @@ -5535,7 +5535,7 @@ fn push_rtcall(ccx: @crate_ctxt, name: ~str, did: ast::def_id) { fn gather_local_rtcalls(ccx: @crate_ctxt, crate: @ast::crate) { visit::visit_crate(*crate, (), visit::mk_simple_visitor(@{ visit_item: |item| match item.node { - ast::item_fn(decl, _, _) => { + ast::item_fn(decl, _, _, _) => { let attr_metas = attr::attr_metas( attr::find_attrs_by_name(item.attrs, ~"rt")); do vec::iter(attr_metas) |attr_meta| { diff --git a/src/rustc/middle/trans/debuginfo.rs b/src/rustc/middle/trans/debuginfo.rs index 18603f0edeb..04e0f7be75f 100644 --- a/src/rustc/middle/trans/debuginfo.rs +++ b/src/rustc/middle/trans/debuginfo.rs @@ -721,7 +721,7 @@ fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> { let (ident, ret_ty, id) = match cx.tcx.items.get(fcx.id) { ast_map::node_item(item, _) => { match item.node { - ast::item_fn(decl, _, _) => { + ast::item_fn(decl, _, _, _) => { (item.ident, decl.output, item.id) } _ => fcx.ccx.sess.span_bug(item.span, ~"create_function: item \ diff --git a/src/rustc/middle/trans/foreign.rs b/src/rustc/middle/trans/foreign.rs index 10e657af0f4..efcdc644104 100644 --- a/src/rustc/middle/trans/foreign.rs +++ b/src/rustc/middle/trans/foreign.rs @@ -755,7 +755,7 @@ fn trans_foreign_mod(ccx: @crate_ctxt, for vec::each(foreign_mod.items) |foreign_item| { match foreign_item.node { - ast::foreign_item_fn(fn_decl, typarams) => { + ast::foreign_item_fn(fn_decl, purity, typarams) => { let id = foreign_item.id; if abi != ast::foreign_abi_rust_intrinsic { let llwrapfn = get_item_val(ccx, id); diff --git a/src/rustc/middle/trans/reachable.rs b/src/rustc/middle/trans/reachable.rs index 5ea2d8625e6..48ab856342a 100644 --- a/src/rustc/middle/trans/reachable.rs +++ b/src/rustc/middle/trans/reachable.rs @@ -96,7 +96,7 @@ fn traverse_public_item(cx: ctx, item: @item) { for vec::each(nm.items) |item| { cx.rmap.insert(item.id, ()); } } } - item_fn(_, tps, blk) => { + item_fn(_, _, tps, blk) => { if tps.len() > 0u || attr::find_inline_attr(item.attrs) != attr::ia_none { traverse_inline_body(cx, blk); diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs index ce84269bb67..2b527bb9682 100644 --- a/src/rustc/middle/trans/type_use.rs +++ b/src/rustc/middle/trans/type_use.rs @@ -65,7 +65,7 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint) fn_id_loc)) }; match map_node { - ast_map::node_item(@{node: item_fn(_, _, body), _}, _) | + ast_map::node_item(@{node: item_fn(_, _, _, body), _}, _) | ast_map::node_method(@{body, _}, _, _) => { handle_body(cx, body); } @@ -78,7 +78,7 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint) ast_map::node_variant(_, _, _) => { for uint::range(0u, n_tps) |n| { cx.uses[n] |= use_repr;} } - ast_map::node_foreign_item(i@@{node: foreign_item_fn(_, _), _}, + ast_map::node_foreign_item(i@@{node: foreign_item_fn(*), _}, abi, _) => { if abi == foreign_abi_rust_intrinsic { let flags = match cx.ccx.sess.str_of(i.ident) { diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index 15eaa683bae..b5411dd597c 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -79,7 +79,7 @@ export ty_opaque_closure_ptr, mk_opaque_closure_ptr; export ty_opaque_box, mk_opaque_box; export ty_float, mk_float, mk_mach_float, type_is_fp; export ty_fn, fn_ty, mk_fn; -export ty_fn_proto, 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 mk_i8, mk_u8, mk_i16, mk_u16, mk_i32, mk_u32, mk_i64, mk_u64; export ty_estr, mk_estr, type_is_str; @@ -202,7 +202,6 @@ type method = {ident: ast::ident, tps: @~[param_bounds], fty: fn_ty, self_ty: ast::self_ty_, - purity: ast::purity, vis: ast::visibility}; type mt = {ty: t, mutbl: ast::mutability}; @@ -2358,6 +2357,13 @@ fn ty_fn_proto(fty: t) -> fn_proto { } } +fn ty_fn_purity(fty: t) -> ast::purity { + match get(fty).struct { + ty_fn(ref f) => f.purity, + _ => fail ~"ty_fn_purity() called on non-fn type" + } +} + pure fn ty_fn_ret(fty: t) -> t { match get(fty).struct { ty_fn(ref f) => f.output, diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index 302bc604c2a..d4ed45f99b3 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -259,7 +259,7 @@ fn check_main_fn_ty(ccx: @crate_ctxt, match tcx.items.find(main_id) { some(ast_map::node_item(it,_)) => { match it.node { - ast::item_fn(_,ps,_) if vec::is_not_empty(ps) => { + ast::item_fn(_,_,ps,_) if vec::is_not_empty(ps) => { tcx.sess.span_err(main_span, ~"main function is not allowed to have type parameters"); return; diff --git a/src/rustc/middle/typeck/astconv.rs b/src/rustc/middle/typeck/astconv.rs index 1b6f4e86a61..374e14749f2 100644 --- a/src/rustc/middle/typeck/astconv.rs +++ b/src/rustc/middle/typeck/astconv.rs @@ -201,7 +201,7 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope copy owned>( _ => () } } - ast::ty_fn(ast::proto_block, ast_bounds, ast_fn_decl) => { + ast::ty_fn(ast::proto_block, purity, ast_bounds, ast_fn_decl) => { let new_proto; match vst { ty::vstore_fixed(_) => { @@ -216,7 +216,8 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope copy owned>( // Run through the normal function type conversion process. let bounds = collect::compute_bounds(self.ccx(), ast_bounds); - let fn_decl = ty_of_fn_decl(self, rscope, new_proto, bounds, + let fn_decl = ty_of_fn_decl(self, rscope, new_proto, purity, + bounds, ast_fn_decl, none, span); return ty::mk_fn(tcx, fn_decl); } @@ -301,9 +302,10 @@ fn ast_ty_to_ty<AC: ast_conv, RS: region_scope copy owned>( }; ty::mk_rec(tcx, flds) } - ast::ty_fn(proto, ast_bounds, decl) => { + ast::ty_fn(proto, purity, 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, + let fn_decl = ty_of_fn_decl(self, rscope, proto, purity, + bounds, decl, none, ast_ty.span); ty::mk_fn(tcx, fn_decl) } @@ -465,6 +467,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, ast_proto: ast::proto, + purity: ast::purity, bounds: @~[ty::param_bound], decl: ast::fn_decl, expected_tys: expected_tys, @@ -494,7 +497,7 @@ fn ty_of_fn_decl<AC: ast_conv, RS: region_scope copy owned>( let proto = ast_proto_to_proto(self, rscope, span, ast_proto); - {purity: decl.purity, proto: proto, bounds: bounds, inputs: input_tys, + {purity: 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 7b71c59bf26..aa51f2dd4a2 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -223,12 +223,12 @@ fn check_fn(ccx: @crate_ctxt, none => { {infcx: infer::new_infer_ctxt(tcx), locals: int_hash(), - purity: decl.purity, + purity: fn_ty.purity, node_types: map::int_hash(), node_type_substs: map::int_hash()} } some(fcx) => { - assert decl.purity == ast::impure_fn; + assert fn_ty.purity == ast::impure_fn; {infcx: fcx.infcx, locals: fcx.locals, purity: fcx.purity, @@ -476,7 +476,7 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) { ast::item_enum(enum_definition, _) => { check_enum_variants(ccx, it.span, enum_definition.variants, it.id); } - ast::item_fn(decl, tps, body) => { + ast::item_fn(decl, _, tps, body) => { check_bare_fn(ccx, decl, body, it.id, none); } ast::item_impl(tps, _, ty, ms) => { @@ -1232,8 +1232,11 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, } } + let purity = ast::impure_fn; + // construct the function type - let mut fn_ty = astconv::ty_of_fn_decl(fcx, fcx, ast_proto, @~[], + let mut fn_ty = astconv::ty_of_fn_decl(fcx, fcx, ast_proto, purity, + @~[], decl, expected_tys, expr.span); // Patch up the function declaration, if necessary. @@ -1599,16 +1602,18 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, bot = alt::check_alt(fcx, expr, discrim, arms); } ast::expr_fn(proto, decl, body, cap_clause) => { - check_expr_fn(fcx, expr, foap_ast_proto(proto), decl, body, false, + check_expr_fn(fcx, expr, foap_ast_proto(proto), + decl, body, false, expected); capture::check_capture_clause(tcx, expr.id, cap_clause); } ast::expr_fn_block(decl, body, cap_clause) => { - // Take the prototype from the expected type, but default to block: - let proto = unpack_expected(fcx, expected, |sty| - match sty { ty::ty_fn({proto, _}) => some(proto), _ => none } - ).get_default(ty::proto_vstore(ty::vstore_box)); - check_expr_fn(fcx, expr, foap_fn_proto(proto), decl, body, false, + // Take the prototype from the expected type, but default to block: + let proto = do unpack_expected(fcx, expected) |sty| { + match sty { ty::ty_fn({proto, _}) => some(proto), _ => none } + }.get_default(ty::proto_vstore(ty::vstore_box)); + check_expr_fn(fcx, expr, foap_fn_proto(proto), + decl, body, false, expected); capture::check_capture_clause(tcx, expr.id, cap_clause); } @@ -1642,7 +1647,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, }; match check b.node { ast::expr_fn_block(decl, body, cap_clause) => { - check_expr_fn(fcx, b, foap_fn_proto(proto), decl, body, true, + check_expr_fn(fcx, b, foap_fn_proto(proto), + decl, body, true, some(inner_ty)); demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b)); capture::check_capture_clause(tcx, b.id, cap_clause); @@ -1671,7 +1677,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, }; match check b.node { ast::expr_fn_block(decl, body, cap_clause) => { - check_expr_fn(fcx, b, foap_fn_proto(proto), decl, body, true, + check_expr_fn(fcx, b, foap_fn_proto(proto), + decl, body, true, some(inner_ty)); demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b)); capture::check_capture_clause(tcx, b.id, cap_clause); diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs index 132ec2a4e90..b87380720ce 100644 --- a/src/rustc/middle/typeck/collect.rs +++ b/src/rustc/middle/typeck/collect.rs @@ -247,7 +247,7 @@ fn compare_impl_method(tcx: ty::ctxt, sp: span, trait_m: ty::method, trait_substs: ty::substs, self_ty: ty::t) { - if impl_m.purity != trait_m.purity { + if impl_m.fty.purity != trait_m.fty.purity { tcx.sess.span_err( sp, fmt!("method `%s`'s purity does \ not match the trait method's \ @@ -506,7 +506,8 @@ fn convert_struct(ccx: @crate_ctxt, // Write the dtor type let t_dtor = ty::mk_fn( tcx, - ty_of_fn_decl(ccx, type_rscope(rp), ast::proto_bare, @~[], + ty_of_fn_decl(ccx, type_rscope(rp), ast::proto_bare, + ast::impure_fn, @~[], ast_util::dtor_dec(), none, dtor.span)); write_ty_to_tcx(tcx, dtor.node.id, t_dtor); tcx.tcache.insert(local_def(dtor.node.id), @@ -537,7 +538,7 @@ fn convert_foreign(ccx: @crate_ctxt, i: @ast::foreign_item) { // table. let tpt = ty_of_foreign_item(ccx, i); match i.node { - ast::foreign_item_fn(_, _) => { + ast::foreign_item_fn(*) => { write_ty_to_tcx(ccx.tcx, i.id, tpt.ty); ccx.tcx.tcache.insert(local_def(i.id), tpt); } @@ -549,10 +550,10 @@ fn ty_of_method(ccx: @crate_ctxt, rp: option<ty::region_variance>) -> ty::method { {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.purity, @~[], m.decl, none, m.span), self_ty: m.self_ty.node, - purity: m.decl.purity, vis: m.vis} } @@ -561,11 +562,11 @@ fn ty_of_ty_method(self: @crate_ctxt, rp: option<ty::region_variance>) -> 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, m.span), + fty: ty_of_fn_decl(self, type_rscope(rp), ast::proto_bare, m.purity, + @~[], m.decl, none, m.span), // assume public, because this is only invoked on trait methods self_ty: m.self_ty.node, - purity: m.decl.purity, vis: ast::public} + vis: ast::public} } /* @@ -614,9 +615,10 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item) tcx.tcache.insert(local_def(it.id), tpt); return tpt; } - ast::item_fn(decl, tps, _) => { + ast::item_fn(decl, purity, tps, _) => { let bounds = ty_param_bounds(ccx, tps); - let tofd = ty_of_fn_decl(ccx, empty_rscope, ast::proto_bare, @~[], + let tofd = ty_of_fn_decl(ccx, empty_rscope, + ast::proto_bare, purity, @~[], decl, none, it.span); let tpt = {bounds: bounds, region_param: none, @@ -689,9 +691,9 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item) fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item) -> ty::ty_param_bounds_and_ty { match it.node { - ast::foreign_item_fn(fn_decl, params) => { - return ty_of_foreign_fn_decl(ccx, fn_decl, params, - local_def(it.id)); + ast::foreign_item_fn(fn_decl, purity, params) => { + return ty_of_foreign_fn_decl(ccx, fn_decl, purity, params, + local_def(it.id)); } } } @@ -739,16 +741,17 @@ fn ty_param_bounds(ccx: @crate_ctxt, } fn ty_of_foreign_fn_decl(ccx: @crate_ctxt, - decl: ast::fn_decl, - ty_params: ~[ast::ty_param], - def_id: ast::def_id) -> ty::ty_param_bounds_and_ty { + decl: ast::fn_decl, + purity: ast::purity, + ty_params: ~[ast::ty_param], + def_id: ast::def_id) -> ty::ty_param_bounds_and_ty { let bounds = ty_param_bounds(ccx, ty_params); let rb = in_binding_rscope(empty_rscope); let input_tys = decl.inputs.map(|a| ty_of_arg(ccx, rb, a, none) ); let output_ty = ast_ty_to_ty(ccx, rb, decl.output); - let t_fn = ty::mk_fn(ccx.tcx, {purity: decl.purity, + let t_fn = ty::mk_fn(ccx.tcx, {purity: purity, proto: ty::proto_bare, bounds: @~[], inputs: input_tys, diff --git a/src/rustdoc/extract.rs b/src/rustdoc/extract.rs index b3e5785c06e..2bfc0da36f9 100644 --- a/src/rustdoc/extract.rs +++ b/src/rustdoc/extract.rs @@ -83,7 +83,7 @@ fn moddoc_from_mod( nmoddoc_from_mod(itemdoc, nm) )) } - ast::item_fn(_, _, _) => { + ast::item_fn(*) => { some(doc::fntag( fndoc_from_fn(itemdoc) )) @@ -129,7 +129,7 @@ fn nmoddoc_from_mod( fns: do vec::map(module_.items) |item| { let itemdoc = mk_itemdoc(item.id, to_str(item.ident)); match item.node { - ast::foreign_item_fn(_, _) => { + ast::foreign_item_fn(*) => { fndoc_from_fn(itemdoc) } } diff --git a/src/rustdoc/tystr_pass.rs b/src/rustdoc/tystr_pass.rs index 40789f99ee2..f41c2de4093 100644 --- a/src/rustdoc/tystr_pass.rs +++ b/src/rustdoc/tystr_pass.rs @@ -50,11 +50,11 @@ fn get_fn_sig(srv: astsrv::srv, fn_id: doc::ast_id) -> option<~str> { match ctxt.ast_map.get(fn_id) { ast_map::node_item(@{ ident: ident, - node: ast::item_fn(decl, tys, _), _ + node: ast::item_fn(decl, _, tys, _), _ }, _) | ast_map::node_foreign_item(@{ ident: ident, - node: ast::foreign_item_fn(decl, tys), _ + node: ast::foreign_item_fn(decl, _, tys), _ }, _, _) => { some(pprust::fun_to_str(decl, ident, tys, extract::interner())) }