diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs index b5a2b7feac9d6..9fa26305f6b0b 100644 --- a/src/tools/compiletest/src/errors.rs +++ b/src/tools/compiletest/src/errors.rs @@ -16,6 +16,8 @@ pub enum ErrorKind { Suggestion, Warning, Raw, + /// Used for better recovery and diagnostics in compiletest. + Unknown, } impl ErrorKind { @@ -31,21 +33,25 @@ impl ErrorKind { /// Either the canonical uppercase string, or some additional versions for compatibility. /// FIXME: consider keeping only the canonical versions here. - pub fn from_user_str(s: &str) -> ErrorKind { - match s { + fn from_user_str(s: &str) -> Option { + Some(match s { "HELP" | "help" => ErrorKind::Help, "ERROR" | "error" => ErrorKind::Error, - // `MONO_ITEM` makes annotations in `codegen-units` tests syntactically correct, - // but those tests never use the error kind later on. - "NOTE" | "note" | "MONO_ITEM" => ErrorKind::Note, + "NOTE" | "note" => ErrorKind::Note, "SUGGESTION" => ErrorKind::Suggestion, "WARN" | "WARNING" | "warn" | "warning" => ErrorKind::Warning, "RAW" => ErrorKind::Raw, - _ => panic!( + _ => 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`" - ), - } + `ERROR`, `WARN`, `NOTE`, `HELP`, `SUGGESTION` or `RAW`" + ) + }) } } @@ -58,6 +64,7 @@ impl fmt::Display for ErrorKind { ErrorKind::Suggestion => write!(f, "SUGGESTION"), ErrorKind::Warning => write!(f, "WARN"), ErrorKind::Raw => write!(f, "RAW"), + ErrorKind::Unknown => write!(f, "UNKNOWN"), } } } @@ -65,6 +72,7 @@ impl fmt::Display for ErrorKind { #[derive(Debug)] pub struct Error { pub line_num: Option, + pub column_num: Option, /// What kind of message we expect (e.g., warning, error, suggestion). pub kind: ErrorKind, pub msg: String, @@ -74,17 +82,6 @@ pub struct Error { pub require_annotation: bool, } -impl Error { - pub fn render_for_expected(&self) -> String { - use colored::Colorize; - format!("{: <10}line {: >3}: {}", self.kind, self.line_num_str(), self.msg.cyan()) - } - - pub fn line_num_str(&self) -> String { - self.line_num.map_or("?".to_string(), |line_num| line_num.to_string()) - } -} - /// Looks for either "//~| KIND MESSAGE" or "//~^^... KIND MESSAGE" /// The former is a "follow" that inherits its target from the preceding line; /// the latter is an "adjusts" that goes that many lines up. @@ -168,8 +165,10 @@ fn parse_expected( let rest = line[tag.end()..].trim_start(); let (kind_str, _) = rest.split_once(|c: char| c != '_' && !c.is_ascii_alphabetic()).unwrap_or((rest, "")); - let kind = ErrorKind::from_user_str(kind_str); - let untrimmed_msg = &rest[kind_str.len()..]; + let (kind, untrimmed_msg) = match ErrorKind::from_user_str(kind_str) { + Some(kind) => (kind, &rest[kind_str.len()..]), + None => (ErrorKind::Unknown, rest), + }; let msg = untrimmed_msg.strip_prefix(':').unwrap_or(untrimmed_msg).trim().to_owned(); let line_num_adjust = &captures["adjust"]; @@ -182,6 +181,7 @@ fn parse_expected( } else { (false, Some(line_num - line_num_adjust.len())) }; + let column_num = Some(tag.start() + 1); debug!( "line={:?} tag={:?} follow_prev={:?} kind={:?} msg={:?}", @@ -191,7 +191,7 @@ fn parse_expected( kind, msg ); - Some((follow_prev, Error { line_num, kind, msg, require_annotation: true })) + Some((follow_prev, Error { line_num, column_num, kind, msg, require_annotation: true })) } #[cfg(test)] diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 8bee9caacc949..2b203bb309c63 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -593,7 +593,7 @@ impl TestProps { config.parse_name_value_directive(ln, DONT_REQUIRE_ANNOTATIONS) { self.dont_require_annotations - .insert(ErrorKind::from_user_str(err_kind.trim())); + .insert(ErrorKind::expect_from_user_str(err_kind.trim())); } }, ); diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs index 6ed2b52c66d21..a8e6416e56c84 100644 --- a/src/tools/compiletest/src/json.rs +++ b/src/tools/compiletest/src/json.rs @@ -36,9 +36,7 @@ struct UnusedExternNotification { struct DiagnosticSpan { file_name: String, line_start: usize, - line_end: usize, column_start: usize, - column_end: usize, is_primary: bool, label: Option, suggested_replacement: Option, @@ -148,6 +146,7 @@ pub fn parse_output(file_name: &str, output: &str) -> Vec { Ok(diagnostic) => push_actual_errors(&mut errors, &diagnostic, &[], file_name), Err(_) => errors.push(Error { line_num: None, + column_num: None, kind: ErrorKind::Raw, msg: line.to_string(), require_annotation: false, @@ -193,25 +192,9 @@ fn push_actual_errors( // also ensure that `//~ ERROR E123` *always* works. The // assumption is that these multi-line error messages are on their // way out anyhow. - let with_code = |span: Option<&DiagnosticSpan>, text: &str| { - // FIXME(#33000) -- it'd be better to use a dedicated - // UI harness than to include the line/col number like - // this, but some current tests rely on it. - // - // Note: Do NOT include the filename. These can easily - // cause false matches where the expected message - // appears in the filename, and hence the message - // changes but the test still passes. - let span_str = match span { - Some(DiagnosticSpan { line_start, column_start, line_end, column_end, .. }) => { - format!("{line_start}:{column_start}: {line_end}:{column_end}") - } - None => format!("?:?: ?:?"), - }; - match &diagnostic.code { - Some(code) => format!("{span_str}: {text} [{}]", code.code), - None => format!("{span_str}: {text}"), - } + let with_code = |text| match &diagnostic.code { + Some(code) => format!("{text} [{}]", code.code), + None => format!("{text}"), }; // Convert multi-line messages into multiple errors. @@ -225,8 +208,9 @@ fn push_actual_errors( || Regex::new(r"aborting due to \d+ previous errors?|\d+ warnings? emitted").unwrap(); errors.push(Error { line_num: None, + column_num: None, kind, - msg: with_code(None, first_line), + msg: with_code(first_line), require_annotation: diagnostic.level != "failure-note" && !RE.get_or_init(re_init).is_match(first_line), }); @@ -234,8 +218,9 @@ fn push_actual_errors( for span in primary_spans { errors.push(Error { line_num: Some(span.line_start), + column_num: Some(span.column_start), kind, - msg: with_code(Some(span), first_line), + msg: with_code(first_line), require_annotation: true, }); } @@ -244,16 +229,18 @@ fn push_actual_errors( if primary_spans.is_empty() { errors.push(Error { line_num: None, + column_num: None, kind, - msg: with_code(None, next_line), + msg: with_code(next_line), require_annotation: false, }); } else { for span in primary_spans { errors.push(Error { line_num: Some(span.line_start), + column_num: Some(span.column_start), kind, - msg: with_code(Some(span), next_line), + msg: with_code(next_line), require_annotation: false, }); } @@ -266,6 +253,7 @@ fn push_actual_errors( for (index, line) in suggested_replacement.lines().enumerate() { errors.push(Error { line_num: Some(span.line_start + index), + column_num: Some(span.column_start), kind: ErrorKind::Suggestion, msg: line.to_string(), // Empty suggestions (suggestions to remove something) are common @@ -288,6 +276,7 @@ fn push_actual_errors( if let Some(label) = &span.label { errors.push(Error { line_num: Some(span.line_start), + column_num: Some(span.column_start), kind: ErrorKind::Note, msg: label.clone(), // Empty labels (only underlining spans) are common and do not need annotations. @@ -310,6 +299,7 @@ fn push_backtrace( if Path::new(&expansion.span.file_name) == Path::new(&file_name) { errors.push(Error { line_num: Some(expansion.span.line_start), + column_num: Some(expansion.span.column_start), kind: ErrorKind::Note, msg: format!("in this expansion of {}", expansion.macro_decl_name), require_annotation: true, diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 42c851ea99910..980e89889abba 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -11,7 +11,7 @@ use std::{env, iter, str}; use build_helper::fs::remove_and_create_dir_all; use camino::{Utf8Path, Utf8PathBuf}; -use colored::Colorize; +use colored::{Color, Colorize}; use regex::{Captures, Regex}; use tracing::*; @@ -677,9 +677,6 @@ impl<'test> TestCx<'test> { return; } - // On Windows, translate all '\' path separators to '/' - let file_name = self.testpaths.file.to_string().replace(r"\", "/"); - // On Windows, keep all '\' path separators to match the paths reported in the JSON output // from the compiler let diagnostic_file_name = if self.props.remap_src_base { @@ -704,6 +701,7 @@ impl<'test> TestCx<'test> { .map(|e| Error { msg: self.normalize_output(&e.msg, &[]), ..e }); let mut unexpected = Vec::new(); + let mut unimportant = Vec::new(); let mut found = vec![false; expected_errors.len()]; for actual_error in actual_errors { for pattern in &self.props.error_patterns { @@ -738,14 +736,9 @@ impl<'test> TestCx<'test> { && expected_kinds.contains(&actual_error.kind) && !self.props.dont_require_annotations.contains(&actual_error.kind) { - self.error(&format!( - "{}:{}: unexpected {}: '{}'", - file_name, - actual_error.line_num_str(), - actual_error.kind, - actual_error.msg - )); unexpected.push(actual_error); + } else { + unimportant.push(actual_error); } } } @@ -755,39 +748,140 @@ impl<'test> TestCx<'test> { // anything not yet found is a problem for (index, expected_error) in expected_errors.iter().enumerate() { if !found[index] { - self.error(&format!( - "{}:{}: expected {} not found: {}", - file_name, - expected_error.line_num_str(), - expected_error.kind, - expected_error.msg - )); not_found.push(expected_error); } } if !unexpected.is_empty() || !not_found.is_empty() { self.error(&format!( - "{} unexpected errors found, {} expected errors not found", + "{} unexpected diagnostics reported, {} expected diagnostics not reported", unexpected.len(), not_found.len() )); - println!("status: {}\ncommand: {}\n", proc_res.status, proc_res.cmdline); + + // Emit locations in a format that is short (relative paths) but "clickable" in editors. + // Also normalize path separators to `/`. + let file_name = self + .testpaths + .file + .strip_prefix(self.config.src_root.as_str()) + .unwrap_or(&self.testpaths.file) + .to_string() + .replace(r"\", "/"); + let line_str = |e: &Error| { + let line_num = e.line_num.map_or("?".to_string(), |line_num| line_num.to_string()); + // `file:?:NUM` may be confusing to editors and unclickable. + let opt_col_num = match e.column_num { + Some(col_num) if line_num != "?" => format!(":{col_num}"), + _ => "".to_string(), + }; + format!("{file_name}:{line_num}{opt_col_num}") + }; + let print_error = |e| println!("{}: {}: {}", line_str(e), e.kind, e.msg.cyan()); + let push_suggestion = + |suggestions: &mut Vec<_>, e: &Error, kind, line, msg, color, rank| { + let mut ret = String::new(); + if kind { + ret += &format!("{} {}", "with kind".color(color), e.kind); + } + if line { + if !ret.is_empty() { + ret.push(' '); + } + ret += &format!("{} {}", "on line".color(color), line_str(e)); + } + if msg { + if !ret.is_empty() { + ret.push(' '); + } + ret += &format!("{} {}", "with message".color(color), e.msg.cyan()); + } + suggestions.push((ret, rank)); + }; + let show_suggestions = |mut suggestions: Vec<_>, prefix: &str, color| { + // Only show suggestions with the highest rank. + suggestions.sort_by_key(|(_, rank)| *rank); + if let Some(&(_, top_rank)) = suggestions.first() { + for (suggestion, rank) in suggestions { + if rank == top_rank { + println!(" {} {suggestion}", prefix.color(color)); + } + } + } + }; + + // Fuzzy matching quality: + // - message and line / message and kind - great, suggested + // - only message - good, suggested + // - known line and kind - ok, suggested + // - only known line - meh, but suggested + // - others are not worth suggesting if !unexpected.is_empty() { - println!("{}", "--- unexpected errors (from JSON output) ---".green()); + let header = "--- reported in JSON output but not expected in test file ---"; + println!("{}", header.green()); for error in &unexpected { - println!("{}", error.render_for_expected()); + print_error(error); + let mut suggestions = Vec::new(); + for candidate in ¬_found { + let mut push_red_suggestion = |line, msg, rank| { + push_suggestion( + &mut suggestions, + candidate, + candidate.kind != error.kind, + line, + msg, + Color::Red, + rank, + ) + }; + if error.msg.contains(&candidate.msg) { + push_red_suggestion(candidate.line_num != error.line_num, false, 0); + } else if candidate.line_num.is_some() + && candidate.line_num == error.line_num + { + push_red_suggestion(false, true, 1); + } + } + + show_suggestions(suggestions, "expected", Color::Red); } println!("{}", "---".green()); } if !not_found.is_empty() { - println!("{}", "--- not found errors (from test file) ---".red()); + let header = "--- expected in test file but not reported in JSON output ---"; + println!("{}", header.red()); for error in ¬_found { - println!("{}", error.render_for_expected()); + print_error(error); + let mut suggestions = Vec::new(); + for candidate in unexpected.iter().chain(&unimportant) { + let mut push_green_suggestion = |line, msg, rank| { + push_suggestion( + &mut suggestions, + candidate, + candidate.kind != error.kind, + line, + msg, + Color::Green, + rank, + ) + }; + if candidate.msg.contains(&error.msg) { + push_green_suggestion(candidate.line_num != error.line_num, false, 0); + } else if candidate.line_num.is_some() + && candidate.line_num == error.line_num + { + push_green_suggestion(false, true, 1); + } + } + + show_suggestions(suggestions, "reported", Color::Green); } - println!("{}", "---\n".red()); + println!("{}", "---".red()); } - panic!("errors differ from expected"); + panic!( + "errors differ from expected\nstatus: {}\ncommand: {}\n", + proc_res.status, proc_res.cmdline + ); } } @@ -2073,7 +2167,6 @@ impl<'test> TestCx<'test> { println!("{}", String::from_utf8_lossy(&output.stdout)); eprintln!("{}", String::from_utf8_lossy(&output.stderr)); } else { - use colored::Colorize; eprintln!("warning: no pager configured, falling back to unified diff"); eprintln!( "help: try configuring a git pager (e.g. `delta`) with `git config --global core.pager delta`" diff --git a/tests/incremental/issue-61323.rs b/tests/incremental/issue-61323.rs index b7423c81fc163..4845648d49c87 100644 --- a/tests/incremental/issue-61323.rs +++ b/tests/incremental/issue-61323.rs @@ -1,7 +1,7 @@ //@ revisions: rpass cfail enum A { - //[cfail]~^ ERROR 3:1: 3:7: recursive types `A` and `C` have infinite size [E0072] + //[cfail]~^ ERROR recursive types `A` and `C` have infinite size [E0072] B(C), } diff --git a/tests/ui/argument-suggestions/issue-100478.rs b/tests/ui/argument-suggestions/issue-100478.rs index b0a9703112e31..219870f3b2373 100644 --- a/tests/ui/argument-suggestions/issue-100478.rs +++ b/tests/ui/argument-suggestions/issue-100478.rs @@ -32,8 +32,8 @@ fn four_shuffle(_a: T1, _b: T2, _c: T3, _d: T4) {} fn main() { three_diff(T2::new(0)); //~ ERROR function takes - four_shuffle(T3::default(), T4::default(), T1::default(), T2::default()); //~ ERROR 35:5: 35:17: arguments to this function are incorrect [E0308] - four_shuffle(T3::default(), T2::default(), T1::default(), T3::default()); //~ ERROR 36:5: 36:17: arguments to this function are incorrect [E0308] + four_shuffle(T3::default(), T4::default(), T1::default(), T2::default()); //~ ERROR arguments to this function are incorrect [E0308] + four_shuffle(T3::default(), T2::default(), T1::default(), T3::default()); //~ ERROR arguments to this function are incorrect [E0308] let p1 = T1::new(0); let p2 = Arc::new(T2::new(0)); diff --git a/tests/ui/async-await/incorrect-move-async-order-issue-79694.fixed b/tests/ui/async-await/incorrect-move-async-order-issue-79694.fixed index c74a32e442f3f..9e5e889506c78 100644 --- a/tests/ui/async-await/incorrect-move-async-order-issue-79694.fixed +++ b/tests/ui/async-await/incorrect-move-async-order-issue-79694.fixed @@ -4,5 +4,5 @@ // Regression test for issue 79694 fn main() { - let _ = async move { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect + let _ = async move { }; //~ ERROR the order of `move` and `async` is incorrect } diff --git a/tests/ui/async-await/incorrect-move-async-order-issue-79694.rs b/tests/ui/async-await/incorrect-move-async-order-issue-79694.rs index 81ffbacc3273f..9c36a6c96da61 100644 --- a/tests/ui/async-await/incorrect-move-async-order-issue-79694.rs +++ b/tests/ui/async-await/incorrect-move-async-order-issue-79694.rs @@ -4,5 +4,5 @@ // Regression test for issue 79694 fn main() { - let _ = move async { }; //~ ERROR 7:13: 7:23: the order of `move` and `async` is incorrect + let _ = move async { }; //~ ERROR the order of `move` and `async` is incorrect } diff --git a/tests/ui/compiletest-self-test/line-annotation-mismatches.rs b/tests/ui/compiletest-self-test/line-annotation-mismatches.rs new file mode 100644 index 0000000000000..d2a14374ed4c7 --- /dev/null +++ b/tests/ui/compiletest-self-test/line-annotation-mismatches.rs @@ -0,0 +1,42 @@ +//@ should-fail + +// The warning is reported with unknown line +//@ compile-flags: -D raw_pointer_derive +//~? WARN kind and unknown line match the reported warning, but we do not suggest it + +// The error is expected but not reported at all. +//~ ERROR this error does not exist + +// The error is reported but not expected at all. +// "`main` function not found in crate" (the main function is intentionally not added) + +// An "unimportant" diagnostic is expected on a wrong line. +//~ ERROR aborting due to + +// An "unimportant" diagnostic is expected with a wrong kind. +//~? ERROR For more information about an error + +fn wrong_line_or_kind() { + // A diagnostic expected on a wrong line. + unresolved1; + //~ ERROR cannot find value `unresolved1` in this scope + + // A diagnostic expected with a wrong kind. + unresolved2; //~ WARN cannot find value `unresolved2` in this scope + + // A diagnostic expected with a missing kind (treated as a wrong kind). + unresolved3; //~ cannot find value `unresolved3` in this scope + + // A diagnostic expected with a wrong line and kind. + unresolved4; + //~ WARN cannot find value `unresolved4` in this scope +} + +fn wrong_message() { + // A diagnostic expected with a wrong message, but the line is known and right. + unresolvedA; //~ ERROR stub message 1 + + // A diagnostic expected with a wrong message, but the line is known and right, + // even if the kind doesn't match. + unresolvedB; //~ WARN stub message 2 +} diff --git a/tests/ui/compiletest-self-test/line-annotation-mismatches.stderr b/tests/ui/compiletest-self-test/line-annotation-mismatches.stderr new file mode 100644 index 0000000000000..7ca3bfaf396c9 --- /dev/null +++ b/tests/ui/compiletest-self-test/line-annotation-mismatches.stderr @@ -0,0 +1,61 @@ +warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok + | + = note: requested on the command line with `-D raw_pointer_derive` + = note: `#[warn(renamed_and_removed_lints)]` on by default + +error[E0425]: cannot find value `unresolved1` in this scope + --> $DIR/line-annotation-mismatches.rs:21:5 + | +LL | unresolved1; + | ^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `unresolved2` in this scope + --> $DIR/line-annotation-mismatches.rs:25:5 + | +LL | unresolved2; + | ^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `unresolved3` in this scope + --> $DIR/line-annotation-mismatches.rs:28:5 + | +LL | unresolved3; + | ^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `unresolved4` in this scope + --> $DIR/line-annotation-mismatches.rs:31:5 + | +LL | unresolved4; + | ^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `unresolvedA` in this scope + --> $DIR/line-annotation-mismatches.rs:37:5 + | +LL | unresolvedA; + | ^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `unresolvedB` in this scope + --> $DIR/line-annotation-mismatches.rs:41:5 + | +LL | unresolvedB; + | ^^^^^^^^^^^ not found in this scope + +warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok + | + = note: requested on the command line with `-D raw_pointer_derive` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0601]: `main` function not found in crate `line_annotation_mismatches` + --> $DIR/line-annotation-mismatches.rs:42:2 + | +LL | } + | ^ consider adding a `main` function to `$DIR/line-annotation-mismatches.rs` + +warning: lint `raw_pointer_derive` has been removed: using derive with raw pointers is ok + | + = note: requested on the command line with `-D raw_pointer_derive` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 7 previous errors; 3 warnings emitted + +Some errors have detailed explanations: E0425, E0601. +For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/feature-gates/feature-gate-cfi_encoding.rs b/tests/ui/feature-gates/feature-gate-cfi_encoding.rs index 3cef8156014bf..b6312dd7817f9 100644 --- a/tests/ui/feature-gates/feature-gate-cfi_encoding.rs +++ b/tests/ui/feature-gates/feature-gate-cfi_encoding.rs @@ -1,4 +1,4 @@ #![crate_type = "lib"] -#[cfi_encoding = "3Bar"] //~ERROR 3:1: 3:25: the `#[cfi_encoding]` attribute is an experimental feature [E0658] +#[cfi_encoding = "3Bar"] //~ ERROR the `#[cfi_encoding]` attribute is an experimental feature [E0658] pub struct Foo(i32); diff --git a/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs b/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs index b5fbcc9ccf8c0..c146986379275 100644 --- a/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs +++ b/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs @@ -1,4 +1,4 @@ fn main() { let _ : &(dyn Send,) = &((),); - //~^ ERROR 2:28: 2:34: mismatched types [E0308] + //~^ ERROR mismatched types [E0308] } diff --git a/tests/ui/impl-header-lifetime-elision/assoc-type.rs b/tests/ui/impl-header-lifetime-elision/assoc-type.rs index db3c416540fcd..14b2ea647f190 100644 --- a/tests/ui/impl-header-lifetime-elision/assoc-type.rs +++ b/tests/ui/impl-header-lifetime-elision/assoc-type.rs @@ -9,7 +9,7 @@ trait MyTrait { impl MyTrait for &i32 { type Output = &i32; - //~^ ERROR 11:19: 11:20: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + //~^ ERROR in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type } impl MyTrait for &u32 { diff --git a/tests/ui/imports/issue-28134.rs b/tests/ui/imports/issue-28134.rs index 70d3a327c1afa..aef2fe8facdcf 100644 --- a/tests/ui/imports/issue-28134.rs +++ b/tests/ui/imports/issue-28134.rs @@ -2,4 +2,4 @@ #![allow(soft_unstable)] #![test] -//~^ ERROR 4:1: 4:9: `test` attribute cannot be used at crate level +//~^ ERROR `test` attribute cannot be used at crate level diff --git a/tests/ui/inference/hint-closure-signature-119266.rs b/tests/ui/inference/hint-closure-signature-119266.rs index 35be600fd6ab8..6e136c57ccad3 100644 --- a/tests/ui/inference/hint-closure-signature-119266.rs +++ b/tests/ui/inference/hint-closure-signature-119266.rs @@ -3,7 +3,7 @@ fn main() { //~^ NOTE: the found closure let x: fn(i32) = x; - //~^ ERROR: 5:22: 5:23: mismatched types [E0308] + //~^ ERROR: mismatched types [E0308] //~| NOTE: incorrect number of function parameters //~| NOTE: expected due to this //~| NOTE: expected fn pointer `fn(i32)` diff --git a/tests/ui/integral-indexing.rs b/tests/ui/integral-indexing.rs index f076dfcb0a42c..e20553af8a26f 100644 --- a/tests/ui/integral-indexing.rs +++ b/tests/ui/integral-indexing.rs @@ -3,14 +3,14 @@ pub fn main() { let s: String = "abcdef".to_string(); v[3_usize]; v[3]; - v[3u8]; //~ERROR : the type `[isize]` cannot be indexed by `u8` - v[3i8]; //~ERROR : the type `[isize]` cannot be indexed by `i8` - v[3u32]; //~ERROR : the type `[isize]` cannot be indexed by `u32` - v[3i32]; //~ERROR : the type `[isize]` cannot be indexed by `i32` + v[3u8]; //~ ERROR the type `[isize]` cannot be indexed by `u8` + v[3i8]; //~ ERROR the type `[isize]` cannot be indexed by `i8` + v[3u32]; //~ ERROR the type `[isize]` cannot be indexed by `u32` + v[3i32]; //~ ERROR the type `[isize]` cannot be indexed by `i32` s.as_bytes()[3_usize]; s.as_bytes()[3]; - s.as_bytes()[3u8]; //~ERROR : the type `[u8]` cannot be indexed by `u8` - s.as_bytes()[3i8]; //~ERROR : the type `[u8]` cannot be indexed by `i8` - s.as_bytes()[3u32]; //~ERROR : the type `[u8]` cannot be indexed by `u32` - s.as_bytes()[3i32]; //~ERROR : the type `[u8]` cannot be indexed by `i32` + s.as_bytes()[3u8]; //~ ERROR the type `[u8]` cannot be indexed by `u8` + s.as_bytes()[3i8]; //~ ERROR the type `[u8]` cannot be indexed by `i8` + s.as_bytes()[3u32]; //~ ERROR the type `[u8]` cannot be indexed by `u32` + s.as_bytes()[3i32]; //~ ERROR the type `[u8]` cannot be indexed by `i32` } diff --git a/tests/ui/issues/issue-92741.rs b/tests/ui/issues/issue-92741.rs index f2e5fdafd9cb8..1c5d5810a57ee 100644 --- a/tests/ui/issues/issue-92741.rs +++ b/tests/ui/issues/issue-92741.rs @@ -1,17 +1,17 @@ //@ run-rustfix fn main() {} fn _foo() -> bool { - & //~ ERROR 4:5: 6:36: mismatched types [E0308] + & //~ ERROR mismatched types [E0308] mut if true { true } else { false } } fn _bar() -> bool { - & //~ ERROR 10:5: 11:40: mismatched types [E0308] + & //~ ERROR mismatched types [E0308] mut if true { true } else { false } } fn _baz() -> bool { - & mut //~ ERROR 15:5: 16:36: mismatched types [E0308] + & mut //~ ERROR mismatched types [E0308] if true { true } else { false } } diff --git a/tests/ui/lifetimes/no_lending_iterators.rs b/tests/ui/lifetimes/no_lending_iterators.rs index b3e8ad08ba18b..88b8cda0898be 100644 --- a/tests/ui/lifetimes/no_lending_iterators.rs +++ b/tests/ui/lifetimes/no_lending_iterators.rs @@ -2,7 +2,7 @@ struct Data(String); impl Iterator for Data { type Item = &str; - //~^ ERROR 4:17: 4:18: associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + //~^ ERROR associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type fn next(&mut self) -> Option { Some(&self.0) @@ -16,7 +16,7 @@ trait Bar { impl Bar for usize { type Item = &usize; - //~^ ERROR 18:17: 18:18: in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type + //~^ ERROR in the trait associated type is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type fn poke(&mut self, item: Self::Item) { self += *item; @@ -25,7 +25,7 @@ impl Bar for usize { impl Bar for isize { type Item<'a> = &'a isize; - //~^ ERROR 27:14: 27:18: lifetime parameters or bounds on associated type `Item` do not match the trait declaration [E0195] + //~^ ERROR lifetime parameters or bounds on associated type `Item` do not match the trait declaration [E0195] fn poke(&mut self, item: Self::Item) { self += *item; diff --git a/tests/ui/mismatched_types/transforming-option-ref-issue-127545.rs b/tests/ui/mismatched_types/transforming-option-ref-issue-127545.rs index f589e88f68e44..0632b822c55c8 100644 --- a/tests/ui/mismatched_types/transforming-option-ref-issue-127545.rs +++ b/tests/ui/mismatched_types/transforming-option-ref-issue-127545.rs @@ -2,17 +2,17 @@ #![crate_type = "lib"] pub fn foo(arg: Option<&Vec>) -> Option<&[i32]> { - arg //~ ERROR 5:5: 5:8: mismatched types [E0308] + arg //~ ERROR mismatched types [E0308] } pub fn bar(arg: Option<&Vec>) -> &[i32] { - arg.unwrap_or(&[]) //~ ERROR 9:19: 9:22: mismatched types [E0308] + arg.unwrap_or(&[]) //~ ERROR mismatched types [E0308] } pub fn barzz<'a>(arg: Option<&'a Vec>, v: &'a [i32]) -> &'a [i32] { - arg.unwrap_or(v) //~ ERROR 13:19: 13:20: mismatched types [E0308] + arg.unwrap_or(v) //~ ERROR mismatched types [E0308] } pub fn convert_result(arg: Result<&Vec, ()>) -> &[i32] { - arg.unwrap_or(&[]) //~ ERROR 17:19: 17:22: mismatched types [E0308] + arg.unwrap_or(&[]) //~ ERROR mismatched types [E0308] } diff --git a/tests/ui/sanitizer/cfi/invalid-attr-encoding.rs b/tests/ui/sanitizer/cfi/invalid-attr-encoding.rs index 7ef6bd2f0acc3..23ffabad62fe8 100644 --- a/tests/ui/sanitizer/cfi/invalid-attr-encoding.rs +++ b/tests/ui/sanitizer/cfi/invalid-attr-encoding.rs @@ -7,5 +7,5 @@ #![no_core] #![no_main] -#[cfi_encoding] //~ERROR 10:1: 10:16: malformed `cfi_encoding` attribute input +#[cfi_encoding] //~ ERROR malformed `cfi_encoding` attribute input pub struct Type1(i32); diff --git a/tests/ui/suggestions/issue-105645.rs b/tests/ui/suggestions/issue-105645.rs index 681ce1c6e37a6..f3ca8ccbb3c71 100644 --- a/tests/ui/suggestions/issue-105645.rs +++ b/tests/ui/suggestions/issue-105645.rs @@ -2,7 +2,7 @@ fn main() { let mut buf = [0u8; 50]; let mut bref = buf.as_slice(); foo(&mut bref); - //~^ ERROR 4:9: 4:18: the trait bound `&[u8]: std::io::Write` is not satisfied [E0277] + //~^ ERROR the trait bound `&[u8]: std::io::Write` is not satisfied [E0277] } fn foo(_: &mut impl std::io::Write) {} diff --git a/tests/ui/suggestions/suggest-full-enum-variant-for-local-module.rs b/tests/ui/suggestions/suggest-full-enum-variant-for-local-module.rs index 1dfc0786668f2..807fba0ab7e71 100644 --- a/tests/ui/suggestions/suggest-full-enum-variant-for-local-module.rs +++ b/tests/ui/suggestions/suggest-full-enum-variant-for-local-module.rs @@ -6,5 +6,5 @@ mod option { } fn main() { - let _: option::O<()> = (); //~ ERROR 9:28: 9:30: mismatched types [E0308] + let _: option::O<()> = (); //~ ERROR mismatched types [E0308] } diff --git a/tests/ui/type/option-ref-advice.rs b/tests/ui/type/option-ref-advice.rs index 2dcee5a2eb912..435b15d01e3c3 100644 --- a/tests/ui/type/option-ref-advice.rs +++ b/tests/ui/type/option-ref-advice.rs @@ -3,9 +3,9 @@ fn takes_option(_arg: Option<&String>) {} fn main() { - takes_option(&None); //~ ERROR 6:18: 6:23: mismatched types [E0308] + takes_option(&None); //~ ERROR mismatched types [E0308] let x = String::from("x"); let res = Some(x); - takes_option(&res); //~ ERROR 10:18: 10:22: mismatched types [E0308] + takes_option(&res); //~ ERROR mismatched types [E0308] } diff --git a/tests/ui/typeck/issue-100246.rs b/tests/ui/typeck/issue-100246.rs index 8f0b34bab0c87..e05bb2a1362a5 100644 --- a/tests/ui/typeck/issue-100246.rs +++ b/tests/ui/typeck/issue-100246.rs @@ -25,6 +25,6 @@ fn downcast<'a, W: ?Sized>() -> std::io::Result<&'a W> { struct Other; fn main() -> std::io::Result<()> { - let other: Other = downcast()?;//~ERROR 28:24: 28:35: `?` operator has incompatible types + let other: Other = downcast()?; //~ ERROR `?` operator has incompatible types Ok(()) } diff --git a/tests/ui/typeck/issue-89275.rs b/tests/ui/typeck/issue-89275.rs index b91c001754872..6e4211de1857f 100644 --- a/tests/ui/typeck/issue-89275.rs +++ b/tests/ui/typeck/issue-89275.rs @@ -25,5 +25,5 @@ fn downcast<'a, W: ?Sized>() -> &'a W { struct Other; fn main() { - let other: &mut Other = downcast();//~ERROR 28:29: 28:39: mismatched types [E0308] + let other: &mut Other = downcast();//~ ERROR mismatched types [E0308] }