@@ -36,6 +36,7 @@ use rustc_middle::middle::stability;
36
36
use rustc_middle:: ty:: layout:: { LayoutError , LayoutOfHelpers , TyAndLayout } ;
37
37
use rustc_middle:: ty:: print:: with_no_trimmed_paths;
38
38
use rustc_middle:: ty:: { self , print:: Printer , subst:: GenericArg , RegisteredTools , Ty , TyCtxt } ;
39
+ use rustc_session:: config:: ExpectedValues ;
39
40
use rustc_session:: lint:: { BuiltinLintDiagnostics , LintExpectationId } ;
40
41
use rustc_session:: lint:: { FutureIncompatibleInfo , Level , Lint , LintBuffer , LintId } ;
41
42
use rustc_session:: Session ;
@@ -768,23 +769,51 @@ pub trait LintContext: Sized {
768
769
db. help ( help) ;
769
770
db. note ( "see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information" ) ;
770
771
} ,
771
- BuiltinLintDiagnostics :: UnexpectedCfg ( ( name, name_span) , None ) => {
772
+ BuiltinLintDiagnostics :: UnexpectedCfgName ( ( name, name_span) , value ) => {
772
773
let possibilities: Vec < Symbol > = sess. parse_sess . check_config . expecteds . keys ( ) . map ( |s| * s) . collect ( ) ;
773
774
774
775
// Suggest the most probable if we found one
775
776
if let Some ( best_match) = find_best_match_for_name ( & possibilities, name, None ) {
776
- db. span_suggestion ( name_span, "there is an config with a similar name" , best_match, Applicability :: MaybeIncorrect ) ;
777
+ if let Some ( ExpectedValues :: Some ( best_match_values) ) =
778
+ sess. parse_sess . check_config . expecteds . get ( & best_match) {
779
+ let mut possibilities = best_match_values. iter ( )
780
+ . flatten ( )
781
+ . map ( Symbol :: as_str)
782
+ . collect :: < Vec < _ > > ( ) ;
783
+ possibilities. sort ( ) ;
784
+
785
+ if let Some ( ( value, value_span) ) = value {
786
+ if best_match_values. contains ( & Some ( value) ) {
787
+ db. span_suggestion ( name_span, "there is a config with a similar name and value" , best_match, Applicability :: MaybeIncorrect ) ;
788
+ } else if best_match_values. contains ( & None ) {
789
+ db. span_suggestion ( name_span. to ( value_span) , "there is a config with a similar name and no value" , best_match, Applicability :: MaybeIncorrect ) ;
790
+ } else if let Some ( first_value) = possibilities. first ( ) {
791
+ db. span_suggestion ( name_span. to ( value_span) , "there is a config with a similar name and different values" , format ! ( "{best_match} = \" {first_value}\" " ) , Applicability :: MaybeIncorrect ) ;
792
+ } else {
793
+ db. span_suggestion ( name_span. to ( value_span) , "there is a config with a similar name and different values" , best_match, Applicability :: MaybeIncorrect ) ;
794
+ } ;
795
+ } else {
796
+ db. span_suggestion ( name_span, "there is a config with a similar name" , best_match, Applicability :: MaybeIncorrect ) ;
797
+ }
798
+
799
+ if !possibilities. is_empty ( ) {
800
+ let possibilities = possibilities. join ( "`, `" ) ;
801
+ db. help ( format ! ( "expected values for `{best_match}` are: `{possibilities}`" ) ) ;
802
+ }
803
+ } else {
804
+ db. span_suggestion ( name_span, "there is a config with a similar name" , best_match, Applicability :: MaybeIncorrect ) ;
805
+ }
777
806
}
778
807
} ,
779
- BuiltinLintDiagnostics :: UnexpectedCfg ( ( name, name_span) , Some ( ( value, value_span ) ) ) => {
780
- let Some ( rustc_session :: config :: ExpectedValues :: Some ( values) ) = & sess. parse_sess . check_config . expecteds . get ( & name) else {
808
+ BuiltinLintDiagnostics :: UnexpectedCfgValue ( ( name, name_span) , value) => {
809
+ let Some ( ExpectedValues :: Some ( values) ) = & sess. parse_sess . check_config . expecteds . get ( & name) else {
781
810
bug ! ( "it shouldn't be possible to have a diagnostic on a value whose name is not in values" ) ;
782
811
} ;
783
812
let mut have_none_possibility = false ;
784
813
let possibilities: Vec < Symbol > = values. iter ( )
785
814
. inspect ( |a| have_none_possibility |= a. is_none ( ) )
786
815
. copied ( )
787
- . filter_map ( std :: convert :: identity )
816
+ . flatten ( )
788
817
. collect ( ) ;
789
818
790
819
// Show the full list if all possible values for a given name, but don't do it
@@ -800,13 +829,20 @@ pub trait LintContext: Sized {
800
829
db. note ( format ! ( "expected values for `{name}` are: {none}`{possibilities}`" ) ) ;
801
830
}
802
831
803
- // Suggest the most probable if we found one
804
- if let Some ( best_match) = find_best_match_for_name ( & possibilities, value, None ) {
805
- db. span_suggestion ( value_span, "there is an expected value with a similar name" , format ! ( "\" {best_match}\" " ) , Applicability :: MaybeIncorrect ) ;
832
+ if let Some ( ( value, value_span) ) = value {
833
+ // Suggest the most probable if we found one
834
+ if let Some ( best_match) = find_best_match_for_name ( & possibilities, value, None ) {
835
+ db. span_suggestion ( value_span, "there is a expected value with a similar name" , format ! ( "\" {best_match}\" " ) , Applicability :: MaybeIncorrect ) ;
836
+
837
+ }
838
+ } else if let & [ first_possibility] = & possibilities[ ..] {
839
+ db. span_suggestion ( name_span. shrink_to_hi ( ) , "specify a config value" , format ! ( " = \" {first_possibility}\" " ) , Applicability :: MaybeIncorrect ) ;
806
840
}
807
841
} else if have_none_possibility {
808
842
db. note ( format ! ( "no expected value for `{name}`" ) ) ;
809
- db. span_suggestion ( name_span. shrink_to_hi ( ) . to ( value_span) , "remove the value" , "" , Applicability :: MaybeIncorrect ) ;
843
+ if let Some ( ( _value, value_span) ) = value {
844
+ db. span_suggestion ( name_span. shrink_to_hi ( ) . to ( value_span) , "remove the value" , "" , Applicability :: MaybeIncorrect ) ;
845
+ }
810
846
}
811
847
} ,
812
848
BuiltinLintDiagnostics :: DeprecatedWhereclauseLocation ( new_span, suggestion) => {
0 commit comments