Skip to content

Commit 562dc2a

Browse files
committed
---
yaml --- r: 272755 b: refs/heads/beta c: bb2a425 h: refs/heads/master i: 272753: ae95f32 272751: 90baa0e
1 parent 18173d0 commit 562dc2a

File tree

4 files changed

+89
-28
lines changed

4 files changed

+89
-28
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ refs/tags/0.9: 36870b185fc5f5486636d4515f0e22677493f225
2323
refs/tags/0.10: ac33f2b15782272ae348dbd7b14b8257b2148b5a
2424
refs/tags/0.11.0: e1247cb1d0d681be034adb4b558b5a0c0d5720f9
2525
refs/tags/0.12.0: f0c419429ef30723ceaf6b42f9b5a2aeb5d2e2d1
26-
refs/heads/beta: d78b4a93509174bed2080b627d74c956d2654366
26+
refs/heads/beta: bb2a425d5861297a9a5d08b8d5826b7703ecea04
2727
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
2828
refs/heads/tmp: e06d2ad9fcd5027bcaac5b08fc9aa39a49d0ecd3
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f

branches/beta/src/compiletest/errors.rs

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ enum WhichLine { ThisLine, FollowPrevious(usize), AdjustBackward(usize) }
3030
/// Goal is to enable tests both like: //~^^^ ERROR go up three
3131
/// and also //~^ ERROR message one for the preceding line, and
3232
/// //~| ERROR message two for that same line.
33-
// Load any test directives embedded in the file
34-
pub fn load_errors(testfile: &Path) -> Vec<ExpectedError> {
33+
///
34+
/// If cfg is not None (i.e., in an incremental test), then we look
35+
/// for `//[X]~` instead, where `X` is the current `cfg`.
36+
pub fn load_errors(testfile: &Path, cfg: &Option<String>) -> Vec<ExpectedError> {
3537
let rdr = BufReader::new(File::open(testfile).unwrap());
3638

3739
// `last_nonfollow_error` tracks the most recently seen
@@ -44,30 +46,41 @@ pub fn load_errors(testfile: &Path) -> Vec<ExpectedError> {
4446
// updating it in the map callback below.)
4547
let mut last_nonfollow_error = None;
4648

47-
rdr.lines().enumerate().filter_map(|(line_no, ln)| {
48-
parse_expected(last_nonfollow_error,
49-
line_no + 1,
50-
&ln.unwrap())
51-
.map(|(which, error)| {
52-
match which {
53-
FollowPrevious(_) => {}
54-
_ => last_nonfollow_error = Some(error.line),
55-
}
56-
error
57-
})
58-
}).collect()
49+
let tag = match *cfg {
50+
Some(ref rev) => format!("//[{}]~", rev),
51+
None => format!("//~")
52+
};
53+
54+
rdr.lines()
55+
.enumerate()
56+
.filter_map(|(line_no, ln)| {
57+
parse_expected(last_nonfollow_error,
58+
line_no + 1,
59+
&ln.unwrap(),
60+
&tag)
61+
.map(|(which, error)| {
62+
match which {
63+
FollowPrevious(_) => {}
64+
_ => last_nonfollow_error = Some(error.line),
65+
}
66+
error
67+
})
68+
})
69+
.collect()
5970
}
6071

6172
fn parse_expected(last_nonfollow_error: Option<usize>,
6273
line_num: usize,
63-
line: &str) -> Option<(WhichLine, ExpectedError)> {
64-
let start = match line.find("//~") { Some(i) => i, None => return None };
65-
let (follow, adjusts) = if line.char_at(start + 3) == '|' {
74+
line: &str,
75+
tag: &str)
76+
-> Option<(WhichLine, ExpectedError)> {
77+
let start = match line.find(tag) { Some(i) => i, None => return None };
78+
let (follow, adjusts) = if line.char_at(start + tag.len()) == '|' {
6679
(true, 0)
6780
} else {
68-
(false, line[start + 3..].chars().take_while(|c| *c == '^').count())
81+
(false, line[start + tag.len()..].chars().take_while(|c| *c == '^').count())
6982
};
70-
let kind_start = start + 3 + adjusts + (follow as usize);
83+
let kind_start = start + tag.len() + adjusts + (follow as usize);
7184
let letters = line[kind_start..].chars();
7285
let kind = letters.skip_while(|c| c.is_whitespace())
7386
.take_while(|c| !c.is_whitespace())
@@ -91,7 +104,9 @@ fn parse_expected(last_nonfollow_error: Option<usize>,
91104
(which, line)
92105
};
93106

94-
debug!("line={} which={:?} kind={:?} msg={:?}", line_num, which, kind, msg);
107+
debug!("line={} tag={:?} which={:?} kind={:?} msg={:?}",
108+
line_num, tag, which, kind, msg);
109+
95110
Some((which, ExpectedError { line: line,
96111
kind: kind,
97112
msg: msg, }))

branches/beta/src/compiletest/header.rs

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,18 @@ use common::Config;
1818
use common;
1919
use util;
2020

21+
#[derive(Clone, Debug)]
2122
pub struct TestProps {
23+
// For the main test file, this is initialized to `None`. But
24+
// when running tests that test multiple revisions, such as
25+
// incremental tests, we will set this to `Some(foo)` where `foo`
26+
// is the current revision identifier.
27+
//
28+
// Note that, unlike the other options here, this value is never
29+
// loaded from the input file (though it is always set to one of
30+
// the values listed in the vec `self.revisions`, which is loaded
31+
// from the file).
32+
pub revision: Option<String>,
2233
// Lines that should be expected, in order, on standard out
2334
pub error_patterns: Vec<String> ,
2435
// Extra flags to pass to the compiler
@@ -50,6 +61,8 @@ pub struct TestProps {
5061
pub pretty_compare_only: bool,
5162
// Patterns which must not appear in the output of a cfail test.
5263
pub forbid_output: Vec<String>,
64+
// Revisions to test for incremental compilation.
65+
pub revisions: Vec<String>,
5366
}
5467

5568
// Load any test directives embedded in the file
@@ -68,11 +81,13 @@ pub fn load_props(testfile: &Path) -> TestProps {
6881
let pretty_compare_only = false;
6982
let forbid_output = Vec::new();
7083
let mut props = TestProps {
84+
revision: None,
7185
error_patterns: error_patterns,
7286
compile_flags: vec![],
7387
run_flags: run_flags,
7488
pp_exact: pp_exact,
7589
aux_builds: aux_builds,
90+
revisions: vec![],
7691
exec_env: exec_env,
7792
check_lines: check_lines,
7893
build_aux_docs: build_aux_docs,
@@ -84,12 +99,16 @@ pub fn load_props(testfile: &Path) -> TestProps {
8499
pretty_compare_only: pretty_compare_only,
85100
forbid_output: forbid_output,
86101
};
87-
load_props_into(&mut props, testfile);
102+
load_props_into(&mut props, testfile, None);
88103
props
89104
}
90105

91-
pub fn load_props_into(props: &mut TestProps, testfile: &Path) {
92-
iter_header(testfile, &mut |ln| {
106+
/// Load properties from `testfile` into `props`. If a property is
107+
/// tied to a particular revision `foo` (indicated by writing
108+
/// `//[foo]`), then the property is ignored unless `cfg` is
109+
/// `Some("foo")`.
110+
pub fn load_props_into(props: &mut TestProps, testfile: &Path, cfg: Option<&str>) {
111+
iter_header(testfile, cfg, &mut |ln| {
93112
if let Some(ep) = parse_error_pattern(ln) {
94113
props.error_patterns.push(ep);
95114
}
@@ -101,6 +120,10 @@ pub fn load_props_into(props: &mut TestProps, testfile: &Path) {
101120
.map(|s| s.to_owned()));
102121
}
103122

123+
if let Some(r) = parse_revisions(ln) {
124+
props.revisions.extend(r);
125+
}
126+
104127
if props.run_flags.is_none() {
105128
props.run_flags = parse_run_flags(ln);
106129
}
@@ -235,7 +258,7 @@ pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool {
235258
}
236259
}
237260

238-
let val = iter_header(testfile, &mut |ln| {
261+
let val = iter_header(testfile, None, &mut |ln| {
239262
!parse_name_directive(ln, "ignore-test") &&
240263
!parse_name_directive(ln, &ignore_target(config)) &&
241264
!parse_name_directive(ln, &ignore_architecture(config)) &&
@@ -250,7 +273,10 @@ pub fn is_test_ignored(config: &Config, testfile: &Path) -> bool {
250273
!val
251274
}
252275

253-
fn iter_header(testfile: &Path, it: &mut FnMut(&str) -> bool) -> bool {
276+
fn iter_header(testfile: &Path,
277+
cfg: Option<&str>,
278+
it: &mut FnMut(&str) -> bool)
279+
-> bool {
254280
let rdr = BufReader::new(File::open(testfile).unwrap());
255281
for ln in rdr.lines() {
256282
// Assume that any directives will be found before the first
@@ -260,6 +286,21 @@ fn iter_header(testfile: &Path, it: &mut FnMut(&str) -> bool) -> bool {
260286
let ln = ln.trim();
261287
if ln.starts_with("fn") || ln.starts_with("mod") {
262288
return true;
289+
} else if ln.starts_with("//[") {
290+
// A comment like `//[foo]` is specific to revision `foo`
291+
if let Some(close_brace) = ln.find("]") {
292+
let lncfg = &ln[3..close_brace];
293+
let matches = match cfg {
294+
Some(s) => s == &lncfg[..],
295+
None => false,
296+
};
297+
if matches && !it(&ln[close_brace+1..]) {
298+
return false;
299+
}
300+
} else {
301+
panic!("malformed condition directive: expected `//[foo]`, found `{}`",
302+
ln)
303+
}
263304
} else if ln.starts_with("//") {
264305
if !it(&ln[2..]) {
265306
return false;
@@ -285,6 +326,11 @@ fn parse_compile_flags(line: &str) -> Option<String> {
285326
parse_name_value_directive(line, "compile-flags")
286327
}
287328

329+
fn parse_revisions(line: &str) -> Option<Vec<String>> {
330+
parse_name_value_directive(line, "revisions")
331+
.map(|r| r.split_whitespace().map(|t| t.to_string()).collect())
332+
}
333+
288334
fn parse_run_flags(line: &str) -> Option<String> {
289335
parse_name_value_directive(line, "run-flags")
290336
}

branches/beta/src/compiletest/runtest.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ fn run_cfail_test(config: &Config, props: &TestProps, testpaths: &TestPaths) {
8585
}
8686

8787
let output_to_check = get_output(props, &proc_res);
88-
let expected_errors = errors::load_errors(&testpaths.file);
88+
let expected_errors = errors::load_errors(&testpaths.file, &props.revision);
8989
if !expected_errors.is_empty() {
9090
if !props.error_patterns.is_empty() {
9191
fatal("both error pattern and expected errors specified");
@@ -1821,7 +1821,7 @@ fn run_codegen_units_test(config: &Config, props: &TestProps, testpaths: &TestPa
18211821
.map(|s| (&s[prefix.len()..]).to_string())
18221822
.collect();
18231823

1824-
let expected: HashSet<String> = errors::load_errors(&testpaths.file)
1824+
let expected: HashSet<String> = errors::load_errors(&testpaths.file, &props.revision)
18251825
.iter()
18261826
.map(|e| e.msg.trim().to_string())
18271827
.collect();

0 commit comments

Comments
 (0)