@@ -11,6 +11,7 @@ use rustc_ast::{
1111 Item , ItemKind , MethodCall , NodeId , Path , PathSegment , Ty , TyKind ,
1212} ;
1313use rustc_ast_pretty:: pprust:: where_bound_predicate_to_string;
14+ use rustc_attr_parsing:: is_doc_alias_attrs_contain_symbol;
1415use rustc_data_structures:: fx:: { FxHashSet , FxIndexSet } ;
1516use rustc_errors:: codes:: * ;
1617use rustc_errors:: {
@@ -39,7 +40,7 @@ use crate::late::{
3940} ;
4041use crate :: ty:: fast_reject:: SimplifiedType ;
4142use crate :: {
42- Module , ModuleKind , ModuleOrUniformRoot , PathResult , PathSource , Segment , errors,
43+ Module , ModuleKind , ModuleOrUniformRoot , PathResult , PathSource , Resolver , Segment , errors,
4344 path_names_to_string,
4445} ;
4546
@@ -477,6 +478,18 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
477478 return ( err, Vec :: new ( ) ) ;
478479 }
479480
481+ if let Some ( did) = self . lookup_doc_alias_name ( path, source. namespace ( ) ) {
482+ err. span_help (
483+ self . r . def_span ( did) ,
484+ format ! (
485+ "`{}` has a name defined in the doc alias attribute as `{}`" ,
486+ self . r. tcx. item_name( did) ,
487+ path. last( ) . unwrap( ) . ident
488+ ) ,
489+ ) ;
490+ return ( err, Vec :: new ( ) ) ;
491+ } ;
492+
480493 let ( found, suggested_candidates, mut candidates) = self . try_lookup_name_relaxed (
481494 & mut err,
482495 source,
@@ -852,6 +865,51 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
852865 ( false , suggested_candidates, candidates)
853866 }
854867
868+ fn lookup_doc_alias_name ( & mut self , path : & [ Segment ] , ns : Namespace ) -> Option < DefId > {
869+ let item = path. last ( ) ?. ident ;
870+
871+ let find_doc_alias_name = |r : & mut Resolver < ' ra , ' _ > , m : Module < ' ra > | {
872+ for resolution in r. resolutions ( m) . borrow ( ) . values ( ) {
873+ let Some ( did) =
874+ resolution. borrow ( ) . binding . and_then ( |binding| binding. res ( ) . opt_def_id ( ) )
875+ else {
876+ continue ;
877+ } ;
878+ if did. is_local ( ) {
879+ // We don't record the doc alias name in the local crate
880+ // because the people who write doc alias are usually not
881+ // confused by them.
882+ continue ;
883+ }
884+ if is_doc_alias_attrs_contain_symbol ( r. tcx . get_attrs ( did, sym:: doc) , item. name ) {
885+ return Some ( did) ;
886+ }
887+ }
888+ None
889+ } ;
890+
891+ if path. len ( ) == 1 {
892+ for rib in self . ribs [ ns] . iter ( ) . rev ( ) {
893+ if let RibKind :: Module ( module) = rib. kind
894+ && let Some ( did) = find_doc_alias_name ( self . r , module)
895+ {
896+ return Some ( did) ;
897+ }
898+ }
899+ } else {
900+ let mod_seg = path[ path. len ( ) - 2 ] ;
901+ if let Some ( seg_id) = mod_seg. id
902+ && let Some ( res) = self . r . partial_res_map . get ( & seg_id)
903+ && let hir:: def:: Res :: Def ( hir:: def:: DefKind :: Mod , module) = res. base_res ( )
904+ && let Some ( module) = self . r . get_module ( module)
905+ && let Some ( did) = find_doc_alias_name ( self . r , module)
906+ {
907+ return Some ( did) ;
908+ }
909+ }
910+ None
911+ }
912+
855913 fn suggest_trait_and_bounds (
856914 & mut self ,
857915 err : & mut Diag < ' _ > ,
0 commit comments