@@ -134,6 +134,7 @@ impl<'a> Resolver<'a> {
134
134
& candidates,
135
135
instead,
136
136
found_use,
137
+ false ,
137
138
) ;
138
139
} else if let Some ( ( span, msg, sugg, appl) ) = suggestion {
139
140
err. span_suggestion ( span, msg, sugg, appl) ;
@@ -493,14 +494,14 @@ impl<'a> Resolver<'a> {
493
494
///
494
495
/// This takes the error provided, combines it with the span and any additional spans inside the
495
496
/// 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 > ) {
497
498
self . into_struct_error ( span, resolution_error) . emit ( ) ;
498
499
}
499
500
500
501
crate fn into_struct_error (
501
- & self ,
502
+ & mut self ,
502
503
span : Span ,
503
- resolution_error : ResolutionError < ' _ > ,
504
+ resolution_error : ResolutionError < ' a > ,
504
505
) -> DiagnosticBuilder < ' _ , ErrorGuaranteed > {
505
506
match resolution_error {
506
507
ResolutionError :: GenericParamsFromOuterFunction ( outer_res, has_generic_params) => {
@@ -650,7 +651,7 @@ impl<'a> Resolver<'a> {
650
651
}
651
652
err
652
653
}
653
- ResolutionError :: VariableNotBoundInPattern ( binding_error) => {
654
+ ResolutionError :: VariableNotBoundInPattern ( binding_error, parent_scope ) => {
654
655
let BindingError { name, target, origin, could_be_path } = binding_error;
655
656
656
657
let target_sp = target. iter ( ) . copied ( ) . collect :: < Vec < _ > > ( ) ;
@@ -670,13 +671,41 @@ impl<'a> Resolver<'a> {
670
671
for sp in origin_sp {
671
672
err. span_label ( sp, "variable not in all patterns" ) ;
672
673
}
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 ,
678
708
) ;
679
- err. span_help ( span, & help_msg) ;
680
709
}
681
710
err
682
711
}
@@ -1022,7 +1051,7 @@ impl<'a> Resolver<'a> {
1022
1051
}
1023
1052
1024
1053
crate fn report_vis_error (
1025
- & self ,
1054
+ & mut self ,
1026
1055
vis_resolution_error : VisResolutionError < ' _ > ,
1027
1056
) -> ErrorGuaranteed {
1028
1057
match vis_resolution_error {
@@ -1455,6 +1484,7 @@ impl<'a> Resolver<'a> {
1455
1484
& import_suggestions,
1456
1485
false ,
1457
1486
true ,
1487
+ false ,
1458
1488
) ;
1459
1489
1460
1490
if macro_kind == MacroKind :: Derive && ( ident. name == sym:: Send || ident. name == sym:: Sync ) {
@@ -2402,6 +2432,7 @@ fn show_candidates(
2402
2432
candidates : & [ ImportSuggestion ] ,
2403
2433
instead : bool ,
2404
2434
found_use : bool ,
2435
+ is_pattern : bool ,
2405
2436
) {
2406
2437
if candidates. is_empty ( ) {
2407
2438
return ;
@@ -2428,20 +2459,34 @@ fn show_candidates(
2428
2459
}
2429
2460
2430
2461
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 ) )
2433
2464
} else {
2434
- ( "one of these" , "items" )
2465
+ ( "one of these" , "items" , String :: new ( ) )
2435
2466
} ;
2436
2467
2437
2468
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
+ } ;
2439
2477
2440
2478
for note in accessible_path_strings. iter ( ) . flat_map ( |cand| cand. 3 . as_ref ( ) ) {
2441
2479
err. note ( note) ;
2442
2480
}
2443
2481
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 {
2445
2490
for candidate in & mut accessible_path_strings {
2446
2491
// produce an additional newline to separate the new use statement
2447
2492
// from the directly following item.
@@ -2453,7 +2498,7 @@ fn show_candidates(
2453
2498
span,
2454
2499
& msg,
2455
2500
accessible_path_strings. into_iter ( ) . map ( |a| a. 0 ) ,
2456
- Applicability :: Unspecified ,
2501
+ Applicability :: MaybeIncorrect ,
2457
2502
) ;
2458
2503
} else {
2459
2504
msg. push ( ':' ) ;
@@ -2468,9 +2513,16 @@ fn show_candidates(
2468
2513
} else {
2469
2514
assert ! ( !inaccessible_path_strings. is_empty( ) ) ;
2470
2515
2516
+ let prefix = if is_pattern { "you might have meant to match on " } else { "" } ;
2471
2517
if inaccessible_path_strings. len ( ) == 1 {
2472
2518
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
+ ) ;
2474
2526
2475
2527
if let Some ( local_def_id) = def_id. and_then ( |did| did. as_local ( ) ) {
2476
2528
let span = definitions. def_span ( local_def_id) ;
@@ -2496,7 +2548,7 @@ fn show_candidates(
2496
2548
"item" . to_string ( )
2497
2549
} ;
2498
2550
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) ;
2500
2552
let mut has_colon = false ;
2501
2553
2502
2554
let mut spans = Vec :: new ( ) ;
0 commit comments