@@ -57,6 +57,9 @@ enum ResolutionFailure<'a> {
5757 /// This resolved, but with the wrong namespace.
5858 /// `Namespace` is the expected namespace (as opposed to the actual).
5959 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 ) ,
6063 /// `String` is the base name of the path (not necessarily the whole link)
6164 NotInScope ( Cow < ' a , str > ) ,
6265 /// this is a primitive type without an impls (no associated methods)
@@ -90,7 +93,8 @@ impl ResolutionFailure<'a> {
9093 | NoPrimitiveImpl ( res, _)
9194 | NotAnEnum ( res)
9295 | NotAVariant ( res, _)
93- | WrongNamespace ( res, _) => Some ( * res) ,
96+ | WrongNamespace ( res, _)
97+ | CannotHaveAssociatedItems ( res, _) => Some ( * res) ,
9498 NotInScope ( _) | NoParentItem | Dummy => None ,
9599 }
96100 }
@@ -360,21 +364,39 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
360364 } ) ) ;
361365 }
362366
363- let ( _ , ty_res) = cx
367+ let ty_res = cx
364368 . enter_resolver ( |resolver| {
365369 // only types can have associated items
366370 resolver. resolve_str_path_error ( DUMMY_SP , & path_root, TypeNS , module_id)
367371 } )
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+ } ;
378400 let ty_res = ty_res. map_id ( |_| panic ! ( "unexpected node_id" ) ) ;
379401 let res = match ty_res {
380402 Res :: Def (
@@ -1006,14 +1028,12 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
10061028 Ok ( res) => ( res, extra_fragment) ,
10071029 Err ( mut kind) => {
10081030 // `macro_resolve` only looks in the macro namespace. Try to give a better error if possible.
1009- //if kind.res().is_none() {
10101031 for & ns in & [ TypeNS , ValueNS ] {
10111032 if let Some ( res) = check_full_res ( self , ns) {
10121033 kind = ResolutionFailure :: WrongNamespace ( res, MacroNS ) ;
10131034 break ;
10141035 }
10151036 }
1016- //}
10171037 resolution_failure (
10181038 cx,
10191039 & item,
@@ -1456,6 +1476,20 @@ fn resolution_failure(
14561476 diag. note ( & note) ;
14571477 }
14581478 }
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+ }
14591493 // TODO: is there ever a case where this happens?
14601494 ResolutionFailure :: NotAnEnum ( res) => {
14611495 let ( item, comma) = item ( res) ;
0 commit comments