@@ -36,6 +36,7 @@ use rustc_middle::middle::stability;
3636use rustc_middle:: ty:: layout:: { LayoutError , LayoutOfHelpers , TyAndLayout } ;
3737use rustc_middle:: ty:: print:: with_no_trimmed_paths;
3838use rustc_middle:: ty:: { self , print:: Printer , subst:: GenericArg , RegisteredTools , Ty , TyCtxt } ;
39+ use rustc_session:: config:: ExpectedValues ;
3940use rustc_session:: lint:: { BuiltinLintDiagnostics , LintExpectationId } ;
4041use rustc_session:: lint:: { FutureIncompatibleInfo , Level , Lint , LintBuffer , LintId } ;
4142use rustc_session:: Session ;
@@ -768,23 +769,51 @@ pub trait LintContext: Sized {
768769 db. help ( help) ;
769770 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" ) ;
770771 } ,
771- BuiltinLintDiagnostics :: UnexpectedCfg ( ( name, name_span) , None ) => {
772+ BuiltinLintDiagnostics :: UnexpectedCfgName ( ( name, name_span) , value ) => {
772773 let possibilities: Vec < Symbol > = sess. parse_sess . check_config . expecteds . keys ( ) . map ( |s| * s) . collect ( ) ;
773774
774775 // Suggest the most probable if we found one
775776 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+ }
777806 }
778807 } ,
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 {
781810 bug ! ( "it shouldn't be possible to have a diagnostic on a value whose name is not in values" ) ;
782811 } ;
783812 let mut have_none_possibility = false ;
784813 let possibilities: Vec < Symbol > = values. iter ( )
785814 . inspect ( |a| have_none_possibility |= a. is_none ( ) )
786815 . copied ( )
787- . filter_map ( std :: convert :: identity )
816+ . flatten ( )
788817 . collect ( ) ;
789818
790819 // 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 {
800829 db. note ( format ! ( "expected values for `{name}` are: {none}`{possibilities}`" ) ) ;
801830 }
802831
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 ) ;
806840 }
807841 } else if have_none_possibility {
808842 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+ }
810846 }
811847 } ,
812848 BuiltinLintDiagnostics :: DeprecatedWhereclauseLocation ( new_span, suggestion) => {
0 commit comments