@@ -33,7 +33,7 @@ use rustc_middle::ty::{self, print::Printer, GenericArg, RegisteredTools, Ty, Ty
33
33
use rustc_session:: lint:: { BuiltinLintDiagnostics , LintExpectationId } ;
34
34
use rustc_session:: lint:: { FutureIncompatibleInfo , Level , Lint , LintBuffer , LintId } ;
35
35
use rustc_session:: { LintStoreMarker , Session } ;
36
- use rustc_span:: edit_distance:: find_best_match_for_name ;
36
+ use rustc_span:: edit_distance:: find_best_match_for_names ;
37
37
use rustc_span:: symbol:: { sym, Ident , Symbol } ;
38
38
use rustc_span:: Span ;
39
39
use rustc_target:: abi;
@@ -117,7 +117,7 @@ struct LintGroup {
117
117
pub enum CheckLintNameResult < ' a > {
118
118
Ok ( & ' a [ LintId ] ) ,
119
119
/// Lint doesn't exist. Potentially contains a suggestion for a correct lint name.
120
- NoLint ( Option < Symbol > ) ,
120
+ NoLint ( Option < ( Symbol , bool ) > ) ,
121
121
/// The lint refers to a tool that has not been registered.
122
122
NoTool ,
123
123
/// The lint has been renamed to a new name.
@@ -377,7 +377,7 @@ impl LintStore {
377
377
debug ! ( "lints={:?}" , self . by_name. keys( ) . collect:: <Vec <_>>( ) ) ;
378
378
let tool_prefix = format ! ( "{tool_name}::" ) ;
379
379
return if self . by_name . keys ( ) . any ( |lint| lint. starts_with ( & tool_prefix) ) {
380
- self . no_lint_suggestion ( & complete_name)
380
+ self . no_lint_suggestion ( & complete_name, tool_name . as_str ( ) )
381
381
} else {
382
382
// 2. The tool isn't currently running, so no lints will be registered.
383
383
// To avoid giving a false positive, ignore all unknown lints.
@@ -419,13 +419,14 @@ impl LintStore {
419
419
}
420
420
}
421
421
422
- fn no_lint_suggestion ( & self , lint_name : & str ) -> CheckLintNameResult < ' _ > {
422
+ fn no_lint_suggestion ( & self , lint_name : & str , tool_name : & str ) -> CheckLintNameResult < ' _ > {
423
423
let name_lower = lint_name. to_lowercase ( ) ;
424
424
425
425
if lint_name. chars ( ) . any ( char:: is_uppercase) && self . find_lints ( & name_lower) . is_ok ( ) {
426
426
// First check if the lint name is (partly) in upper case instead of lower case...
427
- return CheckLintNameResult :: NoLint ( Some ( Symbol :: intern ( & name_lower) ) ) ;
427
+ return CheckLintNameResult :: NoLint ( Some ( ( Symbol :: intern ( & name_lower) , false ) ) ) ;
428
428
}
429
+
429
430
// ...if not, search for lints with a similar name
430
431
// Note: find_best_match_for_name depends on the sort order of its input vector.
431
432
// To ensure deterministic output, sort elements of the lint_groups hash map.
@@ -441,7 +442,16 @@ impl LintStore {
441
442
let groups = groups. iter ( ) . map ( |k| Symbol :: intern ( k) ) ;
442
443
let lints = self . lints . iter ( ) . map ( |l| Symbol :: intern ( & l. name_lower ( ) ) ) ;
443
444
let names: Vec < Symbol > = groups. chain ( lints) . collect ( ) ;
444
- let suggestion = find_best_match_for_name ( & names, Symbol :: intern ( & name_lower) , None ) ;
445
+ let mut lookups = vec ! [ Symbol :: intern( & name_lower) ] ;
446
+ if let Some ( stripped) = name_lower. split ( "::" ) . last ( ) {
447
+ lookups. push ( Symbol :: intern ( stripped) ) ;
448
+ }
449
+ let res = find_best_match_for_names ( & names, & lookups, None ) ;
450
+ let is_rustc = res. map_or_else (
451
+ || false ,
452
+ |s| name_lower. contains ( "::" ) && !s. as_str ( ) . starts_with ( tool_name) ,
453
+ ) ;
454
+ let suggestion = res. map ( |s| ( s, is_rustc) ) ;
445
455
CheckLintNameResult :: NoLint ( suggestion)
446
456
}
447
457
@@ -454,7 +464,7 @@ impl LintStore {
454
464
match self . by_name . get ( & complete_name) {
455
465
None => match self . lint_groups . get ( & * complete_name) {
456
466
// Now we are sure, that this lint exists nowhere
457
- None => self . no_lint_suggestion ( lint_name) ,
467
+ None => self . no_lint_suggestion ( lint_name, tool_name ) ,
458
468
Some ( LintGroup { lint_ids, depr, .. } ) => {
459
469
// Reaching this would be weird, but let's cover this case anyway
460
470
if let Some ( LintAlias { name, silent } ) = depr {
0 commit comments