@@ -57,6 +57,9 @@ enum ResolutionFailure<'a> {
57
57
/// This resolved, but with the wrong namespace.
58
58
/// `Namespace` is the expected namespace (as opposed to the actual).
59
59
WrongNamespace ( Res , Namespace ) ,
60
+ /// This has a partial resolution, but is not in the TypeNS and so cannot
61
+ /// have associated items or fields.
62
+ CannotHaveAssociatedItems ( Res , Namespace ) ,
60
63
/// `String` is the base name of the path (not necessarily the whole link)
61
64
NotInScope ( Cow < ' a , str > ) ,
62
65
/// this is a primitive type without an impls (no associated methods)
@@ -90,7 +93,8 @@ impl ResolutionFailure<'a> {
90
93
| NoPrimitiveImpl ( res, _)
91
94
| NotAnEnum ( res)
92
95
| NotAVariant ( res, _)
93
- | WrongNamespace ( res, _) => Some ( * res) ,
96
+ | WrongNamespace ( res, _)
97
+ | CannotHaveAssociatedItems ( res, _) => Some ( * res) ,
94
98
NotInScope ( _) | NoParentItem | Dummy => None ,
95
99
}
96
100
}
@@ -360,21 +364,39 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
360
364
} ) ) ;
361
365
}
362
366
363
- let ( _ , ty_res) = cx
367
+ let ty_res = cx
364
368
. enter_resolver ( |resolver| {
365
369
// only types can have associated items
366
370
resolver. resolve_str_path_error ( DUMMY_SP , & path_root, TypeNS , module_id)
367
371
} )
368
- . map_err ( |_| {
369
- ErrorKind :: Resolve ( ResolutionFailure :: NotInScope ( path_root. clone ( ) . into ( ) ) )
370
- } ) ?;
371
- if let Res :: Err = ty_res {
372
- return if ns == Namespace :: ValueNS {
373
- self . variant_field ( path_str, current_item, module_id)
374
- } else {
375
- Err ( ErrorKind :: Resolve ( ResolutionFailure :: NotInScope ( path_root. into ( ) ) ) )
376
- } ;
377
- }
372
+ . map ( |( _, res) | res) ;
373
+ let ty_res = match ty_res {
374
+ Err ( ( ) ) | Ok ( Res :: Err ) => {
375
+ return if ns == Namespace :: ValueNS {
376
+ self . variant_field ( path_str, current_item, module_id)
377
+ } else {
378
+ // See if it only broke because of the namespace.
379
+ let kind = cx. enter_resolver ( |resolver| {
380
+ for & ns in & [ MacroNS , ValueNS ] {
381
+ match resolver
382
+ . resolve_str_path_error ( DUMMY_SP , & path_root, ns, module_id)
383
+ {
384
+ Ok ( ( _, Res :: Err ) ) | Err ( ( ) ) => { }
385
+ Ok ( ( _, res) ) => {
386
+ let res = res. map_id ( |_| panic ! ( "unexpected node_id" ) ) ;
387
+ return ResolutionFailure :: CannotHaveAssociatedItems (
388
+ res, ns,
389
+ ) ;
390
+ }
391
+ }
392
+ }
393
+ ResolutionFailure :: NotInScope ( path_root. into ( ) )
394
+ } ) ;
395
+ Err ( ErrorKind :: Resolve ( kind) )
396
+ } ;
397
+ }
398
+ Ok ( res) => res,
399
+ } ;
378
400
let ty_res = ty_res. map_id ( |_| panic ! ( "unexpected node_id" ) ) ;
379
401
let res = match ty_res {
380
402
Res :: Def (
@@ -1006,14 +1028,12 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
1006
1028
Ok ( res) => ( res, extra_fragment) ,
1007
1029
Err ( mut kind) => {
1008
1030
// `macro_resolve` only looks in the macro namespace. Try to give a better error if possible.
1009
- //if kind.res().is_none() {
1010
1031
for & ns in & [ TypeNS , ValueNS ] {
1011
1032
if let Some ( res) = check_full_res ( self , ns) {
1012
1033
kind = ResolutionFailure :: WrongNamespace ( res, MacroNS ) ;
1013
1034
break ;
1014
1035
}
1015
1036
}
1016
- //}
1017
1037
resolution_failure (
1018
1038
cx,
1019
1039
& item,
@@ -1456,6 +1476,20 @@ fn resolution_failure(
1456
1476
diag. note ( & note) ;
1457
1477
}
1458
1478
}
1479
+ ResolutionFailure :: CannotHaveAssociatedItems ( res, _) => {
1480
+ let ( item, _) = item ( res) ;
1481
+ diag. note ( & format ! ( "this link partially resolves to {}" , item) ) ;
1482
+ if let Res :: Def ( kind, def_id) = res {
1483
+ let name = cx. tcx . item_name ( def_id) ;
1484
+ let note = format ! (
1485
+ "`{}` is {} {}, not a module or type, and cannot have associated items" ,
1486
+ name,
1487
+ kind. article( ) ,
1488
+ kind. descr( def_id)
1489
+ ) ;
1490
+ diag. note ( & note) ;
1491
+ }
1492
+ }
1459
1493
// TODO: is there ever a case where this happens?
1460
1494
ResolutionFailure :: NotAnEnum ( res) => {
1461
1495
let ( item, comma) = item ( res) ;
0 commit comments