88//! Thank you!
99//! ~The `INTERNAL_METADATA_COLLECTOR` lint
1010
11- use rustc_errors:: { Applicability , Diag , DiagMessage , MultiSpan , SubdiagMessage } ;
11+ use rustc_errors:: {
12+ Applicability , Diag , DiagMessage , EmissionGuarantee , MultiSpan , SubdiagMessage , SubstitutionPart , Suggestions ,
13+ } ;
1214use rustc_hir:: HirId ;
1315use rustc_lint:: { LateContext , Lint , LintContext } ;
1416use rustc_span:: Span ;
@@ -28,6 +30,42 @@ fn docs_link(diag: &mut Diag<'_, ()>, lint: &'static Lint) {
2830 }
2931}
3032
33+ /// Makes sure that a diagnostic is well formed.
34+ ///
35+ /// rustc debug asserts a few properties about spans,
36+ /// but the clippy repo uses a distributed rustc build with debug assertions disabled,
37+ /// so this has historically led to problems during subtree syncs where those debug assertions
38+ /// only started triggered there.
39+ ///
40+ /// This function makes sure we also validate them in debug clippy builds.
41+ fn validate_diag ( diag : & Diag < ' _ , impl EmissionGuarantee > ) {
42+ let suggestions = match & diag. suggestions {
43+ Suggestions :: Enabled ( suggs) => & * * suggs,
44+ Suggestions :: Sealed ( suggs) => & * * suggs,
45+ Suggestions :: Disabled => return ,
46+ } ;
47+
48+ for substitution in suggestions. iter ( ) . flat_map ( |s| & s. substitutions ) {
49+ assert_eq ! (
50+ substitution
51+ . parts
52+ . iter( )
53+ . find( |SubstitutionPart { snippet, span } | snippet. is_empty( ) && span. is_empty( ) ) ,
54+ None ,
55+ "span must not be empty and have no suggestion"
56+ ) ;
57+
58+ assert_eq ! (
59+ substitution
60+ . parts
61+ . array_windows( )
62+ . find( |[ a, b] | a. span. overlaps( b. span) ) ,
63+ None ,
64+ "suggestion must not have overlapping parts"
65+ ) ;
66+ }
67+ }
68+
3169/// Emit a basic lint message with a `msg` and a `span`.
3270///
3371/// This is the most primitive of our lint emission methods and can
@@ -64,6 +102,9 @@ pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<Mult
64102 cx. span_lint ( lint, sp, |diag| {
65103 diag. primary_message ( msg) ;
66104 docs_link ( diag, lint) ;
105+
106+ #[ cfg( debug_assertions) ]
107+ validate_diag ( diag) ;
67108 } ) ;
68109}
69110
@@ -118,6 +159,9 @@ pub fn span_lint_and_help<T: LintContext>(
118159 diag. help ( help. into ( ) ) ;
119160 }
120161 docs_link ( diag, lint) ;
162+
163+ #[ cfg( debug_assertions) ]
164+ validate_diag ( diag) ;
121165 } ) ;
122166}
123167
@@ -175,6 +219,9 @@ pub fn span_lint_and_note<T: LintContext>(
175219 diag. note ( note. into ( ) ) ;
176220 }
177221 docs_link ( diag, lint) ;
222+
223+ #[ cfg( debug_assertions) ]
224+ validate_diag ( diag) ;
178225 } ) ;
179226}
180227
@@ -208,6 +255,9 @@ where
208255 diag. primary_message ( msg) ;
209256 f ( diag) ;
210257 docs_link ( diag, lint) ;
258+
259+ #[ cfg( debug_assertions) ]
260+ validate_diag ( diag) ;
211261 } ) ;
212262}
213263
@@ -240,6 +290,9 @@ pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, s
240290 cx. tcx . node_span_lint ( lint, hir_id, sp, |diag| {
241291 diag. primary_message ( msg) ;
242292 docs_link ( diag, lint) ;
293+
294+ #[ cfg( debug_assertions) ]
295+ validate_diag ( diag) ;
243296 } ) ;
244297}
245298
@@ -280,6 +333,9 @@ pub fn span_lint_hir_and_then(
280333 diag. primary_message ( msg) ;
281334 f ( diag) ;
282335 docs_link ( diag, lint) ;
336+
337+ #[ cfg( debug_assertions) ]
338+ validate_diag ( diag) ;
283339 } ) ;
284340}
285341
@@ -316,7 +372,7 @@ pub fn span_lint_hir_and_then(
316372/// |
317373/// = note: `-D fold-any` implied by `-D warnings`
318374/// ```
319- #[ expect( clippy:: collapsible_span_lint_calls) ]
375+ #[ cfg_attr ( not ( debug_assertions ) , expect( clippy:: collapsible_span_lint_calls) ) ]
320376pub fn span_lint_and_sugg < T : LintContext > (
321377 cx : & T ,
322378 lint : & ' static Lint ,
@@ -328,5 +384,8 @@ pub fn span_lint_and_sugg<T: LintContext>(
328384) {
329385 span_lint_and_then ( cx, lint, sp, msg. into ( ) , |diag| {
330386 diag. span_suggestion ( sp, help. into ( ) , sugg, applicability) ;
387+
388+ #[ cfg( debug_assertions) ]
389+ validate_diag ( diag) ;
331390 } ) ;
332391}
0 commit comments