diff options
| author | bors <bors@rust-lang.org> | 2014-09-20 04:55:41 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-09-20 04:55:41 +0000 |
| commit | f7fb0f5a172bcde42293bf64ffafd1e5df4bd0f8 (patch) | |
| tree | 6f9513f09a30e3aae088a378d86a2c842ce8dd1e /src | |
| parent | aef6c4b1382dcf2f943bd5872656625f935c0b7c (diff) | |
| parent | 5b42f79ff088bf3f9136f6f668a481097e22bed9 (diff) | |
| download | rust-f7fb0f5a172bcde42293bf64ffafd1e5df4bd0f8.tar.gz rust-f7fb0f5a172bcde42293bf64ffafd1e5df4bd0f8.zip | |
auto merge of #17319 : kmcallister/rust/method-macro-bt, r=pcwalton
We were leaving these on the stack, causing spurious backtraces.
Diffstat (limited to 'src')
| -rw-r--r-- | src/compiletest/header.rs | 15 | ||||
| -rw-r--r-- | src/compiletest/runtest.rs | 40 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 5 | ||||
| -rw-r--r-- | src/test/compile-fail/method-macro-backtrace.rs | 37 |
4 files changed, 83 insertions, 14 deletions
diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index 9ad2582dec8..cc765695cb7 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -42,6 +42,8 @@ pub struct TestProps { pub pretty_mode: String, // Only compare pretty output and don't try compiling pub pretty_compare_only: bool, + // Patterns which must not appear in the output of a cfail test. + pub forbid_output: Vec<String>, } // Load any test directives embedded in the file @@ -59,6 +61,7 @@ pub fn load_props(testfile: &Path) -> TestProps { let mut no_pretty_expanded = false; let mut pretty_mode = None; let mut pretty_compare_only = false; + let mut forbid_output = Vec::new(); iter_header(testfile, |ln| { match parse_error_pattern(ln) { Some(ep) => error_patterns.push(ep), @@ -116,6 +119,11 @@ pub fn load_props(testfile: &Path) -> TestProps { None => () }; + match parse_forbid_output(ln) { + Some(of) => forbid_output.push(of), + None => (), + } + true }); @@ -132,7 +140,8 @@ pub fn load_props(testfile: &Path) -> TestProps { no_prefer_dynamic: no_prefer_dynamic, no_pretty_expanded: no_pretty_expanded, pretty_mode: pretty_mode.unwrap_or("normal".to_string()), - pretty_compare_only: pretty_compare_only + pretty_compare_only: pretty_compare_only, + forbid_output: forbid_output, } } @@ -210,6 +219,10 @@ fn parse_error_pattern(line: &str) -> Option<String> { parse_name_value_directive(line, "error-pattern") } +fn parse_forbid_output(line: &str) -> Option<String> { + parse_name_value_directive(line, "forbid-output") +} + fn parse_aux_build(line: &str) -> Option<String> { parse_name_value_directive(line, "aux-build") } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 40acb7da175..d64d3317e2e 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -71,6 +71,14 @@ pub fn run_metrics(config: Config, testfile: String, mm: &mut MetricMap) { } } +fn get_output(props: &TestProps, proc_res: &ProcRes) -> String { + if props.check_stdout { + format!("{}{}", proc_res.stdout, proc_res.stderr) + } else { + proc_res.stderr.clone() + } +} + fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) { let proc_res = compile_test(config, props, testfile); @@ -81,6 +89,11 @@ fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) { check_correct_failure_status(&proc_res); + if proc_res.status.success() { + fatal("process did not return an error status"); + } + + let output_to_check = get_output(props, &proc_res); let expected_errors = errors::load_errors(&config.cfail_regex, testfile); if !expected_errors.is_empty() { if !props.error_patterns.is_empty() { @@ -88,9 +101,10 @@ fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) { } check_expected_errors(expected_errors, testfile, &proc_res); } else { - check_error_patterns(props, testfile, &proc_res); + check_error_patterns(props, testfile, output_to_check.as_slice(), &proc_res); } check_no_compiler_crash(&proc_res); + check_forbid_output(props, output_to_check.as_slice(), &proc_res); } fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) { @@ -112,8 +126,9 @@ fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) { fatal_proc_rec("run-fail test isn't valgrind-clean!", &proc_res); } + let output_to_check = get_output(props, &proc_res); check_correct_failure_status(&proc_res); - check_error_patterns(props, testfile, &proc_res); + check_error_patterns(props, testfile, output_to_check.as_slice(), &proc_res); } fn check_correct_failure_status(proc_res: &ProcRes) { @@ -834,24 +849,15 @@ fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[String]) fn check_error_patterns(props: &TestProps, testfile: &Path, + output_to_check: &str, proc_res: &ProcRes) { if props.error_patterns.is_empty() { fatal(format!("no error pattern specified in {}", testfile.display()).as_slice()); } - - if proc_res.status.success() { - fatal("process did not return an error status"); - } - let mut next_err_idx = 0u; let mut next_err_pat = &props.error_patterns[next_err_idx]; let mut done = false; - let output_to_check = if props.check_stdout { - format!("{}{}", proc_res.stdout, proc_res.stderr) - } else { - proc_res.stderr.clone() - }; for line in output_to_check.as_slice().lines() { if line.contains(next_err_pat.as_slice()) { debug!("found error pattern {}", next_err_pat); @@ -890,6 +896,16 @@ fn check_no_compiler_crash(proc_res: &ProcRes) { } } +fn check_forbid_output(props: &TestProps, + output_to_check: &str, + proc_res: &ProcRes) { + for pat in props.forbid_output.iter() { + if output_to_check.contains(pat.as_slice()) { + fatal_proc_rec("forbidden pattern found in compiler output", proc_res); + } + } +} + fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> , testfile: &Path, proc_res: &ProcRes) { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index e173b93e468..70cf41d5e17 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -895,7 +895,10 @@ fn expand_method(m: P<ast::Method>, fld: &mut MacroExpander) -> SmallVector<P<as }; // expand again if necessary - new_methods.into_iter().flat_map(|m| fld.fold_method(m).into_iter()).collect() + let new_methods = new_methods.move_iter() + .flat_map(|m| fld.fold_method(m).into_iter()).collect(); + fld.cx.bt_pop(); + new_methods } }) } diff --git a/src/test/compile-fail/method-macro-backtrace.rs b/src/test/compile-fail/method-macro-backtrace.rs new file mode 100644 index 00000000000..dc41e2e02a8 --- /dev/null +++ b/src/test/compile-fail/method-macro-backtrace.rs @@ -0,0 +1,37 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// forbid-output: in expansion of + +#![feature(macro_rules)] + +macro_rules! make_method ( ($name:ident) => ( + fn $name(&self) { } +)) + +struct S; + +impl S { + // We had a bug where these wouldn't clean up macro backtrace frames. + make_method!(foo1) + make_method!(foo2) + make_method!(foo3) + make_method!(foo4) + make_method!(foo5) + make_method!(foo6) + make_method!(foo7) + make_method!(foo8) + + // Cause an error. It shouldn't have any macro backtrace frames. + fn bar(&self) { } + fn bar(&self) { } //~ ERROR duplicate definition +} + +fn main() { } |
