@@ -63,6 +63,7 @@ use rustc_span::source_map::SourceMap;
63
63
use rustc_span:: { Loc , Span , DUMMY_SP } ;
64
64
use std:: backtrace:: { Backtrace , BacktraceStatus } ;
65
65
use std:: borrow:: Cow ;
66
+ use std:: cell:: Cell ;
66
67
use std:: error:: Report ;
67
68
use std:: fmt;
68
69
use std:: hash:: Hash ;
@@ -98,9 +99,9 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
98
99
99
100
// `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
100
101
#[ cfg( target_pointer_width = "64" ) ]
101
- rustc_data_structures:: static_assert_size!( PResult <' _, ( ) >, 16 ) ;
102
+ rustc_data_structures:: static_assert_size!( PResult <' _, ( ) >, 24 ) ;
102
103
#[ 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 ) ;
104
105
105
106
#[ derive( Debug , PartialEq , Eq , Clone , Copy , Hash , Encodable , Decodable ) ]
106
107
pub enum SuggestionStyle {
@@ -417,6 +418,7 @@ pub struct DiagCtxt {
417
418
#[ derive( Copy , Clone ) ]
418
419
pub struct DiagCtxtHandle < ' a > {
419
420
dcx : & ' a DiagCtxt ,
421
+ tainted_with_errors : Option < & ' a Cell < Option < ErrorGuaranteed > > > ,
420
422
}
421
423
422
424
impl < ' a > std:: ops:: Deref for DiagCtxtHandle < ' a > {
@@ -752,7 +754,14 @@ impl DiagCtxt {
752
754
}
753
755
754
756
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) }
756
765
}
757
766
}
758
767
@@ -795,7 +804,9 @@ impl<'a> DiagCtxtHandle<'a> {
795
804
// can be used to create a backtrace at the stashing site insted of whenever the
796
805
// diagnostic context is dropped and thus delayed bugs are emitted.
797
806
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
+ }
799
810
ForceWarning ( _) | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow
800
811
| Expect ( _) => None ,
801
812
} ;
@@ -947,16 +958,19 @@ impl<'a> DiagCtxtHandle<'a> {
947
958
( 0 , _) => {
948
959
// Use `ForceWarning` rather than `Warning` to guarantee emission, e.g. with a
949
960
// 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
+ ) ;
954
965
}
955
966
( _, 0 ) => {
956
- inner. emit_diagnostic ( DiagInner :: new ( Error , errors) ) ;
967
+ inner. emit_diagnostic ( DiagInner :: new ( Error , errors) , self . tainted_with_errors ) ;
957
968
}
958
969
( _, _) => {
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
+ ) ;
960
974
}
961
975
}
962
976
@@ -987,14 +1001,14 @@ impl<'a> DiagCtxtHandle<'a> {
987
1001
"For more information about an error, try `rustc --explain {}`." ,
988
1002
& error_codes[ 0 ]
989
1003
) ;
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 ) ;
992
1006
} else {
993
1007
let msg = format ! (
994
1008
"For more information about this error, try `rustc --explain {}`." ,
995
1009
& error_codes[ 0 ]
996
1010
) ;
997
- inner. emit_diagnostic ( DiagInner :: new ( FailureNote , msg) ) ;
1011
+ inner. emit_diagnostic ( DiagInner :: new ( FailureNote , msg) , None ) ;
998
1012
}
999
1013
}
1000
1014
}
@@ -1020,7 +1034,7 @@ impl<'a> DiagCtxtHandle<'a> {
1020
1034
}
1021
1035
1022
1036
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 )
1024
1038
}
1025
1039
1026
1040
pub fn emit_artifact_notification ( & self , path : & Path , artifact_type : & str ) {
@@ -1080,7 +1094,7 @@ impl<'a> DiagCtxtHandle<'a> {
1080
1094
// Here the diagnostic is given back to `emit_diagnostic` where it was first
1081
1095
// intercepted. Now it should be processed as usual, since the unstable expectation
1082
1096
// id is now stable.
1083
- inner. emit_diagnostic ( diag) ;
1097
+ inner. emit_diagnostic ( diag, self . tainted_with_errors ) ;
1084
1098
}
1085
1099
}
1086
1100
@@ -1430,13 +1444,17 @@ impl DiagCtxtInner {
1430
1444
continue ;
1431
1445
}
1432
1446
}
1433
- guar = guar. or ( self . emit_diagnostic ( diag) ) ;
1447
+ guar = guar. or ( self . emit_diagnostic ( diag, None ) ) ;
1434
1448
}
1435
1449
guar
1436
1450
}
1437
1451
1438
1452
// 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 > {
1440
1458
match diagnostic. level {
1441
1459
Expect ( expect_id) | ForceWarning ( Some ( expect_id) ) => {
1442
1460
// The `LintExpectationId` can be stable or unstable depending on when it was
@@ -1609,6 +1627,9 @@ impl DiagCtxtInner {
1609
1627
if is_lint {
1610
1628
self . lint_err_guars . push ( guar) ;
1611
1629
} else {
1630
+ if let Some ( taint) = taint {
1631
+ taint. set ( Some ( guar) ) ;
1632
+ }
1612
1633
self . err_guars . push ( guar) ;
1613
1634
}
1614
1635
self . panic_if_treat_err_as_bug ( ) ;
@@ -1718,8 +1739,8 @@ impl DiagCtxtInner {
1718
1739
// `-Ztreat-err-as-bug`, which we don't want.
1719
1740
let note1 = "no errors encountered even though delayed bugs were created" ;
1720
1741
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 ) ;
1723
1744
1724
1745
for bug in bugs {
1725
1746
if let Some ( out) = & mut out {
@@ -1752,7 +1773,7 @@ impl DiagCtxtInner {
1752
1773
}
1753
1774
bug. level = Bug ;
1754
1775
1755
- self . emit_diagnostic ( bug) ;
1776
+ self . emit_diagnostic ( bug, None ) ;
1756
1777
}
1757
1778
1758
1779
// Panic with `DelayedBugPanic` to avoid "unexpected panic" messages.
0 commit comments