about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-07-11 15:00:40 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-07-17 15:46:43 -0700
commitdb020ab63cd51dd4a25cba2d00117f016128762b (patch)
tree2b6f1e99ba4356f3e3bf5338332c278d2a85109b /src/libsyntax
parentb5729bd60095fb5ca884936775e031cf19900760 (diff)
downloadrust-db020ab63cd51dd4a25cba2d00117f016128762b.tar.gz
rust-db020ab63cd51dd4a25cba2d00117f016128762b.zip
rustc: Implement and enforce instance coherence
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast_util.rs8
-rw-r--r--src/libsyntax/ext/auto_serialize.rs29
-rw-r--r--src/libsyntax/ext/pipes/ast_builder.rs52
-rw-r--r--src/libsyntax/ext/pipes/parse_proto.rs7
-rw-r--r--src/libsyntax/ext/pipes/pipec.rs39
-rw-r--r--src/libsyntax/ext/tt/earley_parser.rs1
-rw-r--r--src/libsyntax/parse/attr.rs16
-rw-r--r--src/libsyntax/parse/common.rs39
-rw-r--r--src/libsyntax/parse/parser.rs17
-rw-r--r--src/libsyntax/parse/token.rs7
-rw-r--r--src/libsyntax/print/pp.rs38
11 files changed, 213 insertions, 40 deletions
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 7a0a0725d95..37e8671facd 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -306,7 +306,13 @@ pure fn class_member_visibility(ci: @class_member) -> visibility {
   }
 }
 
