Skip to content

Commit a65366d

Browse files
committed
Parse explicit self in more places. Work on #2585.
1 parent 0845579 commit a65366d

File tree

1 file changed

+68
-54
lines changed

1 file changed

+68
-54
lines changed

src/libsyntax/parse/parser.rs

Lines changed: 68 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -291,17 +291,8 @@ struct parser {
291291
let inputs = do self.parse_unspanned_seq(
292292
token::LPAREN, token::RPAREN,
293293
seq_sep_trailing_disallowed(token::COMMA)) |p| {
294-
let mode = p.parse_arg_mode();
295-
let name = if is_plain_ident(p.token)
296-
&& p.look_ahead(1u) == token::COLON {
297294

298-
let name = self.parse_value_ident();
299-
p.bump();
300-
name
301-
} else { @~"" };
302-
303-
{mode: mode, ty: p.parse_ty(false), ident: name,
304-
id: p.get_id()}
295+
p.parse_arg_general(false)
305296
};
306297
let (ret_style, ret_ty) = self.parse_ret_ty();
307298
return {inputs: inputs, output: ret_ty,
@@ -321,11 +312,18 @@ struct parser {
321312
// could change.
322313
let vis = p.parse_visibility();
323314
let ident = p.parse_method_name();
315+
324316
let tps = p.parse_ty_params();
325-
let d = p.parse_ty_fn_decl(pur);
317+
318+
let (self_ty, d, _) = do self.parse_fn_decl_with_self(pur) |p| {
319+
// This is somewhat dubious; We don't want to allow argument
320+
// names to be left off if there is a definition...
321+
either::Left(p.parse_arg_general(false))
322+
};
323+
// XXX: Wrong. Shouldn't allow both static and self_ty
324+
let self_ty = if is_static { static_sty } else { self_ty };
325+
326326
let hi = p.last_span.hi;
327-
let self_ty = if is_static { static_sty } else
328-
{ spanned(lo, hi, sty_by_ref) }; // XXX: Wrong.
329327
debug!{"parse_trait_methods(): trait method signature ends in \
330328
`%s`",
331329
token_to_str(p.reader, p.token)};
@@ -571,12 +569,30 @@ struct parser {
571569
}
572570
}
573571

574-
fn parse_arg() -> arg_or_capture_item {
572+
// This version of parse arg doesn't necessarily require
573+
// identifier names.
574+
fn parse_arg_general(require_name: bool) -> arg {
575575
let m = self.parse_arg_mode();
576-
let i = self.parse_value_ident();
577-
self.expect(token::COLON);
576+
let i = if require_name {
577+
let name = self.parse_value_ident();
578+
self.expect(token::COLON);
579+
name
580+
} else {
581+
if is_plain_ident(self.token)
582+
&& self.look_ahead(1u) == token::COLON {
583+
let name = self.parse_value_ident();
584+
self.bump();
585+
name
586+
} else { @~"" }
587+
};
588+
578589
let t = self.parse_ty(false);
579-
either::Left({mode: m, ty: t, ident: i, id: self.get_id()})
590+
591+
{mode: m, ty: t, ident: i, id: self.get_id()}
592+
}
593+
594+
fn parse_arg() -> arg_or_capture_item {
595+
either::Left(self.parse_arg_general(true))
580596
}
581597

582598
fn parse_arg_or_capture_item() -> arg_or_capture_item {
@@ -2308,48 +2324,46 @@ struct parser {
23082324
fn(parser) -> arg_or_capture_item)
23092325
-> (self_ty, fn_decl, capture_clause) {
23102326

2327+
fn maybe_parse_self_ty(cnstr: fn(+mutability) -> ast::self_ty_,
2328+
p: parser) -> ast::self_ty_ {
2329+
// We need to make sure it isn't a mode or a type
2330+
if p.token_is_keyword(~"self", p.look_ahead(1)) ||
2331+
((p.token_is_keyword(~"const", p.look_ahead(1)) ||
2332+
p.token_is_keyword(~"mut", p.look_ahead(1))) &&
2333+
p.token_is_keyword(~"self", p.look_ahead(2))) {
2334+
2335+
p.bump();
2336+
let mutability = p.parse_mutability();
2337+
p.expect_self_ident();
2338+
cnstr(mutability)
2339+
} else {
2340+
sty_by_ref
2341+
}
2342+
}
2343+
23112344
self.expect(token::LPAREN);
23122345

23132346
// A bit of complexity and lookahead is needed here in order to to be
23142347
// backwards compatible.
23152348
let lo = self.span.lo;
2316-
let self_ty;
2317-
match copy self.token {
2318-
token::BINOP(token::AND) => {
2319-
// We need to make sure it isn't a mode.
2320-
if self.token_is_keyword(~"self", self.look_ahead(1)) ||
2321-
((self.token_is_keyword(~"const", self.look_ahead(1)) ||
2322-
self.token_is_keyword(~"mut", self.look_ahead(1))) &&
2323-
self.token_is_keyword(~"self", self.look_ahead(2))) {
2324-
2325-
self.bump();
2326-
let mutability = self.parse_mutability();
2327-
self.expect_self_ident();
2328-
self_ty = sty_region(mutability);
2329-
} else {
2330-
self_ty = sty_by_ref;
2331-
}
2332-
}
2333-
token::AT => {
2334-
self.bump();
2335-
let mutability = self.parse_mutability();
2336-
self.expect_self_ident();
2337-
self_ty = sty_box(mutability);
2338-
}
2339-
token::TILDE => {
2340-
self.bump();
2341-
let mutability = self.parse_mutability();
2342-
self.expect_self_ident();
2343-
self_ty = sty_uniq(mutability);
2344-
}
2345-
token::IDENT(*) if self.is_self_ident() => {
2346-
self.bump();
2347-
self_ty = sty_value;
2348-
}
2349-
_ => {
2350-
self_ty = sty_by_ref;
2351-
}
2352-
}
2349+
let self_ty = match copy self.token {
2350+
token::BINOP(token::AND) => {
2351+
maybe_parse_self_ty(sty_region, self)
2352+
}
2353+
token::AT => {
2354+
maybe_parse_self_ty(sty_box, self)
2355+
}
2356+
token::TILDE => {
2357+
maybe_parse_self_ty(sty_uniq, self)
2358+
}
2359+
token::IDENT(*) if self.is_self_ident() => {
2360+
self.bump();
2361+
sty_value
2362+
}
2363+
_ => {
2364+
sty_by_ref
2365+
}
2366+
};
23532367

23542368
// If we parsed a self type, expect a comma before the argument list.
23552369
let args_or_capture_items;

0 commit comments

Comments
 (0)