@@ -262,11 +262,11 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
262
262
false ,
263
263
) {
264
264
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" ) ) ) ) ;
266
266
}
267
267
}
268
268
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" ) ) ) ) ;
270
270
}
271
271
if let Some ( module_id) = parent_id {
272
272
debug ! ( "resolving {} as a macro in the module {:?}" , path_str, module_id) ;
@@ -276,14 +276,32 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
276
276
// don't resolve builtins like `#[derive]`
277
277
if let Res :: Def ( ..) = res {
278
278
let res = res. map_id ( |_| panic ! ( "unexpected node_id" ) ) ;
279
- return Ok ( res) ;
279
+ return Some ( Ok ( res) ) ;
280
280
}
281
281
}
282
282
} else {
283
283
debug ! ( "attempting to resolve item without parent module: {}" , path_str) ;
284
- return Err ( ResolutionFailure :: NoParentItem ) ;
284
+ return Some ( Err ( ResolutionFailure :: NoParentItem ) ) ;
285
285
}
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 ( ) ) )
287
305
} )
288
306
}
289
307
/// 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> {
981
999
cx,
982
1000
& item,
983
1001
path_str,
1002
+ disambiguator,
984
1003
& dox,
985
1004
link_range,
986
1005
smallvec ! [ kind] ,
@@ -1060,6 +1079,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
1060
1079
cx,
1061
1080
& item,
1062
1081
path_str,
1082
+ disambiguator,
1063
1083
& dox,
1064
1084
link_range,
1065
1085
candidates. into_iter ( ) . filter_map ( |res| res. err ( ) ) . collect ( ) ,
@@ -1114,6 +1134,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
1114
1134
cx,
1115
1135
& item,
1116
1136
path_str,
1137
+ disambiguator,
1117
1138
& dox,
1118
1139
link_range,
1119
1140
smallvec ! [ kind] ,
@@ -1489,6 +1510,7 @@ fn resolution_failure(
1489
1510
cx : & DocContext < ' _ > ,
1490
1511
item : & Item ,
1491
1512
path_str : & str ,
1513
+ disambiguator : Option < Disambiguator > ,
1492
1514
dox : & str ,
1493
1515
link_range : Option < Range < usize > > ,
1494
1516
kinds : SmallVec < [ ResolutionFailure < ' _ > ; 3 ] > ,
@@ -1581,34 +1603,39 @@ fn resolution_failure(
1581
1603
1582
1604
let ( kind, def_id) = match res {
1583
1605
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,
1586
1609
) ,
1587
1610
} ;
1588
1611
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
+ }
1612
1639
} ;
1613
1640
let note = format ! (
1614
1641
"the {} `{}` has no {} named `{}`" ,
0 commit comments