@@ -411,6 +411,8 @@ pub struct Handler {
411411/// as well as inconsistent state observation.
412412struct HandlerInner {
413413 flags : HandlerFlags ,
414+ /// The number of lint errors that have been emitted.
415+ lint_err_count : usize ,
414416 /// The number of errors that have been emitted, including duplicates.
415417 ///
416418 /// This is not necessarily the count that's reported to the user once
@@ -550,6 +552,7 @@ impl Handler {
550552 flags,
551553 inner : Lock :: new ( HandlerInner {
552554 flags,
555+ lint_err_count : 0 ,
553556 err_count : 0 ,
554557 warn_count : 0 ,
555558 deduplicated_err_count : 0 ,
@@ -726,7 +729,13 @@ impl Handler {
726729 /// Construct a builder at the `Error` level with the `msg`.
727730 // FIXME: This method should be removed (every error should have an associated error code).
728731 pub fn struct_err ( & self , msg : & str ) -> DiagnosticBuilder < ' _ > {
729- DiagnosticBuilder :: new ( self , Level :: Error , msg)
732+ DiagnosticBuilder :: new ( self , Level :: Error { lint : false } , msg)
733+ }
734+
735+ /// This should only be used by `rustc_middle::lint::struct_lint_level`. Do not use it for hard errors.
736+ #[ doc( hidden) ]
737+ pub fn struct_err_lint ( & self , msg : & str ) -> DiagnosticBuilder < ' _ > {
738+ DiagnosticBuilder :: new ( self , Level :: Error { lint : true } , msg)
730739 }
731740
732741 /// Construct a builder at the `Error` level with the `msg` and the `code`.
@@ -790,11 +799,14 @@ impl Handler {
790799 }
791800
792801 pub fn span_err ( & self , span : impl Into < MultiSpan > , msg : & str ) {
793- self . emit_diag_at_span ( Diagnostic :: new ( Error , msg) , span) ;
802+ self . emit_diag_at_span ( Diagnostic :: new ( Error { lint : false } , msg) , span) ;
794803 }
795804
796805 pub fn span_err_with_code ( & self , span : impl Into < MultiSpan > , msg : & str , code : DiagnosticId ) {
797- self . emit_diag_at_span ( Diagnostic :: new_with_code ( Error , Some ( code) , msg) , span) ;
806+ self . emit_diag_at_span (
807+ Diagnostic :: new_with_code ( Error { lint : false } , Some ( code) , msg) ,
808+ span,
809+ ) ;
798810 }
799811
800812 pub fn span_warn ( & self , span : impl Into < MultiSpan > , msg : & str ) {
@@ -862,6 +874,9 @@ impl Handler {
862874 pub fn has_errors ( & self ) -> bool {
863875 self . inner . borrow ( ) . has_errors ( )
864876 }
877+ pub fn has_errors_or_lint_errors ( & self ) -> bool {
878+ self . inner . borrow ( ) . has_errors_or_lint_errors ( )
879+ }
865880 pub fn has_errors_or_delayed_span_bugs ( & self ) -> bool {
866881 self . inner . borrow ( ) . has_errors_or_delayed_span_bugs ( )
867882 }
@@ -979,7 +994,11 @@ impl HandlerInner {
979994 }
980995 }
981996 if diagnostic. is_error ( ) {
982- self . bump_err_count ( ) ;
997+ if matches ! ( diagnostic. level, Level :: Error { lint: true } ) {
998+ self . bump_lint_err_count ( ) ;
999+ } else {
1000+ self . bump_err_count ( ) ;
1001+ }
9831002 } else {
9841003 self . bump_warn_count ( ) ;
9851004 }
@@ -1073,11 +1092,14 @@ impl HandlerInner {
10731092 fn has_errors ( & self ) -> bool {
10741093 self . err_count ( ) > 0
10751094 }
1095+ fn has_errors_or_lint_errors ( & self ) -> bool {
1096+ self . has_errors ( ) || self . lint_err_count > 0
1097+ }
10761098 fn has_errors_or_delayed_span_bugs ( & self ) -> bool {
10771099 self . has_errors ( ) || !self . delayed_span_bugs . is_empty ( )
10781100 }
10791101 fn has_any_message ( & self ) -> bool {
1080- self . err_count ( ) > 0 || self . warn_count > 0
1102+ self . err_count ( ) > 0 || self . lint_err_count > 0 || self . warn_count > 0
10811103 }
10821104
10831105 fn abort_if_errors ( & mut self ) {
@@ -1131,7 +1153,7 @@ impl HandlerInner {
11311153 }
11321154
11331155 fn err ( & mut self , msg : & str ) {
1134- self . emit_error ( Error , msg) ;
1156+ self . emit_error ( Error { lint : false } , msg) ;
11351157 }
11361158
11371159 /// Emit an error; level should be `Error` or `Fatal`.
@@ -1167,6 +1189,11 @@ impl HandlerInner {
11671189 }
11681190 }
11691191
1192+ fn bump_lint_err_count ( & mut self ) {
1193+ self . lint_err_count += 1 ;
1194+ self . panic_if_treat_err_as_bug ( ) ;
1195+ }
1196+
11701197 fn bump_err_count ( & mut self ) {
11711198 self . err_count += 1 ;
11721199 self . panic_if_treat_err_as_bug ( ) ;
@@ -1210,7 +1237,10 @@ impl DelayedDiagnostic {
12101237pub enum Level {
12111238 Bug ,
12121239 Fatal ,
1213- Error ,
1240+ Error {
1241+ /// If this error comes from a lint, don't abort compilation even when abort_if_errors() is called.
1242+ lint : bool ,
1243+ } ,
12141244 Warning ,
12151245 Note ,
12161246 Help ,
@@ -1229,7 +1259,7 @@ impl Level {
12291259 fn color ( self ) -> ColorSpec {
12301260 let mut spec = ColorSpec :: new ( ) ;
12311261 match self {
1232- Bug | Fatal | Error => {
1262+ Bug | Fatal | Error { .. } => {
12331263 spec. set_fg ( Some ( Color :: Red ) ) . set_intense ( true ) ;
12341264 }
12351265 Warning => {
@@ -1250,7 +1280,7 @@ impl Level {
12501280 pub fn to_str ( self ) -> & ' static str {
12511281 match self {
12521282 Bug => "error: internal compiler error" ,
1253- Fatal | Error => "error" ,
1283+ Fatal | Error { .. } => "error" ,
12541284 Warning => "warning" ,
12551285 Note => "note" ,
12561286 Help => "help" ,
0 commit comments