From 12375304524ffe732752f5a29551c2caf0b14b4f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 10 May 2014 17:39:08 -0700 Subject: Touch up and rebase previous commits * Added `// no-pretty-expanded` to pretty-print a test, but not run it through the `expanded` variant. * Removed #[deriving] and other expanded attributes after they are expanded * Removed hacks around &str and &&str and friends (from both the parser and the pretty printer). * Un-ignored a bunch of tests --- src/libsyntax/parse/parser.rs | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2201b08f2ca..a83bb7d1bf5 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2241,9 +2241,6 @@ impl<'a> Parser<'a> { ExprVec(..) if m == MutImmutable => { ExprVstore(e, ExprVstoreSlice) } - ExprLit(lit) if lit_is_str(lit) && m == MutImmutable => { - ExprVstore(e, ExprVstoreSlice) - } ExprVec(..) if m == MutMutable => { ExprVstore(e, ExprVstoreMutSlice) } -- cgit 1.4.1-3-g733a5 From 042c8ae40e0bb642263d8b891ef7a0d4e81fe819 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 10 May 2014 20:16:51 -0700 Subject: syntax: Fix printing INT64_MIN Integers are always parsed as a u64 in libsyntax, but they're stored as i64. The parser and pretty printer both printed an i64 instead of u64, sometimes introducing an extra negative sign. --- src/librustc/util/ppaux.rs | 22 +++++++++------------- src/libsyntax/ast.rs | 6 ++++-- src/libsyntax/ast_util.rs | 21 ++++++++++++++++----- src/libsyntax/parse/token.rs | 8 +++++--- src/libsyntax/print/pprust.rs | 6 ++++-- src/test/run-pass/big-literals.rs | 1 + 6 files changed, 39 insertions(+), 25 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 5060c5572cd..f18f39ac925 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -355,18 +355,14 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> StrBuf { ty_bot => "!".to_strbuf(), ty_bool => "bool".to_strbuf(), ty_char => "char".to_strbuf(), - ty_int(t) => ast_util::int_ty_to_str(t, None), - ty_uint(t) => ast_util::uint_ty_to_str(t, None), - ty_float(t) => ast_util::float_ty_to_str(t), - ty_box(typ) => { - ("@".to_owned() + ty_to_str(cx, typ).as_slice()).to_strbuf() - } - ty_uniq(typ) => { - ("~".to_owned() + ty_to_str(cx, typ).as_slice()).to_strbuf() - } - ty_ptr(ref tm) => { - ("*".to_owned() + mt_to_str(cx, tm).as_slice()).to_strbuf() - } + ty_int(t) => ast_util::int_ty_to_str(t, None, + ast_util::AutoSuffix).to_strbuf(), + ty_uint(t) => ast_util::uint_ty_to_str(t, None, + ast_util::AutoSuffix).to_strbuf(), + ty_float(t) => ast_util::float_ty_to_str(t).to_strbuf(), + ty_box(typ) => "@".to_strbuf() + ty_to_str(cx, typ), + ty_uniq(typ) => "~".to_strbuf() + ty_to_str(cx, typ), + ty_ptr(ref tm) => "*".to_strbuf() + mt_to_str(cx, tm), ty_rptr(r, ref tm) => { let mut buf = region_ptr_to_str(cx, r); buf.push_str(mt_to_str(cx, tm).as_slice()); @@ -374,7 +370,7 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> StrBuf { } ty_tup(ref elems) => { let strs: Vec = elems.iter().map(|elem| ty_to_str(cx, *elem)).collect(); - ("(".to_owned() + strs.connect(",") + ")").to_strbuf() + ("(".to_strbuf() + strs.connect(",") + ")").to_strbuf() } ty_closure(ref f) => { closure_to_str(cx, *f) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 391116d2dbc..e5ef31a95a3 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -711,7 +711,8 @@ pub enum IntTy { impl fmt::Show for IntTy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f.buf, "{}", ast_util::int_ty_to_str(*self, None)) + write!(f.buf, "{}", + ast_util::int_ty_to_str(*self, None, ast_util::AutoSuffix)) } } @@ -726,7 +727,8 @@ pub enum UintTy { impl fmt::Show for UintTy { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f.buf, "{}", ast_util::uint_ty_to_str(*self, None)) + write!(f.buf, "{}", + ast_util::uint_ty_to_str(*self, None, ast_util::AutoSuffix)) } } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 550b6603d5d..74fc43e521b 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -132,11 +132,19 @@ pub fn is_path(e: @Expr) -> bool { return match e.node { ExprPath(_) => true, _ => false }; } +pub enum SuffixMode { + ForceSuffix, + AutoSuffix, +} + // Get a string representation of a signed int type, with its value. // We want to avoid "45int" and "-3int" in favor of "45" and "-3" -pub fn int_ty_to_str(t: IntTy, val: Option) -> StrBuf { +pub fn int_ty_to_str(t: IntTy, val: Option, mode: SuffixMode) -> StrBuf { let s = match t { - TyI if val.is_some() => "", + TyI if val.is_some() => match mode { + AutoSuffix => "", + ForceSuffix => "i", + }, TyI => "int", TyI8 => "i8", TyI16 => "i16", @@ -145,7 +153,7 @@ pub fn int_ty_to_str(t: IntTy, val: Option) -> StrBuf { }; match val { - Some(n) => format!("{}{}", n, s).to_strbuf(), + Some(n) => format!("{}{}", n as u64, s).to_strbuf(), None => s.to_strbuf() } } @@ -161,9 +169,12 @@ pub fn int_ty_max(t: IntTy) -> u64 { // Get a string representation of an unsigned int type, with its value. // We want to avoid "42uint" in favor of "42u" -pub fn uint_ty_to_str(t: UintTy, val: Option) -> StrBuf { +pub fn uint_ty_to_str(t: UintTy, val: Option, mode: SuffixMode) -> StrBuf { let s = match t { - TyU if val.is_some() => "u", + TyU if val.is_some() => match mode { + AutoSuffix => "", + ForceSuffix => "u", + }, TyU => "uint", TyU8 => "u8", TyU16 => "u16", diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 3888ed6b8d1..68ce8cb2bc1 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -203,9 +203,11 @@ pub fn to_str(t: &Token) -> StrBuf { res.push_char('\''); res } - LIT_INT(i, t) => ast_util::int_ty_to_str(t, Some(i)), - LIT_UINT(u, t) => ast_util::uint_ty_to_str(t, Some(u)), - LIT_INT_UNSUFFIXED(i) => { i.to_str().to_strbuf() } + LIT_INT(i, t) => ast_util::int_ty_to_str(t, Some(i), + ast_util::ForceSuffix), + LIT_UINT(u, t) => ast_util::uint_ty_to_str(t, Some(u), + ast_util::ForceSuffix), + LIT_INT_UNSUFFIXED(i) => { (i as u64).to_str().to_strbuf() } LIT_FLOAT(s, t) => { let mut body = StrBuf::from_str(get_ident(s).get()); if body.as_slice().ends_with(".") { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 326f31d11e9..0b6efcd4f40 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2232,11 +2232,13 @@ impl<'a> State<'a> { } ast::LitInt(i, t) => { word(&mut self.s, - ast_util::int_ty_to_str(t, Some(i)).as_slice()) + ast_util::int_ty_to_str(t, Some(i), + ast_util::AutoSuffix).as_slice()) } ast::LitUint(u, t) => { word(&mut self.s, - ast_util::uint_ty_to_str(t, Some(u)).as_slice()) + ast_util::uint_ty_to_str(t, Some(u), + ast_util::AutoSuffix).as_slice()) } ast::LitIntUnsuffixed(i) => { word(&mut self.s, format!("{}", i)) diff --git a/src/test/run-pass/big-literals.rs b/src/test/run-pass/big-literals.rs index f8eaa99b5f0..3b2618c060d 100644 --- a/src/test/run-pass/big-literals.rs +++ b/src/test/run-pass/big-literals.rs @@ -16,4 +16,5 @@ pub fn main() { assert_eq!(-2147483648i32 - 1i32, 2147483647i32); assert_eq!(-9223372036854775808i64 - 1i64, 9223372036854775807i64); + assert_eq!(-9223372036854775808 - 1, 9223372036854775807); } -- cgit 1.4.1-3-g733a5 From ac1a27043a7481676502e383716e20c017122bcb Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 10 May 2014 21:27:44 -0700 Subject: syntax: Fix parsing << with closure types This uses the trick of replacing the << token with a < token to parse closure types correctly. Closes #13324 --- src/libsyntax/parse/parser.rs | 60 ++++++++++++++++++++++++++++++---- src/test/run-pass/borrowck-pat-enum.rs | 2 ++ src/test/run-pass/closure-syntax.rs | 16 ++++++++- 3 files changed, 71 insertions(+), 7 deletions(-) (limited to 'src/libsyntax/parse') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a83bb7d1bf5..92e5f8da6aa 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -587,16 +587,64 @@ impl<'a> Parser<'a> { self.replace_token(token::BINOP(token::OR), lo, self.span.hi) } _ => { - let token_str = self.this_token_to_str(); - let found_token = + let found_token = self.this_token_to_str(); + let token_str = Parser::token_to_str(&token::BINOP(token::OR)); self.fatal(format!("expected `{}`, found `{}`", - found_token, - token_str)) + token_str, found_token)) } } } + // Attempt to consume a `<`. If `<<` is seen, replace it with a single + // `<` 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 { + 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 lo = self.span.lo + BytePos(1); + self.replace_token(token::LT, lo, self.span.hi); + true + } else { + false + } + } + _ => false, + } + } + + fn expect_lt(&mut self) { + if !self.eat_lt(true) { + let found_token = self.this_token_to_str(); + let token_str = Parser::token_to_str(&token::LT); + self.fatal(format!("expected `{}`, found `{}`", + token_str, found_token)) + } + } + // Parse a sequence bracketed by `|` and `|`, stopping before the `|`. fn parse_seq_to_before_or( &mut self, @@ -1500,7 +1548,7 @@ impl<'a> Parser<'a> { // Parse the `<` before the lifetime and types, if applicable. let (any_lifetime_or_types, lifetimes, types) = { - if mode != NoTypesAllowed && self.eat(&token::LT) { + if mode != NoTypesAllowed && self.eat_lt(false) { let (lifetimes, types) = self.parse_generic_values_after_lt(); (true, lifetimes, OwnedSlice::from_vec(types)) @@ -1948,7 +1996,7 @@ impl<'a> Parser<'a> { hi = self.span.hi; self.bump(); let (_, tys) = if self.eat(&token::MOD_SEP) { - self.expect(&token::LT); + self.expect_lt(); self.parse_generic_values_after_lt() } else { (Vec::new(), Vec::new()) diff --git a/src/test/run-pass/borrowck-pat-enum.rs b/src/test/run-pass/borrowck-pat-enum.rs index 7b668029499..74ce8ef2e45 100644 --- a/src/test/run-pass/borrowck-pat-enum.rs +++ b/src/test/run-pass/borrowck-pat-enum.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-pretty + fn match_ref(v: Option) -> int { match v { Some(ref i) => { diff --git a/src/test/run-pass/closure-syntax.rs b/src/test/run-pass/closure-syntax.rs index 30c01ba9d51..2bb0e6fa19c 100644 --- a/src/test/run-pass/closure-syntax.rs +++ b/src/test/run-pass/closure-syntax.rs @@ -43,6 +43,12 @@ fn g<'a>(a: &'a int, f: proc<'b>(&'b int) -> &'b int) -> &'a int { f(a) } +struct A; + +impl A { + fn foo(&self) {} +} + fn bar<'b>() { foo::<||>(); foo::<|| -> ()>(); @@ -58,17 +64,25 @@ fn bar<'b>() { foo::(); foo::(int, f32, &'a int):'static + Share -> &'a int>(); + foo::<<'a>||>(); + // issue #11209 let _: ||: 'b; // for comparison let _: <'a> ||; let _: Option<||:'b>; - // let _: Option<<'a>||>; + let _: Option<<'a>||>; let _: Option< <'a>||>; // issue #11210 let _: ||: 'static; + + let a = A; + a.foo::<<'a>||>(); } +struct B; +impl<'b> B<<'a>||: 'b> {} + pub fn main() { } -- cgit 1.4.1-3-g733a5