@@ -121,7 +121,7 @@ struct LinkCollector<'a, 'tcx> {
121
121
/// This is used to store the kind of associated items,
122
122
/// because `clean` and the disambiguator code expect them to be different.
123
123
/// 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 ) > > ,
125
125
}
126
126
127
127
impl < ' a , ' tcx > LinkCollector < ' a , ' tcx > {
@@ -381,7 +381,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
381
381
) => {
382
382
debug ! ( "looking for associated item named {} for item {:?}" , item_name, did) ;
383
383
// Checks if item_name belongs to `impl SomeItem`
384
- let kind = cx
384
+ let assoc_item = cx
385
385
. tcx
386
386
. inherent_impls ( did)
387
387
. iter ( )
@@ -393,7 +393,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
393
393
imp,
394
394
)
395
395
} )
396
- . map ( |item| item. kind )
396
+ . map ( |item| ( item. kind , item . def_id ) )
397
397
// There should only ever be one associated item that matches from any inherent impl
398
398
. next ( )
399
399
// Check if item_name belongs to `impl SomeTrait for SomeItem`
@@ -409,7 +409,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
409
409
kind
410
410
} ) ;
411
411
412
- if let Some ( kind) = kind {
412
+ if let Some ( ( kind, id ) ) = assoc_item {
413
413
let out = match kind {
414
414
ty:: AssocKind :: Fn => "method" ,
415
415
ty:: AssocKind :: Const => "associatedconstant" ,
@@ -425,7 +425,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
425
425
// HACK(jynelson): `clean` expects the type, not the associated item.
426
426
// but the disambiguator logic expects the associated item.
427
427
// 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 ) ) ) ;
429
429
Ok ( ( ty_res, Some ( format ! ( "{}.{}" , out, item_name) ) ) )
430
430
} )
431
431
} else if ns == Namespace :: ValueNS {
@@ -525,7 +525,7 @@ fn resolve_associated_trait_item(
525
525
item_name : Symbol ,
526
526
ns : Namespace ,
527
527
cx : & DocContext < ' _ > ,
528
- ) -> Option < ty:: AssocKind > {
528
+ ) -> Option < ( ty:: AssocKind , DefId ) > {
529
529
let ty = cx. tcx . type_of ( did) ;
530
530
// First consider automatic impls: `impl From<T> for T`
531
531
let implicit_impls = crate :: clean:: get_auto_trait_and_blanket_impls ( cx, ty, did) ;
@@ -553,7 +553,7 @@ fn resolve_associated_trait_item(
553
553
// but provided methods come directly from `tcx`.
554
554
// Fortunately, we don't need the whole method, we just need to know
555
555
// what kind of associated item it is.
556
- Some ( ( assoc. def_id , kind ) )
556
+ Some ( ( kind , assoc. def_id ) )
557
557
} ) ;
558
558
let assoc = items. next ( ) ;
559
559
debug_assert_eq ! ( items. count( ) , 0 ) ;
@@ -575,7 +575,7 @@ fn resolve_associated_trait_item(
575
575
ns,
576
576
trait_,
577
577
)
578
- . map ( |assoc| ( assoc. def_id , assoc. kind ) )
578
+ . map ( |assoc| ( assoc. kind , assoc. def_id ) )
579
579
}
580
580
}
581
581
_ => panic ! ( "get_impls returned something that wasn't an impl" ) ,
@@ -592,12 +592,12 @@ fn resolve_associated_trait_item(
592
592
cx. tcx
593
593
. associated_items ( trait_)
594
594
. 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 ) )
596
596
} ) ) ;
597
597
}
598
598
// FIXME: warn about ambiguity
599
599
debug ! ( "the candidates were {:?}" , candidates) ;
600
- candidates. pop ( ) . map ( | ( _ , kind ) | kind )
600
+ candidates. pop ( )
601
601
}
602
602
603
603
/// 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> {
851
851
852
852
// used for reporting better errors
853
853
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)
866
869
} ;
867
870
868
871
match disambiguator. map ( Disambiguator :: ns) {
@@ -876,7 +879,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
876
879
if kind. full_res ( ) . is_none ( ) {
877
880
let other_ns = if ns == ValueNS { TypeNS } else { ValueNS } ;
878
881
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) ;
880
884
}
881
885
}
882
886
resolution_failure (
@@ -1092,7 +1096,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
1092
1096
// Disallow e.g. linking to enums with `struct@`
1093
1097
if let Res :: Def ( kind, _) = res {
1094
1098
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) {
1096
1100
| ( DefKind :: Const | DefKind :: ConstParam | DefKind :: AssocConst | DefKind :: AnonConst , Some ( Disambiguator :: Kind ( DefKind :: Const ) ) )
1097
1101
// NOTE: this allows 'method' to mean both normal functions and associated functions
1098
1102
// This can't cause ambiguity because both are in the same namespace.
0 commit comments