@@ -16,6 +16,9 @@ use std::iter;
1616use std:: path:: Path ;
1717use std:: sync:: Arc ;
1818
19+ use anstream:: ColorChoice ;
20+ use anstream:: stream:: { AsLockedWrite , RawStream } ;
21+ use anstyle:: { AnsiColor , Effects } ;
1922use derive_setters:: Setters ;
2023use rustc_data_structures:: fx:: { FxIndexMap , FxIndexSet } ;
2124use rustc_data_structures:: sync:: { DynSend , IntoDynSyncSend } ;
@@ -25,7 +28,6 @@ use rustc_lint_defs::pluralize;
2528use rustc_span:: hygiene:: { ExpnKind , MacroKind } ;
2629use rustc_span:: source_map:: SourceMap ;
2730use rustc_span:: { FileLines , FileName , SourceFile , Span , char_width, str_width} ;
28- use termcolor:: { Buffer , BufferWriter , Color , ColorChoice , ColorSpec , StandardStream , WriteColor } ;
2931use tracing:: { debug, instrument, trace, warn} ;
3032
3133use crate :: registry:: Registry ;
@@ -1701,7 +1703,6 @@ impl HumanEmitter {
17011703 } else {
17021704 col_sep_before_no_show_source = true ;
17031705 }
1704-
17051706 // print out the span location and spacer before we print the annotated source
17061707 // to do this, we need to know if this span will be primary
17071708 let is_primary = primary_lo. file . name == annotated_file. file . name ;
@@ -3127,7 +3128,6 @@ impl FileWithAnnotatedLines {
31273128 multiline_depth : 0 ,
31283129 } ) ;
31293130 }
3130-
31313131 let mut output = vec ! [ ] ;
31323132 let mut multiline_annotations = vec ! [ ] ;
31333133
@@ -3361,7 +3361,7 @@ const OUTPUT_REPLACEMENTS: &[(char, &str)] = &[
33613361 ( '\u{2069}' , "�" ) ,
33623362] ;
33633363
3364- fn normalize_whitespace ( s : & str ) -> String {
3364+ pub ( crate ) fn normalize_whitespace ( s : & str ) -> String {
33653365 const {
33663366 let mut i = 1 ;
33673367 while i < OUTPUT_REPLACEMENTS . len ( ) {
@@ -3406,7 +3406,26 @@ fn overlaps(a1: &Annotation, a2: &Annotation, padding: usize) -> bool {
34063406 )
34073407}
34083408
3409- fn emit_to_destination (
3409+ pub trait WriteColor : io:: Write {
3410+ fn supports_color ( & self ) -> bool ;
3411+ }
3412+
3413+ impl < S : RawStream + AsLockedWrite > WriteColor for anstream:: AutoStream < S > {
3414+ fn supports_color ( & self ) -> bool {
3415+ match self . current_choice ( ) {
3416+ ColorChoice :: Always | ColorChoice :: AlwaysAnsi | ColorChoice :: Auto => true ,
3417+ ColorChoice :: Never => false ,
3418+ }
3419+ }
3420+ }
3421+
3422+ impl WriteColor for std:: io:: Sink {
3423+ fn supports_color ( & self ) -> bool {
3424+ false
3425+ }
3426+ }
3427+
3428+ pub ( crate ) fn emit_to_destination (
34103429 rendered_buffer : & [ Vec < StyledString > ] ,
34113430 lvl : & Level ,
34123431 dst : & mut Destination ,
@@ -3429,10 +3448,8 @@ fn emit_to_destination(
34293448 let _buffer_lock = lock:: acquire_global_lock ( "rustc_errors" ) ;
34303449 for ( pos, line) in rendered_buffer. iter ( ) . enumerate ( ) {
34313450 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 ( ) ?;
3451+ let style = part. style . anstyle ( * lvl) ;
3452+ write ! ( dst, "{style}{}{style:#}" , part. text) ?;
34363453 }
34373454 if !short_message && ( !lvl. is_failure_note ( ) || pos != rendered_buffer. len ( ) - 1 ) {
34383455 writeln ! ( dst) ?;
@@ -3445,8 +3462,8 @@ fn emit_to_destination(
34453462pub type Destination = Box < dyn WriteColor + Send > ;
34463463
34473464struct Buffy {
3448- buffer_writer : BufferWriter ,
3449- buffer : Buffer ,
3465+ buffer_writer : anstream :: Stderr ,
3466+ buffer : Vec < u8 > ,
34503467}
34513468
34523469impl Write for Buffy {
@@ -3455,7 +3472,7 @@ impl Write for Buffy {
34553472 }
34563473
34573474 fn flush ( & mut self ) -> io:: Result < ( ) > {
3458- self . buffer_writer . print ( & self . buffer ) ?;
3475+ self . buffer_writer . write_all ( & self . buffer ) ?;
34593476 self . buffer . clear ( ) ;
34603477 Ok ( ( ) )
34613478 }
@@ -3472,15 +3489,11 @@ impl Drop for Buffy {
34723489
34733490impl WriteColor for Buffy {
34743491 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 ( )
3492+ self . buffer_writer . current_choice ( ) ;
3493+ match self . buffer_writer . current_choice ( ) {
3494+ ColorChoice :: Always | ColorChoice :: AlwaysAnsi | ColorChoice :: Auto => true ,
3495+ ColorChoice :: Never => false ,
3496+ }
34843497 }
34853498}
34863499
@@ -3492,61 +3505,44 @@ pub fn stderr_destination(color: ColorConfig) -> Destination {
34923505 //
34933506 // On non-Windows we rely on the atomicity of `write` to ensure errors
34943507 // don't get all jumbled up.
3508+ let buffer_writer = anstream:: Stderr :: new ( std:: io:: stderr ( ) , choice) ;
34953509 if cfg ! ( windows) {
3496- Box :: new ( StandardStream :: stderr ( choice ) )
3510+ Box :: new ( buffer_writer )
34973511 } else {
3498- let buffer_writer = BufferWriter :: stderr ( choice) ;
3499- let buffer = buffer_writer. buffer ( ) ;
3512+ let buffer = Vec :: new ( ) ;
35003513 Box :: new ( Buffy { buffer_writer, buffer } )
35013514 }
35023515}
35033516
35043517/// On Windows, BRIGHT_BLUE is hard to read on black. Use cyan instead.
35053518///
35063519/// See #36178.
3507- const BRIGHT_BLUE : Color = if cfg ! ( windows) { Color :: Cyan } else { Color :: Blue } ;
3520+ const BRIGHT_BLUE : anstyle:: Style = if cfg ! ( windows) {
3521+ AnsiColor :: BrightCyan . on_default ( )
3522+ } else {
3523+ AnsiColor :: BrightBlue . on_default ( )
3524+ } ;
35083525
35093526impl Style {
3510- fn color_spec ( & self , lvl : Level ) -> ColorSpec {
3511- let mut spec = ColorSpec :: new ( ) ;
3527+ pub ( crate ) fn anstyle ( & self , lvl : Level ) -> anstyle:: Style {
35123528 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 ) ) ;
3529+ Style :: Addition => AnsiColor :: BrightGreen . on_default ( ) ,
3530+ Style :: Removal => AnsiColor :: BrightRed . on_default ( ) ,
3531+ Style :: LineAndColumn => anstyle:: Style :: new ( ) ,
3532+ Style :: LineNumber => BRIGHT_BLUE . effects ( Effects :: BOLD ) ,
3533+ Style :: Quotation => anstyle:: Style :: new ( ) ,
3534+ Style :: MainHeaderMsg => if cfg ! ( windows) {
3535+ AnsiColor :: BrightWhite . on_default ( )
3536+ } else {
3537+ anstyle:: Style :: new ( )
35473538 }
3539+ . effects ( Effects :: BOLD ) ,
3540+ Style :: UnderlinePrimary | Style :: LabelPrimary => lvl. color ( ) . effects ( Effects :: BOLD ) ,
3541+ Style :: UnderlineSecondary | Style :: LabelSecondary => BRIGHT_BLUE . effects ( Effects :: BOLD ) ,
3542+ Style :: HeaderMsg | Style :: NoStyle => anstyle:: Style :: new ( ) ,
3543+ Style :: Level ( lvl) => lvl. color ( ) . effects ( Effects :: BOLD ) ,
3544+ Style :: Highlight => AnsiColor :: Magenta . on_default ( ) . effects ( Effects :: BOLD ) ,
35483545 }
3549- spec
35503546 }
35513547}
35523548
0 commit comments