diff --git a/src/test/incremental/warnings-reemitted.rs b/src/test/incremental/warnings-reemitted.rs index a1d11f8aa5bbe..5fc89395827c8 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 ebf52918153c1..8c6073e2f7a49 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 2ca17050ae2a4..58217ff74b8d6 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 b50cce335bd8c..38189816da849 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 { impl Foo 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 f2d483e66e013..09e5bbd846d6c 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 Foo for Vec 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 94e4426e822d9..371d2e4ba43ac 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 Foo for Vec 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 5b3936ffc1e3b..0ec2738181ee2 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 { // 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, 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[\w,]+)])?~(?P\||\^*)").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::() - { - 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::(); - } - Err(_) => { - // Otherwise we found `//~ foo`: - kind = None; - let letters = line[kind_start..].chars(); - msg = letters - .skip_while(|c| c.is_whitespace()) - .collect::(); - } + .expect("Encountered unexpected empty comment"); + + // If we find `//~ ERROR foo` or something like that, skip the first word. + let kind = first_word.parse::().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,