about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorMichael Sullivan <sully@msully.net>2012-08-23 18:17:16 -0700
committerMichael Sullivan <sully@msully.net>2012-08-23 19:40:01 -0700
commit0f996f70a632d1427801f20935a69a57fbb3679e (patch)
tree10bb420206b95838c5bd1b2ac6451cf93ef0b8f4 /src/libsyntax
parent34886ed488f6cc18c3fdc20cdeccab6178e00c0f (diff)
Remove purity from fn_decl and move it out to containing AST elements.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs12
-rw-r--r--src/libsyntax/ast_util.rs7
-rw-r--r--src/libsyntax/ext/auto_serialize.rs6
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs2
-rw-r--r--src/libsyntax/fold.rs24
-rw-r--r--src/libsyntax/parse/parser.rs64
-rw-r--r--src/libsyntax/print/pprust.rs40
-rw-r--r--src/libsyntax/visit.rs15
8 files changed, 86 insertions, 84 deletions
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);
       }