From df9fed17ed93018165c7e8b626a3a312438396f2 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 20 Nov 2019 14:13:24 +0100 Subject: [PATCH] Update tidy check for error codes testing --- src/tools/tidy/src/error_codes_check.rs | 68 ++++++++++++++++++------- 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs index bd58de81c778a..5364005840aa1 100644 --- a/src/tools/tidy/src/error_codes_check.rs +++ b/src/tools/tidy/src/error_codes_check.rs @@ -3,6 +3,8 @@ use std::collections::HashMap; use std::ffi::OsStr; +use std::fs::read_to_string; +use std::io::Read; use std::path::Path; // A few of those error codes can't be tested but all the others can and *should* be tested! @@ -50,29 +52,60 @@ const WHITELIST: &[&str] = &[ "E0729", ]; -fn extract_error_codes(f: &str, error_codes: &mut HashMap) { +fn check_error_code_explanation( + f: &str, + error_codes: &mut HashMap, + err_code: String, +) { + for line in f.lines() { + let s = line.trim(); + if s.starts_with("```") && s.contains("compile_fail") && s.contains('E') { + error_codes.insert(err_code, true); + return; + } else if s.starts_with("#### Note: this error code is no longer emitted by the compiler") { + error_codes.get_mut(&err_code).map(|x| *x = true); + return; + } + } +} + +macro_rules! some_or_continue { + ($e:expr) => ( + match $e { + Some(e) => e, + None => continue, + } + ); +} + +fn extract_error_codes(f: &str, error_codes: &mut HashMap, path: &Path) { let mut reached_no_explanation = false; - let mut last_error_code = None; for line in f.lines() { let s = line.trim(); - if s.starts_with('E') && s.ends_with(": r##\"") { + if !reached_no_explanation && s.starts_with('E') && s.contains("include_str!(\"") { if let Some(err_code) = s.splitn(2, ':').next() { let err_code = err_code.to_owned(); - last_error_code = Some(err_code.clone()); if !error_codes.contains_key(&err_code) { - error_codes.insert(err_code, false); + error_codes.insert(err_code.clone(), false); } - } - } else if s.starts_with("```") && s.contains("compile_fail") && s.contains('E') { - if let Some(err_code) = s.splitn(2, 'E').skip(1).next() { - if let Some(err_code) = err_code.splitn(2, ',').next() { - let nb = error_codes.entry(format!("E{}", err_code)).or_insert(false); - *nb = true; + // Now we extract the tests from the markdown file! + let md = some_or_continue!(s.splitn(2, "include_str!(\"").skip(1).next()); + let md_file_name = some_or_continue!(md.splitn(2, "\")").next()); + let path = some_or_continue!(path.parent()).join(md_file_name); + match read_to_string(&path) { + Ok(content) => { + check_error_code_explanation( + &content, + error_codes, + err_code, + ); + } + Err(e) => { + eprintln!("Couldn't read `{}`: {}", path.display(), e); + } } } - } else if s == ";" { - reached_no_explanation = true; } else if reached_no_explanation && s.starts_with('E') { if let Some(err_code) = s.splitn(2, ',').next() { let err_code = err_code.to_owned(); @@ -80,11 +113,8 @@ fn extract_error_codes(f: &str, error_codes: &mut HashMap) { error_codes.insert(err_code, false); } } - } else if s.starts_with("#### Note: this error code is no longer emitted by the compiler") { - if let Some(last) = last_error_code { - error_codes.get_mut(&last).map(|x| *x = true); - } - last_error_code = None; + } else if s == ";" { + reached_no_explanation = true; } } } @@ -111,7 +141,7 @@ pub fn check(path: &Path, bad: &mut bool) { &mut |entry, contents| { let file_name = entry.file_name(); if file_name == "error_codes.rs" { - extract_error_codes(contents, &mut error_codes); + extract_error_codes(contents, &mut error_codes, entry.path()); } else if entry.path().extension() == Some(OsStr::new("stderr")) { extract_error_codes_from_tests(contents, &mut error_codes); }