From 4daacaf063b4d747f2cda704d47d111465b6dced Mon Sep 17 00:00:00 2001 From: klutzy Date: Wed, 16 Apr 2014 14:32:35 +0900 Subject: [PATCH 01/10] rustc: Make std_inject valid for pretty-printer Inject `extern crate {std, native}` before `use` statements. Add `#![feature(glob)]` since `use std::prelude::*` is used. (Unfortunately `rustc --pretty expanded` does not converge, since `extern crate` and `use std::prelude::*` is injected at every iteration.) --- src/librustc/front/std_inject.rs | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index 0ff2098e6f234..d86c588c8aeee 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -97,6 +97,7 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> { }); } + // `extern crate` must be precede `use` items vis.push_all_move(krate.module.view_items.clone()); let new_module = ast::Mod { view_items: vis, @@ -127,8 +128,20 @@ impl<'a> fold::Folder for PreludeInjector<'a> { if !no_prelude(krate.attrs.as_slice()) { // only add `use std::prelude::*;` if there wasn't a // `#![no_implicit_prelude]` at the crate level. + + let mut attrs = krate.attrs.clone(); + + // fold_mod() will insert glob path. + let globs_attr = attr::mk_attr(attr::mk_list_item( + InternedString::new("feature"), + vec!( + attr::mk_word_item(InternedString::new("globs")), + ))); + attrs.push(globs_attr); + ast::Crate { module: self.fold_mod(&krate.module), + attrs: attrs, ..krate } } else { @@ -172,11 +185,20 @@ impl<'a> fold::Folder for PreludeInjector<'a> { span: DUMMY_SP, }; - let vis = (vec!(vi2)).append(module.view_items.as_slice()); + let (crates, uses) = module.view_items.partitioned(|x| { + match x.node { + ast::ViewItemExternCrate(..) => true, + _ => false, + } + }); + + // add vi2 after any `extern crate` but before any `use` + let mut view_items = crates; + view_items.push(vi2); + view_items.push_all_move(uses); - // FIXME #2543: Bad copy. let new_module = ast::Mod { - view_items: vis, + view_items: view_items, ..(*module).clone() }; fold::noop_fold_mod(&new_module, self) From 1a373f900e84301a31d256b20fbba6c20f2a2de7 Mon Sep 17 00:00:00 2001 From: klutzy Date: Thu, 17 Apr 2014 03:46:41 +0900 Subject: [PATCH 02/10] syntax: Rename `#[deriving(...)]` after expansion This patch renames `#[deriving]` into `#[!deriving]` (starting with `!`) to mark that expansion has completed. This makes output of `--pretty expanded` valid. --- src/librustc/middle/lint.rs | 15 +++++++++++---- src/libsyntax/attr.rs | 15 +++++++++++++++ src/libsyntax/ext/expand.rs | 24 ++++++++++++++++++++---- src/libsyntax/print/pprust.rs | 4 ++++ 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index e376f85ff6db0..47a382acc5974 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -986,7 +986,7 @@ impl<'a> Visitor<()> for RawPtrDerivingVisitor<'a> { } fn check_raw_ptr_deriving(cx: &Context, item: &ast::Item) { - if !attr::contains_name(item.attrs.as_slice(), "deriving") { + if !attr::contains_name(item.attrs.as_slice(), "!deriving") { return } match item.node { @@ -1030,15 +1030,17 @@ static other_attrs: &'static [&'static str] = &[ // fn-level "test", "bench", "should_fail", "ignore", "inline", "lang", "main", "start", "no_split_stack", "cold", "macro_registrar", "linkage", - - // internal attribute: bypass privacy inside items - "!resolve_unexported", ]; fn check_crate_attrs_usage(cx: &Context, attrs: &[ast::Attribute]) { for attr in attrs.iter() { let name = attr.node.value.name(); + if name.get().char_at(0) == '!' { + // special attributes for internal use + continue; + } + let mut iter = crate_attrs.iter().chain(other_attrs.iter()); if !iter.any(|other_attr| { name.equiv(other_attr) }) { cx.span_lint(AttributeUsage, attr.span, "unknown crate attribute"); @@ -1057,6 +1059,11 @@ fn check_attrs_usage(cx: &Context, attrs: &[ast::Attribute]) { for attr in attrs.iter() { let name = attr.node.value.name(); + if name.get().char_at(0) == '!' { + // special attributes for internal use + continue; + } + for crate_attr in crate_attrs.iter() { if name.equiv(crate_attr) { let msg = match attr.node.style { diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 0c0d7bbb535f7..880ccc2791632 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -175,6 +175,21 @@ pub fn mk_sugared_doc_attr(text: InternedString, lo: BytePos, hi: BytePos) spanned(lo, hi, attr) } +pub fn rename_attr(attr: &Attribute, new_name: &str) -> Attribute { + let new_mname = token::intern_and_get_ident(new_name); + let meta = attr.meta(); + let new_item: ast::MetaItem_ = match meta.node { + ast::MetaWord(_) => ast::MetaWord(new_mname), + ast::MetaList(_, ref v) => ast::MetaList(new_mname, (*v).clone()), + ast::MetaNameValue(_, ref l) => ast::MetaNameValue(new_mname, (*l).clone()), + }; + + dummy_spanned(ast::Attribute_ { + value: @dummy_spanned(new_item), + .. (attr.node).clone() + }) +} + /* Searching */ /// Check if `needle` occurs in `haystack` by a structural /// comparison. This is slightly subtle, and relies on ignoring the diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index d73cb3856f95f..3816e45be0fa4 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())) { @@ -285,8 +286,17 @@ pub fn expand_item(it: @ast::Item, fld: &mut MacroExpander) .flat_map(|item| expand_item(item, fld).move_iter())); fld.cx.bt_pop(); + + // raw_pointer_deriving lint wants `#[deriving(..)]` attribute, + // but pprust-expanded doesn't want it because it already expanded deriving code. + // so here we rename `deriving` to `!deriving` and think + // it's only valid for internal usage. this is not so elegant though.. + let new_attr = attr::rename_attr(attr, "!" + mname.get()); + new_attrs.push(new_attr); + } + _ => { + new_attrs.push((*attr).clone()); } - _ => {} } } @@ -294,14 +304,20 @@ 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/print/pprust.rs b/src/libsyntax/print/pprust.rs index 429540efd37e7..c296a0b5a79c7 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -947,6 +947,10 @@ impl<'a> State<'a> { } pub fn print_attribute(&mut self, attr: &ast::Attribute) -> IoResult<()> { + // skip any attribute which starts with `!`. it's only for internal usage. + if attr.name().get().char_at(0) == '!' { + return Ok(()); + } try!(self.hardbreak_if_not_bol()); try!(self.maybe_print_comment(attr.span.lo)); if attr.node.is_sugared_doc { From 2a185e82773180a01e2f5c25834267f5e1483ae3 Mon Sep 17 00:00:00 2001 From: klutzy Date: Thu, 17 Apr 2014 05:33:58 +0900 Subject: [PATCH 03/10] 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(-) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c296a0b5a79c7..5bf4407cfb804 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) -> ~str { } } +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); @@ -1118,6 +1127,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)); @@ -1191,7 +1212,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) => { @@ -1215,17 +1236,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) => { From f86d6b62a2137e97ccf30646c5a279b22289138b Mon Sep 17 00:00:00 2001 From: klutzy Date: Thu, 17 Apr 2014 17:35:40 +0900 Subject: [PATCH 04/10] pprust: Fix asm output --- src/libsyntax/print/pprust.rs | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 5bf4407cfb804..152ee6f2181f9 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1493,22 +1493,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()); } From 1e6e223c323a9e6a9c16e8090165854418cbbb52 Mon Sep 17 00:00:00 2001 From: klutzy Date: Fri, 18 Apr 2014 15:44:25 +0900 Subject: [PATCH 05/10] pprust: Print `&&e` instead of `& &e` --- src/libsyntax/print/pprust.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 152ee6f2181f9..138504873b518 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1261,11 +1261,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)); } From 0af7342cc81aced0723105ba9927f428e6a0a481 Mon Sep 17 00:00:00 2001 From: klutzy Date: Fri, 18 Apr 2014 15:48:47 +0900 Subject: [PATCH 06/10] pprust: Remove unnecessary && of `print_tt` --- src/libsyntax/print/pprust.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 138504873b518..95bf15323e512 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) -> ~str { } pub fn tts_to_str(tts: &[ast::TokenTree]) -> ~str { - to_str(|s| s.print_tts(&tts)) + to_str(|s| s.print_tts(tts)) } pub fn stmt_to_str(stmt: &ast::Stmt) -> ~str { @@ -709,7 +709,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()); } @@ -818,7 +818,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)) } @@ -843,7 +843,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 { @@ -1104,7 +1104,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() } } From cd381509b953bd9eb45b0e5163ded7dafeede666 Mon Sep 17 00:00:00 2001 From: klutzy Date: Thu, 17 Apr 2014 17:35:36 +0900 Subject: [PATCH 07/10] libsyntax: Workaround pprust `for` issue --- src/libsyntax/ext/expand.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 3816e45be0fa4..b890294137be9 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"); From 4a21c02803c0a09950c0ebc417f9868cbab73008 Mon Sep 17 00:00:00 2001 From: klutzy Date: Thu, 17 Apr 2014 18:20:37 +0900 Subject: [PATCH 08/10] test: Add missing `#![feature(managed_boxes)]` The tests use managed boxes, but are not perfectly feature-gated because they use `@` inside macros. (It causes issue after `--pretty expanded`.) --- src/test/run-pass/assert-eq-macro-success.rs | 2 ++ src/test/run-pass/binops.rs | 2 ++ src/test/run-pass/box-compare.rs | 2 +- src/test/run-pass/ifmt.rs | 2 +- src/test/run-pass/nullable-pointer-iotareduction.rs | 2 +- src/test/run-pass/nullable-pointer-size.rs | 2 +- 6 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/test/run-pass/assert-eq-macro-success.rs b/src/test/run-pass/assert-eq-macro-success.rs index f7389f6506716..0f872b4314fc6 100644 --- a/src/test/run-pass/assert-eq-macro-success.rs +++ b/src/test/run-pass/assert-eq-macro-success.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(managed_boxes)] + #[deriving(Eq, Show)] struct Point { x : int } diff --git a/src/test/run-pass/binops.rs b/src/test/run-pass/binops.rs index 3e3d9aab84e89..937d5df18652c 100644 --- a/src/test/run-pass/binops.rs +++ b/src/test/run-pass/binops.rs @@ -10,6 +10,8 @@ // Binop corner cases +#![feature(managed_boxes)] + fn test_nil() { assert_eq!((), ()); assert!((!(() != ()))); diff --git a/src/test/run-pass/box-compare.rs b/src/test/run-pass/box-compare.rs index b68ecd3f4d3e0..ddc008c5e660f 100644 --- a/src/test/run-pass/box-compare.rs +++ b/src/test/run-pass/box-compare.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - +#![feature(managed_boxes)] pub fn main() { assert!((@1 < @3)); diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs index ba0d5c3ea44cb..fbff321d5d366 100644 --- a/src/test/run-pass/ifmt.rs +++ b/src/test/run-pass/ifmt.rs @@ -9,7 +9,7 @@ // except according to those terms. -#![feature(macro_rules)] +#![feature(macro_rules, managed_boxes)] #![deny(warnings)] #![allow(unused_must_use)] #![allow(deprecated_owned_vector)] diff --git a/src/test/run-pass/nullable-pointer-iotareduction.rs b/src/test/run-pass/nullable-pointer-iotareduction.rs index de9ca643f071f..ae323d0b8f15f 100644 --- a/src/test/run-pass/nullable-pointer-iotareduction.rs +++ b/src/test/run-pass/nullable-pointer-iotareduction.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(macro_rules)] +#![feature(macro_rules, managed_boxes)] use std::{option, cast}; diff --git a/src/test/run-pass/nullable-pointer-size.rs b/src/test/run-pass/nullable-pointer-size.rs index 4e5627237fb8e..4063d43c47cfd 100644 --- a/src/test/run-pass/nullable-pointer-size.rs +++ b/src/test/run-pass/nullable-pointer-size.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(macro_rules)] +#![feature(macro_rules, managed_boxes)] use std::mem; From 16d22f4d48d7faaf12566e30414663f76cee9038 Mon Sep 17 00:00:00 2001 From: klutzy Date: Wed, 16 Apr 2014 13:56:39 +0900 Subject: [PATCH 09/10] compiletest: Modernize typenames --- src/compiletest/common.rs | 49 ++++++++++++++---- src/compiletest/compiletest.rs | 71 +++++++------------------ src/compiletest/header.rs | 10 ++-- src/compiletest/runtest.rs | 95 ++++++++++++++++------------------ src/compiletest/util.rs | 4 +- 5 files changed, 113 insertions(+), 116 deletions(-) diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index ea6e98fafa7cd..3fb6645b0394b 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -8,18 +8,49 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::from_str::FromStr; +use std::fmt; + #[deriving(Clone, Eq)] -pub enum mode { - mode_compile_fail, - mode_run_fail, - mode_run_pass, - mode_pretty, - mode_debug_info, - mode_codegen +pub enum Mode { + CompileFail, + RunFail, + RunPass, + Pretty, + DebugInfo, + Codegen +} + +impl FromStr for Mode { + fn from_str(s: &str) -> Option { + match s { + "compile-fail" => Some(CompileFail), + "run-fail" => Some(RunFail), + "run-pass" => Some(RunPass), + "pretty" => Some(Pretty), + "debug-info" => Some(DebugInfo), + "codegen" => Some(Codegen), + _ => None, + } + } +} + +impl fmt::Show for Mode { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let msg = match *self { + CompileFail => "compile-fail", + RunFail => "run-fail", + RunPass => "run-pass", + Pretty => "pretty", + DebugInfo => "debug-info", + Codegen => "codegen", + }; + write!(f.buf, "{}", msg) + } } #[deriving(Clone)] -pub struct config { +pub struct Config { // The library paths required for running the compiler pub compile_lib_path: ~str, @@ -48,7 +79,7 @@ pub struct config { pub stage_id: ~str, // The test mode, compile-fail, run-fail, run-pass - pub mode: mode, + pub mode: Mode, // Run ignored tests pub run_ignored: bool, diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index d2499ea33bdd6..170316518adb4 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -14,7 +14,6 @@ // we use our own (green) start below; do not link in libnative; issue #13247. #![no_start] -#![allow(non_camel_case_types)] #![deny(warnings)] extern crate test; @@ -27,15 +26,10 @@ extern crate rustuv; use std::os; use std::io; use std::io::fs; +use std::from_str::FromStr; use getopts::{optopt, optflag, reqopt}; -use common::config; -use common::mode_run_pass; -use common::mode_run_fail; -use common::mode_compile_fail; -use common::mode_pretty; -use common::mode_debug_info; -use common::mode_codegen; -use common::mode; +use common::Config; +use common::{Pretty, DebugInfo, Codegen}; use util::logv; pub mod procsrv; @@ -57,7 +51,7 @@ pub fn main() { run_tests(&config); } -pub fn parse_config(args: Vec<~str> ) -> config { +pub fn parse_config(args: Vec<~str> ) -> Config { let groups : Vec = vec!(reqopt("", "compile-lib-path", "path to host shared libraries", "PATH"), @@ -117,7 +111,7 @@ pub fn parse_config(args: Vec<~str> ) -> config { Path::new(m.opt_str(nm).unwrap()) } - config { + Config { compile_lib_path: matches.opt_str("compile-lib-path").unwrap(), run_lib_path: matches.opt_str("run-lib-path").unwrap(), rustc_path: opt_path(matches, "rustc-path"), @@ -127,7 +121,7 @@ pub fn parse_config(args: Vec<~str> ) -> config { build_base: opt_path(matches, "build-base"), aux_base: opt_path(matches, "aux-base"), stage_id: matches.opt_str("stage-id").unwrap(), - mode: str_mode(matches.opt_str("mode").unwrap()), + mode: FromStr::from_str(matches.opt_str("mode").unwrap()).expect("invalid mode"), run_ignored: matches.opt_present("ignored"), filter: if !matches.free.is_empty() { @@ -159,7 +153,7 @@ pub fn parse_config(args: Vec<~str> ) -> config { } } -pub fn log_config(config: &config) { +pub fn log_config(config: &Config) { let c = config; logv(c, format!("configuration:")); logv(c, format!("compile_lib_path: {}", config.compile_lib_path)); @@ -168,7 +162,7 @@ pub fn log_config(config: &config) { logv(c, format!("src_base: {}", config.src_base.display())); logv(c, format!("build_base: {}", config.build_base.display())); logv(c, format!("stage_id: {}", config.stage_id)); - logv(c, format!("mode: {}", mode_str(config.mode))); + logv(c, format!("mode: {}", config.mode)); logv(c, format!("run_ignored: {}", config.run_ignored)); logv(c, format!("filter: {}", opt_str(&config.filter))); logv(c, format!("runtool: {}", opt_str(&config.runtool))); @@ -202,33 +196,10 @@ pub fn opt_str2(maybestr: Option<~str>) -> ~str { match maybestr { None => ~"(none)", Some(s) => { s } } } -pub fn str_mode(s: ~str) -> mode { - match s.as_slice() { - "compile-fail" => mode_compile_fail, - "run-fail" => mode_run_fail, - "run-pass" => mode_run_pass, - "pretty" => mode_pretty, - "debug-info" => mode_debug_info, - "codegen" => mode_codegen, - _ => fail!("invalid mode") - } -} - -pub fn mode_str(mode: mode) -> ~str { - match mode { - mode_compile_fail => ~"compile-fail", - mode_run_fail => ~"run-fail", - mode_run_pass => ~"run-pass", - mode_pretty => ~"pretty", - mode_debug_info => ~"debug-info", - mode_codegen => ~"codegen", - } -} - -pub fn run_tests(config: &config) { +pub fn run_tests(config: &Config) { if config.target == ~"arm-linux-androideabi" { match config.mode{ - mode_debug_info => { + DebugInfo => { println!("arm-linux-androideabi debug-info \ test uses tcp 5039 port. please reserve it"); } @@ -257,7 +228,7 @@ pub fn run_tests(config: &config) { } } -pub fn test_opts(config: &config) -> test::TestOpts { +pub fn test_opts(config: &Config) -> test::TestOpts { test::TestOpts { filter: config.filter.clone(), run_ignored: config.run_ignored, @@ -271,7 +242,7 @@ pub fn test_opts(config: &config) -> test::TestOpts { } } -pub fn make_tests(config: &config) -> Vec { +pub fn make_tests(config: &Config) -> Vec { debug!("making tests from {}", config.src_base.display()); let mut tests = Vec::new(); @@ -282,7 +253,7 @@ pub fn make_tests(config: &config) -> Vec { if is_test(config, &file) { let t = make_test(config, &file, || { match config.mode { - mode_codegen => make_metrics_test_closure(config, &file), + Codegen => make_metrics_test_closure(config, &file), _ => make_test_closure(config, &file) } }); @@ -292,11 +263,11 @@ pub fn make_tests(config: &config) -> Vec { tests } -pub fn is_test(config: &config, testfile: &Path) -> bool { +pub fn is_test(config: &Config, testfile: &Path) -> bool { // Pretty-printer does not work with .rc files yet let valid_extensions = match config.mode { - mode_pretty => vec!(~".rs"), + Pretty => vec!(~".rs"), _ => vec!(~".rc", ~".rs") }; let invalid_prefixes = vec!(~".", ~"#", ~"~"); @@ -315,7 +286,7 @@ pub fn is_test(config: &config, testfile: &Path) -> bool { return valid; } -pub fn make_test(config: &config, testfile: &Path, f: || -> test::TestFn) +pub fn make_test(config: &Config, testfile: &Path, f: || -> test::TestFn) -> test::TestDescAndFn { test::TestDescAndFn { desc: test::TestDesc { @@ -327,7 +298,7 @@ pub fn make_test(config: &config, testfile: &Path, f: || -> test::TestFn) } } -pub fn make_test_name(config: &config, testfile: &Path) -> test::TestName { +pub fn make_test_name(config: &Config, testfile: &Path) -> test::TestName { // Try to elide redundant long paths fn shorten(path: &Path) -> ~str { @@ -337,19 +308,17 @@ pub fn make_test_name(config: &config, testfile: &Path) -> test::TestName { format!("{}/{}", dir.unwrap_or(""), filename.unwrap_or("")) } - test::DynTestName(format!("[{}] {}", - mode_str(config.mode), - shorten(testfile))) + test::DynTestName(format!("[{}] {}", config.mode, shorten(testfile))) } -pub fn make_test_closure(config: &config, testfile: &Path) -> test::TestFn { +pub fn make_test_closure(config: &Config, testfile: &Path) -> test::TestFn { let config = (*config).clone(); // FIXME (#9639): This needs to handle non-utf8 paths let testfile = testfile.as_str().unwrap().to_owned(); test::DynTestFn(proc() { runtest::run(config, testfile) }) } -pub fn make_metrics_test_closure(config: &config, testfile: &Path) -> test::TestFn { +pub fn make_metrics_test_closure(config: &Config, testfile: &Path) -> test::TestFn { let config = (*config).clone(); // FIXME (#9639): This needs to handle non-utf8 paths let testfile = testfile.as_str().unwrap().to_owned(); diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index b45a68518a3ec..f0ce2a791c5c1 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use common::config; +use common::Config; use common; use util; @@ -110,11 +110,11 @@ pub fn load_props(testfile: &Path) -> TestProps { }; } -pub fn is_test_ignored(config: &config, testfile: &Path) -> bool { - fn ignore_target(config: &config) -> ~str { +pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool { + fn ignore_target(config: &Config) -> ~str { ~"ignore-" + util::get_os(config.target) } - fn ignore_stage(config: &config) -> ~str { + fn ignore_stage(config: &Config) -> ~str { ~"ignore-" + config.stage_id.split('-').next().unwrap() } @@ -122,7 +122,7 @@ pub fn is_test_ignored(config: &config, testfile: &Path) -> bool { if parse_name_directive(ln, "ignore-test") { false } else if parse_name_directive(ln, ignore_target(config)) { false } else if parse_name_directive(ln, ignore_stage(config)) { false } - else if config.mode == common::mode_pretty && + else if config.mode == common::Pretty && parse_name_directive(ln, "ignore-pretty") { false } else if config.target != config.host && parse_name_directive(ln, "ignore-cross-compile") { false } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 1885f20bd8853..2b9c73e89a434 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -8,11 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use common::config; -use common::mode_compile_fail; -use common::mode_pretty; -use common::mode_run_fail; -use common::mode_run_pass; +use common::Config; +use common::{CompileFail, Pretty, RunFail, RunPass}; use errors; use header::TestProps; use header::load_props; @@ -36,7 +33,7 @@ use std::task; use std::slice; use test::MetricMap; -pub fn run(config: config, testfile: ~str) { +pub fn run(config: Config, testfile: ~str) { match config.target.as_slice() { @@ -53,7 +50,7 @@ pub fn run(config: config, testfile: ~str) { run_metrics(config, testfile, &mut _mm); } -pub fn run_metrics(config: config, testfile: ~str, mm: &mut MetricMap) { +pub fn run_metrics(config: Config, testfile: ~str, mm: &mut MetricMap) { if config.verbose { // We're going to be dumping a lot of info. Start on a new line. print!("\n\n"); @@ -63,16 +60,16 @@ pub fn run_metrics(config: config, testfile: ~str, mm: &mut MetricMap) { let props = load_props(&testfile); debug!("loaded props"); match config.mode { - mode_compile_fail => run_cfail_test(&config, &props, &testfile), - mode_run_fail => run_rfail_test(&config, &props, &testfile), - mode_run_pass => run_rpass_test(&config, &props, &testfile), - mode_pretty => run_pretty_test(&config, &props, &testfile), - mode_debug_info => run_debuginfo_test(&config, &props, &testfile), - mode_codegen => run_codegen_test(&config, &props, &testfile, mm) + CompileFail => run_cfail_test(&config, &props, &testfile), + RunFail => run_rfail_test(&config, &props, &testfile), + RunPass => run_rpass_test(&config, &props, &testfile), + Pretty => run_pretty_test(&config, &props, &testfile), + DebugInfo => run_debuginfo_test(&config, &props, &testfile), + Codegen => run_codegen_test(&config, &props, &testfile, mm) } } -fn run_cfail_test(config: &config, props: &TestProps, testfile: &Path) { +fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) { let proc_res = compile_test(config, props, testfile); if proc_res.status.success() { @@ -92,7 +89,7 @@ fn run_cfail_test(config: &config, props: &TestProps, testfile: &Path) { } } -fn run_rfail_test(config: &config, props: &TestProps, testfile: &Path) { +fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) { let proc_res = if !config.jit { let proc_res = compile_test(config, props, testfile); @@ -125,7 +122,7 @@ fn check_correct_failure_status(proc_res: &ProcRes) { } } -fn run_rpass_test(config: &config, props: &TestProps, testfile: &Path) { +fn run_rpass_test(config: &Config, props: &TestProps, testfile: &Path) { if !config.jit { let mut proc_res = compile_test(config, props, testfile); @@ -145,7 +142,7 @@ fn run_rpass_test(config: &config, props: &TestProps, testfile: &Path) { } } -fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) { +fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { if props.pp_exact.is_some() { logv(config, ~"testing for exact pretty-printing"); } else { logv(config, ~"testing for converging pretty-printing"); } @@ -202,12 +199,12 @@ fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) { return; - fn print_source(config: &config, testfile: &Path, src: ~str) -> ProcRes { + fn print_source(config: &Config, testfile: &Path, src: ~str) -> ProcRes { compose_and_run(config, testfile, make_pp_args(config, testfile), Vec::new(), config.compile_lib_path, Some(src)) } - fn make_pp_args(config: &config, _testfile: &Path) -> ProcArgs { + fn make_pp_args(config: &Config, _testfile: &Path) -> ProcArgs { let args = vec!(~"-", ~"--pretty", ~"normal", ~"--target=" + config.target); // FIXME (#9639): This needs to handle non-utf8 paths @@ -232,13 +229,13 @@ actual:\n\ } } - fn typecheck_source(config: &config, props: &TestProps, + fn typecheck_source(config: &Config, props: &TestProps, testfile: &Path, src: ~str) -> ProcRes { let args = make_typecheck_args(config, props, testfile); compose_and_run_compiler(config, props, testfile, args, Some(src)) } - fn make_typecheck_args(config: &config, props: &TestProps, testfile: &Path) -> ProcArgs { + fn make_typecheck_args(config: &Config, props: &TestProps, testfile: &Path) -> ProcArgs { let aux_dir = aux_output_dir_name(config, testfile); let target = if props.force_host { config.host.as_slice() @@ -259,8 +256,8 @@ actual:\n\ } } -fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) { - let mut config = config { +fn run_debuginfo_test(config: &Config, props: &TestProps, testfile: &Path) { + let mut config = Config { target_rustcflags: cleanup_debug_info_options(&config.target_rustcflags), host_rustcflags: cleanup_debug_info_options(&config.host_rustcflags), .. config.clone() @@ -667,16 +664,16 @@ struct ProcArgs {prog: ~str, args: Vec<~str> } struct ProcRes {status: ProcessExit, stdout: ~str, stderr: ~str, cmdline: ~str} -fn compile_test(config: &config, props: &TestProps, +fn compile_test(config: &Config, props: &TestProps, testfile: &Path) -> ProcRes { compile_test_(config, props, testfile, []) } -fn jit_test(config: &config, props: &TestProps, testfile: &Path) -> ProcRes { +fn jit_test(config: &Config, props: &TestProps, testfile: &Path) -> ProcRes { compile_test_(config, props, testfile, [~"--jit"]) } -fn compile_test_(config: &config, props: &TestProps, +fn compile_test_(config: &Config, props: &TestProps, testfile: &Path, extra_args: &[~str]) -> ProcRes { let aux_dir = aux_output_dir_name(config, testfile); // FIXME (#9639): This needs to handle non-utf8 paths @@ -688,7 +685,7 @@ fn compile_test_(config: &config, props: &TestProps, compose_and_run_compiler(config, props, testfile, args, None) } -fn exec_compiled_test(config: &config, props: &TestProps, +fn exec_compiled_test(config: &Config, props: &TestProps, testfile: &Path) -> ProcRes { let env = props.exec_env.clone(); @@ -709,7 +706,7 @@ fn exec_compiled_test(config: &config, props: &TestProps, } fn compose_and_run_compiler( - config: &config, + config: &Config, props: &TestProps, testfile: &Path, args: ProcArgs, @@ -767,7 +764,7 @@ fn ensure_dir(path: &Path) { fs::mkdir(path, io::UserRWX).unwrap(); } -fn compose_and_run(config: &config, testfile: &Path, +fn compose_and_run(config: &Config, testfile: &Path, ProcArgs{ args, prog }: ProcArgs, procenv: Vec<(~str, ~str)> , lib_path: &str, @@ -781,10 +778,10 @@ enum TargetLocation { ThisDirectory(Path), } -fn make_compile_args(config: &config, +fn make_compile_args(config: &Config, props: &TestProps, extras: Vec<~str> , - xform: |&config, &Path| -> TargetLocation, + xform: |&Config, &Path| -> TargetLocation, testfile: &Path) -> ProcArgs { let xform_file = xform(config, testfile); @@ -816,14 +813,14 @@ fn make_compile_args(config: &config, return ProcArgs {prog: config.rustc_path.as_str().unwrap().to_owned(), args: args}; } -fn make_lib_name(config: &config, auxfile: &Path, testfile: &Path) -> Path { +fn make_lib_name(config: &Config, auxfile: &Path, testfile: &Path) -> Path { // what we return here is not particularly important, as it // happens; rustc ignores everything except for the directory. let auxname = output_testname(auxfile); aux_output_dir_name(config, testfile).join(&auxname) } -fn make_exe_name(config: &config, testfile: &Path) -> Path { +fn make_exe_name(config: &Config, testfile: &Path) -> Path { let mut f = output_base_name(config, testfile); if !os::consts::EXE_SUFFIX.is_empty() { match f.filename().map(|s| s + os::consts::EXE_SUFFIX.as_bytes()) { @@ -834,7 +831,7 @@ fn make_exe_name(config: &config, testfile: &Path) -> Path { f } -fn make_run_args(config: &config, _props: &TestProps, testfile: &Path) -> +fn make_run_args(config: &Config, _props: &TestProps, testfile: &Path) -> ProcArgs { // If we've got another tool to run under (valgrind), // then split apart its command @@ -857,7 +854,7 @@ fn split_maybe_args(argstr: &Option<~str>) -> Vec<~str> { } } -fn program_output(config: &config, testfile: &Path, lib_path: &str, prog: ~str, +fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: ~str, args: Vec<~str> , env: Vec<(~str, ~str)> , input: Option<~str>) -> ProcRes { let cmdline = @@ -897,23 +894,23 @@ fn lib_path_cmd_prefix(path: &str) -> ~str { format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path)) } -fn dump_output(config: &config, testfile: &Path, out: &str, err: &str) { +fn dump_output(config: &Config, testfile: &Path, out: &str, err: &str) { dump_output_file(config, testfile, out, "out"); dump_output_file(config, testfile, err, "err"); maybe_dump_to_stdout(config, out, err); } -fn dump_output_file(config: &config, testfile: &Path, +fn dump_output_file(config: &Config, testfile: &Path, out: &str, extension: &str) { let outfile = make_out_name(config, testfile, extension); File::create(&outfile).write(out.as_bytes()).unwrap(); } -fn make_out_name(config: &config, testfile: &Path, extension: &str) -> Path { +fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> Path { output_base_name(config, testfile).with_extension(extension) } -fn aux_output_dir_name(config: &config, testfile: &Path) -> Path { +fn aux_output_dir_name(config: &Config, testfile: &Path) -> Path { let mut f = output_base_name(config, testfile); match f.filename().map(|s| s + bytes!(".libaux")) { Some(v) => f.set_filename(v), @@ -926,13 +923,13 @@ fn output_testname(testfile: &Path) -> Path { Path::new(testfile.filestem().unwrap()) } -fn output_base_name(config: &config, testfile: &Path) -> Path { +fn output_base_name(config: &Config, testfile: &Path) -> Path { config.build_base .join(&output_testname(testfile)) .with_extension(config.stage_id.as_slice()) } -fn maybe_dump_to_stdout(config: &config, out: &str, err: &str) { +fn maybe_dump_to_stdout(config: &Config, out: &str, err: &str) { if config.verbose { println!("------{}------------------------------", "stdout"); println!("{}", out); @@ -963,7 +960,7 @@ stderr:\n\ fail!(); } -fn _arm_exec_compiled_test(config: &config, props: &TestProps, +fn _arm_exec_compiled_test(config: &Config, props: &TestProps, testfile: &Path, env: Vec<(~str, ~str)> ) -> ProcRes { let args = make_run_args(config, props, testfile); @@ -1063,7 +1060,7 @@ fn _arm_exec_compiled_test(config: &config, props: &TestProps, } } -fn _arm_push_aux_shared_library(config: &config, testfile: &Path) { +fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) { let tdir = aux_output_dir_name(config, testfile); let dirs = fs::readdir(&tdir).unwrap(); @@ -1086,7 +1083,7 @@ fn _arm_push_aux_shared_library(config: &config, testfile: &Path) { // codegen tests (vs. clang) -fn make_o_name(config: &config, testfile: &Path) -> Path { +fn make_o_name(config: &Config, testfile: &Path) -> Path { output_base_name(config, testfile).with_extension("o") } @@ -1099,7 +1096,7 @@ fn append_suffix_to_stem(p: &Path, suffix: &str) -> Path { } } -fn compile_test_and_save_bitcode(config: &config, props: &TestProps, +fn compile_test_and_save_bitcode(config: &Config, props: &TestProps, testfile: &Path) -> ProcRes { let aux_dir = aux_output_dir_name(config, testfile); // FIXME (#9639): This needs to handle non-utf8 paths @@ -1112,7 +1109,7 @@ fn compile_test_and_save_bitcode(config: &config, props: &TestProps, compose_and_run_compiler(config, props, testfile, args, None) } -fn compile_cc_with_clang_and_save_bitcode(config: &config, _props: &TestProps, +fn compile_cc_with_clang_and_save_bitcode(config: &Config, _props: &TestProps, testfile: &Path) -> ProcRes { let bitcodefile = output_base_name(config, testfile).with_extension("bc"); let bitcodefile = append_suffix_to_stem(&bitcodefile, "clang"); @@ -1128,7 +1125,7 @@ fn compile_cc_with_clang_and_save_bitcode(config: &config, _props: &TestProps, compose_and_run(config, testfile, proc_args, Vec::new(), "", None) } -fn extract_function_from_bitcode(config: &config, _props: &TestProps, +fn extract_function_from_bitcode(config: &Config, _props: &TestProps, fname: &str, testfile: &Path, suffix: &str) -> ProcRes { let bitcodefile = output_base_name(config, testfile).with_extension("bc"); @@ -1145,7 +1142,7 @@ fn extract_function_from_bitcode(config: &config, _props: &TestProps, compose_and_run(config, testfile, proc_args, Vec::new(), "", None) } -fn disassemble_extract(config: &config, _props: &TestProps, +fn disassemble_extract(config: &Config, _props: &TestProps, testfile: &Path, suffix: &str) -> ProcRes { let bitcodefile = output_base_name(config, testfile).with_extension("bc"); let bitcodefile = append_suffix_to_stem(&bitcodefile, suffix); @@ -1169,7 +1166,7 @@ fn count_extracted_lines(p: &Path) -> uint { } -fn run_codegen_test(config: &config, props: &TestProps, +fn run_codegen_test(config: &Config, props: &TestProps, testfile: &Path, mm: &mut MetricMap) { if config.llvm_bin_path.is_none() { diff --git a/src/compiletest/util.rs b/src/compiletest/util.rs index d127269ab41ba..6b804f329fc3c 100644 --- a/src/compiletest/util.rs +++ b/src/compiletest/util.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use common::config; +use common::Config; #[cfg(target_os = "win32")] use std::os::getenv; @@ -51,7 +51,7 @@ pub fn lib_path_env_var() -> ~str { ~"PATH" } #[cfg(target_os = "win32")] pub fn path_div() -> ~str { ~";" } -pub fn logv(config: &config, s: ~str) { +pub fn logv(config: &Config, s: ~str) { debug!("{}", s); if config.verbose { println!("{}", s); } } From b24e643853236abeb8158e1ff36a4233a14abfe2 Mon Sep 17 00:00:00 2001 From: klutzy Date: Wed, 16 Apr 2014 14:29:02 +0900 Subject: [PATCH 10/10] compiletest: Test `--pretty expanded` After testing `--pretty normal`, it tries to run `--pretty expanded` and typecheck output. Here we don't check convergence since it really diverges: for every iteration, some extra lines (e.g.`extern crate std`) are inserted. Some tests are `ignore-pretty`-ed since they cause various issues with `--pretty expanded`. --- src/compiletest/runtest.rs | 39 +++++++++++++++---- src/test/run-fail/run-unexported-tests.rs | 1 + src/test/run-fail/test-fail.rs | 1 + src/test/run-fail/test-tasks-invalid-value.rs | 1 + .../quote-unused-sp-no-warning.rs | 2 + src/test/run-pass/hygienic-labels-in-let.rs | 2 + src/test/run-pass/ifmt.rs | 1 + src/test/run-pass/shebang.rs | 2 +- src/test/run-pass/test-ignore-cfg.rs | 1 + src/test/run-pass/test-runner-hides-main.rs | 1 + 10 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 2b9c73e89a434..9d0898e16c323 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -157,9 +157,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { let mut round = 0; while round < rounds { logv(config, format!("pretty-printing round {}", round)); - let proc_res = print_source(config, - testfile, - (*srcs.get(round)).clone()); + let proc_res = print_source(config, props, testfile, (*srcs.get(round)).clone(), "normal"); if !proc_res.status.success() { fatal_ProcRes(format!("pretty-printing failed in round {}", round), @@ -197,16 +195,41 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) { fatal_ProcRes(~"pretty-printed source does not typecheck", &proc_res); } + // additionally, run `--pretty expanded` and try to build it. + let proc_res = print_source(config, props, testfile, (*srcs.get(round)).clone(), "expanded"); + if !proc_res.status.success() { + fatal_ProcRes(format!("pretty-printing (expanded) failed"), &proc_res); + } + + let ProcRes{ stdout: expanded_src, .. } = proc_res; + let proc_res = typecheck_source(config, props, testfile, expanded_src); + if !proc_res.status.success() { + fatal_ProcRes(format!("pretty-printed source (expanded) does not typecheck"), &proc_res); + } + return; - fn print_source(config: &Config, testfile: &Path, src: ~str) -> ProcRes { - compose_and_run(config, testfile, make_pp_args(config, testfile), + fn print_source(config: &Config, + props: &TestProps, + testfile: &Path, + src: ~str, + pretty_type: &str) -> ProcRes { + compose_and_run(config, testfile, + make_pp_args(config, props, testfile, pretty_type.to_owned()), Vec::new(), config.compile_lib_path, Some(src)) } - fn make_pp_args(config: &Config, _testfile: &Path) -> ProcArgs { - let args = vec!(~"-", ~"--pretty", ~"normal", - ~"--target=" + 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); + let mut args = vec!(~"-", ~"--pretty", pretty_type, + ~"--target=" + config.target, + ~"-L", + 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)); // FIXME (#9639): This needs to handle non-utf8 paths return ProcArgs {prog: config.rustc_path.as_str().unwrap().to_owned(), args: args}; } diff --git a/src/test/run-fail/run-unexported-tests.rs b/src/test/run-fail/run-unexported-tests.rs index b894127559161..70ef4a0c0c3d3 100644 --- a/src/test/run-fail/run-unexported-tests.rs +++ b/src/test/run-fail/run-unexported-tests.rs @@ -11,6 +11,7 @@ // error-pattern:runned an unexported test // compile-flags:--test // check-stdout +// ignore-pretty: does not work well with `--test` mod m { pub fn exported() { } diff --git a/src/test/run-fail/test-fail.rs b/src/test/run-fail/test-fail.rs index 77d87c22c6f1c..b628f101fd576 100644 --- a/src/test/run-fail/test-fail.rs +++ b/src/test/run-fail/test-fail.rs @@ -11,6 +11,7 @@ // check-stdout // error-pattern:task 'test_foo' failed at // compile-flags: --test +// ignore-pretty: does not work well with `--test` #[test] fn test_foo() { diff --git a/src/test/run-fail/test-tasks-invalid-value.rs b/src/test/run-fail/test-tasks-invalid-value.rs index 74531deb58ef6..8c9cd2d63cb47 100644 --- a/src/test/run-fail/test-tasks-invalid-value.rs +++ b/src/test/run-fail/test-tasks-invalid-value.rs @@ -14,6 +14,7 @@ // error-pattern:should be a positive integer // compile-flags: --test // exec-env:RUST_TEST_TASKS=foo +// ignore-pretty: does not work well with `--test` #[test] fn do_nothing() {} diff --git a/src/test/run-pass-fulldeps/quote-unused-sp-no-warning.rs b/src/test/run-pass-fulldeps/quote-unused-sp-no-warning.rs index 5025cc12b4a64..2d5bbd43e826f 100644 --- a/src/test/run-pass-fulldeps/quote-unused-sp-no-warning.rs +++ b/src/test/run-pass-fulldeps/quote-unused-sp-no-warning.rs @@ -9,6 +9,8 @@ // except according to those terms. // ignore-android +// ignore-pretty: does not work well with `--test` + #![feature(quote)] #![deny(unused_variable)] diff --git a/src/test/run-pass/hygienic-labels-in-let.rs b/src/test/run-pass/hygienic-labels-in-let.rs index 22523f5e6ccb7..ee90cfd3475b1 100644 --- a/src/test/run-pass/hygienic-labels-in-let.rs +++ b/src/test/run-pass/hygienic-labels-in-let.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-pretty: pprust doesn't print hygiene output + #![feature(macro_rules)] macro_rules! loop_x { diff --git a/src/test/run-pass/ifmt.rs b/src/test/run-pass/ifmt.rs index fbff321d5d366..d810dcc6d5441 100644 --- a/src/test/run-pass/ifmt.rs +++ b/src/test/run-pass/ifmt.rs @@ -8,6 +8,7 @@ // 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)] diff --git a/src/test/run-pass/shebang.rs b/src/test/run-pass/shebang.rs index b6451c5777266..2f78513b95cf9 100644 --- a/src/test/run-pass/shebang.rs +++ b/src/test/run-pass/shebang.rs @@ -9,6 +9,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// pp-exact +// ignore-pretty: `expand` addes some preludes before shebang pub fn main() { println!("Hello World"); } diff --git a/src/test/run-pass/test-ignore-cfg.rs b/src/test/run-pass/test-ignore-cfg.rs index 54546560c14ab..66c847dc50500 100644 --- a/src/test/run-pass/test-ignore-cfg.rs +++ b/src/test/run-pass/test-ignore-cfg.rs @@ -9,6 +9,7 @@ // except according to those terms. // compile-flags: --test --cfg ignorecfg +// ignore-pretty: does not work well with `--test` #[test] #[ignore(cfg(ignorecfg))] diff --git a/src/test/run-pass/test-runner-hides-main.rs b/src/test/run-pass/test-runner-hides-main.rs index 954d88c0bdc5e..05d5506f0a6b0 100644 --- a/src/test/run-pass/test-runner-hides-main.rs +++ b/src/test/run-pass/test-runner-hides-main.rs @@ -10,6 +10,7 @@ // compile-flags:--test // ignore-win32 #10872 +// ignore-pretty: does not work well with `--test` // Building as a test runner means that a synthetic main will be run, // not ours