@@ -178,6 +178,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
178178 let result = cx. enter_resolver ( |resolver| {
179179 resolver. resolve_str_path_error ( DUMMY_SP , & path_str, ns, module_id)
180180 } ) ;
181+ debug ! ( "{} resolved to {:?} in namespace {:?}" , path_str, result, ns) ;
181182 let result = match result {
182183 Ok ( ( _, Res :: Err ) ) => Err ( ErrorKind :: ResolutionFailure ) ,
183184 _ => result. map_err ( |_| ErrorKind :: ResolutionFailure ) ,
@@ -202,7 +203,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
202203 }
203204 return Ok ( ( res, Some ( path_str. to_owned ( ) ) ) ) ;
204205 }
205- _ => return Ok ( ( res, extra_fragment. clone ( ) ) ) ,
206+ other => {
207+ debug ! (
208+ "failed to resolve {} in namespace {:?} (got {:?})" ,
209+ path_str, ns, other
210+ ) ;
211+ return Ok ( ( res, extra_fragment. clone ( ) ) ) ;
212+ }
206213 } ;
207214
208215 if value != ( ns == ValueNS ) {
@@ -555,12 +562,13 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
555562 } else {
556563 ( parts[ 0 ] . to_owned ( ) , None )
557564 } ;
565+ let resolved_self;
566+ let mut path_str;
558567 let ( res, fragment) = {
559568 let mut kind = None ;
560- let mut path_str = if let Some ( prefix) =
561- [ "struct@" , "enum@" , "type@" , "trait@" , "union@" ]
562- . iter ( )
563- . find ( |p| link. starts_with ( * * p) )
569+ path_str = if let Some ( prefix) = [ "struct@" , "enum@" , "type@" , "trait@" , "union@" ]
570+ . iter ( )
571+ . find ( |p| link. starts_with ( * * p) )
564572 {
565573 kind = Some ( TypeNS ) ;
566574 link. trim_start_matches ( prefix)
@@ -614,7 +622,6 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
614622 let base_node =
615623 if item. is_mod ( ) && item. attrs . inner_docs { None } else { parent_node } ;
616624
617- let resolved_self;
618625 // replace `Self` with suitable item's parent name
619626 if path_str. starts_with ( "Self::" ) {
620627 if let Some ( ref name) = parent_name {
@@ -760,6 +767,32 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
760767 if let Res :: PrimTy ( _) = res {
761768 item. attrs . links . push ( ( ori_link, None , fragment) ) ;
762769 } else {
770+ debug ! ( "intra-doc link to {} resolved to {:?}" , path_str, res) ;
771+ if let Some ( local) = res. opt_def_id ( ) . and_then ( |def_id| def_id. as_local ( ) ) {
772+ use rustc_hir:: def_id:: LOCAL_CRATE ;
773+
774+ let hir_id = self . cx . tcx . hir ( ) . as_local_hir_id ( local) ;
775+ if !self . cx . tcx . privacy_access_levels ( LOCAL_CRATE ) . is_exported ( hir_id)
776+ && !self . cx . render_options . document_private
777+ {
778+ let item_name = item. name . as_deref ( ) . unwrap_or ( "<unknown>" ) ;
779+ let err_msg = format ! (
780+ "public documentation for `{}` links to a private item" ,
781+ item_name
782+ ) ;
783+ build_diagnostic (
784+ cx,
785+ & item,
786+ path_str,
787+ & dox,
788+ link_range,
789+ & err_msg,
790+ "this item is private" ,
791+ None ,
792+ ) ;
793+ continue ;
794+ }
795+ }
763796 let id = register_res ( cx, res) ;
764797 item. attrs . links . push ( ( ori_link, Some ( id) , fragment) ) ;
765798 }
0 commit comments