@@ -121,7 +121,7 @@ struct LinkCollector<'a, 'tcx> {
121121 /// This is used to store the kind of associated items,
122122 /// because `clean` and the disambiguator code expect them to be different.
123123 /// See the code for associated items on inherent impls for details.
124- kind_side_channel : Cell < Option < DefKind > > ,
124+ kind_side_channel : Cell < Option < ( DefKind , DefId ) > > ,
125125}
126126
127127impl < ' a , ' tcx > LinkCollector < ' a , ' tcx > {
@@ -381,7 +381,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
381381 ) => {
382382 debug ! ( "looking for associated item named {} for item {:?}" , item_name, did) ;
383383 // Checks if item_name belongs to `impl SomeItem`
384- let kind = cx
384+ let assoc_item = cx
385385 . tcx
386386 . inherent_impls ( did)
387387 . iter ( )
@@ -393,7 +393,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
393393 imp,
394394 )
395395 } )
396- . map ( |item| item. kind )
396+ . map ( |item| ( item. kind , item . def_id ) )
397397 // There should only ever be one associated item that matches from any inherent impl
398398 . next ( )
399399 // Check if item_name belongs to `impl SomeTrait for SomeItem`
@@ -409,7 +409,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
409409 kind
410410 } ) ;
411411
412- if let Some ( kind) = kind {
412+ if let Some ( ( kind, id ) ) = assoc_item {
413413 let out = match kind {
414414 ty:: AssocKind :: Fn => "method" ,
415415 ty:: AssocKind :: Const => "associatedconstant" ,
@@ -425,7 +425,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
425425 // HACK(jynelson): `clean` expects the type, not the associated item.
426426 // but the disambiguator logic expects the associated item.
427427 // Store the kind in a side channel so that only the disambiguator logic looks at it.
428- self . kind_side_channel . set ( Some ( kind. as_def_kind ( ) ) ) ;
428+ self . kind_side_channel . set ( Some ( ( kind. as_def_kind ( ) , id ) ) ) ;
429429 Ok ( ( ty_res, Some ( format ! ( "{}.{}" , out, item_name) ) ) )
430430 } )
431431 } else if ns == Namespace :: ValueNS {
@@ -525,7 +525,7 @@ fn resolve_associated_trait_item(
525525 item_name : Symbol ,
526526 ns : Namespace ,
527527 cx : & DocContext < ' _ > ,
528- ) -> Option < ty:: AssocKind > {
528+ ) -> Option < ( ty:: AssocKind , DefId ) > {
529529 let ty = cx. tcx . type_of ( did) ;
530530 // First consider automatic impls: `impl From<T> for T`
531531 let implicit_impls = crate :: clean:: get_auto_trait_and_blanket_impls ( cx, ty, did) ;
@@ -553,7 +553,7 @@ fn resolve_associated_trait_item(
553553 // but provided methods come directly from `tcx`.
554554 // Fortunately, we don't need the whole method, we just need to know
555555 // what kind of associated item it is.
556- Some ( ( assoc. def_id , kind ) )
556+ Some ( ( kind , assoc. def_id ) )
557557 } ) ;
558558 let assoc = items. next ( ) ;
559559 debug_assert_eq ! ( items. count( ) , 0 ) ;
@@ -575,7 +575,7 @@ fn resolve_associated_trait_item(
575575 ns,
576576 trait_,
577577 )
578- . map ( |assoc| ( assoc. def_id , assoc. kind ) )
578+ . map ( |assoc| ( assoc. kind , assoc. def_id ) )
579579 }
580580 }
581581 _ => panic ! ( "get_impls returned something that wasn't an impl" ) ,
@@ -592,12 +592,12 @@ fn resolve_associated_trait_item(
592592 cx. tcx
593593 . associated_items ( trait_)
594594 . find_by_name_and_namespace ( cx. tcx , Ident :: with_dummy_span ( item_name) , ns, trait_)
595- . map ( |assoc| ( assoc. def_id , assoc. kind ) )
595+ . map ( |assoc| ( assoc. kind , assoc. def_id ) )
596596 } ) ) ;
597597 }
598598 // FIXME: warn about ambiguity
599599 debug ! ( "the candidates were {:?}" , candidates) ;
600- candidates. pop ( ) . map ( | ( _ , kind ) | kind )
600+ candidates. pop ( )
601601}
602602
603603/// Given a type, return all traits in scope in `module` implemented by that type.
@@ -851,18 +851,21 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
851851
852852 // used for reporting better errors
853853 let check_full_res = |this : & mut Self , ns| {
854- match this. resolve ( path_str, ns, & current_item, base_node, & extra_fragment) {
855- Ok ( res) => {
856- debug ! (
857- "check_full_res: saw res for {} in {:?} ns: {:?}" ,
858- path_str, ns, res. 0
859- ) ;
860- Some ( res. 0 )
861- }
862- Err ( ErrorKind :: Resolve ( kind) ) => kind. full_res ( ) ,
863- // TODO: add `Res` to AnchorFailure
864- Err ( ErrorKind :: AnchorFailure ( _) ) => None ,
865- }
854+ let res =
855+ match this. resolve ( path_str, ns, & current_item, base_node, & extra_fragment)
856+ {
857+ Ok ( res) => {
858+ debug ! (
859+ "check_full_res: saw res for {} in {:?} ns: {:?}" ,
860+ path_str, ns, res. 0
861+ ) ;
862+ Some ( res. 0 )
863+ }
864+ Err ( ErrorKind :: Resolve ( kind) ) => kind. full_res ( ) ,
865+ // TODO: add `Res` to AnchorFailure
866+ Err ( ErrorKind :: AnchorFailure ( _) ) => None ,
867+ } ;
868+ this. kind_side_channel . take ( ) . map ( |( kind, id) | Res :: Def ( kind, id) ) . or ( res)
866869 } ;
867870
868871 match disambiguator. map ( Disambiguator :: ns) {
@@ -876,7 +879,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
876879 if kind. full_res ( ) . is_none ( ) {
877880 let other_ns = if ns == ValueNS { TypeNS } else { ValueNS } ;
878881 if let Some ( res) = check_full_res ( self , other_ns) {
879- kind = ResolutionFailure :: WrongNamespace ( res, other_ns) ;
882+ // recall that this stores the _expected_ namespace
883+ kind = ResolutionFailure :: WrongNamespace ( res, ns) ;
880884 }
881885 }
882886 resolution_failure (
@@ -1092,7 +1096,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
10921096 // Disallow e.g. linking to enums with `struct@`
10931097 if let Res :: Def ( kind, _) = res {
10941098 debug ! ( "saw kind {:?} with disambiguator {:?}" , kind, disambiguator) ;
1095- match ( self . kind_side_channel . take ( ) . unwrap_or ( kind) , disambiguator) {
1099+ match ( self . kind_side_channel . take ( ) . map ( | ( kind , _ ) | kind ) . unwrap_or ( kind) , disambiguator) {
10961100 | ( DefKind :: Const | DefKind :: ConstParam | DefKind :: AssocConst | DefKind :: AnonConst , Some ( Disambiguator :: Kind ( DefKind :: Const ) ) )
10971101 // NOTE: this allows 'method' to mean both normal functions and associated functions
10981102 // This can't cause ambiguity because both are in the same namespace.
0 commit comments