auto merge of #17319 : kmcallister/rust/method-macro-bt, r=pcwalton
We were leaving these on the stack, causing spurious backtraces.
This commit is contained in:
commit
f7fb0f5a17
@ -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")
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
}
|
||||
})
|
||||
}
|
||||
|
37
src/test/compile-fail/method-macro-backtrace.rs
Normal file
37
src/test/compile-fail/method-macro-backtrace.rs
Normal file
@ -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() { }
|
Loading…
Reference in New Issue
Block a user