@@ -658,6 +658,23 @@ impl Handler {
658
658
result
659
659
}
660
660
661
+ /// Construct a builder at the `Warning` level at the given `span` and with the `msg`.
662
+ /// The `id` is used for lint emissions which should also fulfill a lint expectation.
663
+ ///
664
+ /// Attempting to `.emit()` the builder will only emit if either:
665
+ /// * `can_emit_warnings` is `true`
666
+ /// * `is_force_warn` was set in `DiagnosticId::Lint`
667
+ pub fn struct_span_warn_with_expectation (
668
+ & self ,
669
+ span : impl Into < MultiSpan > ,
670
+ msg : impl Into < DiagnosticMessage > ,
671
+ id : LintExpectationId ,
672
+ ) -> DiagnosticBuilder < ' _ , ( ) > {
673
+ let mut result = self . struct_warn_with_expectation ( msg, id) ;
674
+ result. set_span ( span) ;
675
+ result
676
+ }
677
+
661
678
/// Construct a builder at the `Allow` level at the given `span` and with the `msg`.
662
679
pub fn struct_span_allow (
663
680
& self ,
@@ -688,7 +705,21 @@ impl Handler {
688
705
/// * `can_emit_warnings` is `true`
689
706
/// * `is_force_warn` was set in `DiagnosticId::Lint`
690
707
pub fn struct_warn ( & self , msg : impl Into < DiagnosticMessage > ) -> DiagnosticBuilder < ' _ , ( ) > {
691
- DiagnosticBuilder :: new ( self , Level :: Warning , msg)
708
+ DiagnosticBuilder :: new ( self , Level :: Warning ( None ) , msg)
709
+ }
710
+
711
+ /// Construct a builder at the `Warning` level with the `msg`. The `id` is used for
712
+ /// lint emissions which should also fulfill a lint expectation.
713
+ ///
714
+ /// Attempting to `.emit()` the builder will only emit if either:
715
+ /// * `can_emit_warnings` is `true`
716
+ /// * `is_force_warn` was set in `DiagnosticId::Lint`
717
+ pub fn struct_warn_with_expectation (
718
+ & self ,
719
+ msg : impl Into < DiagnosticMessage > ,
720
+ id : LintExpectationId ,
721
+ ) -> DiagnosticBuilder < ' _ , ( ) > {
722
+ DiagnosticBuilder :: new ( self , Level :: Warning ( Some ( id) ) , msg)
692
723
}
693
724
694
725
/// Construct a builder at the `Allow` level with the `msg`.
@@ -842,7 +873,7 @@ impl Handler {
842
873
}
843
874
844
875
pub fn span_warn ( & self , span : impl Into < MultiSpan > , msg : impl Into < DiagnosticMessage > ) {
845
- self . emit_diag_at_span ( Diagnostic :: new ( Warning , msg) , span) ;
876
+ self . emit_diag_at_span ( Diagnostic :: new ( Warning ( None ) , msg) , span) ;
846
877
}
847
878
848
879
pub fn span_warn_with_code (
@@ -851,7 +882,7 @@ impl Handler {
851
882
msg : impl Into < DiagnosticMessage > ,
852
883
code : DiagnosticId ,
853
884
) {
854
- self . emit_diag_at_span ( Diagnostic :: new_with_code ( Warning , Some ( code) , msg) , span) ;
885
+ self . emit_diag_at_span ( Diagnostic :: new_with_code ( Warning ( None ) , Some ( code) , msg) , span) ;
855
886
}
856
887
857
888
pub fn span_bug ( & self , span : impl Into < MultiSpan > , msg : impl Into < DiagnosticMessage > ) -> ! {
@@ -905,7 +936,7 @@ impl Handler {
905
936
}
906
937
907
938
pub fn warn ( & self , msg : impl Into < DiagnosticMessage > ) {
908
- let mut db = DiagnosticBuilder :: new ( self , Warning , msg) ;
939
+ let mut db = DiagnosticBuilder :: new ( self , Warning ( None ) , msg) ;
909
940
db. emit ( ) ;
910
941
}
911
942
@@ -1010,13 +1041,10 @@ impl Handler {
1010
1041
for mut diag in diags. into_iter ( ) {
1011
1042
diag. update_unstable_expectation_id ( unstable_to_stable) ;
1012
1043
1013
- let stable_id = diag
1014
- . level
1015
- . get_expectation_id ( )
1016
- . expect ( "all diagnostics inside `unstable_expect_diagnostics` must have a `LintExpectationId`" ) ;
1017
- inner. fulfilled_expectations . insert ( stable_id) ;
1018
-
1019
- ( * TRACK_DIAGNOSTICS ) ( & diag) ;
1044
+ // Here the diagnostic is given back to `emit_diagnostic` where it was first
1045
+ // intercepted. Now it should be processed as usual, since the unstable expectation
1046
+ // id is now stable.
1047
+ inner. emit_diagnostic ( & mut diag) ;
1020
1048
}
1021
1049
}
1022
1050
@@ -1066,6 +1094,15 @@ impl HandlerInner {
1066
1094
1067
1095
// FIXME(eddyb) this should ideally take `diagnostic` by value.
1068
1096
fn emit_diagnostic ( & mut self , diagnostic : & mut Diagnostic ) -> Option < ErrorGuaranteed > {
1097
+ // The `LintExpectationId` can be stable or unstable depending on when it was created.
1098
+ // Diagnostics created before the definition of `HirId`s are unstable and can not yet
1099
+ // be stored. Instead, they are buffered until the `LintExpectationId` is replaced by
1100
+ // a stable one by the `LintLevelsBuilder`.
1101
+ if let Some ( LintExpectationId :: Unstable { .. } ) = diagnostic. level . get_expectation_id ( ) {
1102
+ self . unstable_expect_diagnostics . push ( diagnostic. clone ( ) ) ;
1103
+ return None ;
1104
+ }
1105
+
1069
1106
if diagnostic. level == Level :: DelayedBug {
1070
1107
// FIXME(eddyb) this should check for `has_errors` and stop pushing
1071
1108
// once *any* errors were emitted (and truncate `delayed_span_bugs`
@@ -1082,7 +1119,12 @@ impl HandlerInner {
1082
1119
self . future_breakage_diagnostics . push ( diagnostic. clone ( ) ) ;
1083
1120
}
1084
1121
1085
- if diagnostic. level == Warning
1122
+ if let Some ( expectation_id) = diagnostic. level . get_expectation_id ( ) {
1123
+ self . suppressed_expected_diag = true ;
1124
+ self . fulfilled_expectations . insert ( expectation_id) ;
1125
+ }
1126
+
1127
+ if matches ! ( diagnostic. level, Warning ( _) )
1086
1128
&& !self . flags . can_emit_warnings
1087
1129
&& !diagnostic. is_force_warn ( )
1088
1130
{
@@ -1092,22 +1134,9 @@ impl HandlerInner {
1092
1134
return None ;
1093
1135
}
1094
1136
1095
- // The `LintExpectationId` can be stable or unstable depending on when it was created.
1096
- // Diagnostics created before the definition of `HirId`s are unstable and can not yet
1097
- // be stored. Instead, they are buffered until the `LintExpectationId` is replaced by
1098
- // a stable one by the `LintLevelsBuilder`.
1099
- if let Level :: Expect ( LintExpectationId :: Unstable { .. } ) = diagnostic. level {
1100
- self . unstable_expect_diagnostics . push ( diagnostic. clone ( ) ) ;
1101
- return None ;
1102
- }
1103
-
1104
1137
( * TRACK_DIAGNOSTICS ) ( diagnostic) ;
1105
1138
1106
- if let Level :: Expect ( expectation_id) = diagnostic. level {
1107
- self . suppressed_expected_diag = true ;
1108
- self . fulfilled_expectations . insert ( expectation_id) ;
1109
- return None ;
1110
- } else if diagnostic. level == Allow {
1139
+ if matches ! ( diagnostic. level, Level :: Expect ( _) | Level :: Allow ) {
1111
1140
return None ;
1112
1141
}
1113
1142
@@ -1144,7 +1173,7 @@ impl HandlerInner {
1144
1173
self . emitter . emit_diagnostic ( & diagnostic) ;
1145
1174
if diagnostic. is_error ( ) {
1146
1175
self . deduplicated_err_count += 1 ;
1147
- } else if diagnostic . level == Warning {
1176
+ } else if let Warning ( _ ) = diagnostic . level {
1148
1177
self . deduplicated_warn_count += 1 ;
1149
1178
}
1150
1179
}
@@ -1197,7 +1226,7 @@ impl HandlerInner {
1197
1226
match ( errors. len ( ) , warnings. len ( ) ) {
1198
1227
( 0 , 0 ) => return ,
1199
1228
( 0 , _) => self . emitter . emit_diagnostic ( & Diagnostic :: new (
1200
- Level :: Warning ,
1229
+ Level :: Warning ( None ) ,
1201
1230
DiagnosticMessage :: Str ( warnings) ,
1202
1231
) ) ,
1203
1232
( _, 0 ) => {
@@ -1430,7 +1459,10 @@ pub enum Level {
1430
1459
/// If this error comes from a lint, don't abort compilation even when abort_if_errors() is called.
1431
1460
lint : bool ,
1432
1461
} ,
1433
- Warning ,
1462
+ /// This [`LintExpectationId`] is used for expected lint diagnostics, which should
1463
+ /// also emit a warning due to the `force-warn` flag. In all other cases this should
1464
+ /// be `None`.
1465
+ Warning ( Option < LintExpectationId > ) ,
1434
1466
Note ,
1435
1467
/// A note that is only emitted once.
1436
1468
OnceNote ,
@@ -1453,7 +1485,7 @@ impl Level {
1453
1485
Bug | DelayedBug | Fatal | Error { .. } => {
1454
1486
spec. set_fg ( Some ( Color :: Red ) ) . set_intense ( true ) ;
1455
1487
}
1456
- Warning => {
1488
+ Warning ( _ ) => {
1457
1489
spec. set_fg ( Some ( Color :: Yellow ) ) . set_intense ( cfg ! ( windows) ) ;
1458
1490
}
1459
1491
Note | OnceNote => {
@@ -1472,7 +1504,7 @@ impl Level {
1472
1504
match self {
1473
1505
Bug | DelayedBug => "error: internal compiler error" ,
1474
1506
Fatal | Error { .. } => "error" ,
1475
- Warning => "warning" ,
1507
+ Warning ( _ ) => "warning" ,
1476
1508
Note | OnceNote => "note" ,
1477
1509
Help => "help" ,
1478
1510
FailureNote => "failure-note" ,
@@ -1487,7 +1519,7 @@ impl Level {
1487
1519
1488
1520
pub fn get_expectation_id ( & self ) -> Option < LintExpectationId > {
1489
1521
match self {
1490
- Level :: Expect ( id) => Some ( * id) ,
1522
+ Level :: Expect ( id) | Level :: Warning ( Some ( id ) ) => Some ( * id) ,
1491
1523
_ => None ,
1492
1524
}
1493
1525
}
0 commit comments