]> git.lizzy.rs Git - rust.git/commitdiff
syntax: parse `const fn` for free functions and inherent methods.
authorEduard Burtescu <edy.burt@gmail.com>
Wed, 25 Feb 2015 20:05:07 +0000 (22:05 +0200)
committerNiko Matsakis <niko@alum.mit.edu>
Thu, 21 May 2015 15:47:30 +0000 (11:47 -0400)
34 files changed:
src/librustc/metadata/encoder.rs
src/librustc/middle/effect.rs
src/librustc/middle/infer/error_reporting.rs
src/librustc/middle/reachable.rs
src/librustc/middle/resolve_lifetime.rs
src/librustc/middle/stability.rs
src/librustc/middle/ty.rs
src/librustc_lint/builtin.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_resolve/lib.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/inline.rs
src/librustc_trans/trans/monomorphize.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/lib.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/doctree.rs
src/librustdoc/html/format.rs
src/librustdoc/html/render.rs
src/librustdoc/visit_ast.rs
src/libsyntax/ast.rs
src/libsyntax/ast_map/blocks.rs
src/libsyntax/ast_util.rs
src/libsyntax/ext/build.rs
src/libsyntax/ext/deriving/generic/mod.rs
src/libsyntax/ext/expand.rs
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/parse/parser.rs
src/libsyntax/print/pprust.rs
src/libsyntax/test.rs
src/libsyntax/visit.rs

index 86f33257e09036101239e8f0920348268612043c..744b743a337a9b582b616f3f825444c212f27ea3 100644 (file)
@@ -1049,7 +1049,7 @@ fn add_to_index(item: &ast::Item, rbml_w: &mut Encoder,
         encode_stability(rbml_w, stab);
         rbml_w.end_tag();
       }
