Skip to content

Commit f7fb0f5

Browse files
committed
auto merge of #17319 : kmcallister/rust/method-macro-bt, r=pcwalton
We were leaving these on the stack, causing spurious backtraces.
2 parents aef6c4b + 5b42f79 commit f7fb0f5

File tree

4 files changed

+83
-14
lines changed

4 files changed

+83
-14
lines changed

src/compiletest/header.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ pub struct TestProps {
4242
pub pretty_mode: String,
4343
// Only compare pretty output and don't try compiling
4444
pub pretty_compare_only: bool,
45+
// Patterns which must not appear in the output of a cfail test.
46+
pub forbid_output: Vec<String>,
4547
}
4648

4749
// Load any test directives embedded in the file
@@ -59,6 +61,7 @@ pub fn load_props(testfile: &Path) -> TestProps {
5961
let mut no_pretty_expanded = false;
6062
let mut pretty_mode = None;
6163
let mut pretty_compare_only = false;
64+
let mut forbid_output = Vec::new();
6265
iter_header(testfile, |ln| {
6366
match parse_error_pattern(ln) {
6467
Some(ep) => error_patterns.push(ep),
@@ -116,6 +119,11 @@ pub fn load_props(testfile: &Path) -> TestProps {
116119
None => ()
117120
};
118121

122+
match parse_forbid_output(ln) {
123+
Some(of) => forbid_output.push(of),
124+
None => (),
125+
}
126+
119127
true
120128
});
121129

@@ -132,7 +140,8 @@ pub fn load_props(testfile: &Path) -> TestProps {
132140
no_prefer_dynamic: no_prefer_dynamic,
133141
no_pretty_expanded: no_pretty_expanded,
134142
pretty_mode: pretty_mode.unwrap_or("normal".to_string()),
135-
pretty_compare_only: pretty_compare_only
143+
pretty_compare_only: pretty_compare_only,
144+
forbid_output: forbid_output,
136145
}
137146
}
138147

@@ -210,6 +219,10 @@ fn parse_error_pattern(line: &str) -> Option<String> {
210219
parse_name_value_directive(line, "error-pattern")
211220
}
212221

222+
fn parse_forbid_output(line: &str) -> Option<String> {
223+
parse_name_value_directive(line, "forbid-output")
224+
}
225+
213226
fn parse_aux_build(line: &str) -> Option<String> {
214227
parse_name_value_directive(line, "aux-build")
215228
}

src/compiletest/runtest.rs

+28-12
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ pub fn run_metrics(config: Config, testfile: String, mm: &mut MetricMap) {
7171
}
7272
}
7373

74+
fn get_output(props: &TestProps, proc_res: &ProcRes) -> String {
75+
if props.check_stdout {
76+
format!("{}{}", proc_res.stdout, proc_res.stderr)
77+
} else {
78+
proc_res.stderr.clone()
79+
}
80+
}
81+
7482
fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) {
7583
let proc_res = compile_test(config, props, testfile);
7684

@@ -81,16 +89,22 @@ fn run_cfail_test(config: &Config, props: &TestProps, testfile: &Path) {
8189

8290
check_correct_failure_status(&proc_res);
8391

92+
if proc_res.status.success() {
93+
fatal("process did not return an error status");
94+
}
95+
96+
let output_to_check = get_output(props, &proc_res);
8497
let expected_errors = errors::load_errors(&config.cfail_regex, testfile);
8598
if !expected_errors.is_empty() {
8699
if !props.error_patterns.is_empty() {
87100
fatal("both error pattern and expected errors specified");
88101
}
89102
check_expected_errors(expected_errors, testfile, &proc_res);
90103
} else {
91-
check_error_patterns(props, testfile, &proc_res);
104+
check_error_patterns(props, testfile, output_to_check.as_slice(), &proc_res);
92105
}
93106
check_no_compiler_crash(&proc_res);
107+
check_forbid_output(props, output_to_check.as_slice(), &proc_res);
94108
}
95109

96110
fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) {
@@ -112,8 +126,9 @@ fn run_rfail_test(config: &Config, props: &TestProps, testfile: &Path) {
112126
fatal_proc_rec("run-fail test isn't valgrind-clean!", &proc_res);
113127
}
114128

129+
let output_to_check = get_output(props, &proc_res);
115130
check_correct_failure_status(&proc_res);
116-
check_error_patterns(props, testfile, &proc_res);
131+
check_error_patterns(props, testfile, output_to_check.as_slice(), &proc_res);
117132
}
118133

119134
fn check_correct_failure_status(proc_res: &ProcRes) {
@@ -834,24 +849,15 @@ fn check_debugger_output(debugger_run_result: &ProcRes, check_lines: &[String])
834849

835850
fn check_error_patterns(props: &TestProps,
836851
testfile: &Path,
852+
output_to_check: &str,
837853
proc_res: &ProcRes) {
838854
if props.error_patterns.is_empty() {
839855
fatal(format!("no error pattern specified in {}",
840856
testfile.display()).as_slice());
841857
}
842-
843-
if proc_res.status.success() {
844-
fatal("process did not return an error status");
845-
}
846-
847858
let mut next_err_idx = 0u;
848859
let mut next_err_pat = &props.error_patterns[next_err_idx];
849860
let mut done = false;
850-
let output_to_check = if props.check_stdout {
851-
format!("{}{}", proc_res.stdout, proc_res.stderr)
852-
} else {
853-
proc_res.stderr.clone()
854-
};
855861
for line in output_to_check.as_slice().lines() {
856862
if line.contains(next_err_pat.as_slice()) {
857863
debug!("found error pattern {}", next_err_pat);
@@ -890,6 +896,16 @@ fn check_no_compiler_crash(proc_res: &ProcRes) {
890896
}
891897
}
892898

899+
fn check_forbid_output(props: &TestProps,
900+
output_to_check: &str,
901+
proc_res: &ProcRes) {
902+
for pat in props.forbid_output.iter() {
903+
if output_to_check.contains(pat.as_slice()) {
904+
fatal_proc_rec("forbidden pattern found in compiler output", proc_res);
905+
}
906+
}
907+
}
908+
893909
fn check_expected_errors(expected_errors: Vec<errors::ExpectedError> ,
894910
testfile: &Path,
895911
proc_res: &ProcRes) {

src/libsyntax/ext/expand.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,10 @@ fn expand_method(m: P<ast::Method>, fld: &mut MacroExpander) -> SmallVector<P<as
895895
};
896896

897897
// expand again if necessary
898-
new_methods.into_iter().flat_map(|m| fld.fold_method(m).into_iter()).collect()
898+
let new_methods = new_methods.move_iter()
899+
.flat_map(|m| fld.fold_method(m).into_iter()).collect();
900+
fld.cx.bt_pop();
901+
new_methods
899902
}
900903
})
901904
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// forbid-output: in expansion of
12+
13+
#![feature(macro_rules)]
14+
15+
macro_rules! make_method ( ($name:ident) => (
16+
fn $name(&self) { }
17+
))
18+
19+
struct S;
20+
21+
impl S {
22+
// We had a bug where these wouldn't clean up macro backtrace frames.
23+
make_method!(foo1)
24+
make_method!(foo2)
25+
make_method!(foo3)
26+
make_method!(foo4)
27+
make_method!(foo5)
28+
make_method!(foo6)
29+
make_method!(foo7)
30+
make_method!(foo8)
31+
32+
// Cause an error. It shouldn't have any macro backtrace frames.
33+
fn bar(&self) { }
34+
fn bar(&self) { } //~ ERROR duplicate definition
35+
}
36+
37+
fn main() { }

0 commit comments

Comments
 (0)