diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2025-04-07 17:28:58 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2025-04-09 09:51:39 +0300 |
| commit | cffc5c21fc49e86859ea5601a4f80d4446b594e9 (patch) | |
| tree | 4933ae2a4ae569d463959100c0aeddcc138439dc /src/tools/compiletest | |
| parent | c1b8b7e86f6ca59929ce08471d0877f748f84901 (diff) | |
| download | rust-cffc5c21fc49e86859ea5601a4f80d4446b594e9.tar.gz rust-cffc5c21fc49e86859ea5601a4f80d4446b594e9.zip | |
compiletest: Add directive `dont-require-annotations`
for making matching on specific diagnostic kinds non-exhaustive
Diffstat (limited to 'src/tools/compiletest')
| -rw-r--r-- | src/tools/compiletest/src/directive-list.rs | 1 | ||||
| -rw-r--r-- | src/tools/compiletest/src/errors.rs | 11 | ||||
| -rw-r--r-- | src/tools/compiletest/src/header.rs | 20 | ||||
| -rw-r--r-- | src/tools/compiletest/src/runtest.rs | 24 |
4 files changed, 41 insertions, 15 deletions
diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index b2ad5a3b3d0..44d9c0330f7 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -22,6 +22,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "dont-check-compiler-stderr", "dont-check-compiler-stdout", "dont-check-failure-status", + "dont-require-annotations", "edition", "error-pattern", "exact-llvm-major-version", diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs index 9b59e4968a3..64d68eb7f23 100644 --- a/src/tools/compiletest/src/errors.rs +++ b/src/tools/compiletest/src/errors.rs @@ -8,7 +8,7 @@ use std::sync::OnceLock; use regex::Regex; use tracing::*; -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum ErrorKind { Help, Error, @@ -40,6 +40,15 @@ impl ErrorKind { _ => return None, }) } + + pub fn expect_from_user_str(s: &str) -> ErrorKind { + ErrorKind::from_user_str(s).unwrap_or_else(|| { + panic!( + "unexpected diagnostic kind `{s}`, expected \ + `ERROR`, `WARN`, `NOTE`, `HELP` or `SUGGESTION`" + ) + }) + } } impl fmt::Display for ErrorKind { diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index a0178f4bcc5..36a9e5df583 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -1,4 +1,4 @@ -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use std::env; use std::fs::File; use std::io::BufReader; @@ -11,6 +11,7 @@ use tracing::*; use crate::common::{Config, Debugger, FailMode, Mode, PassMode}; use crate::debuggers::{extract_cdb_version, extract_gdb_version}; +use crate::errors::ErrorKind; use crate::executor::{CollectedTestDesc, ShouldPanic}; use crate::header::auxiliary::{AuxProps, parse_and_update_aux}; use crate::header::needs::CachedNeedsConditions; @@ -196,6 +197,8 @@ pub struct TestProps { /// Build and use `minicore` as `core` stub for `no_core` tests in cross-compilation scenarios /// that don't otherwise want/need `-Z build-std`. pub add_core_stubs: bool, + /// Whether line annotatins are required for the given error kind. + pub require_annotations: HashMap<ErrorKind, bool>, } mod directives { @@ -212,6 +215,7 @@ mod directives { pub const CHECK_RUN_RESULTS: &'static str = "check-run-results"; pub const DONT_CHECK_COMPILER_STDOUT: &'static str = "dont-check-compiler-stdout"; pub const DONT_CHECK_COMPILER_STDERR: &'static str = "dont-check-compiler-stderr"; + pub const DONT_REQUIRE_ANNOTATIONS: &'static str = "dont-require-annotations"; pub const NO_PREFER_DYNAMIC: &'static str = "no-prefer-dynamic"; pub const PRETTY_MODE: &'static str = "pretty-mode"; pub const PRETTY_COMPARE_ONLY: &'static str = "pretty-compare-only"; @@ -297,6 +301,13 @@ impl TestProps { no_auto_check_cfg: false, has_enzyme: false, add_core_stubs: false, + require_annotations: HashMap::from([ + (ErrorKind::Help, true), + (ErrorKind::Note, true), + (ErrorKind::Error, true), + (ErrorKind::Warning, true), + (ErrorKind::Suggestion, false), + ]), } } @@ -570,6 +581,13 @@ impl TestProps { config.set_name_directive(ln, NO_AUTO_CHECK_CFG, &mut self.no_auto_check_cfg); self.update_add_core_stubs(ln, config); + + if let Some(err_kind) = + config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS) + { + self.require_annotations + .insert(ErrorKind::expect_from_user_str(&err_kind), false); + } }, ); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 13f3479247a..872f5f6ce29 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -710,10 +710,6 @@ impl<'test> TestCx<'test> { self.testpaths.file.display().to_string() }; - // If the testcase being checked contains at least one expected "help" - // message, then we'll ensure that all "help" messages are expected. - // Otherwise, all "help" messages reported by the compiler will be ignored. - // This logic also applies to "note" messages. let expect_help = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Help)); let expect_note = expected_errors.iter().any(|ee| ee.kind == Some(ErrorKind::Note)); @@ -801,9 +797,7 @@ impl<'test> TestCx<'test> { } /// Returns `true` if we should report an error about `actual_error`, - /// which did not match any of the expected error. We always require - /// errors/warnings to be explicitly listed, but only require - /// helps/notes if there are explicit helps/notes given. + /// which did not match any of the expected error. fn is_unexpected_compiler_message( &self, actual_error: &Error, @@ -811,12 +805,16 @@ impl<'test> TestCx<'test> { expect_note: bool, ) -> bool { actual_error.require_annotation - && match actual_error.kind { - Some(ErrorKind::Help) => expect_help, - Some(ErrorKind::Note) => expect_note, - Some(ErrorKind::Error) | Some(ErrorKind::Warning) => true, - Some(ErrorKind::Suggestion) | None => false, - } + && actual_error.kind.map_or(false, |err_kind| { + // If the test being checked doesn't contain any "help" or "note" annotations, then + // we don't require annotating "help" or "note" (respecively) diagnostics at all. + let default_require_annotations = self.props.require_annotations[&err_kind]; + match err_kind { + ErrorKind::Help => expect_help && default_require_annotations, + ErrorKind::Note => expect_note && default_require_annotations, + _ => default_require_annotations, + } + }) } fn should_emit_metadata(&self, pm: Option<PassMode>) -> Emit { |
