1- use std:: borrow:: Cow ;
21use std:: path:: Path ;
32use std:: sync:: atomic:: { AtomicBool , Ordering } ;
43
54use rustc_data_structures:: sync:: { IntoDynSyncSend , Lrc } ;
6- use rustc_errors:: emitter:: { DynEmitter , Emitter , HumanEmitter } ;
5+ use rustc_errors:: emitter:: { DynEmitter , Emitter , HumanEmitter , SilentEmitter } ;
76use rustc_errors:: translation:: Translate ;
87use rustc_errors:: {
98 ColorConfig , DiagCtxt , Diagnostic , DiagnosticBuilder , Level as DiagnosticLevel ,
@@ -30,41 +29,6 @@ pub(crate) struct ParseSess {
3029 can_reset_errors : Lrc < AtomicBool > ,
3130}
3231
33- /// Emitter which discards every error.
34- struct SilentEmitter ;
35-
36- impl Translate for SilentEmitter {
37- fn fluent_bundle ( & self ) -> Option < & Lrc < rustc_errors:: FluentBundle > > {
38- None
39- }
40-
41- fn fallback_fluent_bundle ( & self ) -> & rustc_errors:: FluentBundle {
42- panic ! ( "silent emitter attempted to translate a diagnostic" ) ;
43- }
44-
45- // Override `translate_message` for the silent emitter because eager translation of
46- // subdiagnostics result in a call to this.
47- fn translate_message < ' a > (
48- & ' a self ,
49- message : & ' a rustc_errors:: DiagnosticMessage ,
50- _: & ' a rustc_errors:: translation:: FluentArgs < ' _ > ,
51- ) -> Result < Cow < ' _ , str > , rustc_errors:: error:: TranslateError < ' _ > > {
52- rustc_errors:: emitter:: silent_translate ( message)
53- }
54- }
55-
56- impl Emitter for SilentEmitter {
57- fn source_map ( & self ) -> Option < & Lrc < SourceMap > > {
58- None
59- }
60-
61- fn emit_diagnostic ( & mut self , _db : Diagnostic ) { }
62- }
63-
64- fn silent_emitter ( ) -> Box < DynEmitter > {
65- Box :: new ( SilentEmitter { } )
66- }
67-
6832/// Emit errors against every files expect ones specified in the `ignore_path_set`.
6933struct SilentOnIgnoredFilesEmitter {
7034 ignore_path_set : IntoDynSyncSend < Lrc < IgnorePathSet > > ,
@@ -145,15 +109,19 @@ fn default_dcx(
145109 ColorConfig :: Never
146110 } ;
147111
148- let emitter = if hide_parse_errors {
149- silent_emitter ( )
112+ let fallback_bundle = rustc_errors:: fallback_fluent_bundle (
113+ rustc_driver:: DEFAULT_LOCALE_RESOURCES . to_vec ( ) ,
114+ false ,
115+ ) ;
116+ let emitter =
117+ Box :: new ( HumanEmitter :: stderr ( emit_color, fallback_bundle. clone ( ) ) . sm ( Some ( source_map. clone ( ) ) ) ) ;
118+
119+ let emitter: Box < DynEmitter > = if hide_parse_errors {
120+ Box :: new ( SilentEmitter { fallback_bundle, fatal_dcx : DiagCtxt :: with_emitter ( emitter) , fatal_note : None } )
150121 } else {
151- let fallback_bundle = rustc_errors:: fallback_fluent_bundle (
152- rustc_driver:: DEFAULT_LOCALE_RESOURCES . to_vec ( ) ,
153- false ,
154- ) ;
155- Box :: new ( HumanEmitter :: stderr ( emit_color, fallback_bundle) . sm ( Some ( source_map. clone ( ) ) ) )
122+ emitter
156123 } ;
124+
157125 DiagCtxt :: with_emitter ( Box :: new ( SilentOnIgnoredFilesEmitter {
158126 has_non_ignorable_parser_errors : false ,
159127 source_map,
@@ -231,7 +199,21 @@ impl ParseSess {
231199 }
232200
233201 pub ( crate ) fn set_silent_emitter ( & mut self ) {
234- self . parse_sess . dcx = DiagCtxt :: with_emitter ( silent_emitter ( ) ) ;
202+ // Ideally this invocation wouldn't be necessary and the fallback bundle in
203+ // `self.parse_sess.dcx` could be used.
204+ let fallback_bundle = rustc_errors:: fallback_fluent_bundle (
205+ rustc_driver:: DEFAULT_LOCALE_RESOURCES . to_vec ( ) ,
206+ false ,
207+ ) ;
208+ // SAFETY: `fatal_dcx` will not be dropped while it is referenced by `self.parse_sess.dcx`,
209+ // and `self.parse_sess.dcx` is written to by `ptr::write` so won't drop `fatal_dcx`.
210+ unsafe {
211+ let fatal_dcx = std:: ptr:: read ( & self . parse_sess . dcx ) ;
212+ std:: ptr:: write (
213+ & mut self . parse_sess . dcx ,
214+ DiagCtxt :: with_emitter ( Box :: new ( SilentEmitter { fallback_bundle, fatal_dcx, fatal_note : None } ) )
215+ ) ;
216+ }
235217 }
236218
237219 pub ( crate ) fn span_to_filename ( & self , span : Span ) -> FileName {
0 commit comments