@@ -63,6 +63,7 @@ use rustc_span::source_map::SourceMap;
6363use rustc_span:: { Loc , Span , DUMMY_SP } ;
6464use std:: backtrace:: { Backtrace , BacktraceStatus } ;
6565use std:: borrow:: Cow ;
66+ use std:: cell:: Cell ;
6667use std:: error:: Report ;
6768use std:: fmt;
6869use std:: hash:: Hash ;
@@ -98,9 +99,9 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
9899
99100// `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
100101#[ cfg( target_pointer_width = "64" ) ]
101- rustc_data_structures:: static_assert_size!( PResult <' _, ( ) >, 16 ) ;
102+ rustc_data_structures:: static_assert_size!( PResult <' _, ( ) >, 24 ) ;
102103#[ cfg( target_pointer_width = "64" ) ]
103- rustc_data_structures:: static_assert_size!( PResult <' _, bool >, 16 ) ;
104+ rustc_data_structures:: static_assert_size!( PResult <' _, bool >, 24 ) ;
104105
105106#[ derive( Debug , PartialEq , Eq , Clone , Copy , Hash , Encodable , Decodable ) ]
106107pub enum SuggestionStyle {
@@ -417,6 +418,7 @@ pub struct DiagCtxt {
417418#[ derive( Copy , Clone ) ]
418419pub struct DiagCtxtHandle < ' a > {
419420 dcx : & ' a DiagCtxt ,
421+ tainted_with_errors : Option < & ' a Cell < Option < ErrorGuaranteed > > > ,
420422}
421423
422424impl < ' a > std:: ops:: Deref for DiagCtxtHandle < ' a > {
@@ -752,7 +754,14 @@ impl DiagCtxt {
752754 }
753755
754756 pub fn handle < ' a > ( & ' a self ) -> DiagCtxtHandle < ' a > {
755- DiagCtxtHandle { dcx : self }
757+ DiagCtxtHandle { dcx : self , tainted_with_errors : None }
758+ }
759+
760+ pub fn taintable_handle < ' a > (
761+ & ' a self ,
762+ tainted_with_errors : & ' a Cell < Option < ErrorGuaranteed > > ,
763+ ) -> DiagCtxtHandle < ' a > {
764+ DiagCtxtHandle { dcx : self , tainted_with_errors : Some ( tainted_with_errors) }
756765 }
757766}
758767
@@ -795,7 +804,9 @@ impl<'a> DiagCtxtHandle<'a> {
795804 // can be used to create a backtrace at the stashing site insted of whenever the
796805 // diagnostic context is dropped and thus delayed bugs are emitted.
797806 Error => Some ( self . span_delayed_bug ( span, format ! ( "stashing {key:?}" ) ) ) ,
798- DelayedBug => return self . inner . borrow_mut ( ) . emit_diagnostic ( diag) ,
807+ DelayedBug => {
808+ return self . inner . borrow_mut ( ) . emit_diagnostic ( diag, self . tainted_with_errors ) ;
809+ }
799810 ForceWarning ( _) | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow
800811 | Expect ( _) => None ,
801812 } ;
@@ -947,16 +958,19 @@ impl<'a> DiagCtxtHandle<'a> {
947958 ( 0 , _) => {
948959 // Use `ForceWarning` rather than `Warning` to guarantee emission, e.g. with a
949960 // configuration like `--cap-lints allow --force-warn bare_trait_objects`.
950- inner. emit_diagnostic ( DiagInner :: new (
951- ForceWarning ( None ) ,
952- DiagMessage :: Str ( warnings ) ,
953- ) ) ;
961+ inner. emit_diagnostic (
962+ DiagInner :: new ( ForceWarning ( None ) , DiagMessage :: Str ( warnings ) ) ,
963+ None ,
964+ ) ;
954965 }
955966 ( _, 0 ) => {
956- inner. emit_diagnostic ( DiagInner :: new ( Error , errors) ) ;
967+ inner. emit_diagnostic ( DiagInner :: new ( Error , errors) , self . tainted_with_errors ) ;
957968 }
958969 ( _, _) => {
959- inner. emit_diagnostic ( DiagInner :: new ( Error , format ! ( "{errors}; {warnings}" ) ) ) ;
970+ inner. emit_diagnostic (
971+ DiagInner :: new ( Error , format ! ( "{errors}; {warnings}" ) ) ,
972+ self . tainted_with_errors ,
973+ ) ;
960974 }
961975 }
962976
@@ -987,14 +1001,14 @@ impl<'a> DiagCtxtHandle<'a> {
9871001 "For more information about an error, try `rustc --explain {}`." ,
9881002 & error_codes[ 0 ]
9891003 ) ;
990- inner. emit_diagnostic ( DiagInner :: new ( FailureNote , msg1) ) ;
991- inner. emit_diagnostic ( DiagInner :: new ( FailureNote , msg2) ) ;
1004+ inner. emit_diagnostic ( DiagInner :: new ( FailureNote , msg1) , None ) ;
1005+ inner. emit_diagnostic ( DiagInner :: new ( FailureNote , msg2) , None ) ;
9921006 } else {
9931007 let msg = format ! (
9941008 "For more information about this error, try `rustc --explain {}`." ,
9951009 & error_codes[ 0 ]
9961010 ) ;
997- inner. emit_diagnostic ( DiagInner :: new ( FailureNote , msg) ) ;
1011+ inner. emit_diagnostic ( DiagInner :: new ( FailureNote , msg) , None ) ;
9981012 }
9991013 }
10001014 }
@@ -1020,7 +1034,7 @@ impl<'a> DiagCtxtHandle<'a> {
10201034 }
10211035
10221036 pub fn emit_diagnostic ( & self , diagnostic : DiagInner ) -> Option < ErrorGuaranteed > {
1023- self . inner . borrow_mut ( ) . emit_diagnostic ( diagnostic)
1037+ self . inner . borrow_mut ( ) . emit_diagnostic ( diagnostic, self . tainted_with_errors )
10241038 }
10251039
10261040 pub fn emit_artifact_notification ( & self , path : & Path , artifact_type : & str ) {
@@ -1080,7 +1094,7 @@ impl<'a> DiagCtxtHandle<'a> {
10801094 // Here the diagnostic is given back to `emit_diagnostic` where it was first
10811095 // intercepted. Now it should be processed as usual, since the unstable expectation
10821096 // id is now stable.
1083- inner. emit_diagnostic ( diag) ;
1097+ inner. emit_diagnostic ( diag, self . tainted_with_errors ) ;
10841098 }
10851099 }
10861100
@@ -1430,13 +1444,17 @@ impl DiagCtxtInner {
14301444 continue ;
14311445 }
14321446 }
1433- guar = guar. or ( self . emit_diagnostic ( diag) ) ;
1447+ guar = guar. or ( self . emit_diagnostic ( diag, None ) ) ;
14341448 }
14351449 guar
14361450 }
14371451
14381452 // Return value is only `Some` if the level is `Error` or `DelayedBug`.
1439- fn emit_diagnostic ( & mut self , mut diagnostic : DiagInner ) -> Option < ErrorGuaranteed > {
1453+ fn emit_diagnostic (
1454+ & mut self ,
1455+ mut diagnostic : DiagInner ,
1456+ taint : Option < & Cell < Option < ErrorGuaranteed > > > ,
1457+ ) -> Option < ErrorGuaranteed > {
14401458 match diagnostic. level {
14411459 Expect ( expect_id) | ForceWarning ( Some ( expect_id) ) => {
14421460 // The `LintExpectationId` can be stable or unstable depending on when it was
@@ -1609,6 +1627,9 @@ impl DiagCtxtInner {
16091627 if is_lint {
16101628 self . lint_err_guars . push ( guar) ;
16111629 } else {
1630+ if let Some ( taint) = taint {
1631+ taint. set ( Some ( guar) ) ;
1632+ }
16121633 self . err_guars . push ( guar) ;
16131634 }
16141635 self . panic_if_treat_err_as_bug ( ) ;
@@ -1718,8 +1739,8 @@ impl DiagCtxtInner {
17181739 // `-Ztreat-err-as-bug`, which we don't want.
17191740 let note1 = "no errors encountered even though delayed bugs were created" ;
17201741 let note2 = "those delayed bugs will now be shown as internal compiler errors" ;
1721- self . emit_diagnostic ( DiagInner :: new ( Note , note1) ) ;
1722- self . emit_diagnostic ( DiagInner :: new ( Note , note2) ) ;
1742+ self . emit_diagnostic ( DiagInner :: new ( Note , note1) , None ) ;
1743+ self . emit_diagnostic ( DiagInner :: new ( Note , note2) , None ) ;
17231744
17241745 for bug in bugs {
17251746 if let Some ( out) = & mut out {
@@ -1752,7 +1773,7 @@ impl DiagCtxtInner {
17521773 }
17531774 bug. level = Bug ;
17541775
1755- self . emit_diagnostic ( bug) ;
1776+ self . emit_diagnostic ( bug, None ) ;
17561777 }
17571778
17581779 // Panic with `DelayedBugPanic` to avoid "unexpected panic" messages.
0 commit comments