@@ -442,18 +442,18 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
442442 /// NOTE: `resolve_str_path_error` knows only about paths, not about types.
443443 /// Associated items will never be resolved by this function.
444444 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 ( )
449454 } ) ;
450455 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
457457 }
458458
459459 /// Resolves a string as a path within a particular namespace. Returns an
@@ -1075,29 +1075,35 @@ impl LinkCollector<'_, '_> {
10751075 if matches ! (
10761076 disambiguator,
10771077 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+ }
10931106 }
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 ;
11011107 }
11021108 }
11031109 }
0 commit comments