-      ast::ItemFn(ref decl, _, _, ref generics, _) => {
+      ast::ItemFn(ref decl, _, _, _, ref generics, _) => {
         add_to_index(item, rbml_w, index);
         rbml_w.start_tag(tag_items_data_item);
         encode_def_id(rbml_w, def_id);
@@ -1967,7 +1967,7 @@ fn encode_reachable_extern_fns(ecx: &EncodeContext, rbml_w: &mut Encoder) {
 
     for id in ecx.reachable {
         if let Some(ast_map::NodeItem(i)) = ecx.tcx.map.find(*id) {
-            if let ast::ItemFn(_, _, abi, ref generics, _) = i.node {
+            if let ast::ItemFn(_, _, _, abi, ref generics, _) = i.node {
                 if abi != abi::Rust && !generics.is_type_parameterized() {
                     rbml_w.wr_tagged_u32(tag_reachable_extern_fn_id, *id);
                 }
index b6a070c9332fda45b3e894ec19eab99a20252319..963d8cf61bc74909d1bd9493f2d8729c49a8a286 100644 (file)
@@ -87,8 +87,8 @@ fn visit_fn(&mut self, fn_kind: visit::FnKind<'v>, fn_decl: &'v ast::FnDecl,
                 block: &'v ast::Block, span: Span, _: ast::NodeId) {
 
         let (is_item_fn, is_unsafe_fn) = match fn_kind {
-            visit::FkItemFn(_, _, fn_style, _, _) =>
-                (true, fn_style == ast::Unsafety::Unsafe),
+            visit::FkItemFn(_, _, unsafety, _, _) =>
+                (true, unsafety == ast::Unsafety::Unsafe),
             visit::FkMethod(_, sig, _) =>
                 (true, sig.unsafety == ast::Unsafety::Unsafe),
             _ => (false, false),
index 8aca64484bf4506d43b9d4bbcff305477fbe7edf..4ec5cf03364973d241a6c1a19242dc62a522f617 100644 (file)
@@ -158,6 +158,7 @@ fn note_region_origin(&self,
     fn give_expl_lifetime_param(&self,
                                 decl: &ast::FnDecl,
                                 unsafety: ast::Unsafety,
+                                constness: ast::Constness,
                                 ident: ast::Ident,
                                 opt_explicit_self: Option<&ast::ExplicitSelf_>,
                                 generics: &ast::Generics,
@@ -826,8 +827,9 @@ fn give_suggestion(&self, same_regions: &[SameRegions]) {
             Some(ref node) => match *node {
                 ast_map::NodeItem(ref item) => {
                     match item.node {
-                        ast::ItemFn(ref fn_decl, pur, _, ref gen, _) => {
-                            Some((fn_decl, gen, pur, item.ident, None, item.span))
+                        ast::ItemFn(ref fn_decl, unsafety, constness, _, ref gen, _) => {
+                            Some((fn_decl, gen, unsafety, constness,
+                                  item.ident, None, item.span))
                         },
                         _ => None
                     }
@@ -838,6 +840,7 @@ fn give_suggestion(&self, same_regions: &[SameRegions]) {
                             Some((&sig.decl,
                                   &sig.generics,
                                   sig.unsafety,
+                                  sig.constness,
                                   item.ident,
                                   Some(&sig.explicit_self.node),
                                   item.span))
@@ -852,6 +855,7 @@ fn give_suggestion(&self, same_regions: &[SameRegions]) {
                             Some((&sig.decl,
                                   &sig.generics,
                                   sig.unsafety,
+                                  sig.constness,
                                   item.ident,
                                   Some(&sig.explicit_self.node),
                                   item.span))
@@ -863,12 +867,12 @@ fn give_suggestion(&self, same_regions: &[SameRegions]) {
             },
             None => None
         };
-        let (fn_decl, generics, unsafety, ident, expl_self, span)
+        let (fn_decl, generics, unsafety, constness, ident, expl_self, span)
                                     = node_inner.expect("expect item fn");
         let rebuilder = Rebuilder::new(self.tcx, fn_decl, expl_self,
                                        generics, same_regions, &life_giver);
         let (fn_decl, expl_self, generics) = rebuilder.rebuild();
-        self.give_expl_lifetime_param(&fn_decl, unsafety, ident,
+        self.give_expl_lifetime_param(&fn_decl, unsafety, constness, ident,
                                       expl_self.as_ref(), &generics, span);
     }
 }
@@ -1423,12 +1427,13 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> {
     fn give_expl_lifetime_param(&self,
                                 decl: &ast::FnDecl,
                                 unsafety: ast::Unsafety,
+                                constness: ast::Constness,
                                 ident: ast::Ident,
                                 opt_explicit_self: Option<&ast::ExplicitSelf_>,
                                 generics: &ast::Generics,
                                 span: codemap::Span) {
-        let suggested_fn = pprust::fun_to_string(decl, unsafety, ident,
-                                              opt_explicit_self, generics);
+        let suggested_fn = pprust::fun_to_string(decl, unsafety, constness, ident,
+                                                 opt_explicit_self, generics);
         let msg = format!("consider using an explicit lifetime \
                            parameter as shown: {}", suggested_fn);
         self.tcx.sess.span_help(span, &msg[..]);
@@ -1710,7 +1715,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
     let method_id_opt = match tcx.map.find(parent) {
         Some(node) => match node {
             ast_map::NodeItem(item) => match item.node {
-                ast::ItemFn(_, _, _, ref gen, _) => {
+                ast::ItemFn(_, _, _, _, ref gen, _) => {
                     taken.push_all(&gen.lifetimes);
                     None
                 },
index b532dc88df4cb5c939c6935ddd20bd1edbd2fba8..f374c9749c250680ca334810fb1b5c27c4e1f83a 100644 (file)
@@ -46,7 +46,7 @@ fn item_might_be_inlined(item: &ast::Item) -> bool {
 
     match item.node {
         ast::ItemImpl(_, _, ref generics, _, _, _) |
-        ast::ItemFn(_, _, _, ref generics, _) => {
+        ast::ItemFn(_, _, _, _, ref generics, _) => {
             generics_require_inlining(generics)
         }
         _ => false,
@@ -256,7 +256,7 @@ fn propagate_node(&mut self, node: &ast_map::Node,
             // but all other rust-only interfaces can be private (they will not
             // participate in linkage after this product is produced)
             if let ast_map::NodeItem(item) = *node {
-                if let ast::ItemFn(_, _, abi, _, _) = item.node {
+                if let ast::ItemFn(_, _, _, abi, _, _) = item.node {
                     if abi != abi::Rust {
                         self.reachable_symbols.insert(search_item);
                     }
@@ -273,7 +273,7 @@ fn propagate_node(&mut self, node: &ast_map::Node,
         match *node {
             ast_map::NodeItem(item) => {
                 match item.node {
-                    ast::ItemFn(_, _, _, _, ref search_block) => {
+                    ast::ItemFn(_, _, _, _, _, ref search_block) => {
                         if item_might_be_inlined(&*item) {
                             visit::walk_block(self, &**search_block)
                         }
index e7a03a9b7e17439ea4a1557ea9e1c026897d88b4..467e404581187886e5cd2013d67fff84658f5752 100644 (file)
@@ -154,7 +154,7 @@ fn visit_item(&mut self, item: &ast::Item) {
     fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
                 b: &'v ast::Block, s: Span, _: ast::NodeId) {
         match fk {
-            visit::FkItemFn(_, generics, _, _, _) => {
+            visit::FkItemFn(_, generics, _, _, _, _) => {
                 self.visit_early_late(subst::FnSpace, generics, |this| {
                     this.walk_fn(fk, fd, b, s)
                 })
index d75dc861e83304a0702fb699333b7df9c3e3185c..8a9e957f02afaa8fb3739aed5027a98fa143ebfa 100644 (file)
@@ -23,7 +23,7 @@
 use syntax::ast;
 use syntax::ast::{Attribute, Block, Crate, DefId, FnDecl, NodeId, Variant};
 use syntax::ast::{Item, Generics, StructField};
-use syntax::ast_util::is_local;
+use syntax::ast_util::{is_local, PostExpansionMethod};
 use syntax::attr::{Stability, AttrMetaMethods};
 use syntax::visit::{FnKind, Visitor};
 use syntax::feature_gate::emit_feature_err;
index 15e1ac2f2c65e1867f8be316ad02d20cca743425..2765fd638600a7adc523e6b314c454546de18795 100644 (file)
@@ -2428,7 +2428,7 @@ pub fn for_item(cx: &'a ctxt<'tcx>, id: NodeId) -> ParameterEnvironment<'a, 'tcx
             }
             Some(ast_map::NodeItem(item)) => {
                 match item.node {
-                    ast::ItemFn(_, _, _, _, ref body) => {
+                    ast::ItemFn(_, _, _, _, _, ref body) => {
                         // We assume this is a function.
                         let fn_def_id = ast_util::local_def(id);
                         let fn_scheme = lookup_item_type(cx, fn_def_id);
index 6721c4a6636a9a9a94e5d08ac9203b7f468ca135..abf0332b4a22fb8a2e3b3d01ac93969ab4360af5 100644 (file)
@@ -977,7 +977,7 @@ fn check_fn(&mut self, cx: &Context,
                 },
                 _ => (),
             },
-            visit::FkItemFn(ident, _, _, _, _) => {
+            visit::FkItemFn(ident, _, _, _, _, _) => {
                 self.check_snake_case(cx, "function", &token::get_ident(ident), Some(span))
             },
             _ => (),
@@ -1853,7 +1853,7 @@ fn check_fn(&mut self, cx: &Context, fn_kind: visit::FnKind, _: &ast::FnDecl,
                               ast::NodeId, ast::NodeId, ast::Ident, ast::NodeId) -> bool;
 
         let (name, checker) = match fn_kind {
-            visit::FkItemFn(name, _, _, _, _) => (name, id_refers_to_this_fn as F),
+            visit::FkItemFn(name, _, _, _, _, _) => (name, id_refers_to_this_fn as F),
             visit::FkMethod(name, _, _) => (name, id_refers_to_this_method as F),
             // closures can't recur, so they don't matter.
             visit::FkFnBlock => return
index 4ea18968d43ac218df9fbc3dda33aee3c716ad1e..30d5a4f111ba43e9b41bdd3636c52e947ae7714d 100644 (file)
@@ -425,7 +425,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) ->
                     .define_value(DefConst(local_def(item.id)), sp, modifiers);
                 parent.clone()
             }
-            ItemFn(_, _, _, _, _) => {
+            ItemFn(_, _, _, _, _, _) => {
                 let name_bindings = self.add_child(name, parent, ForbidDuplicateValues, sp);
 
                 let def = DefFn(local_def(item.id), false);
index 1f8d23fd4dc0d5e30c333b9ae452f09cfffe4ee8..1723313f015e595e143192f3ad878651fc65d7e0 100644 (file)
@@ -1809,7 +1809,7 @@ fn resolve_item(&mut self, item: &Item) {
                                                                ItemRibKind),
                                              |this| visit::walk_item(this, item));
             }
-            ItemFn(_, _, _, ref generics, _) => {
+            ItemFn(_, _, _, _, ref generics, _) => {
                 self.with_type_parameter_rib(HasTypeParameters(generics,
                                                                FnSpace,
                                                                ItemRibKind),
index e44aae76c19ad9456e17b939e64e7678c72993d4..f21837ed10d0907836904b0d313f184fb13c5665 100644 (file)
@@ -1073,7 +1073,7 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>)
     let blk = match tcx.map.find(id) {
         Some(ast_map::NodeItem(i)) => {
             match i.node {
-                ast::ItemFn(_, _, _, _, ref blk) => {
+                ast::ItemFn(_, _, _, _, _, ref blk) => {
                     blk
                 }
                 _ => tcx.sess.bug("unexpected item variant in has_nested_returns")
@@ -1966,7 +1966,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
     let from_external = ccx.external_srcs().borrow().contains_key(&item.id);
 
     match item.node {
-      ast::ItemFn(ref decl, _fn_style, abi, ref generics, ref body) => {
+      ast::ItemFn(ref decl, _, _, abi, ref generics, ref body) => {
         if !generics.is_type_parameterized() {
             let trans_everywhere = attr::requests_inline(&item.attrs);
             // Ignore `trans_everywhere` for cross-crate inlined items
@@ -2336,7 +2336,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                     }
                 }
 
-                ast::ItemFn(_, _, abi, _, _) => {
+                ast::ItemFn(_, _, _, abi, _, _) => {
                     let sym = sym();
                     let llfn = if abi == Rust {
                         register_fn(ccx, i.span, sym, i.id, ty)
index 3f44bc40f356b7f51362525272d4123adade4c39..9a53c3f0bcdf588790a9c23493f4591af07454b3 100644 (file)
@@ -55,7 +55,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
             trans_item(ccx, &**item);
 
             let linkage = match item.node {
-                ast::ItemFn(_, _, _, ref generics, _) => {
+                ast::ItemFn(_, _, _, _, ref generics, _) => {
                     if generics.is_type_parameterized() {
                         // Generics have no symbol, so they can't be given any
                         // linkage.
index 03fdd0c45c16ae6aa37d19e01b8673ca26956ed5..d086aa93a6f6b37d891427bd86e8df069b00d9e9 100644 (file)
@@ -177,7 +177,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         ast_map::NodeItem(i) => {
             match *i {
               ast::Item {
-                  node: ast::ItemFn(ref decl, _, abi, _, ref body),
+                  node: ast::ItemFn(ref decl, _, _, abi, _, ref body),
                   ..
               } => {
                   let d = mk_lldecl(abi);
index 0e64063d6a402f9981cf9de84f8a5e14b0cd1209..344d525d4cbf4bf3776a0140befaeaaa7d48cad2 100644 (file)
@@ -741,7 +741,7 @@ pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
                             &enum_definition.variants,
                             it.id);
       }
-      ast::ItemFn(_, _, _, _, _) => {} // entirely within check_item_body
+      ast::ItemFn(..) => {} // entirely within check_item_body
       ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
           debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
           match ty::impl_trait_ref(ccx.tcx, local_def(it.id)) {
@@ -796,7 +796,7 @@ pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
            ty::item_path_str(ccx.tcx, local_def(it.id)));
     let _indenter = indenter();
     match it.node {
-      ast::ItemFn(ref decl, _, _, _, ref body) => {
+      ast::ItemFn(ref decl, _, _, _, _, ref body) => {
         let fn_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
         let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
         check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
index 014991f7ea560e377aeb751014bb65e05e67fb1d..48876c2a1889a38cefefd5cfc3ae2809c166af30 100644 (file)
@@ -1440,7 +1440,7 @@ fn compute_type_scheme_of_item<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
             let ty = ccx.icx(&()).to_ty(&ExplicitRscope, &**t);
             ty::TypeScheme { ty: ty, generics: ty::Generics::empty() }
         }
-        ast::ItemFn(ref decl, unsafety, abi, ref generics, _) => {
+        ast::ItemFn(ref decl, unsafety, _, abi, ref generics, _) => {
             let ty_generics = ty_generics_for_fn(ccx, generics, &ty::Generics::empty());
             let tofd = astconv::ty_of_bare_fn(&ccx.icx(generics), unsafety, abi, &**decl);
             let ty = ty::mk_bare_fn(tcx, Some(local_def(it.id)), tcx.mk_bare_fn(tofd));
@@ -1492,7 +1492,7 @@ fn convert_typed_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         ast::ItemStatic(..) | ast::ItemConst(..) => {
             ty::GenericPredicates::empty()
         }
-        ast::ItemFn(_, _, _, ref ast_generics, _) => {
+        ast::ItemFn(_, _, _, _, ref ast_generics, _) => {
             ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
         }
         ast::ItemTy(_, ref generics) => {
index eaf7f1f92a75e15310b5cf43a187019ff21a6810..88ce75486a202711035993347f956f6d13293da0 100644 (file)
@@ -215,7 +215,7 @@ fn check_main_fn_ty(ccx: &CrateCtxt,
             match tcx.map.find(main_id) {
                 Some(ast_map::NodeItem(it)) => {
                     match it.node {
-                        ast::ItemFn(_, _, _, ref ps, _)
+                        ast::ItemFn(_, _, _, _, ref ps, _)
                         if ps.is_parameterized() => {
                             span_err!(ccx.tcx.sess, main_span, E0131,
                                       "main function is not allowed to have type parameters");
@@ -262,7 +262,7 @@ fn check_start_fn_ty(ccx: &CrateCtxt,
             match tcx.map.find(start_id) {
                 Some(ast_map::NodeItem(it)) => {
                     match it.node {
-                        ast::ItemFn(_,_,_,ref ps,_)
+                        ast::ItemFn(_,_,_,_,ref ps,_)
                         if ps.is_parameterized() => {
                             span_err!(tcx.sess, start_span, E0132,
                                       "start function is not allowed to have type parameters");
index 3ce8835b1a8de76744d561010ce4a5794d7e007e..9c64b7b4ab623dcb3aa303e32aff7f6046ff7651 100644 (file)
@@ -175,6 +175,7 @@ fn build_external_function(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) ->
         decl: decl,
         generics: (&t.generics, &predicates, subst::FnSpace).clean(cx),
         unsafety: style,
+        constness: ast::Constness::NotConst,
         abi: abi,
     }
 }
@@ -348,6 +349,7 @@ pub fn build_impl(cx: &DocContext,
                     }) => {
                         clean::MethodItem(clean::Method {
                             unsafety: unsafety,
+                            constness: ast::Constness::NotConst,
                             decl: decl,
                             self_: self_,
                             generics: generics,
index 4c2357f8a8f0d05b1df64fbbe00cafe4997a53e0..c2ae8020f284cf2a0cf97e6b62b3296f4a3b18c1 100644 (file)
@@ -989,6 +989,7 @@ pub struct Method {
     pub generics: Generics,
     pub self_: SelfTy,
     pub unsafety: ast::Unsafety,
+    pub constness: ast::Constness,
     pub decl: FnDecl,
     pub abi: abi::Abi
 }
@@ -1010,7 +1011,8 @@ fn clean(&self, cx: &DocContext) -> Method {
         Method {
             generics: self.generics.clean(cx),
             self_: self.explicit_self.node.clean(cx),
-            unsafety: self.unsafety.clone(),
+            unsafety: self.unsafety,
+            constness: self.constness,
             decl: decl,
             abi: self.abi
         }
@@ -1075,7 +1077,8 @@ pub struct Function {
     pub decl: FnDecl,
     pub generics: Generics,
     pub unsafety: ast::Unsafety,
-    pub abi: abi::Abi
+    pub constness: ast::Constness,
+    pub abi: abi::Abi,
 }
 
 impl Clean<Item> for doctree::Function {
@@ -1091,6 +1094,7 @@ fn clean(&self, cx: &DocContext) -> Item {
                 decl: self.decl.clean(cx),
                 generics: self.generics.clean(cx),
                 unsafety: self.unsafety,
+                constness: self.constness,
                 abi: self.abi,
             }),
         }
@@ -2453,6 +2457,7 @@ fn clean(&self, cx: &DocContext) -> Item {
                     generics: generics.clean(cx),
                     unsafety: ast::Unsafety::Unsafe,
                     abi: abi::Rust,
+                    constness: ast::Constness::NotConst,
                 })
             }
             ast::ForeignItemStatic(ref ty, mutbl) => {
index 8fa92304d249cb9d3adcfdba00d3b77e6250992c..cadd43ec6bfd8eee0c380883c677d55603c4bbb4 100644 (file)
@@ -133,6 +133,7 @@ pub struct Function {
     pub vis: ast::Visibility,
     pub stab: Option<attr::Stability>,
     pub unsafety: ast::Unsafety,
+    pub constness: ast::Constness,
     pub whence: Span,
     pub generics: ast::Generics,
     pub abi: abi::Abi,
index bb53d532f52f725b00453ad44dda63a16e221b70..a68e21aa01d9dee7c6491443646249c242d066a3 100644 (file)
 /// space after it.
 #[derive(Copy, Clone)]
 pub struct UnsafetySpace(pub ast::Unsafety);
+/// Similarly to VisSpace, this structure is used to render a function constness
+/// with a space after it.
+#[derive(Copy)]
+pub struct ConstnessSpace(pub ast::Constness);
 /// Wrapper struct for properly emitting a method declaration.
 pub struct Method<'a>(pub &'a clean::SelfTy, pub &'a clean::FnDecl);
 /// Similar to VisSpace, but used for mutability
@@ -63,6 +67,12 @@ pub fn get(&self) -> ast::Unsafety {
     }
 }
 
+impl ConstnessSpace {
+    pub fn get(&self) -> ast::Constness {
+        let ConstnessSpace(v) = *self; v
+    }
+}
+
 impl<'a, T: fmt::Display> fmt::Display for CommaSep<'a, T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         for (i, item) in self.0.iter().enumerate() {
@@ -607,6 +617,15 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
+impl fmt::Display for ConstnessSpace {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self.get() {
+            ast::Constness::Const => write!(f, "const "),
+            ast::Constness::NotConst => Ok(())
+        }
+    }
+}
+
 impl fmt::Display for clean::Import {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
index 36cf650d54e9af91d2c395d431ee9d2fab1f00fb..582f17168991ffd2ffd6a6c0fc614bdc8ab49daf 100644 (file)
@@ -63,6 +63,7 @@
 use doctree;
 use fold::DocFolder;
 use html::escape::Escape;
+use html::format::{ConstnessSpace};
 use html::format::{TyParamBounds, WhereClause, href, AbiSpace};
 use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace};
 use html::highlight;
@@ -1753,11 +1754,12 @@ fn item_static(w: &mut fmt::Formatter, it: &clean::Item,
 
 fn item_function(w: &mut fmt::Formatter, it: &clean::Item,
                  f: &clean::Function) -> fmt::Result {
-    try!(write!(w, "<pre class='rust fn'>{vis}{unsafety}{abi}fn \
+    try!(write!(w, "<pre class='rust fn'>{vis}{unsafety}{abi}{constness}fn \
                     {name}{generics}{decl}{where_clause}</pre>",
            vis = VisSpace(it.visibility),
            unsafety = UnsafetySpace(f.unsafety),
            abi = AbiSpace(f.abi),
+           constness = ConstnessSpace(f.constness),
            name = it.name.as_ref().unwrap(),
            generics = f.generics,
            where_clause = WhereClause(&f.generics),
@@ -1957,10 +1959,16 @@ fn assoc_type(w: &mut fmt::Formatter, it: &clean::Item,
 
 fn render_assoc_item(w: &mut fmt::Formatter, meth: &clean::Item,
                      link: AssocItemLink) -> fmt::Result {
-    fn method(w: &mut fmt::Formatter, it: &clean::Item,
-              unsafety: ast::Unsafety, abi: abi::Abi,
-              g: &clean::Generics, selfty: &clean::SelfTy,
-              d: &clean::FnDecl, link: AssocItemLink) -> fmt::Result {
+    fn method(w: &mut fmt::Formatter,
+              it: &clean::Item,
+              unsafety: ast::Unsafety,
+              constness: ast::Constness,
+              abi: abi::Abi,
+              g: &clean::Generics,
+              selfty: &clean::SelfTy,
+              d: &clean::FnDecl,
+              link: AssocItemLink)
+              -> fmt::Result {
         use syntax::abi::Abi;
 
         let name = it.name.as_ref().unwrap();
@@ -1971,12 +1979,10 @@ fn method(w: &mut fmt::Formatter, it: &clean::Item,
                 href(did).map(|p| format!("{}{}", p.0, anchor)).unwrap_or(anchor)
             }
         };
-        write!(w, "{}{}fn <a href='{href}' class='fnname'>{name}</a>\
+        write!(w, "{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
                    {generics}{decl}{where_clause}",
-               match unsafety {
-                   ast::Unsafety::Unsafe => "unsafe ",
-                   _ => "",
-               },
+               UnsafetySpace(unsafety),
+               ConstnessSpace(constness),
                match abi {
                    Abi::Rust => String::new(),
                    a => format!("extern {} ", a.to_string())
@@ -1989,11 +1995,12 @@ fn method(w: &mut fmt::Formatter, it: &clean::Item,
     }
     match meth.inner {
         clean::TyMethodItem(ref m) => {
-            method(w, meth, m.unsafety, m.abi, &m.generics, &m.self_, &m.decl,
-                   link)
+            method(w, meth, m.unsafety, ast::Constness::NotConst,
+                   m.abi, &m.generics, &m.self_, &m.decl, link)
         }
         clean::MethodItem(ref m) => {
-            method(w, meth, m.unsafety, m.abi, &m.generics, &m.self_, &m.decl,
+            method(w, meth, m.unsafety, m.constness,
+                   m.abi, &m.generics, &m.self_, &m.decl,
                    link)
         }
         clean::AssociatedConstItem(ref ty, ref default) => {
index 4ad693578ccdc312e3aed9aa689614abe19d0e68..92348aa648dc6ffc33e391a87dc93608b2f7de99 100644 (file)
@@ -123,7 +123,9 @@ pub fn visit_enum_def(&mut self, it: &ast::Item,
 
     pub fn visit_fn(&mut self, item: &ast::Item,
                     name: ast::Ident, fd: &ast::FnDecl,
-                    unsafety: &ast::Unsafety, abi: &abi::Abi,
+                    unsafety: &ast::Unsafety,
+                    constness: ast::Constness,
+                    _abi: &abi::Abi,
                     gen: &ast::Generics) -> Function {
         debug!("Visiting fn");
         Function {
@@ -136,6 +138,7 @@ pub fn visit_fn(&mut self, item: &ast::Item,
             whence: item.span,
             generics: gen.clone(),
             unsafety: *unsafety,
+            constness: constness,
             abi: *abi,
         }
     }
@@ -291,8 +294,9 @@ pub fn visit_item(&mut self, item: &ast::Item,
                 om.enums.push(self.visit_enum_def(item, name, ed, gen)),
             ast::ItemStruct(ref sd, ref gen) =>
                 om.structs.push(self.visit_struct_def(item, name, &**sd, gen)),
-            ast::ItemFn(ref fd, ref pur, ref abi, ref gen, _) =>
-                om.fns.push(self.visit_fn(item, name, &**fd, pur, abi, gen)),
+            ast::ItemFn(ref fd, unsafety, constness, ref abi, ref gen, _) =>
+                om.fns.push(self.visit_fn(item, name, &**fd, unsafety,
+                                          constness, abi, gen)),
             ast::ItemTy(ref ty, ref gen) => {
                 let t = Typedef {
                     ty: ty.clone(),
index e00cb82649b7b6bb538948623d1f1215eafbcd6e..bd7fb441bf53ea4760e91f58115cdcddc790b0d4 100644 (file)
@@ -1475,6 +1475,12 @@ pub enum Unsafety {
     Normal,
 }
 
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum Constness {
+    Const,
+    NotConst,
+}
+
 impl fmt::Display for Unsafety {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         fmt::Display::fmt(match *self {
@@ -1543,6 +1549,7 @@ pub enum ExplicitSelf_ {
 pub type ExplicitSelf = Spanned<ExplicitSelf_>;
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+             Constness,
 pub struct Mod {
     /// A span from the first token past `{` to the last token until `}`.
     /// For `mod foo;`, the inner span ranges from the first token
@@ -1761,7 +1768,7 @@ pub enum Item_ {
     /// A `const` item
     ItemConst(P<Ty>, P<Expr>),
     /// A function declaration
-    ItemFn(P<FnDecl>, Unsafety, Abi, Generics, P<Block>),
+    ItemFn(P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Block>),
     /// A module
     ItemMod(Mod),
     /// An external module
index 36a7f3a93817c127b966e56ea6099ee55446e08e..8b2b2fbeca1407280d0bab046705bafad6a0eda1 100644 (file)
@@ -120,6 +120,7 @@ struct ItemFnParts<'a> {
     ident:    ast::Ident,
     decl:     &'a ast::FnDecl,
     unsafety: ast::Unsafety,
+    constness: ast::Constness,
     abi:      abi::Abi,
     vis:      ast::Visibility,
     generics: &'a ast::Generics,
@@ -180,7 +181,7 @@ pub fn id(self) -> NodeId {
 
     pub fn kind(self) -> visit::FnKind<'a> {
         let item = |p: ItemFnParts<'a>| -> visit::FnKind<'a> {
-            visit::FkItemFn(p.ident, p.generics, p.unsafety, p.abi, p.vis)
+            visit::FkItemFn(p.ident, p.generics, p.unsafety, p.abi, p.constness, p.vis)
         };
         let closure = |_: ClosureParts| {
             visit::FkFnBlock
@@ -204,10 +205,19 @@ fn handle<A, I, M, C>(self, item_fn: I, method: M, closure: C) -> A where
     {
         match self.node {
             ast_map::NodeItem(i) => match i.node {
-                ast::ItemFn(ref decl, unsafety, abi, ref generics, ref block) =>
-                    item_fn(ItemFnParts{
-                        ident: i.ident, decl: &**decl, unsafety: unsafety, body: &**block,
-                        generics: generics, abi: abi, vis: i.vis, id: i.id, span: i.span
+                ast::ItemFn(ref decl, unsafety, constness, ref abi, ref generics, ref block) =>
+                    item_fn(ItemFnParts {
+                        id: i.id,
+                        ident: i.ident,
+                        decl: &**decl,
+                        unsafety: unsafety,
+                        constness: constness,
+                        body: &**block,
+                        generics: generics,
+                        abi: abi,
+                        vis: i.vis,
+                        constness: constness,
+                        span: i.span
                     }),
                 _ => panic!("item FnLikeNode that is not fn-like"),
             },
index 8471fef3487e62f53af6d48d68eaab0fa040d444..45db8cc7b25a5ade6f55bc2a09f471691c5205d9 100644 (file)
@@ -251,6 +251,7 @@ pub fn impl_pretty_name(trait_ref: &Option<TraitRef>, ty: Option<&Ty>) -> Ident
     token::gensym_ident(&pretty[..])
 }
 
+                 _,
 pub fn struct_field_visibility(field: ast::StructField) -> Visibility {
     match field.node.kind {
         ast::NamedField(_, v) | ast::UnnamedField(v) => v
index 354a0bff74998bbcc3c21d93f7d379d0db0f41d3..8a80e291a538405f38c11e9911be3d3421fa855c 100644 (file)
@@ -1034,6 +1034,7 @@ fn item_fn_poly(&self,
                   Vec::new(),
                   ast::ItemFn(self.fn_decl(inputs, output),
                               ast::Unsafety::Normal,
+                              ast::Constness::NotConst,
                               abi::Rust,
                               generics,
                               body))
index b9968ca96088ff5b122ab2f4a083b991b71a5948..eab6c3ae7251a1f41a2e58e7baacce72b966aca5 100644 (file)
@@ -880,6 +880,7 @@ fn create_method(&self,
                 abi: abi,
                 explicit_self: explicit_self,
                 unsafety: unsafety,
+                constness: ast::Constness::NotConst,
                 decl: fn_decl
             }, body_block)
         })
index 484684a87f4cd6d53c8df363119fde4926fe42ea..912cc841a642b6fa24cb55dddda67031952ec5c8 100644 (file)
@@ -513,11 +513,12 @@ pub fn expand_item(it: P<ast::Item>, fld: &mut MacroExpander)
 /// Expand item_underscore
 fn expand_item_underscore(item: ast::Item_, fld: &mut MacroExpander) -> ast::Item_ {
     match item {
-        ast::ItemFn(decl, fn_style, abi, generics, body) => {
+        ast::ItemFn(decl, unsafety, constness, abi, generics, body) => {
             let (rewritten_fn_decl, rewritten_body)
                 = expand_and_rename_fn_decl_and_block(decl, body, fld);
             let expanded_generics = fold::noop_fold_generics(generics,fld);
-            ast::ItemFn(rewritten_fn_decl, fn_style, abi, expanded_generics, rewritten_body)
+            ast::ItemFn(rewritten_fn_decl, unsafety, constness, abi,
+                        expanded_generics, rewritten_body)
         }
         _ => noop_fold_item_underscore(item, fld)
     }
index d79714248c89bd75515e17e5e3de02df532c50e3..84546679b23b2a88d8392973339b575eccd799a0 100644 (file)
@@ -641,12 +641,12 @@ fn visit_fn(&mut self,
                 span: Span,
                 _node_id: NodeId) {
         match fn_kind {
-            visit::FkItemFn(_, _, _, abi, _) if abi == Abi::RustIntrinsic => {
+            visit::FkItemFn(_, _, _, _, abi, _) if abi == Abi::RustIntrinsic => {
                 self.gate_feature("intrinsics",
                                   span,
                                   "intrinsics are subject to change")
             }
-            visit::FkItemFn(_, _, _, abi, _) |
+            visit::FkItemFn(_, _, _, _, abi, _) |
             visit::FkMethod(_, &ast::MethodSig { abi, .. }, _) if abi == Abi::RustCall => {
                 self.gate_feature("unboxed_closures",
                                   span,
index 4bf15f509a048e1f34b833228ba10da97cd43fa2..c2382eaf82e372c002c2af587a9ae6d84cc29edf 100644 (file)
@@ -917,10 +917,11 @@ pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
         ItemConst(t, e) => {
             ItemConst(folder.fold_ty(t), folder.fold_expr(e))
         }
-        ItemFn(decl, unsafety, abi, generics, body) => {
+        ItemFn(decl, unsafety, constness, abi, generics, body) => {
             ItemFn(
                 folder.fold_fn_decl(decl),
                 unsafety,
+                constness,
                 abi,
                 folder.fold_generics(generics),
                 folder.fold_block(body)
@@ -1126,6 +1127,8 @@ pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> Method
         unsafety: sig.unsafety,
         decl: folder.fold_fn_decl(sig.decl)
     }
+                     constness,
+                         constness,
 }
 
 pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
index 2b6f91bbc993ae2500e12fe3e436ebda0b4573e4..6fba8fd47fdce9b300d49720351b8111cf93ec3f 100644 (file)
@@ -17,7 +17,7 @@
 use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
 use ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, BiLt, BiGt, Block};
 use ast::{BlockCheckMode, CaptureByRef, CaptureByValue, CaptureClause};
-use ast::{ConstImplItem, ConstTraitItem, Crate, CrateConfig};
+use ast::{Constness, ConstImplItem, ConstTraitItem, Crate, CrateConfig};
 use ast::{Decl, DeclItem, DeclLocal, DefaultBlock, DefaultReturn};
 use ast::{UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf};
 use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
@@ -1175,7 +1175,7 @@ pub fn parse_trait_items(&mut self) -> PResult<Vec<P<TraitItem>>> {
                 };
                 (ident, ConstTraitItem(ty, default))
             } else {
-                let style = try!(p.parse_unsafety());
+                let unsafety = try!(p.parse_unsafety());
                 let abi = if try!(p.eat_keyword(keywords::Extern)) {
                     try!(p.parse_opt_abi()).unwrap_or(abi::C)
                 } else {
@@ -1195,7 +1195,8 @@ pub fn parse_trait_items(&mut self) -> PResult<Vec<P<TraitItem>>> {
 
                 generics.where_clause = try!(p.parse_where_clause());
                 let sig = ast::MethodSig {
-                    unsafety: style,
+                    unsafety: unsafety,
+                    constness: ast::Constness::NotConst;
                     decl: d,
                     generics: generics,
                     abi: abi,
@@ -4359,12 +4360,16 @@ fn mk_item(&mut self, lo: BytePos, hi: BytePos, ident: Ident,
     }
 
     /// Parse an item-position function declaration.
-    fn parse_item_fn(&mut self, unsafety: Unsafety, abi: abi::Abi) -> PResult<ItemInfo> {
+    fn parse_item_fn(&mut self,
+                     unsafety: Unsafety,
+                     constness: Constness,
+                     abi: abi::Abi)
+                     -> PResult<ItemInfo> {
         let (ident, mut generics) = try!(self.parse_fn_header());
         let decl = try!(self.parse_fn_decl(false));
         generics.where_clause = try!(self.parse_where_clause());
         let (inner_attrs, body) = try!(self.parse_inner_attrs_and_block());
-        Ok((ident, ItemFn(decl, unsafety, abi, generics, body), Some(inner_attrs)))
+        Ok((ident, ItemFn(decl, unsafety, constness, abi, generics, body), Some(inner_attrs)))
     }
 
     /// Parse an impl item.
@@ -4445,11 +4450,17 @@ fn parse_impl_method(&mut self, vis: Visibility)
             }
             Ok((token::special_idents::invalid, vec![], ast::MacImplItem(m)))
         } else {
-            let unsafety = try!(self.parse_unsafety());
-            let abi = if try!(self.eat_keyword(keywords::Extern)) {
-                try!(self.parse_opt_abi()).unwrap_or(abi::C)
+            let is_const_fn = !is_trait_impl && self.eat_keyword(keywords::Const);
+            let (constness, unsafety, abi) = if is_const_fn {
+                (Constness::Const, Unsafety::Normal, abi::Rust)
             } else {
-                abi::Rust
+                let unsafety = try!(self.parse_unsafety());
+                let abi = if try!(self.eat_keyword(keywords::Extern)) {
+                    try!(self.parse_opt_abi()).unwrap_or(abi::C)
+                } else {
+                    abi::Rust
+                };
+                (Constness::NotConst, unsafety, abi)
             };
             try!(self.expect_keyword(keywords::Fn));
             let ident = try!(self.parse_ident());
@@ -4464,6 +4475,7 @@ fn parse_impl_method(&mut self, vis: Visibility)
                 abi: abi,
                 explicit_self: explicit_self,
                 unsafety: unsafety,
+                constness: constness;
                 decl: decl
              }, body)))
         }
@@ -5252,7 +5264,7 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
                 // EXTERN FUNCTION ITEM
                 let abi = opt_abi.unwrap_or(abi::C);
                 let (ident, item_, extra_attrs) =
-                    try!(self.parse_item_fn(Unsafety::Normal, abi));
+                    try!(self.parse_item_fn(Unsafety::Normal, Constness::NotConst, abi));
                 let last_span = self.last_span;
                 let item = self.mk_item(lo,
                                         last_span.hi,
@@ -5287,6 +5299,21 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
             return Ok(Some(item));
         }
         if try!(self.eat_keyword(keywords::Const) ){
+            if self.check_keyword(keywords::Fn) {
+                // CONST FUNCTION ITEM
+                self.bump();
+                let (ident, item_, extra_attrs) =
+                    self.parse_item_fn(Unsafety::Normal, Constness::Const, abi::Rust);
+                let last_span = self.last_span;
+                let item = self.mk_item(lo,
+                                        last_span.hi,
+                                        ident,
+                                        item_,
+                                        visibility,
+                                        maybe_append(attrs, extra_attrs));
+                return Ok(item);
+            }
+
             // CONST ITEM
             if try!(self.eat_keyword(keywords::Mut) ){
                 let last_span = self.last_span;
@@ -5340,7 +5367,7 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
             // FUNCTION ITEM
             try!(self.bump());
             let (ident, item_, extra_attrs) =
-                try!(self.parse_item_fn(Unsafety::Normal, abi::Rust));
+                try!(self.parse_item_fn(Unsafety::Normal, Constness::NotConst, abi::Rust));
             let last_span = self.last_span;
             let item = self.mk_item(lo,
                                     last_span.hi,
@@ -5361,7 +5388,7 @@ fn parse_item_(&mut self, attrs: Vec<Attribute>,
             };
             try!(self.expect_keyword(keywords::Fn));
             let (ident, item_, extra_attrs) =
-                try!(self.parse_item_fn(Unsafety::Unsafe, abi));
+                try!(self.parse_item_fn(Unsafety::Unsafe, Constness::NotConst, abi));
             let last_span = self.last_span;
             let item = self.mk_item(lo,
                                     last_span.hi,
index b71d65a8fb0c5dcafdd173deefdf6e847ac6dd6c..5889b968f41461dbb10a617b356c2dd734daa8db 100644 (file)
@@ -378,12 +378,28 @@ pub fn ident_to_string(id: &ast::Ident) -> String {
     to_string(|s| s.print_ident(*id))
 }
 
+<<<<<<< HEAD
 pub fn fun_to_string(decl: &ast::FnDecl, unsafety: ast::Unsafety, name: ast::Ident,
                   opt_explicit_self: Option<&ast::ExplicitSelf_>,
                   generics: &ast::Generics) -> String {
     to_string(|s| {
+||||||| parent of 61a958e... syntax: parse `const fn` for free functions and inherent methods.
+pub fn fun_to_string(decl: &ast::FnDecl, unsafety: ast::Unsafety, name: ast::Ident,
+                  opt_explicit_self: Option<&ast::ExplicitSelf_>,
+                  generics: &ast::Generics) -> String {
+    $to_string(|s| {
+=======
+pub fn fun_to_string(decl: &ast::FnDecl,
+                     unsafety: ast::Unsafety,
+                     constness: ast::Constness,
+                     name: ast::Ident,
+                     opt_explicit_self: Option<&ast::ExplicitSelf_>,
+                     generics: &ast::Generics)
+                     -> String {
+    $to_string(|s| {
+>>>>>>> 61a958e... syntax: parse `const fn` for free functions and inherent methods.
         try!(s.head(""));
-        try!(s.print_fn(decl, unsafety, abi::Rust, Some(name),
+        try!(s.print_fn(decl, unsafety, constness, abi::Rust, Some(name),
                         generics, opt_explicit_self, ast::Inherited));
         try!(s.end()); // Close the head box
         s.end() // Close the outer box
@@ -740,7 +756,8 @@ pub fn print_foreign_item(&mut self,
         match item.node {
             ast::ForeignItemFn(ref decl, ref generics) => {
                 try!(self.head(""));
-                try!(self.print_fn(&**decl, ast::Unsafety::Normal,
+                try!(self.print_fn(decl, ast::Unsafety::Normal,
+                                   ast::Constness::NotConst,
                                    abi::Rust, Some(item.ident),
                                    generics, None, item.vis));
                 try!(self.end()); // end head-ibox
@@ -866,11 +883,12 @@ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
                 try!(word(&mut self.s, ";"));
                 try!(self.end()); // end the outer cbox
             }
-            ast::ItemFn(ref decl, unsafety, abi, ref typarams, ref body) => {
+            ast::ItemFn(ref decl, unsafety, constness, abi, ref typarams, ref body) => {
                 try!(self.head(""));
                 try!(self.print_fn(
                     decl,
                     unsafety,
+                    constness,
                     abi,
                     Some(item.ident),
                     typarams,
@@ -1241,6 +1259,7 @@ pub fn print_method_sig(&mut self,
                             -> io::Result<()> {
         self.print_fn(&m.decl,
                       m.unsafety,
+                      m.constness,
                       m.abi,
                       Some(ident),
                       &m.generics,
@@ -2335,12 +2354,13 @@ fn print_explicit_self(&mut self,
     pub fn print_fn(&mut self,
                     decl: &ast::FnDecl,
                     unsafety: ast::Unsafety,
+                    constness: ast::Constness,
                     abi: abi::Abi,
                     name: Option<ast::Ident>,
                     generics: &ast::Generics,
                     opt_explicit_self: Option<&ast::ExplicitSelf_>,
                     vis: ast::Visibility) -> io::Result<()> {
-        try!(self.print_fn_header_info(unsafety, abi, vis));
+        try!(self.print_fn_header_info(unsafety, constness, abi, vis));
 
         if let Some(name) = name {
             try!(self.nbsp());
@@ -2726,8 +2746,13 @@ pub fn print_ty_fn(&mut self,
                 predicates: Vec::new(),
             },
         };
-        try!(self.print_fn(decl, unsafety, abi, name,
-                           &generics, opt_explicit_self,
+        try!(self.print_fn(decl,
+                           unsafety,
+                           ast::Constness::NotConst,
+                           abi,
+                           name,
+                           generics,
+                           opt_explicit_self,
                            ast::Inherited));
         self.end()
     }
@@ -2976,11 +3001,17 @@ pub fn print_extern_opt_abi(&mut self,
 
     pub fn print_fn_header_info(&mut self,
                                 unsafety: ast::Unsafety,
+                                constness: ast::Constness,
                                 abi: abi::Abi,
                                 vis: ast::Visibility) -> io::Result<()> {
         try!(word(&mut self.s, &visibility_qualified(vis, "")));
         try!(self.print_unsafety(unsafety));
 
+        match constness {
+            ast::Constness::NotConst => {}
+            ast::Constness::Const => try!(self.word_nbsp("unsafe"))
+        }
+
         if abi != abi::Rust {
             try!(self.word_nbsp("extern"));
             try!(self.word_nbsp(&abi.to_string()));
@@ -3018,8 +3049,10 @@ fn test_fun_to_string() {
             variadic: false
         };
         let generics = ast_util::empty_generics();
-        assert_eq!(fun_to_string(&decl, ast::Unsafety::Normal, abba_ident,
-                               None, &generics),
+        assert_eq!(fun_to_string(&decl, ast::Unsafety::Normal,
+                                 ast::Constness::NotConst,
+                                 abba_ident,
+                                 None, &generics),
                    "fn abba()");
     }
 
index 458e3f7f0bd9b048e5381f6f198545ecc6ed18ba..c680d5bbbdf7ad24581aacf11fd08e6b97edc0a3 100644 (file)
@@ -123,7 +123,7 @@ fn fold_item(&mut self, i: P<ast::Item>) -> SmallVector<P<ast::Item>> {
 
         let i = if is_test_fn(&self.cx, &*i) || is_bench_fn(&self.cx, &*i) {
             match i.node {
-                ast::ItemFn(_, ast::Unsafety::Unsafe, _, _, _) => {
+                ast::ItemFn(_, ast::Unsafety::Unsafe, _, _, _, _) => {
                     let diag = self.cx.span_diagnostic;
                     panic!(diag.span_fatal(i.span, "unsafe functions cannot be used for tests"));
                 }
@@ -320,7 +320,7 @@ fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
 
     fn has_test_signature(i: &ast::Item) -> HasTestSignature {
         match &i.node {
-          &ast::ItemFn(ref decl, _, _, ref generics, _) => {
+          &ast::ItemFn(ref decl, _, _, _, ref generics, _) => {
             let no_output = match decl.output {
                 ast::DefaultReturn(..) => true,
                 ast::Return(ref t) if t.node == ast::TyTup(vec![]) => true,
@@ -356,7 +356,7 @@ fn is_bench_fn(cx: &TestCtxt, i: &ast::Item) -> bool {
 
     fn has_test_signature(i: &ast::Item) -> bool {
         match i.node {
-            ast::ItemFn(ref decl, _, _, ref generics, _) => {
+            ast::ItemFn(ref decl, _, _, _, ref generics, _) => {
                 let input_cnt = decl.inputs.len();
                 let no_output = match decl.output {
                     ast::DefaultReturn(..) => true,
@@ -469,7 +469,9 @@ fn mk_main(cx: &mut TestCtxt) -> P<ast::Item> {
     let main_ret_ty = ecx.ty(sp, ast::TyTup(vec![]));
     let main_body = ecx.block_all(sp, vec![call_test_main], None);
     let main = ast::ItemFn(ecx.fn_decl(vec![], main_ret_ty),
-                           ast::Unsafety::Normal, ::abi::Rust, empty_generics(), main_body);
+                           ast::Unsafety::Normal,
+                           ast::Constness::NotConst,
+                           ::abi::Rust, empty_generics(), main_body);
     let main = P(ast::Item {
         ident: token::str_to_ident("main"),
         attrs: vec![main_attr],
index 6cf791b10be67612eaa75ad146d630fafb1a5602..b9b81bd7c6f8e0cf0057044f698c12f8b9eb98bf 100644 (file)
@@ -35,7 +35,7 @@
 #[derive(Copy, Clone)]
 pub enum FnKind<'a> {
     /// fn foo() or extern "Abi" fn foo()
-    FkItemFn(Ident, &'a Generics, Unsafety, Abi, Visibility),
+    FkItemFn(Ident, &'a Generics, Unsafety, Constness, Abi, Visibility),
 
     /// fn foo(&self)
     FkMethod(Ident, &'a MethodSig, Option<Visibility>),
@@ -246,8 +246,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
             visitor.visit_ty(&**typ);
             visitor.visit_expr(&**expr);
         }
-        ItemFn(ref declaration, fn_style, abi, ref generics, ref body) => {
-            visitor.visit_fn(FkItemFn(item.ident, generics, fn_style, abi, item.vis),
+        ItemFn(ref declaration, unsafety, constness, abi, ref generics, ref body) => {
+            visitor.visit_fn(FkItemFn(item.ident, generics, unsafety,
+                                      constness, abi, item.vis),
                              &**declaration,
                              &**body,
                              item.span,