diff options
| author | bors <bors@rust-lang.org> | 2019-11-22 04:06:52 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-11-22 04:06:52 +0000 |
| commit | bd816fd76f4f7a040ca7ac8ca5bc556d761f96fa (patch) | |
| tree | 0bfe068351cf25b176f2d8ab16c43ae33eb69f68 /src | |
| parent | abd69551bf8b8755b5e00d4f4d45ae5d4a0cd17d (diff) | |
| parent | c537f229009bcec23ac89132fd6f571acbc23c38 (diff) | |
| download | rust-bd816fd76f4f7a040ca7ac8ca5bc556d761f96fa.tar.gz rust-bd816fd76f4f7a040ca7ac8ca5bc556d761f96fa.zip | |
Auto merge of #66524 - ecstatic-morse:compiletest-multiple-revisions, r=Centril
Support multiple revisions in `compiletest` The `//[X]~` syntax filters errors for tests that are run across multiple cfgs with `// revisions:`. This commit extends that syntax to accept `//[X,Y]~`, which will match multiple cfgs to the same error annotation. This is functionally the same as writing two comments, `//[X]~` and `//[Y]~`, but can fit on a single line. While refactoring `compiletest` to support this, I also uncovered a small bug that was causing an incremental test to always pass, despite no errors being emitted. r? @Centril
Diffstat (limited to 'src')
7 files changed, 55 insertions, 61 deletions
diff --git a/src/test/incremental/warnings-reemitted.rs b/src/test/incremental/warnings-reemitted.rs index a1d11f8aa5b..5fc89395827 100644 --- a/src/test/incremental/warnings-reemitted.rs +++ b/src/test/incremental/warnings-reemitted.rs @@ -2,9 +2,8 @@ // compile-flags: -Coverflow-checks=on // build-pass (FIXME(62277): could be check-pass?) -#![allow(warnings)] #![warn(const_err)] fn main() { - 255u8 + 1; //~ WARNING this expression will panic at run-time + let _ = 255u8 + 1; //~ WARNING attempt to add with overflow } diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs index ebf52918153..8c6073e2f7a 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs +++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs @@ -47,6 +47,4 @@ fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) { } #[rustc_error] -fn main() { } -//[ok]~^ ERROR fatal error triggered by #[rustc_error] -//[oneuse]~^^ ERROR fatal error triggered by #[rustc_error] +fn main() { } //[ok,oneuse]~ ERROR fatal error triggered by #[rustc_error] diff --git a/src/test/ui/error-codes/E0161.rs b/src/test/ui/error-codes/E0161.rs index 2ca17050ae2..58217ff74b8 100644 --- a/src/test/ui/error-codes/E0161.rs +++ b/src/test/ui/error-codes/E0161.rs @@ -20,14 +20,8 @@ fn foo(x: Box<[i32]>) { box *x; - //[migrate]~^ ERROR E0161 - //[nll]~^^ ERROR E0161 - //[zflags]~^^^ ERROR E0161 - //[edition]~^^^^ ERROR E0161 - //[migrateul]~^^^^^ ERROR E0161 - //[nllul]~^^^^^^ ERROR E0161 - //[zflagsul]~^^^^^^^ ERROR E0161 - //[editionul]~^^^^^^^^ ERROR E0161 + //[migrate,nll,zflags,edition]~^ ERROR E0161 + //[migrateul,nllul,zflagsul,editionul]~^^ ERROR E0161 } fn main() {} diff --git a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rs b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rs index b50cce335bd..38189816da8 100644 --- a/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rs +++ b/src/test/ui/underscore-lifetime/where-clause-inherent-impl-underscore.rs @@ -11,8 +11,7 @@ struct Foo<T> { impl<T> Foo<T> where T: WithRegion<'_> -//[rust2015]~^ ERROR `'_` cannot be used here -//[rust2018]~^^ ERROR `'_` cannot be used here +//[rust2015,rust2018]~^ ERROR `'_` cannot be used here { } fn main() {} diff --git a/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rs b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rs index f2d483e66e0..09e5bbd846d 100644 --- a/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rs +++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-region.rs @@ -9,8 +9,7 @@ trait Foo { } impl<T> Foo for Vec<T> where T: WithType<&u32> -//[rust2015]~^ ERROR `&` without an explicit lifetime name cannot be used here -//[rust2018]~^^ ERROR `&` without an explicit lifetime name cannot be used here +//[rust2015,rust2018]~^ ERROR `&` without an explicit lifetime name cannot be used here { } fn main() {} diff --git a/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rs b/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rs index 94e4426e822..371d2e4ba43 100644 --- a/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rs +++ b/src/test/ui/underscore-lifetime/where-clause-trait-impl-underscore.rs @@ -9,8 +9,7 @@ trait Foo { } impl<T> Foo for Vec<T> where T: WithRegion<'_> -//[rust2015]~^ ERROR `'_` cannot be used here -//[rust2018]~^^ ERROR `'_` cannot be used here +//[rust2015,rust2018]~^ ERROR `'_` cannot be used here { } fn main() {} diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs index 5b3936ffc1e..0ec2738181e 100644 --- a/src/tools/compiletest/src/errors.rs +++ b/src/tools/compiletest/src/errors.rs @@ -7,7 +7,9 @@ use std::io::BufReader; use std::path::Path; use std::str::FromStr; +use lazy_static::lazy_static; use log::*; +use regex::Regex; #[derive(Clone, Debug, PartialEq)] pub enum ErrorKind { @@ -85,20 +87,16 @@ pub fn load_errors(testfile: &Path, cfg: Option<&str>) -> Vec<Error> { // updating it in the map callback below.) let mut last_nonfollow_error = None; - let tag = match cfg { - Some(rev) => format!("//[{}]~", rev), - None => "//~".to_string(), - }; - rdr.lines() .enumerate() .filter_map(|(line_num, line)| { - parse_expected(last_nonfollow_error, line_num + 1, &line.unwrap(), &tag).map( + parse_expected(last_nonfollow_error, line_num + 1, &line.unwrap(), cfg).map( |(which, error)| { match which { FollowPrevious(_) => {} _ => last_nonfollow_error = Some(error.line_num), } + error }, ) @@ -110,46 +108,54 @@ fn parse_expected( last_nonfollow_error: Option<usize>, line_num: usize, line: &str, - tag: &str, + cfg: Option<&str>, ) -> Option<(WhichLine, Error)> { - let start = line.find(tag)?; - let (follow, adjusts) = if line[start + tag.len()..].chars().next().unwrap() == '|' { - (true, 0) - } else { - ( - false, - line[start + tag.len()..] - .chars() - .take_while(|c| *c == '^') - .count(), - ) + // Matches comments like: + // //~ + // //~| + // //~^ + // //~^^^^^ + // //[cfg1]~ + // //[cfg1,cfg2]~^^ + lazy_static! { + static ref RE: Regex = + Regex::new(r"//(?:\[(?P<cfgs>[\w,]+)])?~(?P<adjust>\||\^*)").unwrap(); + } + + let captures = RE.captures(line)?; + + match (cfg, captures.name("cfgs")) { + // Only error messages that contain our `cfg` betweeen the square brackets apply to us. + (Some(cfg), Some(filter)) if !filter.as_str().split(',').any(|s| s == cfg) + => return None, + (Some(_), Some(_)) => {} + + (None, Some(_)) => panic!("Only tests with revisions should use `//[X]~`"), + + // If an error has no list of revisions, it applies to all revisions. + (Some(_), None) | (None, None) => {} + } + + let (follow, adjusts) = match &captures["adjust"] { + "|" => (true, 0), + circumflexes => (false, circumflexes.len()), }; - let kind_start = start + tag.len() + adjusts + (follow as usize); - let (kind, msg); - match line[kind_start..] + + // Get the part of the comment after the sigil (e.g. `~^^` or ~|). + let whole_match = captures.get(0).unwrap(); + let (_, mut msg) = line.split_at(whole_match.end()); + + let first_word = msg .split_whitespace() .next() - .expect("Encountered unexpected empty comment") - .parse::<ErrorKind>() - { - Ok(k) => { - // If we find `//~ ERROR foo` or something like that: - kind = Some(k); - let letters = line[kind_start..].chars(); - msg = letters - .skip_while(|c| c.is_whitespace()) - .skip_while(|c| !c.is_whitespace()) - .collect::<String>(); - } - Err(_) => { - // Otherwise we found `//~ foo`: - kind = None; - let letters = line[kind_start..].chars(); - msg = letters - .skip_while(|c| c.is_whitespace()) - .collect::<String>(); - } + .expect("Encountered unexpected empty comment"); + + // If we find `//~ ERROR foo` or something like that, skip the first word. + let kind = first_word.parse::<ErrorKind>().ok(); + if let Some(_) = kind { + msg = &msg.trim_start().split_at(first_word.len()).1; } + let msg = msg.trim().to_owned(); let (which, line_num) = if follow { @@ -171,7 +177,7 @@ fn parse_expected( debug!( "line={} tag={:?} which={:?} kind={:?} msg={:?}", - line_num, tag, which, kind, msg + line_num, whole_match.as_str(), which, kind, msg ); Some(( which, |
