From b55f27d4be8e07e6d20d298f6e5129687629c8ae Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 28 Oct 2025 12:53:40 -0600 Subject: [PATCH 1/6] chore: Update annotate-snippets to 0.12.8 --- Cargo.lock | 6 +++--- compiler/rustc_errors/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5e9ba9b432793..6720a9eb9cf55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,9 +80,9 @@ dependencies = [ [[package]] name = "annotate-snippets" -version = "0.12.7" +version = "0.12.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47224528f74de27d1d06aad6a5dda4f865b6ebe2e56c538943d746a7270cb67e" +checksum = "025c7edcdffa4ccc5c0905f472a0ae3759378cfbef88ef518a3575e19ae3aebd" dependencies = [ "anstyle", "unicode-width 0.2.2", @@ -3767,7 +3767,7 @@ dependencies = [ name = "rustc_errors" version = "0.0.0" dependencies = [ - "annotate-snippets 0.12.7", + "annotate-snippets 0.12.8", "anstream", "anstyle", "derive_setters", diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index 6ade87ea3b255..6606092e421eb 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start -annotate-snippets = "0.12.7" +annotate-snippets = "0.12.8" anstream = "0.6.20" anstyle = "1.0.13" derive_setters = "0.1.6" From 0aaf27fe3f92c6a2fedc8a49e8a0efeee1e295f5 Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 28 Oct 2025 00:00:34 -0600 Subject: [PATCH 2/6] chore: Make AnnotateSnippetEmitter match revert of "all spans must be disjoint" --- .../src/annotate_snippet_emitter_writer.rs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index 854e3ddf15e4a..5d22a8b8e30ab 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -329,7 +329,7 @@ impl AnnotateSnippetEmitter { let substitutions = suggestion .substitutions .into_iter() - .filter_map(|mut subst| { + .filter(|subst| { // Suggestions coming from macros can have malformed spans. This is a heavy // handed approach to avoid ICEs by ignoring the suggestion outright. let invalid = @@ -337,12 +337,14 @@ impl AnnotateSnippetEmitter { if invalid { debug!("suggestion contains an invalid span: {:?}", subst); } - + !invalid + }) + .filter_map(|mut subst| { // Assumption: all spans are in the same file, and all spans // are disjoint. Sort in ascending order. subst.parts.sort_by_key(|part| part.span.lo()); // Verify the assumption that all spans are disjoint - assert_eq!( + debug_assert_eq!( subst.parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)), None, "all spans must be disjoint", @@ -355,13 +357,11 @@ impl AnnotateSnippetEmitter { let item_span = subst.parts.first()?; let file = sm.lookup_source_file(item_span.span.lo()); - if !invalid - && should_show_source_code( - &self.ignored_directories_in_source_blocks, - sm, - &file, - ) - { + if should_show_source_code( + &self.ignored_directories_in_source_blocks, + sm, + &file, + ) { Some(subst) } else { None From 01bd7c0e19dba1812ad1573a6a68859fd56a0b5d Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 14 Oct 2025 18:27:08 -0600 Subject: [PATCH 3/6] fix: Respect HumanReadableErrorType::AnnotateSnippet --- compiler/rustc_errors/src/json.rs | 54 +++++++++++++++++++-------- compiler/rustc_session/src/session.rs | 30 ++++++++++----- src/librustdoc/core.rs | 43 ++++++++++++++------- 3 files changed, 90 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 03ce1d82ef3c4..260559a9ef337 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -25,6 +25,7 @@ use rustc_span::hygiene::ExpnData; use rustc_span::source_map::{FilePathMapping, SourceMap}; use serde::Serialize; +use crate::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use crate::diagnostic::IsLint; use crate::emitter::{ ColorConfig, Destination, Emitter, HumanEmitter, HumanReadableErrorType, OutputTheme, @@ -378,21 +379,44 @@ impl Diagnostic { choice => choice, }, ); - HumanEmitter::new(dst, je.translator.clone()) - .short_message(short) - .sm(je.sm.clone()) - .diagnostic_width(je.diagnostic_width) - .macro_backtrace(je.macro_backtrace) - .track_diagnostics(je.track_diagnostics) - .terminal_url(je.terminal_url) - .ui_testing(je.ui_testing) - .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); + if let HumanReadableErrorType::AnnotateSnippet = je.json_rendered { + AnnotateSnippetEmitter::new(dst, je.translator.clone()) + .short_message(short) + .sm(je.sm.clone()) + .diagnostic_width(je.diagnostic_width) + .macro_backtrace(je.macro_backtrace) + .track_diagnostics(je.track_diagnostics) + .terminal_url(je.terminal_url) + .ui_testing(je.ui_testing) + .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); + } else { + HumanEmitter::new(dst, je.translator.clone()) + .short_message(short) + .sm(je.sm.clone()) + .diagnostic_width(je.diagnostic_width) + .macro_backtrace(je.macro_backtrace) + .track_diagnostics(je.track_diagnostics) + .terminal_url(je.terminal_url) + .ui_testing(je.ui_testing) + .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); + } + let buf = Arc::try_unwrap(buf.0).unwrap().into_inner().unwrap(); let buf = String::from_utf8(buf).unwrap(); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 522faf1db9ff1..4bbdbf46fdb15 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1501,15 +1501,27 @@ fn mk_emitter(output: ErrorOutputType) -> Box { let emitter: Box = match output { config::ErrorOutputType::HumanReadable { kind, color_config } => { let short = kind.short(); - Box::new( - HumanEmitter::new(stderr_destination(color_config), translator) - .theme(if let HumanReadableErrorType::Unicode = kind { - OutputTheme::Unicode - } else { - OutputTheme::Ascii - }) - .short_message(short), - ) + if let HumanReadableErrorType::AnnotateSnippet = kind { + Box::new( + AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) + .theme(if let HumanReadableErrorType::Unicode = kind { + 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 + }) + .short_message(short), + ) + } } config::ErrorOutputType::Json { pretty, json_rendered, color_config } => { Box::new(JsonEmitter::new( diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 44bac8197539b..8ee2fc7a43eed 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -5,6 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_data_structures::unord::UnordSet; use rustc_driver::USING_INTERNAL_FEATURES; use rustc_errors::TerminalUrl; +use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; use rustc_errors::codes::*; use rustc_errors::emitter::{ DynEmitter, HumanEmitter, HumanReadableErrorType, OutputTheme, stderr_destination, @@ -154,19 +155,35 @@ pub(crate) fn new_dcx( let emitter: Box = match error_format { ErrorOutputType::HumanReadable { kind, color_config } => { let short = kind.short(); - Box::new( - HumanEmitter::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 - }) - .ui_testing(unstable_opts.ui_testing), - ) + if let HumanReadableErrorType::AnnotateSnippet = 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 + }) + .ui_testing(unstable_opts.ui_testing), + ) + } else { + Box::new( + HumanEmitter::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 + }) + .ui_testing(unstable_opts.ui_testing), + ) + } } ErrorOutputType::Json { pretty, json_rendered, color_config } => { let source_map = source_map.unwrap_or_else(|| { From 2203b641557352bb4b063820806c8ef29af2fa01 Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 14 Oct 2025 17:49:34 -0600 Subject: [PATCH 4/6] 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 9e32a85e361a5..44e379e2059bc 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -48,8 +48,7 @@ const DEFAULT_COLUMN_WIDTH: usize = 140; #[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 260559a9ef337..d495d6b6b1a7a 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -379,7 +379,7 @@ impl Diagnostic { 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 @@ impl Diagnostic { .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 @@ impl Diagnostic { .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 5fe921da13817..9b157cb6c7bf9 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::token::{self, Delimiter, Token}; 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 60e301a5fd870..0d63dec0b2b8c 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2071,7 +2071,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, @@ -2110,7 +2110,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") => { @@ -2123,7 +2123,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) => { @@ -2191,8 +2191,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 4bbdbf46fdb15..2c7f7d7308c9d 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 8ee2fc7a43eed..abbdef05ef831 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 c9cd9f7fd4b11..dea41da0aa187 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -599,7 +599,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 4dff15642aeb4..6220a6ba7b310 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 9c1b7c80f4331..5623421ab7886 100644 --- a/tests/ui/error-emitter/unicode-output.svg +++ b/tests/ui/error-emitter/unicode-output.svg @@ -55,7 +55,7 @@ LL )>>) {} - ╰╴└───┘ + ╰╴└───┘ From 26e1b1e590ba3cc6957e627d4dbc431ebf7fdd6b Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Mon, 27 Oct 2025 11:22:39 -0600 Subject: [PATCH 5/6] refactor: Make short a field on HumanReadableErrorType varinants --- compiler/rustc_errors/src/emitter.rs | 10 +++-- compiler/rustc_errors/src/json.rs | 60 +++++++++++++------------ compiler/rustc_errors/src/json/tests.rs | 2 +- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_session/src/config.rs | 26 ++++++----- compiler/rustc_session/src/session.rs | 38 +++++++--------- src/librustdoc/core.rs | 44 +++++++++--------- src/librustdoc/doctest.rs | 2 +- 8 files changed, 92 insertions(+), 92 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 44e379e2059bc..72bfa1d313cd1 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -47,14 +47,16 @@ const DEFAULT_COLUMN_WIDTH: usize = 140; /// Describes the way the content of the `rendered` field of the json output is generated #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum HumanReadableErrorType { - Default, - AnnotateSnippet { unicode: bool }, - Short, + Default { short: bool }, + AnnotateSnippet { short: bool, unicode: bool }, } impl HumanReadableErrorType { pub fn short(&self) -> bool { - *self == HumanReadableErrorType::Short + match self { + HumanReadableErrorType::Default { short } + | HumanReadableErrorType::AnnotateSnippet { short, .. } => *short, + } } } diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index d495d6b6b1a7a..ce5c830bbfcd6 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -371,7 +371,6 @@ impl Diagnostic { .insert(0, Diagnostic::from_sub_diagnostic(&diag.emitted_at_sub_diag(), &args, je)); } let buf = BufWriter(Arc::new(Mutex::new(Vec::new()))); - let short = je.json_rendered.short(); let dst: Destination = AutoStream::new( Box::new(buf.clone()), match je.color_config.to_color_choice() { @@ -379,34 +378,37 @@ impl Diagnostic { choice => choice, }, ); - if let HumanReadableErrorType::AnnotateSnippet { unicode } = je.json_rendered { - AnnotateSnippetEmitter::new(dst, je.translator.clone()) - .short_message(short) - .sm(je.sm.clone()) - .diagnostic_width(je.diagnostic_width) - .macro_backtrace(je.macro_backtrace) - .track_diagnostics(je.track_diagnostics) - .terminal_url(je.terminal_url) - .ui_testing(je.ui_testing) - .ignored_directories_in_source_blocks( - je.ignored_directories_in_source_blocks.clone(), - ) - .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) - .emit_diagnostic(diag, registry) - } else { - HumanEmitter::new(dst, je.translator.clone()) - .short_message(short) - .sm(je.sm.clone()) - .diagnostic_width(je.diagnostic_width) - .macro_backtrace(je.macro_backtrace) - .track_diagnostics(je.track_diagnostics) - .terminal_url(je.terminal_url) - .ui_testing(je.ui_testing) - .ignored_directories_in_source_blocks( - je.ignored_directories_in_source_blocks.clone(), - ) - .theme(OutputTheme::Ascii) - .emit_diagnostic(diag, registry) + match je.json_rendered { + HumanReadableErrorType::AnnotateSnippet { short, unicode } => { + AnnotateSnippetEmitter::new(dst, je.translator.clone()) + .short_message(short) + .sm(je.sm.clone()) + .diagnostic_width(je.diagnostic_width) + .macro_backtrace(je.macro_backtrace) + .track_diagnostics(je.track_diagnostics) + .terminal_url(je.terminal_url) + .ui_testing(je.ui_testing) + .ignored_directories_in_source_blocks( + je.ignored_directories_in_source_blocks.clone(), + ) + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) + .emit_diagnostic(diag, registry) + } + HumanReadableErrorType::Default { short } => { + HumanEmitter::new(dst, je.translator.clone()) + .short_message(short) + .sm(je.sm.clone()) + .diagnostic_width(je.diagnostic_width) + .macro_backtrace(je.macro_backtrace) + .track_diagnostics(je.track_diagnostics) + .terminal_url(je.terminal_url) + .ui_testing(je.ui_testing) + .ignored_directories_in_source_blocks( + je.ignored_directories_in_source_blocks.clone(), + ) + .theme(OutputTheme::Ascii) + .emit_diagnostic(diag, registry) + } } let buf = Arc::try_unwrap(buf.0).unwrap().into_inner().unwrap(); diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index 8cf81f467d84c..79bb5054dfeff 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -50,7 +50,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { Some(sm), translator, true, // pretty - HumanReadableErrorType::Short, + HumanReadableErrorType::Default { short: true }, ColorConfig::Never, ); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index be33db21d1df6..e0b69d41b95a9 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -321,7 +321,7 @@ fn test_search_paths_tracking_hash_different_order() { let early_dcx = EarlyDiagCtxt::new(JSON); const JSON: ErrorOutputType = ErrorOutputType::Json { pretty: false, - json_rendered: HumanReadableErrorType::Default, + json_rendered: HumanReadableErrorType::Default { short: false }, color_config: ColorConfig::Never, }; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 0d63dec0b2b8c..2bb963756182e 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -837,7 +837,7 @@ pub enum ErrorOutputType { /// Output meant for the consumption of humans. #[default] HumanReadable { - kind: HumanReadableErrorType = HumanReadableErrorType::Default, + kind: HumanReadableErrorType = HumanReadableErrorType::Default { short: false }, color_config: ColorConfig = ColorConfig::Auto, }, /// Output that's consumed by other tools such as `rustfix` or the `RLS`. @@ -2053,7 +2053,7 @@ impl JsonUnusedExterns { /// The first value returned is how to render JSON diagnostics, and the second /// is whether or not artifact notifications are enabled. pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> JsonConfig { - let mut json_rendered = HumanReadableErrorType::Default; + let mut json_rendered = HumanReadableErrorType::Default { short: false }; let mut json_color = ColorConfig::Never; let mut json_artifact_notifications = false; let mut json_unused_externs = JsonUnusedExterns::No; @@ -2069,9 +2069,12 @@ pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Json for sub_option in option.split(',') { match sub_option { - "diagnostic-short" => json_rendered = HumanReadableErrorType::Short, + "diagnostic-short" => { + json_rendered = HumanReadableErrorType::Default { short: true } + } "diagnostic-unicode" => { - json_rendered = HumanReadableErrorType::AnnotateSnippet { unicode: true }; + json_rendered = + HumanReadableErrorType::AnnotateSnippet { short: false, unicode: true }; } "diagnostic-rendered-ansi" => json_color = ColorConfig::Always, "artifacts" => json_artifact_notifications = true, @@ -2110,7 +2113,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 { unicode: false }, + kind: HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false }, color_config, }, Some("json") => { @@ -2119,11 +2122,12 @@ pub fn parse_error_format( Some("pretty-json") => { ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color } } - Some("short") => { - ErrorOutputType::HumanReadable { kind: HumanReadableErrorType::Short, color_config } - } + Some("short") => ErrorOutputType::HumanReadable { + kind: HumanReadableErrorType::Default { short: true }, + color_config, + }, Some("human-unicode") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType::AnnotateSnippet { unicode: true }, + kind: HumanReadableErrorType::AnnotateSnippet { short: false, unicode: true }, color_config, }, Some(arg) => { @@ -2191,8 +2195,8 @@ fn check_error_format_stability( let format = match format { ErrorOutputType::Json { pretty: true, .. } => "pretty-json", ErrorOutputType::HumanReadable { kind, .. } => match kind { - HumanReadableErrorType::AnnotateSnippet { unicode: false } => "human-annotate-rs", - HumanReadableErrorType::AnnotateSnippet { unicode: true } => "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 2c7f7d7308c9d..424d729307926 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -950,9 +950,8 @@ fn default_emitter( let source_map = if sopts.unstable_opts.link_only { None } else { Some(source_map) }; match sopts.error_format { - config::ErrorOutputType::HumanReadable { kind, color_config } => { - let short = kind.short(); - if let HumanReadableErrorType::AnnotateSnippet { unicode } = kind { + config::ErrorOutputType::HumanReadable { kind, color_config } => match kind { + HumanReadableErrorType::AnnotateSnippet { short, unicode } => { let emitter = AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) .sm(source_map) @@ -969,7 +968,8 @@ fn default_emitter( .clone(), ); Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing)) - } else { + } + HumanReadableErrorType::Default { short } => { let emitter = HumanEmitter::new(stderr_destination(color_config), translator) .sm(source_map) .short_message(short) @@ -983,7 +983,7 @@ fn default_emitter( ); Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing)) } - } + }, config::ErrorOutputType::Json { pretty, json_rendered, color_config } => Box::new( JsonEmitter::new( Box::new(io::BufWriter::new(io::stderr())), @@ -1490,22 +1490,18 @@ fn mk_emitter(output: ErrorOutputType) -> Box { let translator = Translator::with_fallback_bundle(vec![rustc_errors::DEFAULT_LOCALE_RESOURCE], false); let emitter: Box = match output { - config::ErrorOutputType::HumanReadable { kind, color_config } => { - let short = kind.short(); - if let HumanReadableErrorType::AnnotateSnippet { unicode } = kind { - Box::new( - AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) - .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) - .short_message(short), - ) - } else { - Box::new( - HumanEmitter::new(stderr_destination(color_config), translator) - .theme(OutputTheme::Ascii) - .short_message(short), - ) - } - } + config::ErrorOutputType::HumanReadable { kind, color_config } => match kind { + HumanReadableErrorType::AnnotateSnippet { short, unicode } => Box::new( + AnnotateSnippetEmitter::new(stderr_destination(color_config), translator) + .theme(if unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) + .short_message(short), + ), + HumanReadableErrorType::Default { short } => Box::new( + HumanEmitter::new(stderr_destination(color_config), translator) + .theme(OutputTheme::Ascii) + .short_message(short), + ), + }, config::ErrorOutputType::Json { pretty, json_rendered, color_config } => { Box::new(JsonEmitter::new( Box::new(io::BufWriter::new(io::stderr())), diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index abbdef05ef831..451d0b4f5be91 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -153,30 +153,26 @@ pub(crate) fn new_dcx( ) -> rustc_errors::DiagCtxt { let translator = rustc_driver::default_translator(); let emitter: Box = match error_format { - ErrorOutputType::HumanReadable { kind, color_config } => { - let short = kind.short(); - 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 unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) - .ui_testing(unstable_opts.ui_testing), - ) - } else { - Box::new( - HumanEmitter::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(OutputTheme::Ascii) - .ui_testing(unstable_opts.ui_testing), - ) - } - } + ErrorOutputType::HumanReadable { kind, color_config } => match kind { + HumanReadableErrorType::AnnotateSnippet { short, unicode } => 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 unicode { OutputTheme::Unicode } else { OutputTheme::Ascii }) + .ui_testing(unstable_opts.ui_testing), + ), + HumanReadableErrorType::Default { short } => Box::new( + HumanEmitter::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(OutputTheme::Ascii) + .ui_testing(unstable_opts.ui_testing), + ), + }, ErrorOutputType::Json { pretty, json_rendered, color_config } => { let source_map = source_map.unwrap_or_else(|| { Arc::new(source_map::SourceMap::new(source_map::FilePathMapping::empty())) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index dea41da0aa187..26bea1ac8a84d 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -599,7 +599,7 @@ fn run_test( ]); if let ErrorOutputType::HumanReadable { kind, color_config } = rustdoc_options.error_format { let short = kind.short(); - let unicode = kind == HumanReadableErrorType::AnnotateSnippet { unicode: true }; + let unicode = kind == HumanReadableErrorType::AnnotateSnippet { unicode: true, short }; if short { compiler_args.extend_from_slice(&["--error-format".to_owned(), "short".to_owned()]); From 0d8882c739ad7c3047cc804a6e2a13c1e4389e6c Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 14 Oct 2025 19:19:46 -0600 Subject: [PATCH 6/6] feat: Use annotate-snippets by default on nightly --- compiler/rustc_session/src/config.rs | 66 +++++++++++++++---- src/librustdoc/config.rs | 19 ++++-- .../tests/ui/bool_assert_comparison.stderr | 12 ++-- .../tests/ui/new_without_default.stderr | 3 - tests/crashes/131762.rs | 1 + .../main-alongside-macro-calls.fail.stdout | 2 + ...width-unicode-multiline-label.ascii.stderr | 30 ++++----- .../non-whitespace-trimming-unicode.stderr | 8 +-- .../ui/diagnostic-width/tabs-trimming.stderr | 20 +++--- .../ui/include-macros/mismatched-types.stderr | 2 + tests/ui/macros/same-sequence-span.stderr | 10 +-- 11 files changed, 105 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 2bb963756182e..0ee6e3a143bd4 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2052,8 +2052,16 @@ impl JsonUnusedExterns { /// /// The first value returned is how to render JSON diagnostics, and the second /// is whether or not artifact notifications are enabled. -pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> JsonConfig { - let mut json_rendered = HumanReadableErrorType::Default { short: false }; +pub fn parse_json( + early_dcx: &EarlyDiagCtxt, + matches: &getopts::Matches, + is_nightly_build: bool, +) -> JsonConfig { + let mut json_rendered = if is_nightly_build { + HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false } + } else { + HumanReadableErrorType::Default { short: false } + }; let mut json_color = ColorConfig::Never; let mut json_artifact_notifications = false; let mut json_unused_externs = JsonUnusedExterns::No; @@ -2070,7 +2078,11 @@ pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Json for sub_option in option.split(',') { match sub_option { "diagnostic-short" => { - json_rendered = HumanReadableErrorType::Default { short: true } + json_rendered = if is_nightly_build { + HumanReadableErrorType::AnnotateSnippet { short: true, unicode: false } + } else { + HumanReadableErrorType::Default { short: true } + }; } "diagnostic-unicode" => { json_rendered = @@ -2104,14 +2116,22 @@ pub fn parse_error_format( color_config: ColorConfig, json_color: ColorConfig, json_rendered: HumanReadableErrorType, + is_nightly_build: bool, ) -> ErrorOutputType { + let default_kind = if is_nightly_build { + HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false } + } else { + HumanReadableErrorType::Default { short: false } + }; // We need the `opts_present` check because the driver will send us Matches // with only stable options if no unstable options are used. Since error-format // is unstable, it will not be present. We have to use `opts_present` not // `opt_present` because the latter will panic. let error_format = if matches.opts_present(&["error-format".to_owned()]) { match matches.opt_str("error-format").as_deref() { - None | Some("human") => ErrorOutputType::HumanReadable { color_config, .. }, + None | Some("human") => { + ErrorOutputType::HumanReadable { color_config, kind: default_kind } + } Some("human-annotate-rs") => ErrorOutputType::HumanReadable { kind: HumanReadableErrorType::AnnotateSnippet { short: false, unicode: false }, color_config, @@ -2123,7 +2143,11 @@ pub fn parse_error_format( ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color } } Some("short") => ErrorOutputType::HumanReadable { - kind: HumanReadableErrorType::Default { short: true }, + kind: if is_nightly_build { + HumanReadableErrorType::AnnotateSnippet { short: true, unicode: false } + } else { + HumanReadableErrorType::Default { short: true } + }, color_config, }, Some("human-unicode") => ErrorOutputType::HumanReadable { @@ -2131,7 +2155,10 @@ pub fn parse_error_format( color_config, }, Some(arg) => { - early_dcx.set_error_format(ErrorOutputType::HumanReadable { color_config, .. }); + early_dcx.set_error_format(ErrorOutputType::HumanReadable { + color_config, + kind: default_kind, + }); early_dcx.early_fatal(format!( "argument for `--error-format` must be `human`, `human-annotate-rs`, \ `human-unicode`, `json`, `pretty-json` or `short` (instead was `{arg}`)" @@ -2139,7 +2166,7 @@ pub fn parse_error_format( } } } else { - ErrorOutputType::HumanReadable { color_config, .. } + ErrorOutputType::HumanReadable { color_config, kind: default_kind } }; match error_format { @@ -2187,9 +2214,10 @@ pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches fn check_error_format_stability( early_dcx: &EarlyDiagCtxt, unstable_opts: &UnstableOptions, + is_nightly_build: bool, format: ErrorOutputType, ) { - if unstable_opts.unstable_options { + if unstable_opts.unstable_options || is_nightly_build { return; } let format = match format { @@ -2617,6 +2645,8 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let edition = parse_crate_edition(early_dcx, matches); + let crate_name = matches.opt_str("crate-name"); + let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref()); let JsonConfig { json_rendered, json_color, @@ -2624,9 +2654,16 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M json_timings, json_unused_externs, json_future_incompat, - } = parse_json(early_dcx, matches); + } = parse_json(early_dcx, matches, unstable_features.is_nightly_build()); - let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered); + let error_format = parse_error_format( + early_dcx, + matches, + color, + json_color, + json_rendered, + unstable_features.is_nightly_build(), + ); early_dcx.set_error_format(error_format); @@ -2647,7 +2684,12 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M early_dcx.early_fatal("--json=timings is unstable and requires using `-Zunstable-options`"); } - check_error_format_stability(early_dcx, &unstable_opts, error_format); + check_error_format_stability( + early_dcx, + &unstable_opts, + unstable_features.is_nightly_build(), + error_format, + ); let output_types = parse_output_types(early_dcx, &unstable_opts, matches); @@ -2834,8 +2876,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M ) } - let crate_name = matches.opt_str("crate-name"); - let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref()); // Parse any `-l` flags, which link to native libraries. let libs = parse_native_libs(early_dcx, &unstable_opts, unstable_features, matches); diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 55e04671b83ca..da19f506a3700 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -389,10 +389,19 @@ impl Options { } let color = config::parse_color(early_dcx, matches); + let crate_name = matches.opt_str("crate-name"); + let unstable_features = + rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref()); let config::JsonConfig { json_rendered, json_unused_externs, json_color, .. } = - config::parse_json(early_dcx, matches); - let error_format = - config::parse_error_format(early_dcx, matches, color, json_color, json_rendered); + config::parse_json(early_dcx, matches, unstable_features.is_nightly_build()); + let error_format = config::parse_error_format( + early_dcx, + matches, + color, + json_color, + json_rendered, + unstable_features.is_nightly_build(), + ); let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_default(); let mut target_modifiers = BTreeMap::::new(); @@ -753,7 +762,6 @@ impl Options { } }; - let crate_name = matches.opt_str("crate-name"); let bin_crate = crate_types.contains(&CrateType::Executable); let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro); let playground_url = matches.opt_str("playground-url"); @@ -815,9 +823,6 @@ impl Options { crate::scrape_examples::load_call_locations(with_examples, dcx, &mut loaded_paths); let doctest_build_args = matches.opt_strs("doctest-build-arg"); - let unstable_features = - rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref()); - let disable_minification = matches.opt_present("disable-minification"); let options = Options { diff --git a/src/tools/clippy/tests/ui/bool_assert_comparison.stderr b/src/tools/clippy/tests/ui/bool_assert_comparison.stderr index f823f08f31dca..72aa6303a2026 100644 --- a/src/tools/clippy/tests/ui/bool_assert_comparison.stderr +++ b/src/tools/clippy/tests/ui/bool_assert_comparison.stderr @@ -272,10 +272,8 @@ LL | assert_eq!(a!(), true); | help: replace it with `assert!(..)` | -LL | true -... -LL | -LL ~ assert!(a!()); +LL - assert_eq!(a!(), true); +LL + assert!(a!()); | error: used `assert_eq!` with a literal bool @@ -286,10 +284,8 @@ LL | assert_eq!(true, b!()); | help: replace it with `assert!(..)` | -LL | true -... -LL | -LL ~ assert!(b!()); +LL - assert_eq!(true, b!()); +LL + assert!(b!()); | error: used `debug_assert_eq!` with a literal bool diff --git a/src/tools/clippy/tests/ui/new_without_default.stderr b/src/tools/clippy/tests/ui/new_without_default.stderr index 1e0d5e2131994..0593dbb00fb6b 100644 --- a/src/tools/clippy/tests/ui/new_without_default.stderr +++ b/src/tools/clippy/tests/ui/new_without_default.stderr @@ -191,7 +191,6 @@ LL + fn default() -> Self { LL + Self::new() LL + } LL + } -LL | impl NewWithCfg { | error: you should consider adding a `Default` implementation for `NewWith2Cfgs` @@ -212,7 +211,6 @@ LL + fn default() -> Self { LL + Self::new() LL + } LL + } -LL | impl NewWith2Cfgs { | error: you should consider adding a `Default` implementation for `NewWithExtraneous` @@ -250,7 +248,6 @@ LL + fn default() -> Self { LL + Self::new() LL + } LL + } -LL | impl NewWithCfgAndExtraneous { | error: aborting due to 13 previous errors diff --git a/tests/crashes/131762.rs b/tests/crashes/131762.rs index 85cb9c8f20a8b..4080272226d94 100644 --- a/tests/crashes/131762.rs +++ b/tests/crashes/131762.rs @@ -1,3 +1,4 @@ +//@ needs-rustc-debug-assertions //@ known-bug: #131762 // ignore-tidy-linelength diff --git a/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout b/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout index 65989a8ef47c7..1048db07ae95a 100644 --- a/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout +++ b/tests/rustdoc-ui/doctest/main-alongside-macro-calls.fail.stdout @@ -19,6 +19,7 @@ LL | println!(); error: macro expansion ignores `{` and any tokens following --> $SRC_DIR/std/src/macros.rs:LL:COL | + | ::: $DIR/main-alongside-macro-calls.rs:30:1 | LL | println!(); @@ -41,6 +42,7 @@ LL | println!(); error: macro expansion ignores `{` and any tokens following --> $SRC_DIR/std/src/macros.rs:LL:COL | + | ::: $DIR/main-alongside-macro-calls.rs:34:1 | LL | println!(); diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr index fe1ecfbe71d4c..66d5a808d03c9 100644 --- a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.stderr +++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.ascii.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/diagnostic-width/non-whitespace-trimming-unicode.stderr b/tests/ui/diagnostic-width/non-whitespace-trimming-unicode.stderr index e74afbfeac478..46369c551cf38 100644 --- a/tests/ui/diagnostic-width/non-whitespace-trimming-unicode.stderr +++ b/tests/ui/diagnostic-width/non-whitespace-trimming-unicode.stderr @@ -1,10 +1,10 @@ error[E0308]: mismatched types --> $DIR/non-whitespace-trimming-unicode.rs:5:415 | -LL | ...♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4"; let _: () = 42; let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓ ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽ ... - | -- ^^ expected `()`, found integer - | | - | expected due to this +LL | ...♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4"; let _: () = 42; let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓ ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳... + | -- ^^ expected `()`, found integer + | | + | expected due to this error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic-width/tabs-trimming.stderr b/tests/ui/diagnostic-width/tabs-trimming.stderr index e0d1c2d95a965..dfda30e6005b0 100644 --- a/tests/ui/diagnostic-width/tabs-trimming.stderr +++ b/tests/ui/diagnostic-width/tabs-trimming.stderr @@ -1,20 +1,20 @@ error[E0408]: variable `v` is not bound in all patterns --> $DIR/tabs-trimming.rs:9:16 | -LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... - | - ^ ^ pattern doesn't bind `v` - | | | - | | pattern doesn't bind `v` - | variable not in all patterns +LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... + | - ^ ^ pattern doesn't bind `v` + | | | + | | pattern doesn't bind `v` + | variable not in all patterns error[E0381]: used binding `v` is possibly-uninitialized --> $DIR/tabs-trimming.rs:9:67 | -LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... - | - ^ `v` used here but it is possibly-uninitialized - | | - | binding initialized here in some conditions - | binding declared here but left uninitialized +LL | ... v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT... + | - ^ `v` used here but it is possibly-uninitialized + | | + | binding initialized here in some conditions + | binding declared here but left uninitialized error: aborting due to 2 previous errors diff --git a/tests/ui/include-macros/mismatched-types.stderr b/tests/ui/include-macros/mismatched-types.stderr index 8d541966a6a40..4fab832c2d8e8 100644 --- a/tests/ui/include-macros/mismatched-types.stderr +++ b/tests/ui/include-macros/mismatched-types.stderr @@ -1,6 +1,8 @@ error[E0308]: mismatched types --> $DIR/file.txt:0:1 | +LL | + | ^ expected `&[u8]`, found `&str` | ::: $DIR/mismatched-types.rs:2:12 | diff --git a/tests/ui/macros/same-sequence-span.stderr b/tests/ui/macros/same-sequence-span.stderr index 1ca89b6b595c8..d6652453e9a9e 100644 --- a/tests/ui/macros/same-sequence-span.stderr +++ b/tests/ui/macros/same-sequence-span.stderr @@ -17,14 +17,8 @@ LL | $(= $z:tt)* error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments --> $DIR/same-sequence-span.rs:20:1 | -LL | | // `proc_macro_sequence.rs`. - | |_____________________________^not allowed after `expr` fragments -... -LL | proc_macro_sequence::make_foo!(); - | ^------------------------------- - | | - | _in this macro invocation - | | +LL | proc_macro_sequence::make_foo!(); + | -------------------------------- in this macro invocation | = note: allowed there are: `=>`, `,` or `;` = note: this error originates in the macro `proc_macro_sequence::make_foo` (in Nightly builds, run with -Z macro-backtrace for more info)