@@ -2783,33 +2783,56 @@ fn show_candidates(
2783
2783
// by iterating through a hash map, so make sure they are ordered:
2784
2784
for path_strings in [ & mut accessible_path_strings, & mut inaccessible_path_strings] {
2785
2785
path_strings. sort_by ( |a, b| a. 0 . cmp ( & b. 0 ) ) ;
2786
+ path_strings. dedup_by ( |a, b| a. 0 == b. 0 ) ;
2786
2787
let core_path_strings =
2787
2788
path_strings. extract_if ( |p| p. 0 . starts_with ( "core::" ) ) . collect :: < Vec < _ > > ( ) ;
2788
- path_strings. extend ( core_path_strings) ;
2789
- path_strings. dedup_by ( |a, b| a. 0 == b. 0 ) ;
2789
+ let std_path_strings =
2790
+ path_strings. extract_if ( |p| p. 0 . starts_with ( "std::" ) ) . collect :: < Vec < _ > > ( ) ;
2791
+ let foreign_crate_path_strings =
2792
+ path_strings. extract_if ( |p| !p. 0 . starts_with ( "crate::" ) ) . collect :: < Vec < _ > > ( ) ;
2793
+
2794
+ // We list the `crate` local paths first.
2795
+ // Then we list the `std`/`core` paths.
2796
+ if std_path_strings. len ( ) == core_path_strings. len ( ) {
2797
+ // Do not list `core::` paths if we are already listing the `std::` ones.
2798
+ path_strings. extend ( std_path_strings) ;
2799
+ } else {
2800
+ path_strings. extend ( std_path_strings) ;
2801
+ path_strings. extend ( core_path_strings) ;
2802
+ }
2803
+ // List all paths from foreign crates last.
2804
+ path_strings. extend ( foreign_crate_path_strings) ;
2790
2805
}
2791
- accessible_path_strings. sort ( ) ;
2792
2806
2793
2807
if !accessible_path_strings. is_empty ( ) {
2794
- let ( determiner, kind, name, through) =
2795
- if let [ ( name, descr, _, _, via_import) ] = & accessible_path_strings[ ..] {
2796
- (
2797
- "this" ,
2798
- * descr,
2799
- format ! ( " `{name}`" ) ,
2800
- if * via_import { " through its public re-export" } else { "" } ,
2801
- )
2802
- } else {
2803
- ( "one of these" , "items" , String :: new ( ) , "" )
2804
- } ;
2808
+ let ( determiner, kind, s, name, through) = if let [ ( name, descr, _, _, via_import) ] =
2809
+ & accessible_path_strings[ ..]
2810
+ {
2811
+ (
2812
+ "this" ,
2813
+ * descr,
2814
+ "" ,
2815
+ format ! ( " `{name}`" ) ,
2816
+ if * via_import { " through its public re-export" } else { "" } ,
2817
+ )
2818
+ } else {
2819
+ let descr_set: FxHashSet < & str > =
2820
+ accessible_path_strings. iter ( ) . map ( |( _, descr, _, _, _) | * descr) . collect ( ) ;
2821
+ let items =
2822
+ if descr_set. len ( ) == 1 { descr_set. into_iter ( ) . next ( ) . unwrap ( ) } else { "item" } ;
2823
+ let s = if items. ends_with ( 's' ) { "es" } else { "s" } ;
2824
+
2825
+ ( "one of these" , items, s, String :: new ( ) , "" )
2826
+ } ;
2805
2827
2806
2828
let instead = if let Instead :: Yes = instead { " instead" } else { "" } ;
2807
2829
let mut msg = if let DiagMode :: Pattern = mode {
2808
2830
format ! (
2809
- "if you meant to match on {kind}{instead}{name}, use the full path in the pattern" ,
2831
+ "if you meant to match on {kind}{s}{instead}{name}, use the full path in the \
2832
+ pattern",
2810
2833
)
2811
2834
} else {
2812
- format ! ( "consider importing {determiner} {kind}{through}{instead}" )
2835
+ format ! ( "consider importing {determiner} {kind}{s}{ through}{instead}" )
2813
2836
} ;
2814
2837
2815
2838
for note in accessible_path_strings. iter ( ) . flat_map ( |cand| cand. 3 . as_ref ( ) ) {
0 commit comments