1
- use std:: borrow:: Cow ;
2
1
use std:: path:: Path ;
3
2
use std:: sync:: atomic:: { AtomicBool , Ordering } ;
4
3
5
4
use rustc_data_structures:: sync:: { IntoDynSyncSend , Lrc } ;
6
- use rustc_errors:: emitter:: { DynEmitter , Emitter , HumanEmitter } ;
5
+ use rustc_errors:: emitter:: { DynEmitter , Emitter , HumanEmitter , SilentEmitter } ;
7
6
use rustc_errors:: translation:: Translate ;
8
7
use rustc_errors:: {
9
8
ColorConfig , DiagCtxt , Diagnostic , DiagnosticBuilder , Level as DiagnosticLevel ,
@@ -30,41 +29,6 @@ pub(crate) struct ParseSess {
30
29
can_reset_errors : Lrc < AtomicBool > ,
31
30
}
32
31
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
-
68
32
/// Emit errors against every files expect ones specified in the `ignore_path_set`.
69
33
struct SilentOnIgnoredFilesEmitter {
70
34
ignore_path_set : IntoDynSyncSend < Lrc < IgnorePathSet > > ,
@@ -145,15 +109,19 @@ fn default_dcx(
145
109
ColorConfig :: Never
146
110
} ;
147
111
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 } )
150
121
} 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
156
123
} ;
124
+
157
125
DiagCtxt :: with_emitter ( Box :: new ( SilentOnIgnoredFilesEmitter {
158
126
has_non_ignorable_parser_errors : false ,
159
127
source_map,
@@ -231,7 +199,21 @@ impl ParseSess {
231
199
}
232
200
233
201
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
+ }
235
217
}
236
218
237
219
pub ( crate ) fn span_to_filename ( & self , span : Span ) -> FileName {
0 commit comments