From 7f203b69559a669b623240e43080801a475f8b79 Mon Sep 17 00:00:00 2001 From: klutzy Date: Thu, 17 Apr 2014 05:33:58 +0900 Subject: pprust: Add parentheses to some Expr Some `Expr` needs parentheses when printed. For example, without parentheses, `ExprUnary(UnNeg, ExprBinary(BiAdd, ..))` becomes `-lhs + rhs` which is wrong. Those cases don't appear in ordinary code (since parentheses are explicitly added) but they can appear in manually crafted ast by extensions. --- src/libsyntax/print/pprust.rs | 48 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 71c2f6337e0..c8894c1f816 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -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); @@ -1136,6 +1145,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 +1230,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 +1254,38 @@ 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, "&")); + + // `ExprAddrOf(ExprLit("str"))` should be `&&"str"` instead of `&"str"` + // since `&"str"` is `ExprVstore(ExprLit("str"))` which has same meaning to + // `"str"`. + // In many cases adding parentheses (`&("str")`) would help, but it become invalid + // if expr is in `PatLit()`. + let needs_extra_amp = match expr.node { + ast::ExprLit(lit) => { + match lit.node { + ast::LitStr(..) => true, + _ => false, + } + } + ast::ExprVec(..) => true, + _ => false, + }; + if needs_extra_amp { + 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) => { -- cgit 1.4.1-3-g733a5 From cc31bb0a9eebc99e51d5332039c6054e63baf774 Mon Sep 17 00:00:00 2001 From: klutzy Date: Thu, 17 Apr 2014 17:35:40 +0900 Subject: pprust: Fix asm output --- src/libsyntax/print/pprust.rs | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c8894c1f816..7e94fa47588 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1516,22 +1516,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()); } -- cgit 1.4.1-3-g733a5 From 4675a87c8bf4dacdd112c712503f362b7ded1857 Mon Sep 17 00:00:00 2001 From: klutzy Date: Fri, 18 Apr 2014 15:44:25 +0900 Subject: pprust: Print `&&e` instead of `& &e` --- src/libsyntax/print/pprust.rs | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 7e94fa47588..78b9930f8a1 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1279,11 +1279,6 @@ impl<'a> State<'a> { } 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_maybe_paren(expr)); } -- cgit 1.4.1-3-g733a5 From 90d976e8fce44d24acefad884d86be08a4a02212 Mon Sep 17 00:00:00 2001 From: klutzy Date: Fri, 18 Apr 2014 15:48:47 +0900 Subject: pprust: Remove unnecessary && of `print_tt` --- src/libsyntax/print/pprust.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 78b9930f8a1..a0399595572 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -723,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()); } @@ -839,7 +839,7 @@ 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()) } @@ -865,7 +865,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 { @@ -1122,7 +1122,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() } } -- cgit 1.4.1-3-g733a5 From bdd360bb13bb4afad15a9ec7ea1594c22a8d359f Mon Sep 17 00:00:00 2001 From: klutzy Date: Thu, 17 Apr 2014 17:35:36 +0900 Subject: libsyntax: Workaround pprust `for` issue --- src/libsyntax/ext/expand.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 84525718bd9..ccc9d73d544 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"); -- cgit 1.4.1-3-g733a5 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/compiletest/compiletest.rs | 4 +-- src/compiletest/header.rs | 12 +++++++++ src/compiletest/runtest.rs | 24 +++++++++++------ src/librustc/middle/lint.rs | 31 ++++++++++++++++++---- src/librustdoc/html/highlight.rs | 1 + src/librustdoc/html/markdown.rs | 1 + src/libsyntax/ext/expand.rs | 16 ++++++++--- src/libsyntax/parse/parser.rs | 3 --- src/libsyntax/print/pprust.rs | 23 +--------------- src/test/bench/core-set.rs | 4 +-- src/test/bench/shootout-k-nucleotide-pipes.rs | 2 +- src/test/bench/shootout-k-nucleotide.rs | 1 - src/test/bench/shootout-mandelbrot.rs | 2 ++ src/test/bench/shootout-reverse-complement.rs | 2 +- src/test/bench/sudoku.rs | 4 +-- src/test/bench/task-perf-jargon-metal-smoke.rs | 4 +-- src/test/compile-fail/borrowck-lend-flow-match.rs | 2 -- .../compile-fail/borrowck-pat-reassign-binding.rs | 2 -- .../compile-fail/borrowck-preserve-box-in-field.rs | 2 -- .../compile-fail/borrowck-preserve-box-in-uniq.rs | 2 -- src/test/compile-fail/borrowck-preserve-box.rs | 2 -- .../compile-fail/borrowck-preserve-expl-deref.rs | 2 -- src/test/run-pass/anon-extern-mod-cross-crate-2.rs | 1 - src/test/run-pass/big-literals.rs | 2 -- src/test/run-pass/borrowck-pat-enum.rs | 2 -- src/test/run-pass/closure-syntax.rs | 2 -- src/test/run-pass/deriving-global.rs | 12 --------- src/test/run-pass/ifmt.rs | 3 +-- src/test/run-pass/invoke-external-foreign.rs | 1 - src/test/run-pass/numeric-method-autoexport.rs | 5 ++-- .../objects-owned-object-borrowed-method-header.rs | 2 -- src/test/run-pass/super-fast-paren-parsing.rs | 2 -- src/test/run-pass/trait-bounds-in-arc.rs | 2 -- 33 files changed, 85 insertions(+), 95 deletions(-) (limited to 'src/libsyntax') diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index d23182b5225..ee0fe206530 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -29,7 +29,7 @@ use std::io::fs; use std::from_str::FromStr; use getopts::{optopt, optflag, reqopt}; use common::Config; -use common::{Pretty, DebugInfo, Codegen}; +use common::{Pretty, DebugInfoGdb, Codegen}; use util::logv; pub mod procsrv; @@ -199,7 +199,7 @@ pub fn opt_str2(maybestr: Option<~str>) -> ~str { } pub fn run_tests(config: &Config) { - if config.target == ~"arm-linux-androideabi" { + if config.target == "arm-linux-androideabi".to_owned() { match config.mode { DebugInfoGdb => { println!("arm-linux-androideabi debug-info \ diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index e9c41a137d9..047be955477 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -34,6 +34,8 @@ pub struct TestProps { pub check_stdout: bool, // Don't force a --crate-type=dylib flag on the command line pub no_prefer_dynamic: bool, + // Don't run --pretty expanded when running pretty printing tests + pub no_pretty_expanded: bool, } // Load any test directives embedded in the file @@ -48,6 +50,7 @@ pub fn load_props(testfile: &Path) -> TestProps { let mut force_host = false; let mut check_stdout = false; let mut no_prefer_dynamic = false; + let mut no_pretty_expanded = false; iter_header(testfile, |ln| { match parse_error_pattern(ln) { Some(ep) => error_patterns.push(ep), @@ -78,6 +81,10 @@ pub fn load_props(testfile: &Path) -> TestProps { no_prefer_dynamic = parse_no_prefer_dynamic(ln); } + if !no_pretty_expanded { + no_pretty_expanded = parse_no_pretty_expanded(ln); + } + match parse_aux_build(ln) { Some(ab) => { aux_builds.push(ab); } None => {} @@ -107,6 +114,7 @@ pub fn load_props(testfile: &Path) -> TestProps { force_host: force_host, check_stdout: check_stdout, no_prefer_dynamic: no_prefer_dynamic, + no_pretty_expanded: no_pretty_expanded, } } @@ -180,6 +188,10 @@ fn parse_no_prefer_dynamic(line: &str) -> bool { parse_name_directive(line, "no-prefer-dynamic") } +fn parse_no_pretty_expanded(line: &str) -> bool { + parse_name_directive(line, "no-pretty-expanded") +} + fn parse_exec_env(line: &str) -> Option<(~str, ~str)> { parse_name_value_directive(line, "exec-env".to_owned()).map(|nv| { // nv is either FOO or FOO=BAR diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index bd909c8f069..d7fa4f209d4 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -9,7 +9,7 @@ // except according to those terms. use common::Config; -use common::{CompileFail, Pretty, RunFail, RunPass}; +use common::{CompileFail, Pretty, RunFail, RunPass, DebugInfoGdb, DebugInfoLldb}; use errors; use header::TestProps; use header; @@ -64,7 +64,7 @@ pub fn run_metrics(config: Config, testfile: ~str, mm: &mut MetricMap) { Pretty => run_pretty_test(&config, &props, &testfile), DebugInfoGdb => run_debuginfo_gdb_test(&config, &props, &testfile), DebugInfoLldb => run_debuginfo_lldb_test(&config, &props, &testfile), - Codegen => run_codegen_test(&config, &props, &testfile, mm) + Codegen => run_codegen_test(&config, &props, &testfile, mm), } } @@ -194,6 +194,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { if !proc_res.status.success() { fatal_ProcRes("pretty-printed source does not typecheck".to_owned(), &proc_res); } + if props.no_pretty_expanded { return } // additionally, run `--pretty expanded` and try to build it. let proc_res = print_source(config, props, testfile, (*srcs.get(round)).clone(), "expanded"); @@ -219,10 +220,17 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { Vec::new(), config.compile_lib_path, Some(src)) } - fn make_pp_args(config: &Config, _testfile: &Path) -> ProcArgs { - let args = vec!("-".to_owned(), "--pretty".to_owned(), "normal".to_owned(), - "--target=".to_owned() + config.target); + fn make_pp_args(config: &Config, + props: &TestProps, + testfile: &Path, + pretty_type: ~str) -> ProcArgs { + let aux_dir = aux_output_dir_name(config, testfile); // FIXME (#9639): This needs to handle non-utf8 paths + let mut args = vec!("-".to_owned(), "--pretty".to_owned(), pretty_type, + "--target=".to_owned() + config.target, + "-L".to_owned(), aux_dir.as_str().unwrap().to_owned()); + args.push_all_move(split_maybe_args(&config.target_rustcflags)); + args.push_all_move(split_maybe_args(&props.compile_flags)); return ProcArgs {prog: config.rustc_path.as_str().unwrap().to_owned(), args: args}; } @@ -419,14 +427,14 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) { check_debugger_output(&debugger_run_result, check_lines.as_slice()); } -fn run_debuginfo_lldb_test(config: &config, props: &TestProps, testfile: &Path) { +fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) { use std::io::process::{Process, ProcessConfig, ProcessOutput}; if config.lldb_python_dir.is_none() { fatal("Can't run LLDB test because LLDB's python path is not set.".to_owned()); } - let mut config = config { + let mut config = Config { target_rustcflags: cleanup_debug_info_options(&config.target_rustcflags), host_rustcflags: cleanup_debug_info_options(&config.host_rustcflags), .. config.clone() @@ -481,7 +489,7 @@ fn run_debuginfo_lldb_test(config: &config, props: &TestProps, testfile: &Path) check_debugger_output(&debugger_run_result, check_lines.as_slice()); - fn run_lldb(config: &config, test_executable: &Path, debugger_script: &Path) -> ProcRes { + fn run_lldb(config: &Config, test_executable: &Path, debugger_script: &Path) -> ProcRes { // Prepare the lldb_batchmode which executes the debugger script let lldb_batchmode_script = "./src/etc/lldb_batchmode.py".to_owned(); let test_executable_str = test_executable.as_str().unwrap().to_owned(); diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index cc0697ce527..1bf4d0a02fa 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -46,6 +46,7 @@ use middle::typeck::astconv::{ast_ty_to_ty, AstConv}; use middle::typeck::infer; use middle::typeck; use util::ppaux::{ty_to_str}; +use util::nodemap::NodeSet; use std::cmp; use collections::HashMap; @@ -453,10 +454,13 @@ struct Context<'a> { // When recursing into an attributed node of the ast which modifies lint // levels, this stack keeps track of the previous lint levels of whatever // was modified. - lint_stack: Vec<(Lint, level, LintSource)> , + lint_stack: Vec<(Lint, level, LintSource)>, // id of the last visited negated expression - negated_expr_id: ast::NodeId + negated_expr_id: ast::NodeId, + + // ids of structs/enums which have been checked for raw_pointer_deriving + checked_raw_pointers: NodeSet, } impl<'a> Context<'a> { @@ -1014,10 +1018,26 @@ impl<'a> Visitor<()> for RawPtrDerivingVisitor<'a> { fn visit_block(&mut self, _: &ast::Block, _: ()) {} } -fn check_raw_ptr_deriving(cx: &Context, item: &ast::Item) { - if !attr::contains_name(item.attrs.as_slice(), "deriving") { +fn check_raw_ptr_deriving(cx: &mut Context, item: &ast::Item) { + if !attr::contains_name(item.attrs.as_slice(), "automatically_derived") { return } + let did = match item.node { + ast::ItemImpl(..) => { + match ty::get(ty::node_id_to_type(cx.tcx, item.id)).sty { + ty::ty_enum(did, _) => did, + ty::ty_struct(did, _) => did, + _ => return, + } + } + _ => return, + }; + if !ast_util::is_local(did) { return } + let item = match cx.tcx.map.find(did.node) { + Some(ast_map::NodeItem(item)) => item, + _ => return, + }; + if !cx.checked_raw_pointers.insert(item.id) { return } match item.node { ast::ItemStruct(..) | ast::ItemEnum(..) => { let mut visitor = RawPtrDerivingVisitor { cx: cx }; @@ -1848,7 +1868,8 @@ pub fn check_crate(tcx: &ty::ctxt, cur_struct_def_id: -1, is_doc_hidden: false, lint_stack: Vec::new(), - negated_expr_id: -1 + negated_expr_id: -1, + checked_raw_pointers: NodeSet::new(), }; // Install default lint levels, followed by the command line levels, and diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 590086e9d3a..5d4350f8fb5 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -26,6 +26,7 @@ use t = syntax::parse::token; /// Highlights some source code, returning the HTML output. pub fn highlight(src: &str, class: Option<&str>) -> StrBuf { + debug!("highlighting: ================\n{}\n==============", src); let sess = parse::new_parse_sess(); let fm = parse::string_to_filemap(&sess, src.to_strbuf(), diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 76f7949bcf9..d6831e225bc 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -149,6 +149,7 @@ pub fn render(w: &mut io::Writer, s: &str, print_toc: bool) -> fmt::Result { let my_opaque: &MyOpaque = &*((*opaque).opaque as *MyOpaque); slice::raw::buf_as_slice((*text).data, (*text).size as uint, |text| { let text = str::from_utf8(text).unwrap(); + debug!("docblock: ==============\n{}\n=======", text); let mut lines = text.lines().filter(|l| { stripped_filtered_line(*l).is_none() }); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index ccc9d73d544..1898e8bf000 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -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..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) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index a0399595572..326f31d11e9 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 { @@ -1258,28 +1258,7 @@ impl<'a> State<'a> { } ast::ExprAddrOf(m, expr) => { try!(word(&mut self.s, "&")); - - // `ExprAddrOf(ExprLit("str"))` should be `&&"str"` instead of `&"str"` - // since `&"str"` is `ExprVstore(ExprLit("str"))` which has same meaning to - // `"str"`. - // In many cases adding parentheses (`&("str")`) would help, but it become invalid - // if expr is in `PatLit()`. - let needs_extra_amp = match expr.node { - ast::ExprLit(lit) => { - match lit.node { - ast::LitStr(..) => true, - _ => false, - } - } - ast::ExprVec(..) => true, - _ => false, - }; - if needs_extra_amp { - try!(word(&mut self.s, "&")); - } - try!(self.print_mutability(m)); - try!(self.print_expr_maybe_paren(expr)); } ast::ExprLit(lit) => try!(self.print_literal(lit)), diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs index b1181a3c17c..53b371e06cb 100644 --- a/src/test/bench/core-set.rs +++ b/src/test/bench/core-set.rs @@ -1,5 +1,3 @@ -// ignore-pretty - // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. @@ -10,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-pretty very bad with line comments + extern crate collections; extern crate rand; extern crate time; diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index e2bcc55d139..04032c4aa39 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -9,8 +9,8 @@ // except according to those terms. // ignore-android: FIXME(#10393) +// ignore-pretty very bad with line comments -// ignore-pretty the `let to_child` line gets an extra newline // multi tasking k-nucleotide extern crate collections; diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs index dfa287459f3..1434838e59b 100644 --- a/src/test/bench/shootout-k-nucleotide.rs +++ b/src/test/bench/shootout-k-nucleotide.rs @@ -9,7 +9,6 @@ // except according to those terms. // ignore-android see #10393 #13206 -// ignore-pretty extern crate sync; diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs index ee715aecec4..e17324ee596 100644 --- a/src/test/bench/shootout-mandelbrot.rs +++ b/src/test/bench/shootout-mandelbrot.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-pretty very bad with line comments + extern crate sync; use std::io; diff --git a/src/test/bench/shootout-reverse-complement.rs b/src/test/bench/shootout-reverse-complement.rs index 4ee4f94d435..fdd711d22c7 100644 --- a/src/test/bench/shootout-reverse-complement.rs +++ b/src/test/bench/shootout-reverse-complement.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-pretty very bad with line comments // ignore-android doesn't terminate? -// ignore-pretty use std::iter::range_step; use std::io::{stdin, stdout, File}; diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs index bd47734c3da..58568282e15 100644 --- a/src/test/bench/sudoku.rs +++ b/src/test/bench/sudoku.rs @@ -1,5 +1,3 @@ -// ignore-pretty - // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. @@ -10,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-pretty very bad with line comments + #![feature(managed_boxes)] use std::io; diff --git a/src/test/bench/task-perf-jargon-metal-smoke.rs b/src/test/bench/task-perf-jargon-metal-smoke.rs index 35c314dac93..442386e3058 100644 --- a/src/test/bench/task-perf-jargon-metal-smoke.rs +++ b/src/test/bench/task-perf-jargon-metal-smoke.rs @@ -1,5 +1,3 @@ -// ignore-pretty - // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. @@ -17,6 +15,8 @@ // // The filename is a song reference; google it in quotes. +// ignore-pretty very bad with line comments + use std::comm; use std::os; use std::task; diff --git a/src/test/compile-fail/borrowck-lend-flow-match.rs b/src/test/compile-fail/borrowck-lend-flow-match.rs index ea0f5d34b72..6b875ff268d 100644 --- a/src/test/compile-fail/borrowck-lend-flow-match.rs +++ b/src/test/compile-fail/borrowck-lend-flow-match.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-pretty -- comments are unfaithfully preserved - #![allow(unused_variable)] #![allow(dead_assignment)] diff --git a/src/test/compile-fail/borrowck-pat-reassign-binding.rs b/src/test/compile-fail/borrowck-pat-reassign-binding.rs index 47f92d9f4b1..f33e5e9b02d 100644 --- a/src/test/compile-fail/borrowck-pat-reassign-binding.rs +++ b/src/test/compile-fail/borrowck-pat-reassign-binding.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-pretty -- comments are unfaithfully preserved - fn main() { let mut x: Option = None; match x { diff --git a/src/test/compile-fail/borrowck-preserve-box-in-field.rs b/src/test/compile-fail/borrowck-preserve-box-in-field.rs index 168a331e9fe..68410ae4fe1 100644 --- a/src/test/compile-fail/borrowck-preserve-box-in-field.rs +++ b/src/test/compile-fail/borrowck-preserve-box-in-field.rs @@ -1,5 +1,3 @@ -// ignore-pretty - // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. diff --git a/src/test/compile-fail/borrowck-preserve-box-in-uniq.rs b/src/test/compile-fail/borrowck-preserve-box-in-uniq.rs index d79b7e040c7..0db097ec003 100644 --- a/src/test/compile-fail/borrowck-preserve-box-in-uniq.rs +++ b/src/test/compile-fail/borrowck-preserve-box-in-uniq.rs @@ -1,5 +1,3 @@ -// ignore-pretty - // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. diff --git a/src/test/compile-fail/borrowck-preserve-box.rs b/src/test/compile-fail/borrowck-preserve-box.rs index 1a920c7871e..cd36d930604 100644 --- a/src/test/compile-fail/borrowck-preserve-box.rs +++ b/src/test/compile-fail/borrowck-preserve-box.rs @@ -1,5 +1,3 @@ -// ignore-pretty - // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. diff --git a/src/test/compile-fail/borrowck-preserve-expl-deref.rs b/src/test/compile-fail/borrowck-preserve-expl-deref.rs index 9b7966b0af0..ca24192e797 100644 --- a/src/test/compile-fail/borrowck-preserve-expl-deref.rs +++ b/src/test/compile-fail/borrowck-preserve-expl-deref.rs @@ -1,5 +1,3 @@ -// ignore-pretty - // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. diff --git a/src/test/run-pass/anon-extern-mod-cross-crate-2.rs b/src/test/run-pass/anon-extern-mod-cross-crate-2.rs index fd600907ddb..0ef66603111 100644 --- a/src/test/run-pass/anon-extern-mod-cross-crate-2.rs +++ b/src/test/run-pass/anon-extern-mod-cross-crate-2.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-pretty // aux-build:anon-extern-mod-cross-crate-1.rs extern crate anonexternmod; diff --git a/src/test/run-pass/big-literals.rs b/src/test/run-pass/big-literals.rs index 9da3a7079df..f8eaa99b5f0 100644 --- a/src/test/run-pass/big-literals.rs +++ b/src/test/run-pass/big-literals.rs @@ -1,5 +1,3 @@ -// ignore-pretty - // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. diff --git a/src/test/run-pass/borrowck-pat-enum.rs b/src/test/run-pass/borrowck-pat-enum.rs index ade286663a1..7b668029499 100644 --- a/src/test/run-pass/borrowck-pat-enum.rs +++ b/src/test/run-pass/borrowck-pat-enum.rs @@ -1,5 +1,3 @@ -// ignore-pretty - // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. diff --git a/src/test/run-pass/closure-syntax.rs b/src/test/run-pass/closure-syntax.rs index 983cd00f39c..30c01ba9d51 100644 --- a/src/test/run-pass/closure-syntax.rs +++ b/src/test/run-pass/closure-syntax.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-pretty #13324 - #![allow(dead_code)] fn foo() {} diff --git a/src/test/run-pass/deriving-global.rs b/src/test/run-pass/deriving-global.rs index 55e2615835a..3cd50bfff32 100644 --- a/src/test/run-pass/deriving-global.rs +++ b/src/test/run-pass/deriving-global.rs @@ -8,18 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-pretty - does not converge - -// Copyright 2013-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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - extern crate serialize; // {En,De}codable extern crate rand; // Rand diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs index 4d445db302b..b5245275617 100644 --- a/src/test/run-pass/ifmt.rs +++ b/src/test/run-pass/ifmt.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-pretty: `--pretty expand` creates unnecessary `unsafe` block - #![feature(macro_rules, managed_boxes)] #![deny(warnings)] #![allow(unused_must_use)] @@ -77,6 +75,7 @@ pub fn main() { t!(format!("{foo} {1} {bar} {0}", 0, 1, foo=2, bar=3), "2 1 3 0"); t!(format!("{} {0}", "a"), "a a"); t!(format!("{foo_bar}", foo_bar=1), "1"); + t!(format!("{:d}", 5 + 5), "10"); // Methods should probably work t!(format!("{0, plural, =1{a#} =2{b#} zero{c#} other{d#}}", 0u), "c0"); diff --git a/src/test/run-pass/invoke-external-foreign.rs b/src/test/run-pass/invoke-external-foreign.rs index 2603e2d1b09..ef5ef2f215c 100644 --- a/src/test/run-pass/invoke-external-foreign.rs +++ b/src/test/run-pass/invoke-external-foreign.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-pretty // aux-build:foreign_lib.rs // The purpose of this test is to check that we can diff --git a/src/test/run-pass/numeric-method-autoexport.rs b/src/test/run-pass/numeric-method-autoexport.rs index fbb404b3809..585ade71fc6 100644 --- a/src/test/run-pass/numeric-method-autoexport.rs +++ b/src/test/run-pass/numeric-method-autoexport.rs @@ -1,5 +1,3 @@ -// ignore-pretty - // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. @@ -10,10 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// no-pretty-expanded + // This file is intended to test only that methods are automatically // reachable for each numeric type, for each exported impl, with no imports // necessary. Testing the methods of the impls is done within the source // file for each numeric type. + pub fn main() { // ints // num diff --git a/src/test/run-pass/objects-owned-object-borrowed-method-header.rs b/src/test/run-pass/objects-owned-object-borrowed-method-header.rs index 456a5c5d297..7752aed7236 100644 --- a/src/test/run-pass/objects-owned-object-borrowed-method-header.rs +++ b/src/test/run-pass/objects-owned-object-borrowed-method-header.rs @@ -1,5 +1,3 @@ -// ignore-pretty - // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. diff --git a/src/test/run-pass/super-fast-paren-parsing.rs b/src/test/run-pass/super-fast-paren-parsing.rs index 70c7200bee9..759b066c8db 100644 --- a/src/test/run-pass/super-fast-paren-parsing.rs +++ b/src/test/run-pass/super-fast-paren-parsing.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-pretty - static a: int = ((((((((((((((((((((((((((((((((((((((((((((((((((( ((((((((((((((((((((((((((((((((((((((((((((((((((( diff --git a/src/test/run-pass/trait-bounds-in-arc.rs b/src/test/run-pass/trait-bounds-in-arc.rs index 0a6e5ce0b67..98dd3772a4f 100644 --- a/src/test/run-pass/trait-bounds-in-arc.rs +++ b/src/test/run-pass/trait-bounds-in-arc.rs @@ -1,5 +1,3 @@ -// ignore-pretty - // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. -- 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') 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') 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 From d92b9ae7164a73e7c9e44a229d0e1eddbe8121cf Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 10 May 2014 21:57:49 -0700 Subject: syntax: Print suffixed token literals correctly Previously, literals "1i" were printed as "1". This fixes the numeric-method-autoexport test for pretty printing. --- src/libsyntax/ast_util.rs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 74fc43e521b..fb69e440b2f 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -153,6 +153,9 @@ pub fn int_ty_to_str(t: IntTy, val: Option, mode: SuffixMode) -> StrBuf { }; match val { + // 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() } -- cgit 1.4.1-3-g733a5 From 25ac81eb8998e08add3eba703c701a0b9a65173f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 11 May 2014 01:11:33 -0700 Subject: syntax: Preserve attributes in #[deriving] Now that the #[deriving] attribute is removed, the raw_pointers_deriving lint was broken. This commit restores the lint by preserving lint attributes across #[deriving] to the implementations and using #[automatically_derived] as the trigger for activating the lint. --- src/libsyntax/ext/deriving/generic.rs | 36 ++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'src/libsyntax') 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() + }) } /** -- cgit 1.4.1-3-g733a5 From 6878039c122211f227d6c42b7f08282629ceb6c4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 11 May 2014 01:34:28 -0700 Subject: syntax: Improve --pretty normal slightly When printing doc comments, always put a newline after them in a macro invocation to ensure that a line-doc-comment doesn't consume remaining tokens on the line. --- src/librustc/util/ppaux.rs | 8 ++++---- src/libsyntax/print/pprust.rs | 10 ++++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'src/libsyntax') diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index f18f39ac925..95ae05985d3 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -360,9 +360,9 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> 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_box(typ) => format_strbuf!("@{}", ty_to_str(cx, typ)), + ty_uniq(typ) => format_strbuf!("~{}", ty_to_str(cx, typ)), + ty_ptr(ref tm) => format_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()); @@ -370,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_strbuf() + strs.connect(",") + ")").to_strbuf() + format_strbuf!("({})", strs.connect(",")) } ty_closure(ref f) => { closure_to_str(cx, *f) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 0b6efcd4f40..15b931d5854 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -841,7 +841,13 @@ impl<'a> State<'a> { match *tt { 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, "$(")); @@ -2238,7 +2244,7 @@ impl<'a> State<'a> { ast::LitUint(u, t) => { word(&mut self.s, ast_util::uint_ty_to_str(t, Some(u), - ast_util::AutoSuffix).as_slice()) + ast_util::ForceSuffix).as_slice()) } ast::LitIntUnsuffixed(i) => { word(&mut self.s, format!("{}", i)) -- cgit 1.4.1-3-g733a5