@@ -660,6 +660,23 @@ impl Handler {
660
660
result
661
661
}
662
662
663
+ /// Construct a builder at the `Warning` level at the given `span` and with the `msg`.
664
+ /// The `id` is used for lint emissions which should also fulfill a lint expectation.
665
+ ///
666
+ /// Attempting to `.emit()` the builder will only emit if either:
667
+ /// * `can_emit_warnings` is `true`
668
+ /// * `is_force_warn` was set in `DiagnosticId::Lint`
669
+ pub fn struct_span_warn_with_expectation (
670
+ & self ,
671
+ span : impl Into < MultiSpan > ,
672
+ msg : impl Into < DiagnosticMessage > ,
673
+ id : LintExpectationId ,
674
+ ) -> DiagnosticBuilder < ' _ , ( ) > {
675
+ let mut result = self . struct_warn_with_expectation ( msg, id) ;
676
+ result. set_span ( span) ;
677
+ result
678
+ }
679
+
663
680
/// Construct a builder at the `Allow` level at the given `span` and with the `msg`.
664
681
#[ cfg_attr( not( bootstrap) , rustc_lint_diagnostics) ]
665
682
pub fn struct_span_allow (
@@ -693,7 +710,21 @@ impl Handler {
693
710
/// * `is_force_warn` was set in `DiagnosticId::Lint`
694
711
#[ cfg_attr( not( bootstrap) , rustc_lint_diagnostics) ]
695
712
pub fn struct_warn ( & self , msg : impl Into < DiagnosticMessage > ) -> DiagnosticBuilder < ' _ , ( ) > {
696
- DiagnosticBuilder :: new ( self , Level :: Warning , msg)
713
+ DiagnosticBuilder :: new ( self , Level :: Warning ( None ) , msg)
714
+ }
715
+
716
+ /// Construct a builder at the `Warning` level with the `msg`. The `id` is used for
717
+ /// lint emissions which should also fulfill a lint expectation.
718
+ ///
719
+ /// Attempting to `.emit()` the builder will only emit if either:
720
+ /// * `can_emit_warnings` is `true`
721
+ /// * `is_force_warn` was set in `DiagnosticId::Lint`
722
+ pub fn struct_warn_with_expectation (
723
+ & self ,
724
+ msg : impl Into < DiagnosticMessage > ,
725
+ id : LintExpectationId ,
726
+ ) -> DiagnosticBuilder < ' _ , ( ) > {
727
+ DiagnosticBuilder :: new ( self , Level :: Warning ( Some ( id) ) , msg)
697
728
}
698
729
699
730
/// Construct a builder at the `Allow` level with the `msg`.
@@ -864,7 +895,7 @@ impl Handler {
864
895
865
896
#[ cfg_attr( not( bootstrap) , rustc_lint_diagnostics) ]
866
897
pub fn span_warn ( & self , span : impl Into < MultiSpan > , msg : impl Into < DiagnosticMessage > ) {
867
- self . emit_diag_at_span ( Diagnostic :: new ( Warning , msg) , span) ;
898
+ self . emit_diag_at_span ( Diagnostic :: new ( Warning ( None ) , msg) , span) ;
868
899
}
869
900
870
901
#[ cfg_attr( not( bootstrap) , rustc_lint_diagnostics) ]
@@ -874,7 +905,7 @@ impl Handler {
874
905
msg : impl Into < DiagnosticMessage > ,
875
906
code : DiagnosticId ,
876
907
) {
877
- self . emit_diag_at_span ( Diagnostic :: new_with_code ( Warning , Some ( code) , msg) , span) ;
908
+ self . emit_diag_at_span ( Diagnostic :: new_with_code ( Warning ( None ) , Some ( code) , msg) , span) ;
878
909
}
879
910
880
911
pub fn span_bug ( & self , span : impl Into < MultiSpan > , msg : impl Into < DiagnosticMessage > ) -> ! {
@@ -928,7 +959,7 @@ impl Handler {
928
959
}
929
960
930
961
pub fn warn ( & self , msg : impl Into < DiagnosticMessage > ) {
931
- let mut db = DiagnosticBuilder :: new ( self , Warning , msg) ;
962
+ let mut db = DiagnosticBuilder :: new ( self , Warning ( None ) , msg) ;
932
963
db. emit ( ) ;
933
964
}
934
965
@@ -1033,13 +1064,10 @@ impl Handler {
1033
1064
for mut diag in diags. into_iter ( ) {
1034
1065
diag. update_unstable_expectation_id ( unstable_to_stable) ;
1035
1066
1036
- let stable_id = diag
1037
- . level
1038
- . get_expectation_id ( )
1039
- . expect ( "all diagnostics inside `unstable_expect_diagnostics` must have a `LintExpectationId`" ) ;
1040
- inner. fulfilled_expectations . insert ( stable_id) ;
1041
-
1042
- ( * TRACK_DIAGNOSTICS ) ( & diag) ;
1067
+ // Here the diagnostic is given back to `emit_diagnostic` where it was first
1068
+ // intercepted. Now it should be processed as usual, since the unstable expectation
1069
+ // id is now stable.
1070
+ inner. emit_diagnostic ( & mut diag) ;
1043
1071
}
1044
1072
}
1045
1073
@@ -1089,6 +1117,15 @@ impl HandlerInner {
1089
1117
1090
1118
// FIXME(eddyb) this should ideally take `diagnostic` by value.
1091
1119
fn emit_diagnostic ( & mut self , diagnostic : & mut Diagnostic ) -> Option < ErrorGuaranteed > {
1120
+ // The `LintExpectationId` can be stable or unstable depending on when it was created.
1121
+ // Diagnostics created before the definition of `HirId`s are unstable and can not yet
1122
+ // be stored. Instead, they are buffered until the `LintExpectationId` is replaced by
1123
+ // a stable one by the `LintLevelsBuilder`.
1124
+ if let Some ( LintExpectationId :: Unstable { .. } ) = diagnostic. level . get_expectation_id ( ) {
1125
+ self . unstable_expect_diagnostics . push ( diagnostic. clone ( ) ) ;
1126
+ return None ;
1127
+ }
1128
+
1092
1129
if diagnostic. level == Level :: DelayedBug {
1093
1130
// FIXME(eddyb) this should check for `has_errors` and stop pushing
1094
1131
// once *any* errors were emitted (and truncate `delayed_span_bugs`
@@ -1105,7 +1142,12 @@ impl HandlerInner {
1105
1142
self . future_breakage_diagnostics . push ( diagnostic. clone ( ) ) ;
1106
1143
}
1107
1144
1108
- if diagnostic. level == Warning
1145
+ if let Some ( expectation_id) = diagnostic. level . get_expectation_id ( ) {
1146
+ self . suppressed_expected_diag = true ;
1147
+ self . fulfilled_expectations . insert ( expectation_id) ;
1148
+ }
1149
+
1150
+ if matches ! ( diagnostic. level, Warning ( _) )
1109
1151
&& !self . flags . can_emit_warnings
1110
1152
&& !diagnostic. is_force_warn ( )
1111
1153
{
@@ -1115,22 +1157,9 @@ impl HandlerInner {
1115
1157
return None ;
1116
1158
}
1117
1159
1118
- // The `LintExpectationId` can be stable or unstable depending on when it was created.
1119
- // Diagnostics created before the definition of `HirId`s are unstable and can not yet
1120
- // be stored. Instead, they are buffered until the `LintExpectationId` is replaced by
1121
- // a stable one by the `LintLevelsBuilder`.
1122
- if let Level :: Expect ( LintExpectationId :: Unstable { .. } ) = diagnostic. level {
1123
- self . unstable_expect_diagnostics . push ( diagnostic. clone ( ) ) ;
1124
- return None ;
1125
- }
1126
-
1127
1160
( * TRACK_DIAGNOSTICS ) ( diagnostic) ;
1128
1161
1129
- if let Level :: Expect ( expectation_id) = diagnostic. level {
1130
- self . suppressed_expected_diag = true ;
1131
- self . fulfilled_expectations . insert ( expectation_id) ;
1132
- return None ;
1133
- } else if diagnostic. level == Allow {
1162
+ if matches ! ( diagnostic. level, Level :: Expect ( _) | Level :: Allow ) {
1134
1163
return None ;
1135
1164
}
1136
1165
@@ -1167,7 +1196,7 @@ impl HandlerInner {
1167
1196
self . emitter . emit_diagnostic ( & diagnostic) ;
1168
1197
if diagnostic. is_error ( ) {
1169
1198
self . deduplicated_err_count += 1 ;
1170
- } else if diagnostic . level == Warning {
1199
+ } else if let Warning ( _ ) = diagnostic . level {
1171
1200
self . deduplicated_warn_count += 1 ;
1172
1201
}
1173
1202
}
@@ -1220,7 +1249,7 @@ impl HandlerInner {
1220
1249
match ( errors. len ( ) , warnings. len ( ) ) {
1221
1250
( 0 , 0 ) => return ,
1222
1251
( 0 , _) => self . emitter . emit_diagnostic ( & Diagnostic :: new (
1223
- Level :: Warning ,
1252
+ Level :: Warning ( None ) ,
1224
1253
DiagnosticMessage :: Str ( warnings) ,
1225
1254
) ) ,
1226
1255
( _, 0 ) => {
@@ -1453,7 +1482,10 @@ pub enum Level {
1453
1482
/// If this error comes from a lint, don't abort compilation even when abort_if_errors() is called.
1454
1483
lint : bool ,
1455
1484
} ,
1456
- Warning ,
1485
+ /// This [`LintExpectationId`] is used for expected lint diagnostics, which should
1486
+ /// also emit a warning due to the `force-warn` flag. In all other cases this should
1487
+ /// be `None`.
1488
+ Warning ( Option < LintExpectationId > ) ,
1457
1489
Note ,
1458
1490
/// A note that is only emitted once.
1459
1491
OnceNote ,
@@ -1476,7 +1508,7 @@ impl Level {
1476
1508
Bug | DelayedBug | Fatal | Error { .. } => {
1477
1509
spec. set_fg ( Some ( Color :: Red ) ) . set_intense ( true ) ;
1478
1510
}
1479
- Warning => {
1511
+ Warning ( _ ) => {
1480
1512
spec. set_fg ( Some ( Color :: Yellow ) ) . set_intense ( cfg ! ( windows) ) ;
1481
1513
}
1482
1514
Note | OnceNote => {
@@ -1495,7 +1527,7 @@ impl Level {
1495
1527
match self {
1496
1528
Bug | DelayedBug => "error: internal compiler error" ,
1497
1529
Fatal | Error { .. } => "error" ,
1498
- Warning => "warning" ,
1530
+ Warning ( _ ) => "warning" ,
1499
1531
Note | OnceNote => "note" ,
1500
1532
Help => "help" ,
1501
1533
FailureNote => "failure-note" ,
@@ -1510,7 +1542,7 @@ impl Level {
1510
1542
1511
1543
pub fn get_expectation_id ( & self ) -> Option < LintExpectationId > {
1512
1544
match self {
1513
- Level :: Expect ( id) => Some ( * id) ,
1545
+ Level :: Expect ( id) | Level :: Warning ( Some ( id ) ) => Some ( * id) ,
1514
1546
_ => None ,
1515
1547
}
1516
1548
}
0 commit comments