Skip to content

Commit 6474e75

Browse files
committed
compiletest: Make diagnostic kind mandatory on line annotations
1 parent 5ae50d3 commit 6474e75

File tree

371 files changed

+2374
-2106
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

371 files changed

+2374
-2106
lines changed

src/doc/rustc-dev-guide/src/tests/ui.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,9 @@ E.g. use `//@ dont-require-annotations: NOTE` to annotate notes selectively.
372372
Avoid using this directive for `ERROR`s and `WARN`ings, unless there's a serious reason, like
373373
target-dependent compiler output.
374374

375-
Missing diagnostic kinds (`//~ message`) are currently accepted, but are being phased away.
376-
They will match any compiler output kind, but will not force exhaustive annotations for that kind.
377-
Prefer explicit kind and `//@ dont-require-annotations` to achieve the same effect.
375+
Some diagnostics are never required to be line-annotated, regardless of their kind or directives,
376+
for example secondary lines of multiline diagnostics,
377+
or ubiquitous diagnostics like `aborting due to N previous errors`.
378378

379379
UI tests use the `-A unused` flag by default to ignore all unused warnings, as
380380
unused warnings are usually not the focus of a test. However, simple code

src/tools/compiletest/src/errors.rs

+11-22
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,18 @@ impl ErrorKind {
3030

3131
/// Either the canonical uppercase string, or some additional versions for compatibility.
3232
/// FIXME: consider keeping only the canonical versions here.
33-
fn from_user_str(s: &str) -> Option<ErrorKind> {
34-
Some(match s {
33+
pub fn from_user_str(s: &str) -> ErrorKind {
34+
match s {
3535
"HELP" | "help" => ErrorKind::Help,
3636
"ERROR" | "error" => ErrorKind::Error,
37-
"NOTE" | "note" => ErrorKind::Note,
37+
"NOTE" | "note" | "MONO_ITEM" => ErrorKind::Note,
3838
"SUGGESTION" => ErrorKind::Suggestion,
3939
"WARN" | "WARNING" | "warn" | "warning" => ErrorKind::Warning,
40-
_ => return None,
41-
})
42-
}
43-
44-
pub fn expect_from_user_str(s: &str) -> ErrorKind {
45-
ErrorKind::from_user_str(s).unwrap_or_else(|| {
46-
panic!(
40+
_ => panic!(
4741
"unexpected diagnostic kind `{s}`, expected \
4842
`ERROR`, `WARN`, `NOTE`, `HELP` or `SUGGESTION`"
49-
)
50-
})
43+
),
44+
}
5145
}
5246
}
5347

@@ -67,8 +61,7 @@ impl fmt::Display for ErrorKind {
6761
pub struct Error {
6862
pub line_num: Option<usize>,
6963
/// What kind of message we expect (e.g., warning, error, suggestion).
70-
/// `None` if not specified or unknown message kind.
71-
pub kind: Option<ErrorKind>,
64+
pub kind: ErrorKind,
7265
pub msg: String,
7366
/// For some `Error`s, like secondary lines of multi-line diagnostics, line annotations
7467
/// are not mandatory, even if they would otherwise be mandatory for primary errors.
@@ -79,12 +72,7 @@ pub struct Error {
7972
impl Error {
8073
pub fn render_for_expected(&self) -> String {
8174
use colored::Colorize;
82-
format!(
83-
"{: <10}line {: >3}: {}",
84-
self.kind.map(|kind| kind.to_string()).unwrap_or_default(),
85-
self.line_num_str(),
86-
self.msg.cyan(),
87-
)
75+
format!("{: <10}line {: >3}: {}", self.kind, self.line_num_str(), self.msg.cyan())
8876
}
8977

9078
pub fn line_num_str(&self) -> String {
@@ -173,9 +161,10 @@ fn parse_expected(
173161
// Get the part of the comment after the sigil (e.g. `~^^` or ~|).
174162
let tag = captures.get(0).unwrap();
175163
let rest = line[tag.end()..].trim_start();
176-
let (kind_str, _) = rest.split_once(|c: char| !c.is_ascii_alphabetic()).unwrap_or((rest, ""));
164+
let (kind_str, _) =
165+
rest.split_once(|c: char| c != '_' && !c.is_ascii_alphabetic()).unwrap_or((rest, ""));
177166
let kind = ErrorKind::from_user_str(kind_str);
178-
let untrimmed_msg = if kind.is_some() { &rest[kind_str.len()..] } else { rest };
167+
let untrimmed_msg = &rest[kind_str.len()..];
179168
let msg = untrimmed_msg.strip_prefix(':').unwrap_or(untrimmed_msg).trim().to_owned();
180169

181170
let line_num_adjust = &captures["adjust"];

src/tools/compiletest/src/header.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ impl TestProps {
593593
config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS)
594594
{
595595
self.dont_require_annotations
596-
.insert(ErrorKind::expect_from_user_str(err_kind.trim()));
596+
.insert(ErrorKind::from_user_str(err_kind.trim()));
597597
}
598598
},
599599
);

src/tools/compiletest/src/json.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ fn push_actual_errors(
229229
// Convert multi-line messages into multiple errors.
230230
// We expect to replace these with something more structured anyhow.
231231
let mut message_lines = diagnostic.message.lines();
232-
let kind = Some(ErrorKind::from_compiler_str(&diagnostic.level));
232+
let kind = ErrorKind::from_compiler_str(&diagnostic.level);
233233
let first_line = message_lines.next().unwrap_or(&diagnostic.message);
234234
if primary_spans.is_empty() {
235235
static RE: OnceLock<Regex> = OnceLock::new();
@@ -278,7 +278,7 @@ fn push_actual_errors(
278278
for (index, line) in suggested_replacement.lines().enumerate() {
279279
errors.push(Error {
280280
line_num: Some(span.line_start + index),
281-
kind: Some(ErrorKind::Suggestion),
281+
kind: ErrorKind::Suggestion,
282282
msg: line.to_string(),
283283
require_annotation: true,
284284
});
@@ -297,7 +297,7 @@ fn push_actual_errors(
297297
for span in spans_in_this_file.iter().filter(|span| span.label.is_some()) {
298298
errors.push(Error {
299299
line_num: Some(span.line_start),
300-
kind: Some(ErrorKind::Note),
300+
kind: ErrorKind::Note,
301301
msg: span.label.clone().unwrap(),
302302
require_annotation: true,
303303
});
@@ -317,7 +317,7 @@ fn push_backtrace(
317317
if Path::new(&expansion.span.file_name) == Path::new(&file_name) {
318318
errors.push(Error {
319319
line_num: Some(expansion.span.line_start),
320-
kind: Some(ErrorKind::Note),
320+
kind: ErrorKind::Note,
321321
msg: format!("in this expansion of {}", expansion.macro_decl_name),
322322
require_annotation: true,
323323
});

src/tools/compiletest/src/runtest.rs

+7-15
Original file line numberDiff line numberDiff line change
@@ -675,9 +675,7 @@ impl<'test> TestCx<'test> {
675675
"check_expected_errors: expected_errors={:?} proc_res.status={:?}",
676676
expected_errors, proc_res.status
677677
);
678-
if proc_res.status.success()
679-
&& expected_errors.iter().any(|x| x.kind == Some(ErrorKind::Error))
680-
{
678+
if proc_res.status.success() && expected_errors.iter().any(|x| x.kind == ErrorKind::Error) {
681679
self.fatal_proc_rec("process did not return an error status", proc_res);
682680
}
683681

@@ -709,7 +707,7 @@ impl<'test> TestCx<'test> {
709707
// if one of them actually occurs in the test.
710708
let expected_kinds: HashSet<_> = [ErrorKind::Error, ErrorKind::Warning]
711709
.into_iter()
712-
.chain(expected_errors.iter().filter_map(|e| e.kind))
710+
.chain(expected_errors.iter().map(|e| e.kind))
713711
.collect();
714712

715713
// Parse the JSON output from the compiler and extract out the messages.
@@ -723,8 +721,7 @@ impl<'test> TestCx<'test> {
723721
expected_errors.iter().enumerate().position(|(index, expected_error)| {
724722
!found[index]
725723
&& actual_error.line_num == expected_error.line_num
726-
&& (expected_error.kind.is_none()
727-
|| actual_error.kind == expected_error.kind)
724+
&& actual_error.kind == expected_error.kind
728725
&& actual_error.msg.contains(&expected_error.msg)
729726
});
730727

@@ -737,19 +734,14 @@ impl<'test> TestCx<'test> {
737734

738735
None => {
739736
if actual_error.require_annotation
740-
&& actual_error.kind.map_or(false, |kind| {
741-
expected_kinds.contains(&kind)
742-
&& !self.props.dont_require_annotations.contains(&kind)
743-
})
737+
&& expected_kinds.contains(&actual_error.kind)
738+
&& !self.props.dont_require_annotations.contains(&actual_error.kind)
744739
{
745740
self.error(&format!(
746741
"{}:{}: unexpected {}: '{}'",
747742
file_name,
748743
actual_error.line_num_str(),
749-
actual_error
750-
.kind
751-
.as_ref()
752-
.map_or(String::from("message"), |k| k.to_string()),
744+
actual_error.kind,
753745
actual_error.msg
754746
));
755747
unexpected.push(actual_error);
@@ -766,7 +758,7 @@ impl<'test> TestCx<'test> {
766758
"{}:{}: expected {} not found: {}",
767759
file_name,
768760
expected_error.line_num_str(),
769-
expected_error.kind.as_ref().map_or("message".into(), |k| k.to_string()),
761+
expected_error.kind,
770762
expected_error.msg
771763
));
772764
not_found.push(expected_error);

src/tools/compiletest/src/runtest/ui.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use rustfix::{Filter, apply_suggestions, get_suggestions_from_json};
66
use tracing::debug;
77

88
use super::{
9-
AllowUnused, Emit, ErrorKind, FailMode, LinkToAux, PassMode, TargetLocation, TestCx,
10-
TestOutput, Truncated, UI_FIXED, WillExecute,
9+
AllowUnused, Emit, FailMode, LinkToAux, PassMode, TargetLocation, TestCx, TestOutput,
10+
Truncated, UI_FIXED, WillExecute,
1111
};
1212
use crate::{errors, json};
1313

@@ -176,7 +176,7 @@ impl TestCx<'_> {
176176
let msg = format!(
177177
"line {}: cannot combine `--error-format` with {} annotations; use `error-pattern` instead",
178178
expected_errors[0].line_num_str(),
179-
expected_errors[0].kind.unwrap_or(ErrorKind::Error),
179+
expected_errors[0].kind,
180180
);
181181
self.fatal(&msg);
182182
}
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
//@ compile-flags: -Znormalize-docs
2+
//@ dont-require-annotations: NOTE
3+
24
// https://github.com/rust-lang/rust/issues/105742
35
use std::ops::Index;
46

57
pub fn next<'a, T>(s: &'a mut dyn SVec<Item = T, Output = T>) {
6-
//~^ expected 1 lifetime argument
7-
//~| expected 1 generic argument
8+
//~^ NOTE expected 1 lifetime argument
9+
//~| NOTE expected 1 generic argument
810
//~| ERROR the trait `SVec` is not dyn compatible
9-
//~| `SVec` is not dyn compatible
11+
//~| NOTE `SVec` is not dyn compatible
1012
//~| ERROR missing generics for associated type `SVec::Item`
1113
//~| ERROR missing generics for associated type `SVec::Item`
1214
let _ = s;
1315
}
1416

1517
pub trait SVec: Index<
1618
<Self as SVec>::Item,
17-
//~^ expected 1 lifetime argument
18-
//~| expected 1 generic argument
19+
//~^ NOTE expected 1 lifetime argument
20+
//~| NOTE expected 1 generic argument
1921
//~| ERROR missing generics for associated type `SVec::Item`
2022
//~| ERROR missing generics for associated type `SVec::Item`
2123
//~| ERROR missing generics for associated type `SVec::Item`
@@ -25,8 +27,8 @@ pub trait SVec: Index<
2527
//~| ERROR missing generics for associated type `SVec::Item`
2628
//~| ERROR missing generics for associated type `SVec::Item`
2729
Output = <Index<<Self as SVec>::Item,
28-
//~^ expected 1 lifetime argument
29-
//~| expected 1 generic argument
30+
//~^ NOTE expected 1 lifetime argument
31+
//~| NOTE expected 1 generic argument
3032
//~| ERROR missing generics for associated type `SVec::Item`
3133
//~| ERROR missing generics for associated type `SVec::Item`
3234
//~| ERROR missing generics for associated type `SVec::Item`
@@ -36,16 +38,16 @@ pub trait SVec: Index<
3638
//~| ERROR missing generics for associated type `SVec::Item`
3739
//~| ERROR missing generics for associated type `SVec::Item`
3840
Output = <Self as SVec>::Item> as SVec>::Item,
39-
//~^ expected 1 lifetime argument
40-
//~| expected 1 generic argument
41-
//~| expected 1 lifetime argument
41+
//~^ NOTE expected 1 lifetime argument
42+
//~| NOTE expected 1 generic argument
43+
//~| NOTE expected 1 lifetime argument
4244
//~| ERROR missing generics for associated type `SVec::Item`
4345
//~| ERROR missing generics for associated type `SVec::Item`
4446
//~| ERROR missing generics for associated type `SVec::Item`
4547
//~| ERROR missing generics for associated type `SVec::Item`
4648
//~| ERROR missing generics for associated type `SVec::Item`
4749
//~| ERROR missing generics for associated type `SVec::Item`
48-
//~| expected 1 generic argument
50+
//~| NOTE expected 1 generic argument
4951
//~| ERROR missing generics for associated type `SVec::Item`
5052
//~| ERROR missing generics for associated type `SVec::Item`
5153
//~| ERROR missing generics for associated type `SVec::Item`
@@ -60,8 +62,8 @@ pub trait SVec: Index<
6062
type Item<'a, T>;
6163

6264
fn len(&self) -> <Self as SVec>::Item;
63-
//~^ expected 1 lifetime argument
65+
//~^ NOTE expected 1 lifetime argument
6466
//~| ERROR missing generics for associated type `SVec::Item`
65-
//~| expected 1 generic argument
67+
//~| NOTE expected 1 generic argument
6668
//~| ERROR missing generics for associated type `SVec::Item`
6769
}

0 commit comments

Comments
 (0)