@@ -134,6 +134,7 @@ impl<'a> Resolver<'a> {
134134 & candidates,
135135 instead,
136136 found_use,
137+ false ,
137138 ) ;
138139 } else if let Some ( ( span, msg, sugg, appl) ) = suggestion {
139140 err. span_suggestion ( span, msg, sugg, appl) ;
@@ -493,14 +494,14 @@ impl<'a> Resolver<'a> {
493494 ///
494495 /// This takes the error provided, combines it with the span and any additional spans inside the
495496 /// error and emits it.
496- crate fn report_error ( & self , span : Span , resolution_error : ResolutionError < ' _ > ) {
497+ crate fn report_error ( & mut self , span : Span , resolution_error : ResolutionError < ' a > ) {
497498 self . into_struct_error ( span, resolution_error) . emit ( ) ;
498499 }
499500
500501 crate fn into_struct_error (
501- & self ,
502+ & mut self ,
502503 span : Span ,
503- resolution_error : ResolutionError < ' _ > ,
504+ resolution_error : ResolutionError < ' a > ,
504505 ) -> DiagnosticBuilder < ' _ , ErrorGuaranteed > {
505506 match resolution_error {
506507 ResolutionError :: GenericParamsFromOuterFunction ( outer_res, has_generic_params) => {
@@ -650,7 +651,7 @@ impl<'a> Resolver<'a> {
650651 }
651652 err
652653 }
653- ResolutionError :: VariableNotBoundInPattern ( binding_error) => {
654+ ResolutionError :: VariableNotBoundInPattern ( binding_error, parent_scope ) => {
654655 let BindingError { name, target, origin, could_be_path } = binding_error;
655656
656657 let target_sp = target. iter ( ) . copied ( ) . collect :: < Vec < _ > > ( ) ;
@@ -670,13 +671,41 @@ impl<'a> Resolver<'a> {
670671 for sp in origin_sp {
671672 err. span_label ( sp, "variable not in all patterns" ) ;
672673 }
673- if * could_be_path {
674- let help_msg = format ! (
675- "if you meant to match on a variant or a `const` item, consider \
676- making the path in the pattern qualified: `?::{}`",
677- name,
674+ if could_be_path {
675+ let import_suggestions = self . lookup_import_candidates (
676+ Ident :: with_dummy_span ( name) ,
677+ Namespace :: ValueNS ,
678+ & parent_scope,
679+ & |res : Res | match res {
680+ Res :: Def (
681+ DefKind :: Ctor ( CtorOf :: Variant , CtorKind :: Const )
682+ | DefKind :: Ctor ( CtorOf :: Struct , CtorKind :: Const )
683+ | DefKind :: Const
684+ | DefKind :: AssocConst ,
685+ _,
686+ ) => true ,
687+ _ => false ,
688+ } ,
689+ ) ;
690+
691+ if import_suggestions. is_empty ( ) {
692+ let help_msg = format ! (
693+ "if you meant to match on a variant or a `const` item, consider \
694+ making the path in the pattern qualified: `path::to::ModOrType::{}`",
695+ name,
696+ ) ;
697+ err. span_help ( span, & help_msg) ;
698+ }
699+ show_candidates (
700+ & self . definitions ,
701+ self . session ,
702+ & mut err,
703+ Some ( span) ,
704+ & import_suggestions,
705+ false ,
706+ true ,
707+ true ,
678708 ) ;
679- err. span_help ( span, & help_msg) ;
680709 }
681710 err
682711 }
@@ -1022,7 +1051,7 @@ impl<'a> Resolver<'a> {
10221051 }
10231052
10241053 crate fn report_vis_error (
1025- & self ,
1054+ & mut self ,
10261055 vis_resolution_error : VisResolutionError < ' _ > ,
10271056 ) -> ErrorGuaranteed {
10281057 match vis_resolution_error {
@@ -1455,6 +1484,7 @@ impl<'a> Resolver<'a> {
14551484 & import_suggestions,
14561485 false ,
14571486 true ,
1487+ false ,
14581488 ) ;
14591489
14601490 if macro_kind == MacroKind :: Derive && ( ident. name == sym:: Send || ident. name == sym:: Sync ) {
@@ -2402,6 +2432,7 @@ fn show_candidates(
24022432 candidates : & [ ImportSuggestion ] ,
24032433 instead : bool ,
24042434 found_use : bool ,
2435+ is_pattern : bool ,
24052436) {
24062437 if candidates. is_empty ( ) {
24072438 return ;
@@ -2428,20 +2459,34 @@ fn show_candidates(
24282459 }
24292460
24302461 if !accessible_path_strings. is_empty ( ) {
2431- let ( determiner, kind) = if accessible_path_strings. len ( ) == 1 {
2432- ( "this" , accessible_path_strings[ 0 ] . 1 )
2462+ let ( determiner, kind, name ) = if accessible_path_strings. len ( ) == 1 {
2463+ ( "this" , accessible_path_strings[ 0 ] . 1 , format ! ( " `{}`" , accessible_path_strings [ 0 ] . 0 ) )
24332464 } else {
2434- ( "one of these" , "items" )
2465+ ( "one of these" , "items" , String :: new ( ) )
24352466 } ;
24362467
24372468 let instead = if instead { " instead" } else { "" } ;
2438- let mut msg = format ! ( "consider importing {} {}{}" , determiner, kind, instead) ;
2469+ let mut msg = if is_pattern {
2470+ format ! (
2471+ "if you meant to match on {}{}{}, use the full path in the pattern" ,
2472+ kind, instead, name
2473+ )
2474+ } else {
2475+ format ! ( "consider importing {} {}{}" , determiner, kind, instead)
2476+ } ;
24392477
24402478 for note in accessible_path_strings. iter ( ) . flat_map ( |cand| cand. 3 . as_ref ( ) ) {
24412479 err. note ( note) ;
24422480 }
24432481
2444- if let Some ( span) = use_placement_span {
2482+ if let ( true , Some ( span) ) = ( is_pattern, use_placement_span) {
2483+ err. span_suggestions (
2484+ span,
2485+ & msg,
2486+ accessible_path_strings. into_iter ( ) . map ( |a| a. 0 ) ,
2487+ Applicability :: MaybeIncorrect ,
2488+ ) ;
2489+ } else if let Some ( span) = use_placement_span {
24452490 for candidate in & mut accessible_path_strings {
24462491 // produce an additional newline to separate the new use statement
24472492 // from the directly following item.
@@ -2453,7 +2498,7 @@ fn show_candidates(
24532498 span,
24542499 & msg,
24552500 accessible_path_strings. into_iter ( ) . map ( |a| a. 0 ) ,
2456- Applicability :: Unspecified ,
2501+ Applicability :: MaybeIncorrect ,
24572502 ) ;
24582503 } else {
24592504 msg. push ( ':' ) ;
@@ -2468,9 +2513,16 @@ fn show_candidates(
24682513 } else {
24692514 assert ! ( !inaccessible_path_strings. is_empty( ) ) ;
24702515
2516+ let prefix = if is_pattern { "you might have meant to match on " } else { "" } ;
24712517 if inaccessible_path_strings. len ( ) == 1 {
24722518 let ( name, descr, def_id, note) = & inaccessible_path_strings[ 0 ] ;
2473- let msg = format ! ( "{} `{}` exists but is inaccessible" , descr, name) ;
2519+ let msg = format ! (
2520+ "{}{} `{}`{} exists but is inaccessible" ,
2521+ prefix,
2522+ descr,
2523+ name,
2524+ if is_pattern { ", which" } else { "" }
2525+ ) ;
24742526
24752527 if let Some ( local_def_id) = def_id. and_then ( |did| did. as_local ( ) ) {
24762528 let span = definitions. def_span ( local_def_id) ;
@@ -2496,7 +2548,7 @@ fn show_candidates(
24962548 "item" . to_string ( )
24972549 } ;
24982550
2499- let mut msg = format ! ( "these {}s exist but are inaccessible" , descr) ;
2551+ let mut msg = format ! ( "{} these {}s exist but are inaccessible" , prefix , descr) ;
25002552 let mut has_colon = false ;
25012553
25022554 let mut spans = Vec :: new ( ) ;
0 commit comments