mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 22:41:50 +00:00
Parse fully-qualified associated types in generics without whitespace
This breaks code that looks like this: let x = foo as bar << 13; Change such code to look like this: let x = (foo as bar) << 13; Closes #17362. [breaking-change]
This commit is contained in:
parent
7e11b22713
commit
d9769ec383
@ -314,17 +314,17 @@ impl Bitv {
|
||||
|
||||
for i in range(0, complete_words) {
|
||||
bitv.storage.push(
|
||||
(reverse_bits(bytes[i * 4 + 0]) as u32 << 0) |
|
||||
(reverse_bits(bytes[i * 4 + 1]) as u32 << 8) |
|
||||
(reverse_bits(bytes[i * 4 + 2]) as u32 << 16) |
|
||||
(reverse_bits(bytes[i * 4 + 3]) as u32 << 24)
|
||||
((reverse_bits(bytes[i * 4 + 0]) as u32) << 0) |
|
||||
((reverse_bits(bytes[i * 4 + 1]) as u32) << 8) |
|
||||
((reverse_bits(bytes[i * 4 + 2]) as u32) << 16) |
|
||||
((reverse_bits(bytes[i * 4 + 3]) as u32) << 24)
|
||||
);
|
||||
}
|
||||
|
||||
if extra_bytes > 0 {
|
||||
let mut last_word = 0u32;
|
||||
for (i, &byte) in bytes[complete_words*4..].iter().enumerate() {
|
||||
last_word |= reverse_bits(byte) as u32 << (i * 8);
|
||||
last_word |= (reverse_bits(byte) as u32) << (i * 8);
|
||||
}
|
||||
bitv.storage.push(last_word);
|
||||
}
|
||||
@ -645,7 +645,7 @@ impl Bitv {
|
||||
if offset >= bitv.nbits {
|
||||
0
|
||||
} else {
|
||||
bitv[offset] as u8 << (7 - bit)
|
||||
(bitv[offset] as u8) << (7 - bit)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,19 +50,19 @@ pub struct SipState {
|
||||
macro_rules! u8to64_le {
|
||||
($buf:expr, $i:expr) =>
|
||||
($buf[0+$i] as u64 |
|
||||
$buf[1+$i] as u64 << 8 |
|
||||
$buf[2+$i] as u64 << 16 |
|
||||
$buf[3+$i] as u64 << 24 |
|
||||
$buf[4+$i] as u64 << 32 |
|
||||
$buf[5+$i] as u64 << 40 |
|
||||
$buf[6+$i] as u64 << 48 |
|
||||
$buf[7+$i] as u64 << 56);
|
||||
($buf[1+$i] as u64) << 8 |
|
||||
($buf[2+$i] as u64) << 16 |
|
||||
($buf[3+$i] as u64) << 24 |
|
||||
($buf[4+$i] as u64) << 32 |
|
||||
($buf[5+$i] as u64) << 40 |
|
||||
($buf[6+$i] as u64) << 48 |
|
||||
($buf[7+$i] as u64) << 56);
|
||||
($buf:expr, $i:expr, $len:expr) =>
|
||||
({
|
||||
let mut t = 0;
|
||||
let mut out = 0u64;
|
||||
while t < $len {
|
||||
out |= $buf[t+$i] as u64 << t*8;
|
||||
out |= ($buf[t+$i] as u64) << t*8;
|
||||
t += 1;
|
||||
}
|
||||
out
|
||||
|
@ -74,7 +74,7 @@ pub trait Rng {
|
||||
/// these two methods. Similarly to `next_u32`, this rarely needs
|
||||
/// to be called directly, prefer `r.gen()` to `r.next_u64()`.
|
||||
fn next_u64(&mut self) -> u64 {
|
||||
(self.next_u32() as u64 << 32) | (self.next_u32() as u64)
|
||||
((self.next_u32() as u64) << 32) | (self.next_u32() as u64)
|
||||
}
|
||||
|
||||
/// Return the next random f32 selected from the half-open
|
||||
|
@ -267,8 +267,8 @@ impl<'a> Parser<'a> {
|
||||
});
|
||||
match ipv4 {
|
||||
Some(Ipv4Addr(a, b, c, d)) => {
|
||||
groups[i + 0] = (a as u16 << 8) | (b as u16);
|
||||
groups[i + 1] = (c as u16 << 8) | (d as u16);
|
||||
groups[i + 0] = ((a as u16) << 8) | (b as u16);
|
||||
groups[i + 1] = ((c as u16) << 8) | (d as u16);
|
||||
return (i + 2, true);
|
||||
}
|
||||
_ => {}
|
||||
|
@ -55,10 +55,10 @@ pub enum InAddr {
|
||||
pub fn ip_to_inaddr(ip: IpAddr) -> InAddr {
|
||||
match ip {
|
||||
Ipv4Addr(a, b, c, d) => {
|
||||
let ip = (a as u32 << 24) |
|
||||
(b as u32 << 16) |
|
||||
(c as u32 << 8) |
|
||||
(d as u32 << 0);
|
||||
let ip = ((a as u32) << 24) |
|
||||
((b as u32) << 16) |
|
||||
((c as u32) << 8) |
|
||||
((d as u32) << 0);
|
||||
In4Addr(libc::in_addr {
|
||||
s_addr: Int::from_be(ip)
|
||||
})
|
||||
|
@ -669,45 +669,22 @@ impl<'a> Parser<'a> {
|
||||
/// `<` and continue. If a `<` is not seen, return false.
|
||||
///
|
||||
/// This is meant to be used when parsing generics on a path to get the
|
||||
/// starting token. The `force` parameter is used to forcefully break up a
|
||||
/// `<<` token. If `force` is false, then `<<` is only broken when a lifetime
|
||||
/// shows up next. For example, consider the expression:
|
||||
///
|
||||
/// foo as bar << test
|
||||
///
|
||||
/// The parser needs to know if `bar <<` is the start of a generic path or if
|
||||
/// it's a left-shift token. If `test` were a lifetime, then it's impossible
|
||||
/// for the token to be a left-shift, but if it's not a lifetime, then it's
|
||||
/// considered a left-shift.
|
||||
///
|
||||
/// The reason for this is that the only current ambiguity with `<<` is when
|
||||
/// parsing closure types:
|
||||
///
|
||||
/// foo::<<'a> ||>();
|
||||
/// impl Foo<<'a> ||>() { ... }
|
||||
fn eat_lt(&mut self, force: bool) -> bool {
|
||||
/// starting token.
|
||||
fn eat_lt(&mut self) -> bool {
|
||||
match self.token {
|
||||
token::Lt => { self.bump(); true }
|
||||
token::BinOp(token::Shl) => {
|
||||
let next_lifetime = self.look_ahead(1, |t| match *t {
|
||||
token::Lifetime(..) => true,
|
||||
_ => false,
|
||||
});
|
||||
if force || next_lifetime {
|
||||
let span = self.span;
|
||||
let lo = span.lo + BytePos(1);
|
||||
self.replace_token(token::Lt, lo, span.hi);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
let span = self.span;
|
||||
let lo = span.lo + BytePos(1);
|
||||
self.replace_token(token::Lt, lo, span.hi);
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn expect_lt(&mut self) {
|
||||
if !self.eat_lt(true) {
|
||||
if !self.eat_lt() {
|
||||
let found_token = self.this_token_to_string();
|
||||
let token_str = Parser::token_to_string(&token::Lt);
|
||||
self.fatal(format!("expected `{}`, found `{}`",
|
||||
@ -1582,9 +1559,8 @@ impl<'a> Parser<'a> {
|
||||
TyTypeof(e)
|
||||
} else if self.eat_keyword(keywords::Proc) {
|
||||
self.parse_proc_type(Vec::new())
|
||||
} else if self.check(&token::Lt) {
|
||||
} else if self.eat_lt() {
|
||||
// QUALIFIED PATH `<TYPE as TRAIT_REF>::item`
|
||||
self.bump();
|
||||
let self_type = self.parse_ty_sum();
|
||||
self.expect_keyword(keywords::As);
|
||||
let trait_ref = self.parse_trait_ref();
|
||||
@ -1870,7 +1846,7 @@ impl<'a> Parser<'a> {
|
||||
let identifier = self.parse_ident();
|
||||
|
||||
// Parse types, optionally.
|
||||
let parameters = if self.eat_lt(false) {
|
||||
let parameters = if self.eat_lt() {
|
||||
let (lifetimes, types, bindings) = self.parse_generic_values_after_lt();
|
||||
|
||||
ast::AngleBracketedParameters(ast::AngleBracketedParameterData {
|
||||
@ -1931,7 +1907,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
// Check for a type segment.
|
||||
if self.eat_lt(false) {
|
||||
if self.eat_lt() {
|
||||
// Consumed `a::b::<`, go look for types
|
||||
let (lifetimes, types, bindings) = self.parse_generic_values_after_lt();
|
||||
segments.push(ast::PathSegment {
|
||||
|
@ -149,8 +149,8 @@ pub fn get_time() -> Timespec {
|
||||
// A FILETIME contains a 64-bit value representing the number of
|
||||
// hectonanosecond (100-nanosecond) intervals since 1601-01-01T00:00:00Z.
|
||||
// http://support.microsoft.com/kb/167296/en-us
|
||||
let ns_since_1601 = ((time.dwHighDateTime as u64 << 32) |
|
||||
(time.dwLowDateTime as u64 << 0)) / 10;
|
||||
let ns_since_1601 = (((time.dwHighDateTime as u64) << 32) |
|
||||
((time.dwLowDateTime as u64) << 0)) / 10;
|
||||
let ns_since_1970 = ns_since_1601 - NANOSECONDS_FROM_1601_TO_1970;
|
||||
|
||||
((ns_since_1970 / 1000000) as i64,
|
||||
|
@ -459,7 +459,7 @@ impl<'a> Iterator<Utf16Item> for Utf16Items<'a> {
|
||||
}
|
||||
|
||||
// all ok, so lets decode it.
|
||||
let c = ((u - 0xD800) as u32 << 10 | (u2 - 0xDC00) as u32) + 0x1_0000;
|
||||
let c = (((u - 0xD800) as u32) << 10 | (u2 - 0xDC00) as u32) + 0x1_0000;
|
||||
Some(Utf16Item::ScalarValue(unsafe {mem::transmute(c)}))
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ impl Tables {
|
||||
}
|
||||
let mut table16 = [0;1 << 16];
|
||||
for (i, v) in table16.iter_mut().enumerate() {
|
||||
*v = table8[i & 255] as u16 << 8 |
|
||||
*v = (table8[i & 255] as u16) << 8 |
|
||||
table8[i >> 8] as u16;
|
||||
}
|
||||
Tables { table8: table8, table16: table16 }
|
||||
|
18
src/test/run-pass/parse-assoc-type-lt.rs
Normal file
18
src/test/run-pass/parse-assoc-type-lt.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(associated_types)]
|
||||
|
||||
trait Foo {
|
||||
type T;
|
||||
fn foo() -> Box<<Self as Foo>::T>;
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user