@@ -45,13 +45,14 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
45
45
pat_range, pat_rec, pat_tup, pat_uniq, pat_wild, path, private,
46
46
proto, proto_any, proto_bare, proto_block, proto_box, proto_uniq,
47
47
provided, public, pure_fn, purity, re_anon, re_named, region,
48
- rem, required, ret_style, return_val, shl, shr, stmt, stmt_decl,
49
- stmt_expr, stmt_semi, subtract, token_tree, trait_method,
50
- trait_ref, tt_delim, tt_seq, tt_tok, tt_nonterminal, ty,
51
- ty_, ty_bot, ty_box, ty_field, ty_fn, ty_infer, ty_mac,
52
- ty_method, ty_nil, ty_param, ty_path, ty_ptr, ty_rec, ty_rptr,
53
- ty_tup, ty_u32, ty_uniq, ty_vec, ty_fixed_length, unchecked_blk,
54
- uniq, unsafe_blk, unsafe_fn, variant, view_item, view_item_,
48
+ rem, required, ret_style, return_val, self_ty, shl, shr, stmt,
49
+ stmt_decl, stmt_expr, stmt_semi, subtract, sty_box, sty_by_ref,
50
+ sty_region, sty_uniq, sty_value, token_tree, trait_method,
51
+ trait_ref, tt_delim, tt_seq, tt_tok, tt_nonterminal, ty, ty_,
52
+ ty_bot, ty_box, ty_field, ty_fn, ty_infer, ty_mac, ty_method,
53
+ ty_nil, ty_param, ty_path, ty_ptr, ty_rec, ty_rptr, ty_tup,
54
+ ty_u32, ty_uniq, ty_vec, ty_fixed_length, unchecked_blk, uniq,
55
+ unsafe_blk, unsafe_fn, variant, view_item, view_item_,
55
56
view_item_export, view_item_import, view_item_use, view_path,
56
57
view_path_glob, view_path_list, view_path_simple, visibility,
57
58
vstore, vstore_box, vstore_fixed, vstore_slice, vstore_uniq} ;
@@ -273,7 +274,8 @@ class parser {
273
274
let tps = p. parse_ty_params ( ) ;
274
275
let d = p. parse_ty_fn_decl ( pur) ;
275
276
let hi = p. last_span . hi ;
276
- debug ! { "parse_trait_methods(): trait method signature ends in \
277
+ let self_ty = spanned ( lo, hi, sty_by_ref) ; // XXX: Wrong.
278
+ debug ! [ "parse_trait_methods(): trait method signature ends in \
277
279
`%s`",
278
280
token_to_str( p. reader, p. token) } ;
279
281
alt p. token {
@@ -294,6 +296,7 @@ class parser {
294
296
provided( @{ ident: ident,
295
297
attrs: attrs,
296
298
tps: tps,
299
+ self_ty: self_ty,
297
300
decl: d,
298
301
body: body,
299
302
id: p. get_id( ) ,
@@ -1978,6 +1981,142 @@ class parser {
1978
1981
cf: ret_style} , capture_clause) ;
1979
1982
}
1980
1983
1984
+ fn is_self_ident ( ) -> bool {
1985
+ alt self . token {
1986
+ token:: IDENT ( sid, false ) if str:: eq ( ~"self ", * self . get_str ( sid) ) {
1987
+ true
1988
+ }
1989
+ _ => {
1990
+ false
1991
+ }
1992
+ }
1993
+ }
1994
+
1995
+ fn expect_self_ident ( ) {
1996
+ if !self . is_self_ident ( ) {
1997
+ self . fatal ( #fmt ( "expected `self` but found `%s`" ,
1998
+ token_to_str ( self . reader , self . token ) ) ) ;
1999
+ }
2000
+ self . bump ( ) ;
2001
+ }
2002
+
2003
+ fn parse_fn_decl_with_self ( purity : purity ,
2004
+ parse_arg_fn :
2005
+ fn ( parser ) -> arg_or_capture_item )
2006
+ -> ( self_ty , fn_decl , capture_clause ) {
2007
+
2008
+ self . expect ( token:: LPAREN ) ;
2009
+
2010
+ // A bit of complexity and lookahead is needed here in order to to be
2011
+ // backwards compatible.
2012
+ let lo = self . span . lo ;
2013
+ let self_ty;
2014
+ alt copy self . token {
2015
+ token:: BINOP ( token:: AND ) => {
2016
+ // We need to make sure it isn't a mode.
2017
+ self . bump ( ) ;
2018
+ if self . token_is_keyword ( ~"self ", self . look_ahead ( 1 ) ) ||
2019
+ ( ( self . token_is_keyword ( ~"const ", self . look_ahead ( 1 ) ) ||
2020
+ self . token_is_keyword ( ~"mut ", self . look_ahead ( 1 ) ) ) &&
2021
+ self . token_is_keyword ( ~"self ", self . look_ahead ( 2 ) ) ) {
2022
+
2023
+ self . bump ( ) ;
2024
+ let mutability = self . parse_mutability ( ) ;
2025
+ self . expect_self_ident ( ) ;
2026
+
2027
+ // Parse an explicit region, if possible.
2028
+ let region_name;
2029
+ alt copy self . token {
2030
+ token:: BINOP ( token:: SLASH ) => {
2031
+ self . bump ( ) ;
2032
+ alt copy self . token {
2033
+ token:: IDENT ( sid, false ) => {
2034
+ self . bump ( ) ;
2035
+ region_name = some ( self . get_str ( sid) ) ;
2036
+ }
2037
+ _ => {
2038
+ region_name = none;
2039
+ }
2040
+ }
2041
+ }
2042
+ _ => {
2043
+ region_name = none;
2044
+ }
2045
+ }
2046
+
2047
+ let region = self . region_from_name ( region_name) ;
2048
+ self_ty = sty_region ( region, mutability) ;
2049
+ } else {
2050
+ self_ty = sty_by_ref;
2051
+ }
2052
+ }
2053
+ token:: AT => {
2054
+ self . bump ( ) ;
2055
+ let mutability = self . parse_mutability ( ) ;
2056
+ self . expect_self_ident ( ) ;
2057
+ self_ty = sty_box ( mutability) ;
2058
+ }
2059
+ token:: TILDE => {
2060
+ self . bump ( ) ;
2061
+ let mutability = self . parse_mutability ( ) ;
2062
+ self . expect_self_ident ( ) ;
2063
+ self_ty = sty_uniq ( mutability) ;
2064
+ }
2065
+ token:: IDENT ( * ) if self . is_self_ident ( ) => {
2066
+ self . bump ( ) ;
2067
+ self_ty = sty_value;
2068
+ }
2069
+ _ => {
2070
+ self_ty = sty_by_ref;
2071
+ }
2072
+ }
2073
+
2074
+ // If we parsed a self type, expect a comma before the argument list.
2075
+ let args_or_capture_items;
2076
+ if self_ty != sty_by_ref {
2077
+ alt copy self . token {
2078
+ token:: COMMA => {
2079
+ self . bump ( ) ;
2080
+ let sep = seq_sep_trailing_disallowed ( token:: COMMA ) ;
2081
+ args_or_capture_items =
2082
+ self . parse_seq_to_before_end ( token:: RPAREN ,
2083
+ sep,
2084
+ parse_arg_fn) ;
2085
+ }
2086
+ token:: RPAREN => {
2087
+ args_or_capture_items = ~[ ] ;
2088
+ }
2089
+ _ => {
2090
+ self . fatal ( ~"expected `, ` or `) `, found `" +
2091
+ token_to_str ( self . reader , self . token ) + "`" ) ;
2092
+ }
2093
+ }
2094
+ } else {
2095
+ let sep = seq_sep_trailing_disallowed ( token:: COMMA ) ;
2096
+ args_or_capture_items =
2097
+ self . parse_seq_to_before_end ( token:: RPAREN ,
2098
+ sep,
2099
+ parse_arg_fn) ;
2100
+ }
2101
+
2102
+ self . expect ( token:: RPAREN ) ;
2103
+
2104
+ let hi = self . span . hi ;
2105
+
2106
+ let inputs = either:: lefts ( args_or_capture_items) ;
2107
+ let capture_clause = @either:: rights ( args_or_capture_items) ;
2108
+ let ( ret_style, ret_ty) = self . parse_ret_ty ( ) ;
2109
+
2110
+ let fn_decl = {
2111
+ inputs: inputs,
2112
+ output: ret_ty,
2113
+ purity: purity,
2114
+ cf: ret_style
2115
+ } ;
2116
+
2117
+ ( spanned ( lo, hi, self_ty) , fn_decl, capture_clause)
2118
+ }
2119
+
1981
2120
fn parse_fn_block_decl( ) -> ( fn_decl, capture_clause) {
1982
2121
let inputs_captures = {
1983
2122
if self . eat ( token:: OROR ) {
@@ -2049,11 +2188,13 @@ class parser {
2049
2188
let lo = self.span.lo, pur = self.parse_fn_purity();
2050
2189
let ident = self.parse_method_name();
2051
2190
let tps = self.parse_ty_params();
2052
- let (decl, _) = self.parse_fn_decl(pur, |p| p.parse_arg());
2191
+ let (self_ty, decl, _) = do self.parse_fn_decl_with_self(pur) |p| {
2192
+ p.parse_arg()
2193
+ };
2053
2194
let (inner_attrs, body) = self.parse_inner_attrs_and_block(true);
2054
2195
let attrs = vec::append(attrs, inner_attrs);
2055
- @{ident: ident, attrs: attrs, tps: tps, decl: decl, body: body ,
2056
- id: self.get_id(), span: mk_sp(lo, body.span.hi),
2196
+ @{ident: ident, attrs: attrs, tps: tps, self_ty: self_ty, decl: decl ,
2197
+ body: body, id: self.get_id(), span: mk_sp(lo, body.span.hi),
2057
2198
self_id: self.get_id(), vis: pr}
2058
2199
}
2059
2200
0 commit comments