@@ -461,7 +461,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
461
461
static_candidates : Vec :: new ( ) ,
462
462
unsatisfied_predicates : Vec :: new ( ) ,
463
463
out_of_scope_traits : Vec :: new ( ) ,
464
- lev_candidate : None ,
464
+ similar_candidate : None ,
465
465
mode,
466
466
} ) ) ;
467
467
}
@@ -1076,13 +1076,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1076
1076
if let Some ( ( kind, def_id) ) = private_candidate {
1077
1077
return Err ( MethodError :: PrivateMatch ( kind, def_id, out_of_scope_traits) ) ;
1078
1078
}
1079
- let lev_candidate = self . probe_for_lev_candidate ( ) ?;
1079
+ let similar_candidate = self . probe_for_similar_candidate ( ) ?;
1080
1080
1081
1081
Err ( MethodError :: NoMatch ( NoMatchData {
1082
1082
static_candidates,
1083
1083
unsatisfied_predicates,
1084
1084
out_of_scope_traits,
1085
- lev_candidate ,
1085
+ similar_candidate ,
1086
1086
mode : self . mode ,
1087
1087
} ) )
1088
1088
}
@@ -1787,7 +1787,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1787
1787
/// Similarly to `probe_for_return_type`, this method attempts to find the best matching
1788
1788
/// candidate method where the method name may have been misspelled. Similarly to other
1789
1789
/// Levenshtein based suggestions, we provide at most one such suggestion.
1790
- fn probe_for_lev_candidate ( & mut self ) -> Result < Option < ty:: AssocItem > , MethodError < ' tcx > > {
1790
+ fn probe_for_similar_candidate ( & mut self ) -> Result < Option < ty:: AssocItem > , MethodError < ' tcx > > {
1791
1791
debug ! ( "probing for method names similar to {:?}" , self . method_name) ;
1792
1792
1793
1793
let steps = self . steps . clone ( ) ;
@@ -1831,6 +1831,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1831
1831
None ,
1832
1832
)
1833
1833
}
1834
+ . or_else ( || {
1835
+ applicable_close_candidates
1836
+ . iter ( )
1837
+ . find ( |cand| self . matches_by_doc_alias ( cand. def_id ) )
1838
+ . map ( |cand| cand. name )
1839
+ } )
1834
1840
. unwrap ( ) ;
1835
1841
Ok ( applicable_close_candidates. into_iter ( ) . find ( |method| method. name == best_name) )
1836
1842
}
@@ -1981,6 +1987,38 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1981
1987
}
1982
1988
}
1983
1989
1990
+ /// Determine if the associated item withe the given DefId matches
1991
+ /// the desired name via a doc alias.
1992
+ fn matches_by_doc_alias ( & self , def_id : DefId ) -> bool {
1993
+ let Some ( name) = self . method_name else { return false ; } ;
1994
+ let Some ( local_def_id) = def_id. as_local ( ) else { return false ; } ;
1995
+ let hir_id = self . fcx . tcx . hir ( ) . local_def_id_to_hir_id ( local_def_id) ;
1996
+ let attrs = self . fcx . tcx . hir ( ) . attrs ( hir_id) ;
1997
+ for attr in attrs {
1998
+ let sym:: doc = attr. name_or_empty ( ) else { continue ; } ;
1999
+ let Some ( values) = attr. meta_item_list ( ) else { continue ; } ;
2000
+ for v in values {
2001
+ if v. name_or_empty ( ) != sym:: alias {
2002
+ continue ;
2003
+ }
2004
+ if let Some ( nested) = v. meta_item_list ( ) {
2005
+ // #[doc(alias("foo", "bar"))]
2006
+ for n in nested {
2007
+ if let Some ( lit) = n. lit ( ) && name. as_str ( ) == lit. symbol . as_str ( ) {
2008
+ return true ;
2009
+ }
2010
+ }
2011
+ } else if let Some ( meta) = v. meta_item ( )
2012
+ && let Some ( lit) = meta. name_value_literal ( )
2013
+ && name. as_str ( ) == lit. symbol . as_str ( ) {
2014
+ // #[doc(alias = "foo")]
2015
+ return true ;
2016
+ }
2017
+ }
2018
+ }
2019
+ false
2020
+ }
2021
+
1984
2022
/// Finds the method with the appropriate name (or return type, as the case may be). If
1985
2023
/// `allow_similar_names` is set, find methods with close-matching names.
1986
2024
// The length of the returned iterator is nearly always 0 or 1 and this
@@ -1996,6 +2034,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
1996
2034
if !self . is_relevant_kind_for_mode ( x. kind ) {
1997
2035
return false ;
1998
2036
}
2037
+ if self . matches_by_doc_alias ( x. def_id ) {
2038
+ return true ;
2039
+ }
1999
2040
match lev_distance_with_substrings ( name. as_str ( ) , x. name . as_str ( ) , max_dist)
2000
2041
{
2001
2042
Some ( d) => d > 0 ,
0 commit comments