diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2012-07-11 15:00:40 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2012-07-17 15:46:43 -0700 |
| commit | db020ab63cd51dd4a25cba2d00117f016128762b (patch) | |
| tree | 2b6f1e99ba4356f3e3bf5338332c278d2a85109b /src/libsyntax | |
| parent | b5729bd60095fb5ca884936775e031cf19900760 (diff) | |
| download | rust-db020ab63cd51dd4a25cba2d00117f016128762b.tar.gz rust-db020ab63cd51dd4a25cba2d00117f016128762b.zip | |
rustc: Implement and enforce instance coherence
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast_util.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ext/auto_serialize.rs | 29 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/ast_builder.rs | 52 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/parse_proto.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/pipec.rs | 39 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/earley_parser.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/parse/attr.rs | 16 | ||||
| -rw-r--r-- | src/libsyntax/parse/common.rs | 39 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 17 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/print/pp.rs | 38 |
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! |
