about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs2
-rw-r--r--src/libsyntax/ast_util.rs2
-rw-r--r--src/libsyntax/parse/parser.rs54
-rw-r--r--src/libsyntax/print/pprust.rs50
4 files changed, 75 insertions, 33 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 78b1fa0a469..0cc433fdeba 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -71,6 +71,7 @@ type ty_param = {ident: ident, id: node_id, bounds: @~[ty_param_bound]};
 #[auto_serialize]
 enum def {
     def_fn(def_id, purity),
+    def_static_method(def_id, purity),
     def_self(node_id),
     def_mod(def_id),
     def_foreign_mod(def_id),
@@ -596,6 +597,7 @@ enum ret_style {
 
 #[auto_serialize]
 enum self_ty_ {
+    sty_static,                         // no self: static method
     sty_by_ref,                         // old by-reference self: ``
     sty_value,                          // by-value self: `self`
     sty_region(@region, mutability),    // by-region self: `&self`
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index caaf6cca5b1..7bbdac4db3c 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -53,7 +53,7 @@ fn variant_def_ids(d: def) -> {enm: def_id, var: def_id} {
 
 pure fn def_id_of_def(d: def) -> def_id {
     match d {
-      def_fn(id, _) | def_mod(id) |
+      def_fn(id, _) | def_static_method(id, _) | def_mod(id) |
       def_foreign_mod(id) | def_const(id) |
       def_variant(_, id) | def_ty(id) | def_ty_param(id, _) |
       def_use(id) | def_class(id, _) => {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 52a93a60361..780eff1f757 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -43,20 +43,24 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
              match_nonterminal, match_seq, match_tok, method, mode, mt, mul,
              mutability, neg, noreturn, not, pat, pat_box, pat_enum,
              pat_ident, pat_lit, pat_range, pat_rec, pat_struct, pat_tup,
-             pat_uniq, pat_wild, path, private, proto, proto_bare,
-             proto_block, proto_box, proto_uniq, provided, public, pure_fn,
-             purity, re_anon, re_named, region, rem, required, ret_style,
-             return_val, self_ty, shl, shr, stmt, stmt_decl, stmt_expr,
-             stmt_semi, subtract, sty_box, sty_by_ref, sty_region, sty_uniq,
-             sty_value, token_tree, trait_method, trait_ref, tt_delim, tt_seq,
-             tt_tok, tt_nonterminal, tuple_variant_kind, ty, ty_, ty_bot,
-             ty_box, ty_field, ty_fn, ty_infer, ty_mac, ty_method, ty_nil,
-             ty_param, ty_param_bound, ty_path, ty_ptr, ty_rec, ty_rptr,
-             ty_tup, ty_u32, ty_uniq, ty_vec, ty_fixed_length, unchecked_blk,
-             uniq, unsafe_blk, unsafe_fn, variant, view_item, view_item_,
-             view_item_export, view_item_import, view_item_use, view_path,
-             view_path_glob, view_path_list, view_path_simple, visibility,
-             vstore, vstore_box, vstore_fixed, vstore_slice, vstore_uniq};
+             pat_uniq,
+             pat_wild, path, private, proto, proto_bare, proto_block,
+             proto_box, proto_uniq, provided, public, pure_fn, purity,
+             re_anon, re_named, region, rem, required, ret_style, return_val,
+             self_ty, shl, shr, stmt, stmt_decl, stmt_expr, stmt_semi,
+             subtract, sty_box, sty_by_ref, sty_region, sty_static,
+             sty_uniq, sty_value,
+             token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok,
+             tt_nonterminal, ty, ty_, ty_bot, ty_box, ty_field, ty_fn,
+             ty_infer, ty_mac, ty_method, ty_nil, ty_param, ty_param_bound,
+             ty_path, ty_ptr,
+             ty_rec, ty_rptr, ty_tup, ty_u32, ty_uniq, ty_vec,
+             ty_fixed_length, tuple_variant_kind,
+             unchecked_blk, uniq, unsafe_blk, unsafe_fn,
+             variant, view_item, view_item_, view_item_export,
+             view_item_import, view_item_use, view_path, view_path_glob,
+             view_path_list, view_path_simple, visibility, vstore, vstore_box,
+             vstore_fixed, vstore_slice, vstore_uniq};
 
 export file_type;
 export parser;
@@ -279,6 +283,9 @@ class parser {
                                     seq_sep_none()) |p| {
             let attrs = p.parse_outer_attributes();
             let lo = p.span.lo;
+            let is_static = p.parse_staticness();
+            let static_sty = spanned(lo, p.span.hi, sty_static);
+
             let pur = p.parse_fn_purity();
             // NB: at the moment, trait methods are public by default; this
             // could change.
@@ -287,7 +294,8 @@ class parser {
             let tps = p.parse_ty_params();
             let d = p.parse_ty_fn_decl(pur);
             let hi = p.last_span.hi;
-            let self_ty = spanned(lo, hi, sty_by_ref);  // XXX: Wrong.
+            let self_ty = if is_static { static_sty } else
+                { spanned(lo, hi, sty_by_ref) }; // XXX: Wrong.
             debug!{"parse_trait_methods(): trait method signature ends in \
                     `%s`",
                    token_to_str(p.reader, p.token)};
@@ -2379,15 +2387,24 @@ class parser {
 
     fn parse_method(pr: visibility) -> @method {
         let attrs = self.parse_outer_attributes();
-        let lo = self.span.lo, pur = self.parse_fn_purity();
+        let lo = self.span.lo;
+
+        let is_static = self.parse_staticness();
+        let static_sty = spanned(lo, self.span.hi, sty_static);
+
+        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| {
             p.parse_arg()
         };
+        // XXX: interaction between staticness, self_ty is broken now
+        let self_ty = if is_static { static_sty} else { self_ty };
+
         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,
+        @{ident: ident, attrs: attrs,
+          tps: tps, self_ty: self_ty, decl: decl,
           body: body, id: self.get_id(), span: mk_sp(lo, body.span.hi),
           self_id: self.get_id(), vis: pr}
     }
@@ -2689,6 +2706,9 @@ class parser {
         else if self.eat_keyword(~"priv") { private }
         else { inherited }
     }
+    fn parse_staticness() -> bool {
+        self.eat_keyword(~"static")
+    }
 
     fn parse_mod_items(term: token::token,
                        +first_item_attrs: ~[attribute]) -> _mod {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index db62637a673..1965ea73186 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -144,7 +144,7 @@ fn fun_to_str(decl: ast::fn_decl, name: ast::ident,
               params: ~[ast::ty_param]) -> ~str {
     let buffer = io::mem_buffer();
     let s = rust_printer(io::mem_buffer_writer(buffer));
-    print_fn(s, decl, name, params);
+    print_fn(s, decl, name, params, none);
     end(s); // Close the head box
     end(s); // Close the outer box
     eof(s.s);
@@ -400,7 +400,7 @@ fn print_type_ex(s: ps, &&ty: @ast::ty, print_colons: bool) {
         pclose(s);
       }
       ast::ty_fn(proto, bounds, d) => {
-        print_ty_fn(s, some(proto), bounds, d, none, none);
+        print_ty_fn(s, some(proto), bounds, d, none, none, none);
       }
       ast::ty_path(path, _) => print_path(s, path, print_colons),
       ast::ty_fixed_length(t, v) => {
@@ -425,7 +425,7 @@ fn print_foreign_item(s: ps, item: @ast::foreign_item) {
     print_outer_attributes(s, item.attrs);
     match item.node {
       ast::foreign_item_fn(decl, typarams) => {
-        print_fn(s, decl, item.ident, typarams);
+        print_fn(s, decl, item.ident, typarams, none);
         end(s); // end head-ibox
         word(s.s, ~";");
         end(s); // end the outer fn box
@@ -454,7 +454,7 @@ fn print_item(s: ps, &&item: @ast::item) {
 
       }
       ast::item_fn(decl, typarams, body) => {
-        print_fn(s, decl, item.ident, typarams);
+        print_fn(s, decl, 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.decl, some(m.ident), some(m.tps),
+                some(m.self_ty.node));
     word(s.s, ~";");
 }
 
@@ -737,7 +738,7 @@ 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);
+    print_fn(s, meth.decl, meth.ident, meth.tps, some(meth.self_ty.node));
     word(s.s, ~" ");
     print_block_with_attrs(s, meth.body, meth.attrs);
 }
@@ -1150,8 +1151,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);
-        print_purity(s, decl.purity);
-        word(s.s, proto_to_str(proto));
+        word(s.s, fn_header_info_to_str(none, decl.purity, some(proto)));
         print_fn_args_and_ret(s, decl, *cap_clause);
         space(s.s);
         print_block(s, body);
@@ -1455,11 +1455,9 @@ fn print_pat(s: ps, &&pat: @ast::pat) {
 }
 
 fn print_fn(s: ps, decl: ast::fn_decl, name: ast::ident,
-            typarams: ~[ast::ty_param]) {
-    match decl.purity {
-      ast::impure_fn => head(s, ~"fn"),
-      _ => head(s, purity_to_str(decl.purity) + ~" fn")
-    }
+            typarams: ~[ast::ty_param],
+            opt_self_ty: option<ast::self_ty_>) {
+    head(s, fn_header_info_to_str(opt_self_ty, decl.purity, none));
     word(s.s, *name);
     print_type_params(s, typarams);
     print_fn_args_and_ret(s, decl, ~[]);
@@ -1667,9 +1665,10 @@ fn print_arg(s: ps, input: ast::arg) {
 fn print_ty_fn(s: ps, opt_proto: option<ast::proto>,
                bounds: @~[ast::ty_param_bound],
                decl: ast::fn_decl, id: option<ast::ident>,
-               tps: option<~[ast::ty_param]>) {
+               tps: option<~[ast::ty_param]>,
+               opt_self_ty: option<ast::self_ty_>) {
     ibox(s, indent_unit);
-    word(s.s, opt_proto_to_str(opt_proto));
+    word(s.s, fn_header_info_to_str(opt_self_ty, decl.purity, opt_proto));
     print_bounds(s, bounds);
     match id { some(id) => { word(s.s, ~" "); word(s.s, *id); } _ => () }
     match tps { some(tps) => print_type_params(s, tps), _ => () }
@@ -1869,6 +1868,27 @@ fn next_comment(s: ps) -> option<comments::cmnt> {
     }
 }
 
+fn fn_header_info_to_str(opt_sty: option<ast::self_ty_>,
+                         purity: ast::purity,
+                         opt_p: option<ast::proto>) -> ~str {
+    let mut s = match opt_sty {
+      some(ast::sty_static) => ~"static ",
+      _ => ~ ""
+    };
+
+    match purity {
+      ast::impure_fn => { }
+      _ => {
+        str::push_str(s, purity_to_str(purity));
+        str::push_char(s, ' ');
+      }
+    }
+
+    str::push_str(s, opt_proto_to_str(opt_p));
+
+    return s;
+}
+
 fn opt_proto_to_str(opt_p: option<ast::proto>) -> ~str {
     match opt_p {
       none => ~"fn",