From 4748d92a9571f8ed009cfa8aec0aefec0390cb5e Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 14 Oct 2025 17:49:34 -0600 Subject: [PATCH] feat: Always use annotate-snippets for Unicode output --- compiler/rustc_errors/src/emitter.rs | 3 +- compiler/rustc_errors/src/json.rs | 18 ++++------- compiler/rustc_parse/src/parser/tests.rs | 24 ++++++++++----- compiler/rustc_session/src/config.rs | 10 +++---- compiler/rustc_session/src/session.rs | 29 ++++-------------- src/librustdoc/core.rs | 14 ++------- src/librustdoc/doctest.rs | 2 +- ...dth-unicode-multiline-label.unicode.stderr | 30 +++++++++---------- tests/ui/error-emitter/unicode-output.svg | 2 +- 9 files changed, 54 insertions(+), 78 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index d98d6e563645..2c5fb64998fd 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -48,8 +48,7 @@ #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum HumanReadableErrorType { Default, - Unicode, - AnnotateSnippet, + AnnotateSnippet { unicode: bool }, Short, } diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 260559a9ef33..d495d6b6b1a7 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -379,7 +379,7 @@ fn flush(&mut self) -> io::Result<()> { choice => choice, }, ); - if let HumanReadableErrorType::AnnotateSnippet = je.json_rendered { + if let HumanReadableErrorType::AnnotateSnippet { unicode } = je.json_rendered { AnnotateSnippetEmitter::new(dst, je.translator.clone()) .short_message(short) .sm(je.sm.clone()) @@ -391,12 +391,8 @@ fn flush(&mut self) -> io::Result<()> { .ignored_directories_in_source_blocks( je.ignored_directories_in_source_blocks.clone(), ) - .theme(if let HumanReadableErrorType::Unicode = je.json_rendered { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) - .emit_diagnostic(diag, registry); + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) + .emit_diagnostic(diag, registry) } else { HumanEmitter::new(dst, je.translator.clone()) .short_message(short) @@ -409,12 +405,8 @@ fn flush(&mut self) -> io::Result<()> { .ignored_directories_in_source_blocks( je.ignored_directories_in_source_blocks.clone(), ) - .theme(if let HumanReadableErrorType::Unicode = je.json_rendered { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) - .emit_diagnostic(diag, registry); + .theme(OutputTheme::Ascii) + .emit_diagnostic(diag, registry) } let buf = Arc::try_unwrap(buf.0).unwrap().into_inner().unwrap(); diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs index 5fe921da1381..9b157cb6c7bf 100644 --- a/compiler/rustc_parse/src/parser/tests.rs +++ b/compiler/rustc_parse/src/parser/tests.rs @@ -1,5 +1,4 @@ #![allow(rustc::symbol_intern_string_literal)] - use std::assert_matches::assert_matches; use std::io::prelude::*; use std::iter::Peekable; @@ -12,6 +11,7 @@ use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_ast::{self as ast, PatKind, visit}; use rustc_ast_pretty::pprust::item_to_string; +use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::emitter::{HumanEmitter, OutputTheme}; use rustc_errors::translation::Translator; use rustc_errors::{AutoStream, DiagCtxt, MultiSpan, PResult}; @@ -43,12 +43,22 @@ fn create_test_handler(theme: OutputTheme) -> (DiagCtxt, Arc, Arc = Box::new(Shared { data: output.clone() }); + let auto_stream = AutoStream::never(shared); + let dcx = DiagCtxt::new(match theme { + OutputTheme::Ascii => Box::new( + HumanEmitter::new(auto_stream, translator) + .sm(Some(source_map.clone())) + .diagnostic_width(Some(140)) + .theme(theme), + ), + OutputTheme::Unicode => Box::new( + AnnotateSnippetEmitter::new(auto_stream, translator) + .sm(Some(source_map.clone())) + .diagnostic_width(Some(140)) + .theme(theme), + ), + }); (dcx, source_map, output) } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index ce6f6434e793..b980ff5f2ae7 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2060,7 +2060,7 @@ pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Json match sub_option { "diagnostic-short" => json_rendered = HumanReadableErrorType::Short, "diagnostic-unicode" => { - json_rendered = HumanReadableErrorType::Unicode; + json_rendered = HumanReadableErrorType::AnnotateSnippet { unicode: true }; } "diagnostic-rendered-ansi" => json_color = ColorConfig::Always, "artifacts" => json_artifact_notifications = true, @@ -2099,7 +2099,7 @@ pub fn parse_error_format( match matches.opt_str("error-format").as_deref() { None | Some("human") => ErrorOutputType::HumanReadable { color_config, .. }, Some("human-annotate-rs") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType::AnnotateSnippet, + kind: HumanReadableErrorType::AnnotateSnippet { unicode: false }, color_config, }, Some("json") => { @@ -2112,7 +2112,7 @@ pub fn parse_error_format( ErrorOutputType::HumanReadable { kind: HumanReadableErrorType::Short, color_config } } Some("human-unicode") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType::Unicode, + kind: HumanReadableErrorType::AnnotateSnippet { unicode: true }, color_config, }, Some(arg) => { @@ -2180,8 +2180,8 @@ fn check_error_format_stability( let format = match format { ErrorOutputType::Json { pretty: true, .. } => "pretty-json", ErrorOutputType::HumanReadable { kind, .. } => match kind { - HumanReadableErrorType::AnnotateSnippet => "human-annotate-rs", - HumanReadableErrorType::Unicode => "human-unicode", + HumanReadableErrorType::AnnotateSnippet { unicode: false } => "human-annotate-rs", + HumanReadableErrorType::AnnotateSnippet { unicode: true } => "human-unicode", _ => return, }, _ => return, diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index fa8646d8e207..243e1ee9f949 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -952,8 +952,7 @@ fn default_emitter( match sopts.error_format { config::ErrorOutputType::HumanReadable { kind, color_config } => { let short = kind.short(); - - if let HumanReadableErrorType::AnnotateSnippet = kind { + if let HumanReadableErrorType::AnnotateSnippet { unicode } = kind { let emitter = AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) .sm(source_map) @@ -962,11 +961,7 @@ fn default_emitter( .macro_backtrace(macro_backtrace) .track_diagnostics(track_diagnostics) .terminal_url(terminal_url) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) .ignored_directories_in_source_blocks( sopts .unstable_opts @@ -982,11 +977,7 @@ fn default_emitter( .macro_backtrace(macro_backtrace) .track_diagnostics(track_diagnostics) .terminal_url(terminal_url) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(OutputTheme::Ascii) .ignored_directories_in_source_blocks( sopts.unstable_opts.ignore_directory_in_diagnostics_source_blocks.clone(), ); @@ -1501,24 +1492,16 @@ fn mk_emitter(output: ErrorOutputType) -> Box { let emitter: Box = match output { config::ErrorOutputType::HumanReadable { kind, color_config } => { let short = kind.short(); - if let HumanReadableErrorType::AnnotateSnippet = kind { + if let HumanReadableErrorType::AnnotateSnippet { unicode } = kind { Box::new( AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) .short_message(short), ) } else { Box::new( HumanEmitter::new(stderr_destination(color_config), translator) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(OutputTheme::Ascii) .short_message(short), ) } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 8ee2fc7a43ee..abbdef05ef83 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -155,18 +155,14 @@ pub(crate) fn new_dcx( let emitter: Box = match error_format { ErrorOutputType::HumanReadable { kind, color_config } => { let short = kind.short(); - if let HumanReadableErrorType::AnnotateSnippet = kind { + if let HumanReadableErrorType::AnnotateSnippet { unicode } = kind { Box::new( AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) .sm(source_map.map(|sm| sm as _)) .short_message(short) .diagnostic_width(diagnostic_width) .track_diagnostics(unstable_opts.track_diagnostics) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) .ui_testing(unstable_opts.ui_testing), ) } else { @@ -176,11 +172,7 @@ pub(crate) fn new_dcx( .short_message(short) .diagnostic_width(diagnostic_width) .track_diagnostics(unstable_opts.track_diagnostics) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) + .theme(OutputTheme::Ascii) .ui_testing(unstable_opts.ui_testing), ) } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 631c48a4fdb8..c67bf2d891e6 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -600,7 +600,7 @@ fn run_test( ]); if let ErrorOutputType::HumanReadable { kind, color_config } = rustdoc_options.error_format { let short = kind.short(); - let unicode = kind == HumanReadableErrorType::Unicode; + let unicode = kind == HumanReadableErrorType::AnnotateSnippet { unicode: true }; if short { compiler_args.extend_from_slice(&["--error-format".to_owned(), "short".to_owned()]); diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr index 4dff15642aeb..6220a6ba7b31 100644 --- a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr +++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.unicode.stderr @@ -1,11 +1,11 @@ error[E0369]: cannot add `&str` to `&str` ╭▸ $DIR/non-1-width-unicode-multiline-label.rs:8:237 │ -LL │ …👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; - │ ┬───────────── ┯ ────────────── &str - │ │ │ - │ │ `+` cannot be used to concatenate two `&str` strings - │ &str +LL │ … 👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; + │ ┬───────────── ┯ ────────────── &str + │ │ │ + │ │ `+` cannot be used to concatenate two `&str` strings + │ &str │ ╰ note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference @@ -16,11 +16,11 @@ LL │ let _ = "👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧 error[E0369]: cannot add `&str` to `&str` ╭▸ $DIR/non-1-width-unicode-multiline-label.rs:10:384 │ -LL │ …👨👩👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; - │ ┬───────────── ┯ ────────────── &str - │ │ │ - │ │ `+` cannot be used to concatenate two `&str` strings - │ &str +LL │ … 👧👦👨👩👧👦👨👩👧👦"; let _a = unicode_is_fun + " really fun!"; + │ ┬───────────── ┯ ────────────── &str + │ │ │ + │ │ `+` cannot be used to concatenate two `&str` strings + │ &str │ ╰ note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference @@ -31,11 +31,11 @@ LL │ let _ = "👨👩👧👦👨👩👧👦👨👩👧👦👨👩👧 error[E0369]: cannot add `&str` to `&str` ╭▸ $DIR/non-1-width-unicode-multiline-label.rs:12:260 │ -LL │ …࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; - │ ┬───────────── ┯ ────────────── &str - │ │ │ - │ │ `+` cannot be used to concatenate two `&str` strings - │ &str +LL │ …࿄࿅࿆࿇࿈࿉࿊࿋࿌࿍࿎࿏࿐࿑࿒࿓࿔࿕࿖࿗࿘࿙࿚"; let _a = unicode_is_fun + " really fun!"; + │ ┬───────────── ┯ ────────────── &str + │ │ │ + │ │ `+` cannot be used to concatenate two `&str` strings + │ &str │ ╰ note: string concatenation requires an owned `String` on the left help: create an owned `String` from a string reference diff --git a/tests/ui/error-emitter/unicode-output.svg b/tests/ui/error-emitter/unicode-output.svg index 9c1b7c80f433..5623421ab788 100644 --- a/tests/ui/error-emitter/unicode-output.svg +++ b/tests/ui/error-emitter/unicode-output.svg @@ -55,7 +55,7 @@ LL )>>) {} - ╰╴└───┘ + ╰╴└───┘