@@ -4,9 +4,10 @@ use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion};
4
4
use crate :: late:: { AliasPossibility , LateResolutionVisitor , RibKind } ;
5
5
use crate :: late:: { LifetimeBinderKind , LifetimeRes , LifetimeRibKind , LifetimeUseSet } ;
6
6
use crate :: ty:: fast_reject:: SimplifiedType ;
7
- use crate :: { errors, path_names_to_string} ;
7
+ use crate :: { errors, path_names_to_string, Resolver } ;
8
8
use crate :: { Module , ModuleKind , ModuleOrUniformRoot } ;
9
9
use crate :: { PathResult , PathSource , Segment } ;
10
+ use rustc_attr:: collect_doc_alias_symbol_from_attrs;
10
11
use rustc_hir:: def:: Namespace :: { self , * } ;
11
12
12
13
use rustc_ast:: ptr:: P ;
@@ -452,6 +453,18 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
452
453
return ( err, Vec :: new ( ) ) ;
453
454
}
454
455
456
+ if let Some ( did) = self . lookup_doc_alias_name ( path, source. namespace ( ) ) {
457
+ err. span_label (
458
+ self . r . def_span ( did) ,
459
+ format ! (
460
+ "`{}` has a name defined in the doc alias attribute as `{}`" ,
461
+ self . r. tcx. item_name( did) ,
462
+ path. last( ) . unwrap( ) . ident. as_str( )
463
+ ) ,
464
+ ) ;
465
+ return ( err, Vec :: new ( ) ) ;
466
+ } ;
467
+
455
468
let ( found, mut candidates) = self . try_lookup_name_relaxed (
456
469
& mut err,
457
470
source,
@@ -776,6 +789,55 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
776
789
return ( false , candidates) ;
777
790
}
778
791
792
+ fn lookup_doc_alias_name ( & mut self , path : & [ Segment ] , ns : Namespace ) -> Option < DefId > {
793
+ let item_str = path. last ( ) . unwrap ( ) . ident ;
794
+
795
+ let find_doc_alias_name = |r : & mut Resolver < ' a , ' _ > , m : Module < ' a > | {
796
+ for resolution in r. resolutions ( m) . borrow ( ) . values ( ) {
797
+ let Some ( did) =
798
+ resolution. borrow ( ) . binding . and_then ( |binding| binding. res ( ) . opt_def_id ( ) )
799
+ else {
800
+ continue ;
801
+ } ;
802
+ let symbols = if let Some ( local_id) = did. as_local ( ) {
803
+ r. def_id_to_node_id . get ( local_id) . and_then ( |node_id| {
804
+ r. confusable_attr_symbols . get ( node_id) . map ( Cow :: Borrowed )
805
+ } )
806
+ } else {
807
+ let attrs: Vec < _ > = r. tcx . get_attrs ( did, sym:: doc) . collect ( ) ;
808
+ ( attrs. is_empty ( ) )
809
+ . then ( || Cow :: Owned ( collect_doc_alias_symbol_from_attrs ( attrs. into_iter ( ) ) ) )
810
+ } ;
811
+ let Some ( symbols) = symbols else {
812
+ continue ;
813
+ } ;
814
+ if symbols. contains ( & item_str. name ) {
815
+ return Some ( did) ;
816
+ }
817
+ }
818
+ None
819
+ } ;
820
+
821
+ if path. len ( ) == 1 {
822
+ for rib in self . ribs [ ns] . iter ( ) . rev ( ) {
823
+ if let RibKind :: Module ( module) = rib. kind
824
+ && let Some ( did) = find_doc_alias_name ( self . r , module)
825
+ {
826
+ return Some ( did) ;
827
+ }
828
+ }
829
+ } else {
830
+ let mod_path = & path[ ..path. len ( ) - 1 ] ;
831
+ if let PathResult :: Module ( ModuleOrUniformRoot :: Module ( module) ) =
832
+ self . resolve_path ( mod_path, Some ( TypeNS ) , None )
833
+ && let Some ( did) = find_doc_alias_name ( self . r , module)
834
+ {
835
+ return Some ( did) ;
836
+ }
837
+ }
838
+ None
839
+ }
840
+
779
841
fn suggest_trait_and_bounds (
780
842
& mut self ,
781
843
err : & mut Diag < ' _ > ,
0 commit comments