@@ -442,18 +442,18 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
442
442
/// NOTE: `resolve_str_path_error` knows only about paths, not about types.
443
443
/// Associated items will never be resolved by this function.
444
444
fn resolve_path ( & self , path_str : & str , ns : Namespace , module_id : DefId ) -> Option < Res > {
445
- let result = self . cx . enter_resolver ( |resolver| {
446
- resolver
447
- . resolve_str_path_error ( DUMMY_SP , & path_str, ns, module_id)
448
- . and_then ( |( _, res) | res. try_into ( ) )
445
+ // resolver doesn't know about true, false, and types that aren't paths (e.g. `()`)
446
+ // manually as bool. Give them precedence because the `doc(primitive)` check depends on it.
447
+ let result = resolve_primitive ( path_str, ns) . or_else ( || {
448
+ self . cx . enter_resolver ( |resolver| {
449
+ resolver
450
+ . resolve_str_path_error ( DUMMY_SP , & path_str, ns, module_id)
451
+ } )
452
+ . and_then ( |( _, res) | res. try_into ( ) )
453
+ . ok ( )
449
454
} ) ;
450
455
debug ! ( "{} resolved to {:?} in namespace {:?}" , path_str, result, ns) ;
451
- match result {
452
- // resolver doesn't know about true, false, and types that aren't paths (e.g. `()`)
453
- // manually as bool
454
- Err ( ( ) ) => resolve_primitive ( path_str, ns) ,
455
- Ok ( res) => Some ( res) ,
456
- }
456
+ result
457
457
}
458
458
459
459
/// Resolves a string as a path within a particular namespace. Returns an
@@ -1075,29 +1075,35 @@ impl LinkCollector<'_, '_> {
1075
1075
if matches ! (
1076
1076
disambiguator,
1077
1077
None | Some ( Disambiguator :: Namespace ( Namespace :: TypeNS ) | Disambiguator :: Primitive )
1078
- ) && !matches ! ( res, Res :: Primitive ( _) )
1079
- {
1080
- if let Some ( prim) = resolve_primitive ( path_str, TypeNS ) {
1081
- // `prim@char`
1082
- if matches ! ( disambiguator, Some ( Disambiguator :: Primitive ) ) {
1083
- if fragment. is_some ( ) {
1084
- anchor_failure (
1085
- self . cx ,
1086
- & item,
1087
- path_str,
1088
- dox,
1089
- ori_link. range ,
1090
- AnchorFailure :: RustdocAnchorConflict ( prim) ,
1091
- ) ;
1092
- return None ;
1078
+ ) {
1079
+ if let Res :: Def ( kind, id) = res {
1080
+ if let Some ( prim) = resolve_primitive ( path_str, TypeNS ) {
1081
+ // `prim@char`
1082
+ if matches ! ( disambiguator, Some ( Disambiguator :: Primitive ) ) {
1083
+ if fragment. is_some ( ) {
1084
+ anchor_failure (
1085
+ self . cx ,
1086
+ & item,
1087
+ path_str,
1088
+ dox,
1089
+ ori_link. range ,
1090
+ AnchorFailure :: RustdocAnchorConflict ( prim) ,
1091
+ ) ;
1092
+ return None ;
1093
+ }
1094
+ res = prim;
1095
+ fragment = Some ( prim. name ( self . cx . tcx ) ) ;
1096
+ } else {
1097
+ // `[char]` when a `char` module is in scope
1098
+ assert_eq ! ( kind, DefKind :: Mod ) ;
1099
+ // Very special case: when the mod has `doc(primitive)`, don't give an error.
1100
+ let mod_ = rustc_hir:: def:: Res :: Def ( DefKind :: Mod , id) ;
1101
+ if crate :: clean:: parse_primitive ( mod_, self . cx ) . is_none ( ) {
1102
+ let candidates = vec ! [ res, prim] ;
1103
+ ambiguity_error ( self . cx , & item, path_str, dox, ori_link. range , candidates) ;
1104
+ return None ;
1105
+ }
1093
1106
}
1094
- res = prim;
1095
- fragment = Some ( prim. name ( self . cx . tcx ) ) ;
1096
- } else {
1097
- // `[char]` when a `char` module is in scope
1098
- let candidates = vec ! [ res, prim] ;
1099
- ambiguity_error ( self . cx , & item, path_str, dox, ori_link. range , candidates) ;
1100
- return None ;
1101
1107
}
1102
1108
}
1103
1109
}
0 commit comments