@@ -1054,7 +1054,7 @@ impl Handler {
10541054 }
10551055 let mut diagnostic = Diagnostic :: new ( Level :: DelayedBug , msg) ;
10561056 diagnostic. set_span ( sp) ;
1057- inner. emit_diagnostic ( & mut diagnostic) . unwrap ( )
1057+ inner. emit_diagnostic ( diagnostic) . unwrap ( )
10581058 }
10591059
10601060 // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's
@@ -1064,15 +1064,17 @@ impl Handler {
10641064
10651065 let mut diagnostic = Diagnostic :: new ( Level :: DelayedBug , msg) ;
10661066 if inner. flags . report_delayed_bugs {
1067- inner. emit_diagnostic ( & mut diagnostic) ;
1067+ inner. emit_diagnostic_without_consuming ( & mut diagnostic) ;
10681068 }
10691069 let backtrace = std:: backtrace:: Backtrace :: capture ( ) ;
10701070 inner. good_path_delayed_bugs . push ( DelayedDiagnostic :: with_backtrace ( diagnostic, backtrace) ) ;
10711071 }
10721072
10731073 #[ track_caller]
10741074 pub fn span_bug_no_panic ( & self , span : impl Into < MultiSpan > , msg : impl Into < DiagnosticMessage > ) {
1075- self . emit_diagnostic ( Diagnostic :: new ( Bug , msg) . set_span ( span) ) ;
1075+ let mut diag = Diagnostic :: new ( Bug , msg) ;
1076+ diag. set_span ( span) ;
1077+ self . emit_diagnostic ( diag) ;
10761078 }
10771079
10781080 #[ track_caller]
@@ -1185,10 +1187,10 @@ impl Handler {
11851187 DiagnosticMessage :: Str ( warnings) ,
11861188 ) ) ,
11871189 ( _, 0 ) => {
1188- inner. emit_diagnostic ( & mut Diagnostic :: new ( Fatal , errors) ) ;
1190+ inner. emit_diagnostic ( Diagnostic :: new ( Fatal , errors) ) ;
11891191 }
11901192 ( _, _) => {
1191- inner. emit_diagnostic ( & mut Diagnostic :: new ( Fatal , format ! ( "{errors}; {warnings}" ) ) ) ;
1193+ inner. emit_diagnostic ( Diagnostic :: new ( Fatal , format ! ( "{errors}; {warnings}" ) ) ) ;
11921194 }
11931195 }
11941196
@@ -1255,8 +1257,17 @@ impl Handler {
12551257 self . inner . borrow_mut ( ) . emitter . emit_diagnostic ( & db) ;
12561258 }
12571259
1258- pub fn emit_diagnostic ( & self , diagnostic : & mut Diagnostic ) -> Option < ErrorGuaranteed > {
1259- self . inner . borrow_mut ( ) . emit_diagnostic ( diagnostic)
1260+ pub fn emit_diagnostic ( & self , mut diagnostic : Diagnostic ) -> Option < ErrorGuaranteed > {
1261+ self . emit_diagnostic_without_consuming ( & mut diagnostic)
1262+ }
1263+
1264+ // It's unfortunate this exists. `emit_diagnostic` is preferred, because it
1265+ // consumes the diagnostic, thus ensuring it is emitted just once.
1266+ pub ( crate ) fn emit_diagnostic_without_consuming (
1267+ & self ,
1268+ diagnostic : & mut Diagnostic ,
1269+ ) -> Option < ErrorGuaranteed > {
1270+ self . inner . borrow_mut ( ) . emit_diagnostic_without_consuming ( diagnostic)
12601271 }
12611272
12621273 pub fn emit_err < ' a > ( & ' a self , err : impl IntoDiagnostic < ' a > ) -> ErrorGuaranteed {
@@ -1370,7 +1381,7 @@ impl Handler {
13701381 // Here the diagnostic is given back to `emit_diagnostic` where it was first
13711382 // intercepted. Now it should be processed as usual, since the unstable expectation
13721383 // id is now stable.
1373- inner. emit_diagnostic ( & mut diag) ;
1384+ inner. emit_diagnostic ( diag) ;
13741385 }
13751386 }
13761387
@@ -1412,7 +1423,7 @@ impl HandlerInner {
14121423 let has_errors = self . has_errors ( ) ;
14131424 let diags = self . stashed_diagnostics . drain ( ..) . map ( |x| x. 1 ) . collect :: < Vec < _ > > ( ) ;
14141425 let mut reported = None ;
1415- for mut diag in diags {
1426+ for diag in diags {
14161427 // Decrement the count tracking the stash; emitting will increment it.
14171428 if diag. is_error ( ) {
14181429 if matches ! ( diag. level, Level :: Error { lint: true } ) {
@@ -1432,14 +1443,20 @@ impl HandlerInner {
14321443 }
14331444 }
14341445 }
1435- let reported_this = self . emit_diagnostic ( & mut diag) ;
1446+ let reported_this = self . emit_diagnostic ( diag) ;
14361447 reported = reported. or ( reported_this) ;
14371448 }
14381449 reported
14391450 }
14401451
1441- // FIXME(eddyb) this should ideally take `diagnostic` by value.
1442- fn emit_diagnostic ( & mut self , diagnostic : & mut Diagnostic ) -> Option < ErrorGuaranteed > {
1452+ fn emit_diagnostic ( & mut self , mut diagnostic : Diagnostic ) -> Option < ErrorGuaranteed > {
1453+ self . emit_diagnostic_without_consuming ( & mut diagnostic)
1454+ }
1455+
1456+ fn emit_diagnostic_without_consuming (
1457+ & mut self ,
1458+ diagnostic : & mut Diagnostic ,
1459+ ) -> Option < ErrorGuaranteed > {
14431460 if matches ! ( diagnostic. level, Level :: Error { .. } | Level :: Fatal ) && self . treat_err_as_bug ( )
14441461 {
14451462 diagnostic. level = Level :: Bug ;
@@ -1576,12 +1593,14 @@ impl HandlerInner {
15761593
15771594 #[ track_caller]
15781595 fn span_bug ( & mut self , sp : impl Into < MultiSpan > , msg : impl Into < DiagnosticMessage > ) -> ! {
1579- self . emit_diagnostic ( Diagnostic :: new ( Bug , msg) . set_span ( sp) ) ;
1596+ let mut diag = Diagnostic :: new ( Bug , msg) ;
1597+ diag. set_span ( sp) ;
1598+ self . emit_diagnostic ( diag) ;
15801599 panic:: panic_any ( ExplicitBug ) ;
15811600 }
15821601
15831602 fn failure_note ( & mut self , msg : impl Into < DiagnosticMessage > ) {
1584- self . emit_diagnostic ( & mut Diagnostic :: new ( FailureNote , msg) ) ;
1603+ self . emit_diagnostic ( Diagnostic :: new ( FailureNote , msg) ) ;
15851604 }
15861605
15871606 fn flush_delayed (
@@ -1613,7 +1632,7 @@ impl HandlerInner {
16131632 if no_bugs {
16141633 // Put the overall explanation before the `DelayedBug`s, to
16151634 // frame them better (e.g. separate warnings from them).
1616- self . emit_diagnostic ( & mut Diagnostic :: new ( Bug , explanation) ) ;
1635+ self . emit_diagnostic ( Diagnostic :: new ( Bug , explanation) ) ;
16171636 no_bugs = false ;
16181637 }
16191638
@@ -1628,7 +1647,7 @@ impl HandlerInner {
16281647 }
16291648 bug. level = Level :: Bug ;
16301649
1631- self . emit_diagnostic ( & mut bug) ;
1650+ self . emit_diagnostic ( bug) ;
16321651 }
16331652
16341653 // Panic with `DelayedBugPanic` to avoid "unexpected panic" messages.
0 commit comments