Skip to content

Commit 3f8e686

Browse files
committed
auto merge of #13576 : lifthrasiir/rust/double-ref, r=alexcrichton
Uses the same strategy as `||` and `>>`. Closes #11227.
2 parents 0c23140 + 676cd61 commit 3f8e686

File tree

2 files changed

+95
-38
lines changed

2 files changed

+95
-38
lines changed

src/libsyntax/parse/parser.rs

+54-38
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -542,6 +542,26 @@ impl<'a> Parser<'a> {
542542
}
543543
}
544544

545+
// Expect and consume an `&`. If `&&` is seen, replace it with a single
546+
// `&` and continue. If an `&` is not seen, signal an error.
547+
fn expect_and(&mut self) {
548+
match self.token {
549+
token::BINOP(token::AND) => self.bump(),
550+
token::ANDAND => {
551+
let lo = self.span.lo + BytePos(1);
552+
self.replace_token(token::BINOP(token::AND), lo, self.span.hi)
553+
}
554+
_ => {
555+
let token_str = self.this_token_to_str();
556+
let found_token =
557+
Parser::token_to_str(&token::BINOP(token::AND));
558+
self.fatal(format!("expected `{}`, found `{}`",
559+
found_token,
560+
token_str))
561+
}
562+
}
563+
}
564+
545565
// Expect and consume a `|`. If `||` is seen, replace it with a single
546566
// `|` and continue. If a `|` is not seen, signal an error.
547567
fn expect_or(&mut self) {
@@ -1218,9 +1238,10 @@ impl<'a> Parser<'a> {
12181238
};
12191239
self.expect(&token::RBRACKET);
12201240
t
1221-
} else if self.token == token::BINOP(token::AND) {
1241+
} else if self.token == token::BINOP(token::AND) ||
1242+
self.token == token::ANDAND {
12221243
// BORROWED POINTER
1223-
self.bump();
1244+
self.expect_and();
12241245
self.parse_borrowed_pointee()
12251246
} else if self.is_keyword(keywords::Extern) ||
12261247
self.token_is_bare_fn_keyword() {
@@ -2169,42 +2190,37 @@ impl<'a> Parser<'a> {
21692190
hi = e.span.hi;
21702191
ex = self.mk_unary(UnNot, e);
21712192
}
2172-
token::BINOP(b) => {
2173-
match b {
2174-
token::MINUS => {
2175-
self.bump();
2176-
let e = self.parse_prefix_expr();
2177-
hi = e.span.hi;
2178-
ex = self.mk_unary(UnNeg, e);
2193+
token::BINOP(token::MINUS) => {
2194+
self.bump();
2195+
let e = self.parse_prefix_expr();
2196+
hi = e.span.hi;
2197+
ex = self.mk_unary(UnNeg, e);
2198+
}
2199+
token::BINOP(token::STAR) => {
2200+
self.bump();
2201+
let e = self.parse_prefix_expr();
2202+
hi = e.span.hi;
2203+
ex = self.mk_unary(UnDeref, e);
2204+
}
2205+
token::BINOP(token::AND) | token::ANDAND => {
2206+
self.expect_and();
2207+
let _lt = self.parse_opt_lifetime();
2208+
let m = self.parse_mutability();
2209+
let e = self.parse_prefix_expr();
2210+
hi = e.span.hi;
2211+
// HACK: turn &[...] into a &-vec
2212+
ex = match e.node {
2213+
ExprVec(..) if m == MutImmutable => {
2214+
ExprVstore(e, ExprVstoreSlice)
21792215
}
2180-
token::STAR => {
2181-
self.bump();
2182-
let e = self.parse_prefix_expr();
2183-
hi = e.span.hi;
2184-
ex = self.mk_unary(UnDeref, e);
2216+
ExprLit(lit) if lit_is_str(lit) && m == MutImmutable => {
2217+
ExprVstore(e, ExprVstoreSlice)
21852218
}
2186-
token::AND => {
2187-
self.bump();
2188-
let _lt = self.parse_opt_lifetime();
2189-
let m = self.parse_mutability();
2190-
let e = self.parse_prefix_expr();
2191-
hi = e.span.hi;
2192-
// HACK: turn &[...] into a &-vec
2193-
ex = match e.node {
2194-
ExprVec(..) if m == MutImmutable => {
2195-
ExprVstore(e, ExprVstoreSlice)
2196-
}
2197-
ExprLit(lit) if lit_is_str(lit) && m == MutImmutable => {
2198-
ExprVstore(e, ExprVstoreSlice)
2199-
}
2200-
ExprVec(..) if m == MutMutable => {
2201-
ExprVstore(e, ExprVstoreMutSlice)
2202-
}
2203-
_ => ExprAddrOf(m, e)
2204-
};
2219+
ExprVec(..) if m == MutMutable => {
2220+
ExprVstore(e, ExprVstoreMutSlice)
22052221
}
2206-
_ => return self.parse_dot_or_call_expr()
2207-
}
2222+
_ => ExprAddrOf(m, e)
2223+
};
22082224
}
22092225
token::AT => {
22102226
self.bump();
@@ -2749,10 +2765,10 @@ impl<'a> Parser<'a> {
27492765
span: mk_sp(lo, hi)
27502766
}
27512767
}
2752-
token::BINOP(token::AND) => {
2768+
token::BINOP(token::AND) | token::ANDAND => {
27532769
// parse &pat
27542770
let lo = self.span.lo;
2755-
self.bump();
2771+
self.expect_and();
27562772
let sub = self.parse_pat();
27572773
hi = sub.span.hi;
27582774
// HACK: parse &"..." as a literal of a borrowed str

src/test/run-pass/double-ref.rs

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn check_expr() {
12+
let _: & uint = &1u;
13+
let _: & & uint = &&1u;
14+
let _: & & & uint = &&&1u;
15+
let _: & & & uint = & &&1u;
16+
let _: & & & & uint = &&&&1u;
17+
let _: & & & & uint = & &&&1u;
18+
let _: & & & & & uint = &&&&&1u;
19+
}
20+
21+
fn check_ty() {
22+
let _: &uint = & 1u;
23+
let _: &&uint = & & 1u;
24+
let _: &&&uint = & & & 1u;
25+
let _: & &&uint = & & & 1u;
26+
let _: &&&&uint = & & & & 1u;
27+
let _: & &&&uint = & & & & 1u;
28+
let _: &&&&&uint = & & & & & 1u;
29+
}
30+
31+
fn check_pat() {
32+
let &_ = & 1u;
33+
let &&_ = & & 1u;
34+
let &&&_ = & & & 1u;
35+
let & &&_ = & & & 1u;
36+
let &&&&_ = & & & & 1u;
37+
let & &&&_ = & & & & 1u;
38+
let &&&&&_ = & & & & & 1u;
39+
}
40+
41+
pub fn main() {}

0 commit comments

Comments
 (0)