-impl inlined_item_methods for inlined_item {
+trait inlined_item_utils {
+    fn ident() -> ident;
+    fn id() -> ast::node_id;
+    fn accept<E>(e: E, v: visit::vt<E>);
+}
+
+impl inlined_item_methods of inlined_item_utils for inlined_item {
     fn ident() -> ident {
         alt self {
           ii_item(i) { /* FIXME (#2543) */ copy i.ident }
diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs
index a7a6080fb0b..c52617c74bf 100644
--- a/src/libsyntax/ext/auto_serialize.rs
+++ b/src/libsyntax/ext/auto_serialize.rs
@@ -123,7 +123,34 @@ fn expand(cx: ext_ctxt,
     }
 }
 
-impl helpers for ext_ctxt {
+trait ext_ctxt_helpers {
+    fn helper_path(base_path: @ast::path, helper_name: ~str) -> @ast::path;
+    fn path(span: span, strs: ~[ast::ident]) -> @ast::path;
+    fn path_tps(span: span, strs: ~[ast::ident],
+                tps: ~[@ast::ty]) -> @ast::path;
+    fn ty_path(span: span, strs: ~[ast::ident], tps: ~[@ast::ty]) -> @ast::ty;
+    fn ty_fn(span: span,
+             -input_tys: ~[@ast::ty],
+             -output: @ast::ty) -> @ast::ty;
+    fn ty_nil(span: span) -> @ast::ty;
+    fn expr(span: span, node: ast::expr_) -> @ast::expr;
+    fn var_ref(span: span, name: ast::ident) -> @ast::expr;
+    fn blk(span: span, stmts: ~[@ast::stmt]) -> ast::blk;
+    fn expr_blk(expr: @ast::expr) -> ast::blk;
+    fn binder_pat(span: span, nm: ast::ident) -> @ast::pat;
+    fn stmt(expr: @ast::expr) -> @ast::stmt;
+    fn alt_stmt(arms: ~[ast::arm], span: span, -v: @ast::expr) -> @ast::stmt;
+    fn lit_str(span: span, s: @~str) -> @ast::expr;
+    fn lit_uint(span: span, i: uint) -> @ast::expr;
+    fn lambda(blk: ast::blk) -> @ast::expr;
+    fn clone_folder() -> fold::ast_fold;
+    fn clone(v: @ast::expr) -> @ast::expr;
+    fn clone_ty(v: @ast::ty) -> @ast::ty;
+    fn clone_ty_param(v: ast::ty_param) -> ast::ty_param;
+    fn at(span: span, expr: @ast::expr) -> @ast::expr;
+}
+
+impl helpers of ext_ctxt_helpers for ext_ctxt {
     fn helper_path(base_path: @ast::path,
                    helper_name: ~str) -> @ast::path {
         let head = vec::init(base_path.idents);
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index 3ea088b50e2..58f42152437 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -28,18 +28,29 @@ fn path(id: ident) -> @ast::path {
       types: ~[]}
 }
 
-impl methods for ident {
+trait path_concat {
+    fn +(id: ident) -> @ast::path;
+}
+
+impl methods of path_concat for ident {
     fn +(id: ident) -> @ast::path {
         path(self) + id
     }
 }
 
-impl methods for @ast::path {
+impl methods of path_concat for @ast::path {
     fn +(id: ident) -> @ast::path {
         @{idents: vec::append_one(self.idents, id)
           with *self}
     }
+}
+
+trait append_types {
+    fn add_ty(ty: @ast::ty) -> @ast::path;
+    fn add_tys(+tys: ~[@ast::ty]) -> @ast::path;
+}
 
+impl methods of append_types for @ast::path {
     fn add_ty(ty: @ast::ty) -> @ast::path {
         @{types: vec::append_one(self.types, ty)
           with *self}
@@ -51,7 +62,38 @@ impl methods for @ast::path {
     }
 }
 
-impl ast_builder for ext_ctxt {
+trait ext_ctxt_ast_builder {
+    fn ty_param(id: ast::ident, +bounds: ~[ast::ty_param_bound])
+        -> ast::ty_param;
+    fn arg(name: ident, ty: @ast::ty) -> ast::arg;
+    fn arg_mode(name: ident, ty: @ast::ty, mode: ast::rmode) -> ast::arg;
+    fn expr_block(e: @ast::expr) -> ast::blk;
+    fn fn_decl(+inputs: ~[ast::arg], output: @ast::ty) -> ast::fn_decl;
+    fn item(name: ident, +node: ast::item_) -> @ast::item;
+    fn item_fn_poly(name: ident,
+                    +inputs: ~[ast::arg],
+                    output: @ast::ty,
+                    +ty_params: ~[ast::ty_param],
+                    +body: ast::blk) -> @ast::item;
+    fn item_fn(name: ident,
+               +inputs: ~[ast::arg],
+               output: @ast::ty,
+               +body: ast::blk) -> @ast::item;
+    fn item_enum_poly(name: ident,
+                      +variants: ~[ast::variant],
+                      +ty_params: ~[ast::ty_param]) -> @ast::item;
+    fn item_enum(name: ident, +variants: ~[ast::variant]) -> @ast::item;
+    fn variant(name: ident, +tys: ~[@ast::ty]) -> ast::variant;
+    fn item_mod(name: ident, +items: ~[@ast::item]) -> @ast::item;
+    fn ty_path_ast_builder(path: @ast::path) -> @ast::ty;
+    fn item_ty_poly(name: ident,
+                    ty: @ast::ty,
+                    +params: ~[ast::ty_param]) -> @ast::item;
+    fn item_ty(name: ident, ty: @ast::ty) -> @ast::item;
+    fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::ty];
+}
+
+impl ast_builder of ext_ctxt_ast_builder for ext_ctxt {
     fn ty_param(id: ast::ident, +bounds: ~[ast::ty_param_bound])
         -> ast::ty_param
     {
@@ -153,7 +195,7 @@ impl ast_builder for ext_ctxt {
                       items: items}))
     }
 
-    fn ty_path(path: @ast::path) -> @ast::ty {
+    fn ty_path_ast_builder(path: @ast::path) -> @ast::ty {
         // FIXME #2886: make sure the node ids are legal.
         @{id: self.next_id(),
           node: ast::ty_path(path, self.next_id()),
@@ -177,6 +219,6 @@ impl ast_builder for ext_ctxt {
     }
 
     fn ty_vars(+ty_params: ~[ast::ty_param]) -> ~[@ast::ty] {
-        ty_params.map(|p| self.ty_path(path(p.ident)))
+        ty_params.map(|p| self.ty_path_ast_builder(path(p.ident)))
     }
 }
diff --git a/src/libsyntax/ext/pipes/parse_proto.rs b/src/libsyntax/ext/pipes/parse_proto.rs
index 39084def7e4..091eaf697bb 100644
--- a/src/libsyntax/ext/pipes/parse_proto.rs
+++ b/src/libsyntax/ext/pipes/parse_proto.rs
@@ -6,7 +6,12 @@ import parse::token;
 
 import pipec::*;
 
-impl proto_parser for parser {
+trait proto_parser {
+    fn parse_proto(id: ident) -> protocol;
+    fn parse_state(proto: protocol);
+}
+
+impl proto_parser of proto_parser for parser {
     fn parse_proto(id: ident) -> protocol {
         let proto = protocol(id);
 
diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs
index 4af75fa90e7..eab2c58e50e 100644
--- a/src/libsyntax/ext/pipes/pipec.rs
+++ b/src/libsyntax/ext/pipes/pipec.rs
@@ -15,9 +15,9 @@ import pprust::{item_to_str, ty_to_str};
 import ext::base::{mk_ctxt, ext_ctxt};
 import parse;
 import parse::*;
-
 import proto::*;
 
+import ast_builder::append_types;
 import ast_builder::ast_builder;
 import ast_builder::methods;
 import ast_builder::path;
@@ -38,7 +38,7 @@ impl compile for message {
 
             let args_ast = vec::append(
                 ~[cx.arg_mode(@~"pipe",
-                              cx.ty_path(path(this.data_name())
+                              cx.ty_path_ast_builder(path(this.data_name())
                                         .add_tys(cx.ty_vars(this.ty_params))),
                               ast::by_copy)],
                 args_ast);
@@ -64,7 +64,7 @@ impl compile for message {
 
             cx.item_fn_poly(self.name(),
                             args_ast,
-                            cx.ty_path(path(next.data_name())
+                            cx.ty_path_ast_builder(path(next.data_name())
                                       .add_tys(next_tys)),
                             self.get_params(),
                             cx.expr_block(body))
@@ -110,6 +110,11 @@ impl compile for message {
           }
         }
     }
+
+    fn to_ty(cx: ext_ctxt) -> @ast::ty {
+        cx.ty_path_ast_builder(path(self.name)
+          .add_tys(cx.ty_vars(self.ty_params)))
+    }
 }
 
 impl compile for state {
@@ -169,9 +174,9 @@ impl compile for state {
         vec::push(items,
                   cx.item_ty_poly(
                       self.data_name(),
-                      cx.ty_path(
+                      cx.ty_path_ast_builder(
                           (@~"pipes" + @(dir.to_str() + ~"_packet"))
-                          .add_ty(cx.ty_path(
+                          .add_ty(cx.ty_path_ast_builder(
                               (self.proto.name + self.data_name())
                               .add_tys(cx.ty_vars(self.ty_params))))),
                       self.ty_params));
@@ -266,7 +271,12 @@ impl of to_source for @ast::expr {
     }
 }
 
-impl parse_utils for ext_ctxt {
+trait ext_ctxt_parse_utils {
+    fn parse_item(s: ~str) -> @ast::item;
+    fn parse_expr(s: ~str) -> @ast::expr;
+}
+
+impl parse_utils of ext_ctxt_parse_utils for ext_ctxt {
     fn parse_item(s: ~str) -> @ast::item {
         let res = parse::parse_item_from_source_str(
             ~"***protocol expansion***",
@@ -292,3 +302,20 @@ impl parse_utils for ext_ctxt {
             self.parse_sess())
     }
 }
+
+trait two_vector_utils<A, B> {
+    fn zip() -> ~[(A, B)];
+    fn map<C>(f: fn(A, B) -> C) -> ~[C];
+}
+
+impl methods<A: copy, B: copy> of two_vector_utils<A, B> for (~[A], ~[B]) {
+    fn zip() -> ~[(A, B)] {
+        let (a, b) = self;
+        vec::zip(a, b)
+    }
+
+    fn map<C>(f: fn(A, B) -> C) -> ~[C] {
+        let (a, b) = self;
+        vec::map2(a, b, f)
+    }
+}
diff --git a/src/libsyntax/ext/tt/earley_parser.rs b/src/libsyntax/ext/tt/earley_parser.rs
index 3f604aafb3d..152b92a4b53 100644
--- a/src/libsyntax/ext/tt/earley_parser.rs
+++ b/src/libsyntax/ext/tt/earley_parser.rs
@@ -60,6 +60,7 @@ fn count_names(ms: &[matcher]) -> uint {
         }})
 }
 
+#[warn(no_non_implicitly_copyable_typarams)]
 fn new_matcher_pos(ms: ~[matcher], sep: option<token>, lo: uint)
     -> matcher_pos {
     ~{elts: ms, sep: sep, mut idx: 0u, mut up: matcher_pos_up(none),
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index 995feff0b70..fb28f952629 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -9,7 +9,21 @@ export parser_attr;
 // extensions, which both begin with token.POUND
 type attr_or_ext = option<either<~[ast::attribute], @ast::expr>>;
 
-impl parser_attr for parser {
+trait parser_attr {
+    fn parse_outer_attrs_or_ext(first_item_attrs: ~[ast::attribute])
+        -> attr_or_ext;
+    fn parse_outer_attributes() -> ~[ast::attribute];
+    fn parse_attribute(style: ast::attr_style) -> ast::attribute;
+    fn parse_attribute_naked(style: ast::attr_style, lo: uint) ->
+        ast::attribute;
+    fn parse_inner_attrs_and_next() ->
+        {inner: ~[ast::attribute], next: ~[ast::attribute]};
+    fn parse_meta_item() -> @ast::meta_item;
+    fn parse_meta_seq() -> ~[@ast::meta_item];
+    fn parse_optional_meta() -> ~[@ast::meta_item];
+}
+
+impl parser_attr of parser_attr for parser {
 
     fn parse_outer_attrs_or_ext(first_item_attrs: ~[ast::attribute])
         -> attr_or_ext
diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs
index 79ac3aeaf8b..9126bbb3be4 100644
--- a/src/libsyntax/parse/common.rs
+++ b/src/libsyntax/parse/common.rs
@@ -22,9 +22,44 @@ fn token_to_str(reader: reader, ++token: token::token) -> ~str {
     token::to_str(*reader.interner(), token)
 }
 
-// This should be done with traits, once traits work
-impl parser_common for parser {
+trait parser_common {
+    fn unexpected_last(t: token::token) -> !;
+    fn unexpected() -> !;
+    fn expect(t: token::token);
+    fn parse_ident() -> ast::ident;
+    fn parse_path_list_ident() -> ast::path_list_ident;
+    fn parse_value_ident() -> ast::ident;
+    fn eat(tok: token::token) -> bool;
+    // A sanity check that the word we are asking for is a known keyword
+    fn require_keyword(word: ~str);
+    fn token_is_keyword(word: ~str, ++tok: token::token) -> bool;
+    fn is_keyword(word: ~str) -> bool;
+    fn is_any_keyword(tok: token::token) -> bool;
+    fn eat_keyword(word: ~str) -> bool;
+    fn expect_keyword(word: ~str);
+    fn is_restricted_keyword(word: ~str) -> bool;
+    fn check_restricted_keywords();
+    fn check_restricted_keywords_(w: ~str);
+    fn expect_gt();
+    fn parse_seq_to_before_gt<T: copy>(sep: option<token::token>,
+                                       f: fn(parser) -> T) -> ~[T];
+    fn parse_seq_to_gt<T: copy>(sep: option<token::token>,
+                                f: fn(parser) -> T) -> ~[T];
+    fn parse_seq_lt_gt<T: copy>(sep: option<token::token>,
+                                f: fn(parser) -> T) -> spanned<~[T]>;
+    fn parse_seq_to_end<T: copy>(ket: token::token, sep: seq_sep,
+                                 f: fn(parser) -> T) -> ~[T];
+    fn parse_seq_to_before_end<T: copy>(ket: token::token, sep: seq_sep,
+                                        f: fn(parser) -> T) -> ~[T];
+    fn parse_unspanned_seq<T: copy>(bra: token::token,
+                                    ket: token::token,
+                                    sep: seq_sep,
+                                    f: fn(parser) -> T) -> ~[T];
+    fn parse_seq<T: copy>(bra: token::token, ket: token::token, sep: seq_sep,
+                          f: fn(parser) -> T) -> spanned<~[T]>;
+}
 
+impl parser_common of parser_common for parser {
     fn unexpected_last(t: token::token) -> ! {
         self.span_fatal(
             copy self.last_span,
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 74210f74d4d..c7687bf2b98 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2188,14 +2188,23 @@ class parser {
         }
     }
 
+    fn token_is_pound_or_doc_comment(++tok: token::token) -> bool {
+        alt tok {
+            token::POUND | token::DOC_COMMENT(_) { true }
+            _ { false }
+        }
+    }
+
     fn parse_single_class_item(vis: visibility)
         -> @class_member {
-        if self.eat_keyword(~"let") {
+        if (self.eat_keyword(~"let") ||
+                self.token_is_keyword(~"mut", copy self.token) ||
+                !self.is_any_keyword(copy self.token)) &&
+                !self.token_is_pound_or_doc_comment(self.token) {
             let a_var = self.parse_instance_var(vis);
             self.expect(token::SEMI);
             ret a_var;
-        }
-        else {
+        } else {
             let m = self.parse_method(vis);
             ret @{node: class_method(m), span: m.span};
         }
@@ -2510,7 +2519,7 @@ class parser {
             self.parse_item_trait()
         } else if self.eat_keyword(~"impl") {
             self.parse_item_impl()
-        } else if self.eat_keyword(~"class") {
+        } else if self.eat_keyword(~"class") || self.eat_keyword(~"struct") {
             self.parse_item_class()
         } else if !self.is_any_keyword(copy self.token)
             && self.look_ahead(1) == token::NOT
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 949b078d8f0..a39b74eaca3 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -313,8 +313,11 @@ fn restricted_keyword_table() -> hashmap<~str, ()> {
         ~"if", ~"iface", ~"impl", ~"import",
         ~"let", ~"log", ~"loop",
         ~"mod", ~"mut",
-        ~"new", ~"owned",
-        ~"pure", ~"ret",
+        ~"new",
+        ~"owned",
+        ~"pure",
+        ~"ret",
+        ~"struct",
         ~"true", ~"trait", ~"type",
         ~"unchecked", ~"unsafe",
         ~"while"
diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs
index 1a318d53635..79679279f07 100644
--- a/src/libsyntax/print/pp.rs
+++ b/src/libsyntax/print/pp.rs
@@ -103,22 +103,22 @@ fn mk_printer(out: io::writer, linewidth: uint) -> printer {
     let token: ~[mut token] = vec::to_mut(vec::from_elem(n, EOF));
     let size: ~[mut int] = vec::to_mut(vec::from_elem(n, 0));
     let scan_stack: ~[mut uint] = vec::to_mut(vec::from_elem(n, 0u));
-    @{out: out,
-      buf_len: n,
-      mut margin: linewidth as int,
-      mut space: linewidth as int,
-      mut left: 0u,
-      mut right: 0u,
-      token: token,
-      size: size,
-      mut left_total: 0,
-      mut right_total: 0,
-      mut scan_stack: scan_stack,
-      mut scan_stack_empty: true,
-      mut top: 0u,
-      mut bottom: 0u,
-      print_stack: dvec(),
-      mut pending_indentation: 0}
+    printer_(@{out: out,
+               buf_len: n,
+               mut margin: linewidth as int,
+               mut space: linewidth as int,
+               mut left: 0u,
+               mut right: 0u,
+               token: token,
+               size: size,
+               mut left_total: 0,
+               mut right_total: 0,
+               mut scan_stack: scan_stack,
+               mut scan_stack_empty: true,
+               mut top: 0u,
+               mut bottom: 0u,
+               print_stack: dvec(),
+               mut pending_indentation: 0})
 }
 
 
@@ -199,7 +199,7 @@ fn mk_printer(out: io::writer, linewidth: uint) -> printer {
  * the method called 'pretty_print', and the 'PRINT' process is the method
  * called 'print'.
  */
-type printer = @{
+type printer_ = {
     out: io::writer,
     buf_len: uint,
     mut margin: int, // width of lines we're constrained to
@@ -226,6 +226,10 @@ type printer = @{
     mut pending_indentation: int
 };
 
+enum printer {
+    printer_(@printer_)
+}
+
 impl printer for printer {
     fn last_token() -> token { self.token[self.right] }
     // be very careful with this!