@@ -262,11 +262,11 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
262262 false ,
263263 ) {
264264 if let SyntaxExtensionKind :: LegacyBang { .. } = ext. kind {
265- return Ok ( res. map_id ( |_| panic ! ( "unexpected id" ) ) ) ;
265+ return Some ( Ok ( res. map_id ( |_| panic ! ( "unexpected id" ) ) ) ) ;
266266 }
267267 }
268268 if let Some ( res) = resolver. all_macros ( ) . get ( & Symbol :: intern ( path_str) ) {
269- return Ok ( res. map_id ( |_| panic ! ( "unexpected id" ) ) ) ;
269+ return Some ( Ok ( res. map_id ( |_| panic ! ( "unexpected id" ) ) ) ) ;
270270 }
271271 if let Some ( module_id) = parent_id {
272272 debug ! ( "resolving {} as a macro in the module {:?}" , path_str, module_id) ;
@@ -276,14 +276,32 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
276276 // don't resolve builtins like `#[derive]`
277277 if let Res :: Def ( ..) = res {
278278 let res = res. map_id ( |_| panic ! ( "unexpected node_id" ) ) ;
279- return Ok ( res) ;
279+ return Some ( Ok ( res) ) ;
280280 }
281281 }
282282 } else {
283283 debug ! ( "attempting to resolve item without parent module: {}" , path_str) ;
284- return Err ( ResolutionFailure :: NoParentItem ) ;
284+ return Some ( Err ( ResolutionFailure :: NoParentItem ) ) ;
285285 }
286- return Err ( ResolutionFailure :: NotInScope ( path_str. into ( ) ) ) ;
286+ None
287+ } )
288+ // This weird control flow is so we don't borrow the resolver more than once at a time
289+ . unwrap_or_else ( || {
290+ let mut split = path_str. rsplitn ( 2 , "::" ) ;
291+ if let Some ( ( parent, base) ) = split. next ( ) . and_then ( |x| Some ( ( split. next ( ) ?, x) ) ) {
292+ if let Some ( res) = self . check_full_res ( TypeNS , parent, parent_id, & None , & None ) {
293+ return Err ( if matches ! ( res, Res :: PrimTy ( _) ) {
294+ ResolutionFailure :: NoPrimitiveAssocItem {
295+ res,
296+ prim_name : parent,
297+ assoc_item : Symbol :: intern ( base) ,
298+ }
299+ } else {
300+ ResolutionFailure :: NoAssocItem ( res, Symbol :: intern ( base) )
301+ } ) ;
302+ }
303+ }
304+ Err ( ResolutionFailure :: NotInScope ( path_str. into ( ) ) )
287305 } )
288306 }
289307 /// Resolves a string as a path within a particular namespace. Also returns an optional
@@ -981,6 +999,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
981999 cx,
9821000 & item,
9831001 path_str,
1002+ disambiguator,
9841003 & dox,
9851004 link_range,
9861005 smallvec ! [ kind] ,
@@ -1060,6 +1079,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
10601079 cx,
10611080 & item,
10621081 path_str,
1082+ disambiguator,
10631083 & dox,
10641084 link_range,
10651085 candidates. into_iter ( ) . filter_map ( |res| res. err ( ) ) . collect ( ) ,
@@ -1114,6 +1134,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
11141134 cx,
11151135 & item,
11161136 path_str,
1137+ disambiguator,
11171138 & dox,
11181139 link_range,
11191140 smallvec ! [ kind] ,
@@ -1489,6 +1510,7 @@ fn resolution_failure(
14891510 cx : & DocContext < ' _ > ,
14901511 item : & Item ,
14911512 path_str : & str ,
1513+ disambiguator : Option < Disambiguator > ,
14921514 dox : & str ,
14931515 link_range : Option < Range < usize > > ,
14941516 kinds : SmallVec < [ ResolutionFailure < ' _ > ; 3 ] > ,
@@ -1581,34 +1603,39 @@ fn resolution_failure(
15811603
15821604 let ( kind, def_id) = match res {
15831605 Res :: Def ( kind, def_id) => ( kind, def_id) ,
1584- _ => unreachable ! (
1585- "primitives are covered above and other `Res` variants aren't possible at module scope"
1606+ x => unreachable ! (
1607+ "primitives are covered above and other `Res` variants aren't possible at module scope: {:?}" ,
1608+ x,
15861609 ) ,
15871610 } ;
15881611 let name = cx. tcx . item_name ( def_id) ;
1589- let path_description = match kind {
1590- Mod | ForeignMod => "inner item" ,
1591- Struct => "field or associated item" ,
1592- Enum | Union => "variant or associated item" ,
1593- Variant
1594- | Field
1595- | Closure
1596- | Generator
1597- | AssocTy
1598- | AssocConst
1599- | AssocFn
1600- | Fn
1601- | Macro ( _)
1602- | Const
1603- | ConstParam
1604- | ExternCrate
1605- | Use
1606- | LifetimeParam
1607- | Ctor ( _, _)
1608- | AnonConst => return assoc_item_not_allowed ( res, diag) ,
1609- Trait | TyAlias | ForeignTy | OpaqueTy | TraitAlias | TyParam
1610- | Static => "associated item" ,
1611- Impl | GlobalAsm => unreachable ! ( "not a path" ) ,
1612+ let path_description = if let Some ( disambiguator) = disambiguator {
1613+ disambiguator. descr ( )
1614+ } else {
1615+ match kind {
1616+ Mod | ForeignMod => "inner item" ,
1617+ Struct => "field or associated item" ,
1618+ Enum | Union => "variant or associated item" ,
1619+ Variant
1620+ | Field
1621+ | Closure
1622+ | Generator
1623+ | AssocTy
1624+ | AssocConst
1625+ | AssocFn
1626+ | Fn
1627+ | Macro ( _)
1628+ | Const
1629+ | ConstParam
1630+ | ExternCrate
1631+ | Use
1632+ | LifetimeParam
1633+ | Ctor ( _, _)
1634+ | AnonConst => return assoc_item_not_allowed ( res, diag) ,
1635+ Trait | TyAlias | ForeignTy | OpaqueTy | TraitAlias | TyParam
1636+ | Static => "associated item" ,
1637+ Impl | GlobalAsm => unreachable ! ( "not a path" ) ,
1638+ }
16121639 } ;
16131640 let note = format ! (
16141641 "the {} `{}` has no {} named `{}`" ,
0 commit comments