Skip to content

Commit 3932b32

Browse files
committed
---
yaml --- r: 120278 b: refs/heads/dist-snap c: ac1a270 h: refs/heads/master v: v3
1 parent 8ed0632 commit 3932b32

File tree

4 files changed

+72
-8
lines changed

4 files changed

+72
-8
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ refs/heads/try: 1813e5aa1a03b0596b8de7abd1af31edf5d6098f
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c
9-
refs/heads/dist-snap: 042c8ae40e0bb642263d8b891ef7a0d4e81fe819
9+
refs/heads/dist-snap: ac1a27043a7481676502e383716e20c017122bcb
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503
1212
refs/heads/try3: 9387340aab40a73e8424c48fd42f0c521a4875c0

branches/dist-snap/src/libsyntax/parse/parser.rs

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -587,16 +587,64 @@ impl<'a> Parser<'a> {
587587
self.replace_token(token::BINOP(token::OR), lo, self.span.hi)
588588
}
589589
_ => {
590-
let token_str = self.this_token_to_str();
591-
let found_token =
590+
let found_token = self.this_token_to_str();
591+
let token_str =
592592
Parser::token_to_str(&token::BINOP(token::OR));
593593
self.fatal(format!("expected `{}`, found `{}`",
594-
found_token,
595-
token_str))
594+
token_str, found_token))
596595
}
597596
}
598597
}
599598

599+
// Attempt to consume a `<`. If `<<` is seen, replace it with a single
600+
// `<` and continue. If a `<` is not seen, return false.
601+
//
602+
// This is meant to be used when parsing generics on a path to get the
603+
// starting token. The `force` parameter is used to forcefully break up a
604+
// `<<` token. If `force` is false, then `<<` is only broken when a lifetime
605+
// shows up next. For example, consider the expression:
606+
//
607+
// foo as bar << test
608+
//
609+
// The parser needs to know if `bar <<` is the start of a generic path or if
610+
// it's a left-shift token. If `test` were a lifetime, then it's impossible
611+
// for the token to be a left-shift, but if it's not a lifetime, then it's
612+
// considered a left-shift.
613+
//
614+
// The reason for this is that the only current ambiguity with `<<` is when
615+
// parsing closure types:
616+
//
617+
// foo::<<'a> ||>();
618+
// impl Foo<<'a> ||>() { ... }
619+
fn eat_lt(&mut self, force: bool) -> bool {
620+
match self.token {
621+
token::LT => { self.bump(); true }
622+
token::BINOP(token::SHL) => {
623+
let next_lifetime = self.look_ahead(1, |t| match *t {
624+
token::LIFETIME(..) => true,
625+
_ => false,
626+
});
627+
if force || next_lifetime {
628+
let lo = self.span.lo + BytePos(1);
629+
self.replace_token(token::LT, lo, self.span.hi);
630+
true
631+
} else {
632+
false
633+
}
634+
}
635+
_ => false,
636+
}
637+
}
638+
639+
fn expect_lt(&mut self) {
640+
if !self.eat_lt(true) {
641+
let found_token = self.this_token_to_str();
642+
let token_str = Parser::token_to_str(&token::LT);
643+
self.fatal(format!("expected `{}`, found `{}`",
644+
token_str, found_token))
645+
}
646+
}
647+
600648
// Parse a sequence bracketed by `|` and `|`, stopping before the `|`.
601649
fn parse_seq_to_before_or<T>(
602650
&mut self,
@@ -1500,7 +1548,7 @@ impl<'a> Parser<'a> {
15001548

15011549
// Parse the `<` before the lifetime and types, if applicable.
15021550
let (any_lifetime_or_types, lifetimes, types) = {
1503-
if mode != NoTypesAllowed && self.eat(&token::LT) {
1551+
if mode != NoTypesAllowed && self.eat_lt(false) {
15041552
let (lifetimes, types) =
15051553
self.parse_generic_values_after_lt();
15061554
(true, lifetimes, OwnedSlice::from_vec(types))
@@ -1948,7 +1996,7 @@ impl<'a> Parser<'a> {
19481996
hi = self.span.hi;
19491997
self.bump();
19501998
let (_, tys) = if self.eat(&token::MOD_SEP) {
1951-
self.expect(&token::LT);
1999+
self.expect_lt();
19522000
self.parse_generic_values_after_lt()
19532001
} else {
19542002
(Vec::new(), Vec::new())

branches/dist-snap/src/test/run-pass/borrowck-pat-enum.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// ignore-pretty
12+
1113
fn match_ref(v: Option<int>) -> int {
1214
match v {
1315
Some(ref i) => {

branches/dist-snap/src/test/run-pass/closure-syntax.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ fn g<'a>(a: &'a int, f: proc<'b>(&'b int) -> &'b int) -> &'a int {
4343
f(a)
4444
}
4545

46+
struct A;
47+
48+
impl A {
49+
fn foo<T>(&self) {}
50+
}
51+
4652
fn bar<'b>() {
4753
foo::<||>();
4854
foo::<|| -> ()>();
@@ -58,17 +64,25 @@ fn bar<'b>() {
5864
foo::<proc():Share>();
5965
foo::<proc<'a>(int, f32, &'a int):'static + Share -> &'a int>();
6066

67+
foo::<<'a>||>();
68+
6169
// issue #11209
6270
let _: ||: 'b; // for comparison
6371
let _: <'a> ||;
6472

6573
let _: Option<||:'b>;
66-
// let _: Option<<'a>||>;
74+
let _: Option<<'a>||>;
6775
let _: Option< <'a>||>;
6876

6977
// issue #11210
7078
let _: ||: 'static;
79+
80+
let a = A;
81+
a.foo::<<'a>||>();
7182
}
7283

84+
struct B<T>;
85+
impl<'b> B<<'a>||: 'b> {}
86+
7387
pub fn main() {
7488
}

0 commit comments

Comments
 (0)