@@ -1147,69 +1147,70 @@ impl LinkCollector<'_, '_> {
11471147 ) ;
11481148 } ;
11491149
1150- let ( kind, id) = match res {
1150+ let verify = |kind : DefKind , id : DefId | {
1151+ debug ! ( "intra-doc link to {} resolved to {:?}" , path_str, res) ;
1152+
1153+ // Disallow e.g. linking to enums with `struct@`
1154+ debug ! ( "saw kind {:?} with disambiguator {:?}" , kind, disambiguator) ;
1155+ match ( self . kind_side_channel . take ( ) . map ( |( kind, _) | kind) . unwrap_or ( kind) , disambiguator) {
1156+ | ( DefKind :: Const | DefKind :: ConstParam | DefKind :: AssocConst | DefKind :: AnonConst , Some ( Disambiguator :: Kind ( DefKind :: Const ) ) )
1157+ // NOTE: this allows 'method' to mean both normal functions and associated functions
1158+ // This can't cause ambiguity because both are in the same namespace.
1159+ | ( DefKind :: Fn | DefKind :: AssocFn , Some ( Disambiguator :: Kind ( DefKind :: Fn ) ) )
1160+ // These are namespaces; allow anything in the namespace to match
1161+ | ( _, Some ( Disambiguator :: Namespace ( _) ) )
1162+ // If no disambiguator given, allow anything
1163+ | ( _, None )
1164+ // All of these are valid, so do nothing
1165+ => { }
1166+ ( actual, Some ( Disambiguator :: Kind ( expected) ) ) if actual == expected => { }
1167+ ( _, Some ( specified @ Disambiguator :: Kind ( _) | specified @ Disambiguator :: Primitive ) ) => {
1168+ report_mismatch ( specified, Disambiguator :: Kind ( kind) ) ;
1169+ return None ;
1170+ }
1171+ }
1172+
1173+ // item can be non-local e.g. when using #[doc(primitive = "pointer")]
1174+ if let Some ( ( src_id, dst_id) ) = id
1175+ . as_local ( )
1176+ . and_then ( |dst_id| item. def_id . as_local ( ) . map ( |src_id| ( src_id, dst_id) ) )
1177+ {
1178+ use rustc_hir:: def_id:: LOCAL_CRATE ;
1179+
1180+ let hir_src = self . cx . tcx . hir ( ) . local_def_id_to_hir_id ( src_id) ;
1181+ let hir_dst = self . cx . tcx . hir ( ) . local_def_id_to_hir_id ( dst_id) ;
1182+
1183+ if self . cx . tcx . privacy_access_levels ( LOCAL_CRATE ) . is_exported ( hir_src)
1184+ && !self . cx . tcx . privacy_access_levels ( LOCAL_CRATE ) . is_exported ( hir_dst)
1185+ {
1186+ privacy_error ( cx, & item, & path_str, dox, & ori_link) ;
1187+ }
1188+ }
1189+
1190+ Some ( ( kind, id) )
1191+ } ;
1192+
1193+ match res {
11511194 Res :: Primitive ( _) => {
11521195 if let Some ( ( kind, id) ) = self . kind_side_channel . take ( ) {
1153- ( kind, id)
1196+ verify ( kind, id) ? ;
11541197 } else {
11551198 match disambiguator {
1156- Some ( Disambiguator :: Primitive | Disambiguator :: Namespace ( _) ) | None => {
1157- return Some ( ItemLink {
1158- link : ori_link. link ,
1159- link_text,
1160- did : None ,
1161- fragment,
1162- } ) ;
1163- }
1199+ Some ( Disambiguator :: Primitive | Disambiguator :: Namespace ( _) ) | None => { }
11641200 Some ( other) => {
11651201 report_mismatch ( other, Disambiguator :: Primitive ) ;
11661202 return None ;
11671203 }
11681204 }
11691205 }
1206+ Some ( ItemLink { link : ori_link. link , link_text, did : None , fragment } )
11701207 }
1171- Res :: Def ( kind, id) => ( kind, id) ,
1172- } ;
1173-
1174- debug ! ( "intra-doc link to {} resolved to {:?}" , path_str, res) ;
1175-
1176- // Disallow e.g. linking to enums with `struct@`
1177- debug ! ( "saw kind {:?} with disambiguator {:?}" , kind, disambiguator) ;
1178- match ( self . kind_side_channel . take ( ) . map ( |( kind, _) | kind) . unwrap_or ( kind) , disambiguator) {
1179- | ( DefKind :: Const | DefKind :: ConstParam | DefKind :: AssocConst | DefKind :: AnonConst , Some ( Disambiguator :: Kind ( DefKind :: Const ) ) )
1180- // NOTE: this allows 'method' to mean both normal functions and associated functions
1181- // This can't cause ambiguity because both are in the same namespace.
1182- | ( DefKind :: Fn | DefKind :: AssocFn , Some ( Disambiguator :: Kind ( DefKind :: Fn ) ) )
1183- // These are namespaces; allow anything in the namespace to match
1184- | ( _, Some ( Disambiguator :: Namespace ( _) ) )
1185- // If no disambiguator given, allow anything
1186- | ( _, None )
1187- // All of these are valid, so do nothing
1188- => { }
1189- ( actual, Some ( Disambiguator :: Kind ( expected) ) ) if actual == expected => { }
1190- ( _, Some ( specified @ Disambiguator :: Kind ( _) | specified @ Disambiguator :: Primitive ) ) => {
1191- report_mismatch ( specified, Disambiguator :: Kind ( kind) ) ;
1192- return None ;
1193- }
1194- }
1195-
1196- // item can be non-local e.g. when using #[doc(primitive = "pointer")]
1197- if let Some ( ( src_id, dst_id) ) =
1198- id. as_local ( ) . and_then ( |dst_id| item. def_id . as_local ( ) . map ( |src_id| ( src_id, dst_id) ) )
1199- {
1200- use rustc_hir:: def_id:: LOCAL_CRATE ;
1201-
1202- let hir_src = self . cx . tcx . hir ( ) . local_def_id_to_hir_id ( src_id) ;
1203- let hir_dst = self . cx . tcx . hir ( ) . local_def_id_to_hir_id ( dst_id) ;
1204-
1205- if self . cx . tcx . privacy_access_levels ( LOCAL_CRATE ) . is_exported ( hir_src)
1206- && !self . cx . tcx . privacy_access_levels ( LOCAL_CRATE ) . is_exported ( hir_dst)
1207- {
1208- privacy_error ( cx, & item, & path_str, dox, & ori_link) ;
1208+ Res :: Def ( kind, id) => {
1209+ let ( kind, id) = verify ( kind, id) ?;
1210+ let id = clean:: register_res ( cx, rustc_hir:: def:: Res :: Def ( kind, id) ) ;
1211+ Some ( ItemLink { link : ori_link. link , link_text, did : Some ( id) , fragment } )
12091212 }
12101213 }
1211- let id = clean:: register_res ( cx, rustc_hir:: def:: Res :: Def ( kind, id) ) ;
1212- Some ( ItemLink { link : ori_link. link , link_text, did : Some ( id) , fragment } )
12131214 }
12141215
12151216 fn resolve_with_disambiguator_cached (
0 commit comments