@@ -16,6 +16,8 @@ use std::iter;
1616use std:: path:: Path ;
1717use std:: sync:: Arc ;
1818
19+ use anstream:: { AutoStream , ColorChoice } ;
20+ use anstyle:: { Ansi256Color , AnsiColor , Effects } ;
1921use derive_setters:: Setters ;
2022use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
2123use rustc_data_structures:: sync:: { DynSend , IntoDynSyncSend } ;
@@ -25,7 +27,6 @@ use rustc_lint_defs::pluralize;
2527use rustc_span:: hygiene:: { ExpnKind , MacroKind } ;
2628use rustc_span:: source_map:: SourceMap ;
2729use rustc_span:: { FileLines , FileName , SourceFile , Span , char_width, str_width} ;
28- use termcolor:: { Buffer , BufferWriter , Color , ColorChoice , ColorSpec , StandardStream , WriteColor } ;
2930use tracing:: { debug, instrument, trace, warn} ;
3031
3132use crate :: registry:: Registry ;
@@ -525,10 +526,6 @@ impl Emitter for HumanEmitter {
525526 !self . short_message
526527 }
527528
528- fn supports_color ( & self ) -> bool {
529- self . dst . supports_color ( )
530- }
531-
532529 fn translator ( & self ) -> & Translator {
533530 & self . translator
534531 }
@@ -1701,7 +1698,6 @@ impl HumanEmitter {
17011698 } else {
17021699 col_sep_before_no_show_source = true ;
17031700 }
1704-
17051701 // print out the span location and spacer before we print the annotated source
17061702 // to do this, we need to know if this span will be primary
17071703 let is_primary = primary_lo. file . name == annotated_file. file . name ;
@@ -3127,7 +3123,6 @@ impl FileWithAnnotatedLines {
31273123 multiline_depth : 0 ,
31283124 } ) ;
31293125 }
3130-
31313126 let mut output = vec ! [ ] ;
31323127 let mut multiline_annotations = vec ! [ ] ;
31333128
@@ -3361,7 +3356,7 @@ const OUTPUT_REPLACEMENTS: &[(char, &str)] = &[
33613356 ( '\u{2069}' , "�" ) ,
33623357] ;
33633358
3364- fn normalize_whitespace ( s : & str ) -> String {
3359+ pub ( crate ) fn normalize_whitespace ( s : & str ) -> String {
33653360 const {
33663361 let mut i = 1 ;
33673362 while i < OUTPUT_REPLACEMENTS . len ( ) {
@@ -3406,13 +3401,14 @@ fn overlaps(a1: &Annotation, a2: &Annotation, padding: usize) -> bool {
34063401 )
34073402}
34083403
3409- fn emit_to_destination (
3404+ pub ( crate ) fn emit_to_destination (
34103405 rendered_buffer : & [ Vec < StyledString > ] ,
34113406 lvl : & Level ,
34123407 dst : & mut Destination ,
34133408 short_message : bool ,
34143409) -> io:: Result < ( ) > {
34153410 use crate :: lock;
3411+ const RESET : anstyle:: Reset = anstyle:: Reset ;
34163412
34173413 // In order to prevent error message interleaving, where multiple error lines get intermixed
34183414 // when multiple compiler processes error simultaneously, we emit errors with additional
@@ -3429,10 +3425,8 @@ fn emit_to_destination(
34293425 let _buffer_lock = lock:: acquire_global_lock ( "rustc_errors" ) ;
34303426 for ( pos, line) in rendered_buffer. iter ( ) . enumerate ( ) {
34313427 for part in line {
3432- let style = part. style . color_spec ( * lvl) ;
3433- dst. set_color ( & style) ?;
3434- write ! ( dst, "{}" , part. text) ?;
3435- dst. reset ( ) ?;
3428+ let style = part. style . anstyle ( * lvl) ;
3429+ write ! ( dst, "{RESET}{style}{}{RESET}" , part. text) ?;
34363430 }
34373431 if !short_message && ( !lvl. is_failure_note ( ) || pos != rendered_buffer. len ( ) - 1 ) {
34383432 writeln ! ( dst) ?;
@@ -3442,11 +3436,11 @@ fn emit_to_destination(
34423436 Ok ( ( ) )
34433437}
34443438
3445- pub type Destination = Box < dyn WriteColor + Send > ;
3439+ pub type Destination = AutoStream < Box < dyn Write + Send > > ;
34463440
34473441struct Buffy {
3448- buffer_writer : BufferWriter ,
3449- buffer : Buffer ,
3442+ buffer_writer : std :: io :: Stderr ,
3443+ buffer : Vec < u8 > ,
34503444}
34513445
34523446impl Write for Buffy {
@@ -3455,7 +3449,7 @@ impl Write for Buffy {
34553449 }
34563450
34573451 fn flush ( & mut self ) -> io:: Result < ( ) > {
3458- self . buffer_writer . print ( & self . buffer ) ?;
3452+ self . buffer_writer . write_all ( & self . buffer ) ?;
34593453 self . buffer . clear ( ) ;
34603454 Ok ( ( ) )
34613455 }
@@ -3470,83 +3464,59 @@ impl Drop for Buffy {
34703464 }
34713465}
34723466
3473- impl WriteColor for Buffy {
3474- fn supports_color ( & self ) -> bool {
3475- self . buffer . supports_color ( )
3476- }
3477-
3478- fn set_color ( & mut self , spec : & ColorSpec ) -> io:: Result < ( ) > {
3479- self . buffer . set_color ( spec)
3480- }
3481-
3482- fn reset ( & mut self ) -> io:: Result < ( ) > {
3483- self . buffer . reset ( )
3484- }
3485- }
3486-
34873467pub fn stderr_destination ( color : ColorConfig ) -> Destination {
3468+ let buffer_writer = std:: io:: stderr ( ) ;
34883469 let choice = color. to_color_choice ( ) ;
3470+ // We need to resolve `ColorChoice::Auto` before `Box`ing since
3471+ // `ColorChoice::Auto` on `dyn Write` will always resolve to `Never`
3472+ let choice = if matches ! ( choice, ColorChoice :: Auto ) {
3473+ AutoStream :: choice ( & buffer_writer)
3474+ } else {
3475+ choice
3476+ } ;
34893477 // On Windows we'll be performing global synchronization on the entire
34903478 // system for emitting rustc errors, so there's no need to buffer
34913479 // anything.
34923480 //
34933481 // On non-Windows we rely on the atomicity of `write` to ensure errors
34943482 // don't get all jumbled up.
34953483 if cfg ! ( windows) {
3496- Box :: new ( StandardStream :: stderr ( choice ) )
3484+ AutoStream :: new ( Box :: new ( buffer_writer ) , choice )
34973485 } else {
3498- let buffer_writer = BufferWriter :: stderr ( choice) ;
3499- let buffer = buffer_writer. buffer ( ) ;
3500- Box :: new ( Buffy { buffer_writer, buffer } )
3486+ let buffer = Vec :: new ( ) ;
3487+ AutoStream :: new ( Box :: new ( Buffy { buffer_writer, buffer } ) , choice)
35013488 }
35023489}
35033490
35043491/// On Windows, BRIGHT_BLUE is hard to read on black. Use cyan instead.
35053492///
35063493/// See #36178.
3507- const BRIGHT_BLUE : Color = if cfg ! ( windows) { Color :: Cyan } else { Color :: Blue } ;
3494+ const BRIGHT_BLUE : anstyle:: Style = if cfg ! ( windows) {
3495+ Ansi256Color :: from_ansi ( AnsiColor :: BrightCyan ) . on_default ( )
3496+ } else {
3497+ Ansi256Color :: from_ansi ( AnsiColor :: BrightBlue ) . on_default ( )
3498+ } ;
35083499
35093500impl Style {
3510- fn color_spec ( & self , lvl : Level ) -> ColorSpec {
3511- let mut spec = ColorSpec :: new ( ) ;
3501+ pub ( crate ) fn anstyle ( & self , lvl : Level ) -> anstyle:: Style {
35123502 match self {
3513- Style :: Addition => {
3514- spec. set_fg ( Some ( Color :: Green ) ) . set_intense ( true ) ;
3515- }
3516- Style :: Removal => {
3517- spec. set_fg ( Some ( Color :: Red ) ) . set_intense ( true ) ;
3518- }
3519- Style :: LineAndColumn => { }
3520- Style :: LineNumber => {
3521- spec. set_bold ( true ) ;
3522- spec. set_intense ( true ) ;
3523- spec. set_fg ( Some ( BRIGHT_BLUE ) ) ;
3524- }
3525- Style :: Quotation => { }
3526- Style :: MainHeaderMsg => {
3527- spec. set_bold ( true ) ;
3528- if cfg ! ( windows) {
3529- spec. set_intense ( true ) . set_fg ( Some ( Color :: White ) ) ;
3530- }
3531- }
3532- Style :: UnderlinePrimary | Style :: LabelPrimary => {
3533- spec = lvl. color ( ) ;
3534- spec. set_bold ( true ) ;
3535- }
3536- Style :: UnderlineSecondary | Style :: LabelSecondary => {
3537- spec. set_bold ( true ) . set_intense ( true ) ;
3538- spec. set_fg ( Some ( BRIGHT_BLUE ) ) ;
3539- }
3540- Style :: HeaderMsg | Style :: NoStyle => { }
3541- Style :: Level ( lvl) => {
3542- spec = lvl. color ( ) ;
3543- spec. set_bold ( true ) ;
3544- }
3545- Style :: Highlight => {
3546- spec. set_bold ( true ) . set_fg ( Some ( Color :: Magenta ) ) ;
3503+ Style :: Addition => Ansi256Color :: from_ansi ( AnsiColor :: BrightGreen ) . on_default ( ) ,
3504+ Style :: Removal => Ansi256Color :: from_ansi ( AnsiColor :: BrightRed ) . on_default ( ) ,
3505+ Style :: LineAndColumn => anstyle:: Style :: new ( ) ,
3506+ Style :: LineNumber => BRIGHT_BLUE . effects ( Effects :: BOLD ) ,
3507+ Style :: Quotation => anstyle:: Style :: new ( ) ,
3508+ Style :: MainHeaderMsg => if cfg ! ( windows) {
3509+ Ansi256Color :: from_ansi ( AnsiColor :: BrightWhite ) . on_default ( )
3510+ } else {
3511+ anstyle:: Style :: new ( )
35473512 }
3513+ . effects ( Effects :: BOLD ) ,
3514+ Style :: UnderlinePrimary | Style :: LabelPrimary => lvl. color ( ) . effects ( Effects :: BOLD ) ,
3515+ Style :: UnderlineSecondary | Style :: LabelSecondary => BRIGHT_BLUE . effects ( Effects :: BOLD ) ,
3516+ Style :: HeaderMsg | Style :: NoStyle => anstyle:: Style :: new ( ) ,
3517+ Style :: Level ( lvl) => lvl. color ( ) . effects ( Effects :: BOLD ) ,
3518+ Style :: Highlight => AnsiColor :: Magenta . on_default ( ) . effects ( Effects :: BOLD ) ,
35483519 }
3549- spec
35503520 }
35513521}
35523522
0 commit comments