diff options
| author | bors <bors@rust-lang.org> | 2014-05-13 18:31:51 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-05-13 18:31:51 -0700 |
| commit | b2b383cab5959b1ec331e1d77583fa944b7fd593 (patch) | |
| tree | 79540b4f5f7e125a260b9ca00f25e796241425f9 /src/libsyntax | |
| parent | cb115ac2d4f57d8b590c8d46d8f9e2958ed9a527 (diff) | |
| parent | f09592a5d154177f0c9d739c9fe60742ec4cd951 (diff) | |
| download | rust-b2b383cab5959b1ec331e1d77583fa944b7fd593.tar.gz rust-b2b383cab5959b1ec331e1d77583fa944b7fd593.zip | |
auto merge of #14187 : alexcrichton/rust/rollup, r=alexcrichton
Closes #14184 (std: Move the owned module from core to std) Closes #14183 (Allow blocks in const expressions) Closes #14176 (Add tests for from_bits.) Closes #14175 (Replaced ~T by Box<T> in manual) Closes #14173 (Implements Default trait for BigInt and BigUint) Closes #14171 (Fix #8391) Closes #14159 (Clean up unicode code in libstd) Closes #14126 (docs: Add a not found page) Closes #14123 (add a line to the example to clarify semantics) Closes #14106 (Pretty printer improvements) Closes #14083 (rustllvm: Add LLVMRustArrayType) Closes #13957 (io: Implement process wait timeouts)
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 24 | ||||
| -rw-r--r-- | src/libsyntax/ext/deriving/generic.rs | 36 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 63 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 89 |
7 files changed, 179 insertions, 65 deletions
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..fb69e440b2f 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<i64>) -> StrBuf { +pub fn int_ty_to_str(t: IntTy, val: Option<i64>, 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,10 @@ pub fn int_ty_to_str(t: IntTy, val: Option<i64>) -> StrBuf { }; match val { - Some(n) => format!("{}{}", n, s).to_strbuf(), + // cast to a u64 so we can correctly print INT64_MIN. All integral types + // are parsed as u64, so we wouldn't want to print an extra negative + // sign. + Some(n) => format!("{}{}", n as u64, s).to_strbuf(), None => s.to_strbuf() } } @@ -161,9 +172,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<u64>) -> StrBuf { +pub fn uint_ty_to_str(t: UintTy, val: Option<u64>, 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/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index 9c967cfb4ee..6df4da89402 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -182,6 +182,7 @@ use std::cell::RefCell; use ast; use ast::{P, EnumDef, Expr, Ident, Generics, StructDef}; use ast_util; +use attr::AttrMetaMethods; use ext::base::ExtCtxt; use ext::build::AstBuilder; use codemap; @@ -330,21 +331,34 @@ impl<'a> TraitDef<'a> { _mitem: @ast::MetaItem, item: @ast::Item, push: |@ast::Item|) { - match item.node { + let newitem = match item.node { ast::ItemStruct(struct_def, ref generics) => { - push(self.expand_struct_def(cx, - struct_def, - item.ident, - generics)); + self.expand_struct_def(cx, + struct_def, + item.ident, + generics) } ast::ItemEnum(ref enum_def, ref generics) => { - push(self.expand_enum_def(cx, - enum_def, - item.ident, - generics)); + self.expand_enum_def(cx, + enum_def, + item.ident, + generics) } - _ => () - } + _ => return + }; + // Keep the lint attributes of the previous item to control how the + // generated implementations are linted + let mut attrs = newitem.attrs.clone(); + attrs.extend(item.attrs.iter().filter(|a| { + match a.name().get() { + "allow" | "warn" | "deny" | "forbid" => true, + _ => false, + } + }).map(|a| a.clone())); + push(@ast::Item { + attrs: attrs, + ..(*newitem).clone() + }) } /** diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 84525718bd9..1898e8bf000 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -156,7 +156,7 @@ pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr { // } // } - let local_ident = token::gensym_ident("i"); + let local_ident = token::gensym_ident("__i"); // FIXME #13573 let next_ident = fld.cx.ident_of("next"); let none_ident = fld.cx.ident_of("None"); @@ -262,7 +262,8 @@ pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander) let it = expand_item_modifiers(it, fld); let mut decorator_items = SmallVector::zero(); - for attr in it.attrs.iter().rev() { + let mut new_attrs = Vec::new(); + for attr in it.attrs.iter() { let mname = attr.name(); match fld.extsbox.find(&intern(mname.get())) { @@ -286,7 +287,7 @@ pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander) fld.cx.bt_pop(); } - _ => {} + _ => new_attrs.push((*attr).clone()), } } @@ -294,14 +295,21 @@ pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander) ast::ItemMac(..) => expand_item_mac(it, fld), ast::ItemMod(_) | ast::ItemForeignMod(_) => { fld.cx.mod_push(it.ident); - let macro_escape = contains_macro_escape(it.attrs.as_slice()); + let macro_escape = contains_macro_escape(new_attrs.as_slice()); let result = with_exts_frame!(fld.extsbox, macro_escape, noop_fold_item(it, fld)); fld.cx.mod_pop(); result }, - _ => noop_fold_item(it, fld) + _ => { + let it = @ast::Item { + attrs: new_attrs, + ..(*it).clone() + + }; + noop_fold_item(it, fld) + } }; new_items.push_all(decorator_items); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2201b08f2ca..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<T>( &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()) @@ -2241,9 +2289,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) } 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 71c2f6337e0..15b931d5854 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -168,7 +168,7 @@ pub fn tt_to_str(tt: &ast::TokenTree) -> StrBuf { } pub fn tts_to_str(tts: &[ast::TokenTree]) -> StrBuf { - to_str(|s| s.print_tts(&tts)) + to_str(|s| s.print_tts(tts)) } pub fn stmt_to_str(stmt: &ast::Stmt) -> StrBuf { @@ -247,6 +247,15 @@ pub fn visibility_qualified(vis: ast::Visibility, s: &str) -> StrBuf { } } +fn needs_parentheses(expr: &ast::Expr) -> bool { + match expr.node { + ast::ExprAssign(..) | ast::ExprBinary(..) | + ast::ExprFnBlock(..) | ast::ExprProc(..) | + ast::ExprAssignOp(..) | ast::ExprCast(..) => true, + _ => false, + } +} + impl<'a> State<'a> { pub fn ibox(&mut self, u: uint) -> IoResult<()> { self.boxes.push(pp::Inconsistent); @@ -714,7 +723,7 @@ impl<'a> State<'a> { try!(self.print_ident(item.ident)); try!(self.cbox(indent_unit)); try!(self.popen()); - try!(self.print_tts(&(tts.as_slice()))); + try!(self.print_tts(tts.as_slice())); try!(self.pclose()); try!(self.end()); } @@ -830,9 +839,15 @@ impl<'a> State<'a> { /// expression arguments as expressions). It can be done! I think. pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> { match *tt { - ast::TTDelim(ref tts) => self.print_tts(&(tts.as_slice())), + ast::TTDelim(ref tts) => self.print_tts(tts.as_slice()), ast::TTTok(_, ref tk) => { - word(&mut self.s, parse::token::to_str(tk).as_slice()) + try!(word(&mut self.s, parse::token::to_str(tk).as_slice())); + match *tk { + parse::token::DOC_COMMENT(..) => { + hardbreak(&mut self.s) + } + _ => Ok(()) + } } ast::TTSeq(_, ref tts, ref sep, zerok) => { try!(word(&mut self.s, "$(")); @@ -856,7 +871,7 @@ impl<'a> State<'a> { } } - pub fn print_tts(&mut self, tts: & &[ast::TokenTree]) -> IoResult<()> { + pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> IoResult<()> { try!(self.ibox(0)); for (i, tt) in tts.iter().enumerate() { if i != 0 { @@ -1113,7 +1128,7 @@ impl<'a> State<'a> { try!(self.print_path(pth, false)); try!(word(&mut self.s, "!")); try!(self.popen()); - try!(self.print_tts(&tts.as_slice())); + try!(self.print_tts(tts.as_slice())); self.pclose() } } @@ -1136,6 +1151,18 @@ impl<'a> State<'a> { self.pclose() } + pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr) -> IoResult<()> { + let needs_par = needs_parentheses(expr); + if needs_par { + try!(self.popen()); + } + try!(self.print_expr(expr)); + if needs_par { + try!(self.pclose()); + } + Ok(()) + } + pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> { try!(self.maybe_print_comment(expr.span.lo)); try!(self.ibox(indent_unit)); @@ -1209,7 +1236,7 @@ impl<'a> State<'a> { try!(self.pclose()); } ast::ExprCall(func, ref args) => { - try!(self.print_expr(func)); + try!(self.print_expr_maybe_paren(func)); try!(self.print_call_post(args.as_slice())); } ast::ExprMethodCall(ident, ref tys, ref args) => { @@ -1233,17 +1260,12 @@ impl<'a> State<'a> { } ast::ExprUnary(op, expr) => { try!(word(&mut self.s, ast_util::unop_to_str(op))); - try!(self.print_expr(expr)); + try!(self.print_expr_maybe_paren(expr)); } ast::ExprAddrOf(m, expr) => { try!(word(&mut self.s, "&")); try!(self.print_mutability(m)); - // Avoid `& &e` => `&&e`. - match (m, &expr.node) { - (ast::MutImmutable, &ast::ExprAddrOf(..)) => try!(space(&mut self.s)), - _ => { } - } - try!(self.print_expr(expr)); + try!(self.print_expr_maybe_paren(expr)); } ast::ExprLit(lit) => try!(self.print_literal(lit)), ast::ExprCast(expr, ty) => { @@ -1474,22 +1496,27 @@ impl<'a> State<'a> { try!(self.popen()); try!(self.print_string(a.asm.get(), a.asm_str_style)); try!(self.word_space(":")); - for &(ref co, o) in a.outputs.iter() { - try!(self.print_string(co.get(), ast::CookedStr)); - try!(self.popen()); - try!(self.print_expr(o)); - try!(self.pclose()); - try!(self.word_space(",")); - } + + try!(self.commasep(Inconsistent, a.outputs.as_slice(), |s, &(ref co, o)| { + try!(s.print_string(co.get(), ast::CookedStr)); + try!(s.popen()); + try!(s.print_expr(o)); + try!(s.pclose()); + Ok(()) + })); + try!(space(&mut self.s)); try!(self.word_space(":")); - for &(ref co, o) in a.inputs.iter() { - try!(self.print_string(co.get(), ast::CookedStr)); - try!(self.popen()); - try!(self.print_expr(o)); - try!(self.pclose()); - try!(self.word_space(",")); - } + + try!(self.commasep(Inconsistent, a.inputs.as_slice(), |s, &(ref co, o)| { + try!(s.print_string(co.get(), ast::CookedStr)); + try!(s.popen()); + try!(s.print_expr(o)); + try!(s.pclose()); + Ok(()) + })); + try!(space(&mut self.s)); try!(self.word_space(":")); + try!(self.print_string(a.clobbers.get(), ast::CookedStr)); try!(self.pclose()); } @@ -2211,11 +2238,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::ForceSuffix).as_slice()) } ast::LitIntUnsuffixed(i) => { word(&mut self.s, format!("{}", i)) |
