@@ -428,40 +428,33 @@ impl LintStore {
428428 }
429429
430430 // ...if not, search for lints with a similar name
431+ // Note: find_best_match_for_name depends on the sort order of its input vector.
432+ // To ensure deterministic output, sort elements of the lint_groups hash map.
431433 // Also, never suggest deprecated lint groups.
434+ // We will soon sort, so the initial order does not matter.
432435 #[ allow( rustc:: potential_query_instability) ]
433- let groups: Vec < _ > = self
436+ let mut groups: Vec < _ > = self
434437 . lint_groups
435438 . iter ( )
436439 . filter_map ( |( k, LintGroup { depr, .. } ) | depr. is_none ( ) . then_some ( k) )
437440 . collect ( ) ;
441+ groups. sort ( ) ;
438442 let groups = groups. iter ( ) . map ( |k| Symbol :: intern ( k) ) ;
439443 let lints = self . lints . iter ( ) . map ( |l| Symbol :: intern ( & l. name_lower ( ) ) ) ;
440- let mut names: Vec < Symbol > = groups. chain ( lints) . collect ( ) ;
441- // Here, a little bit of extra hack
442- // we use the lint names from rustc and to mock the tool name,
443- // if it's selected we then strip to the right suggestion with `true` for from_rustc
444- // so we can handle these cases:
445- // 1. suggest `missing_docs` from rustc for `clippy::missing_docs`
446- // 2. suggest `dead_code` from rustc for `clippy::dead_cod`
447- let rustc_names = self
448- . by_name
449- . keys ( )
450- . map ( |k| Symbol :: intern ( & format ! ( "{tool_name}::{k}" ) ) )
451- . collect :: < Vec < _ > > ( ) ;
452- names. extend ( rustc_names. clone ( ) ) ;
453- // Note: find_best_match_for_name depends on the sort order of its input vector.
454- // Sort elements here to ensure deterministic output
455- names. sort ( ) ;
456- let suggestion =
457- find_best_match_for_name ( & names, Symbol :: intern ( & name_lower) , None ) . map ( |s| {
458- if rustc_names. contains ( & s) {
459- let stripped = s. as_str ( ) . strip_prefix ( & format ! ( "{tool_name}::" ) ) . unwrap ( ) ;
460- ( Symbol :: intern ( stripped) , true )
461- } else {
462- ( s, false )
463- }
464- } ) ;
444+ let names: Vec < Symbol > = groups. chain ( lints) . collect ( ) ;
445+ let mut res = find_best_match_for_name ( & names, Symbol :: intern ( & name_lower) , Some ( 2 ) ) ;
446+ if res. is_none ( ) && name_lower. contains ( "::" ) {
447+ let stripped = name_lower. split ( "::" ) . last ( ) . unwrap ( ) ;
448+ res = find_best_match_for_name ( & names, Symbol :: intern ( stripped) , Some ( 2 ) ) ;
449+ }
450+ if res. is_none ( ) {
451+ res = find_best_match_for_name ( & names, Symbol :: intern ( & name_lower) , None ) ;
452+ }
453+ let is_rustc = res. map_or_else (
454+ || false ,
455+ |s| name_lower. contains ( "::" ) && !s. as_str ( ) . starts_with ( tool_name) ,
456+ ) ;
457+ let suggestion = res. map ( |s| ( s, is_rustc) ) ;
465458 CheckLintNameResult :: NoLint ( suggestion)
466459 }
467460
0 commit comments