@@ -405,7 +405,8 @@ impl<'a> PrivacyVisitor<'a> {
405405 } ;
406406 }
407407
408- debug ! ( "privacy - local {:?} not public all the way down" , did) ;
408+ debug ! ( "privacy - local {} not public all the way down" ,
409+ self . tcx. map. node_to_str( did. node) ) ;
409410 // return quickly for things in the same module
410411 if self . parents . find ( & did. node ) == self . parents . find ( & self . curitem ) {
411412 debug ! ( "privacy - same parent, we're done here" ) ;
@@ -526,31 +527,60 @@ impl<'a> PrivacyVisitor<'a> {
526527 /// If the result is `None`, no errors were found.
527528 fn ensure_public ( & self , span : Span , to_check : ast:: DefId ,
528529 source_did : Option < ast:: DefId > , msg : & str ) -> CheckResult {
529- match self . def_privacy ( to_check) {
530- ExternallyDenied => Some ( ( span, format ! ( "{} is private" , msg) , None ) ) ,
531- DisallowedBy ( id) => {
532- let ( err_span, err_msg) = if id == source_did. unwrap_or ( to_check) . node {
533- return Some ( ( span, format ! ( "{} is private" , msg) , None ) ) ;
534- } else {
535- ( span, format ! ( "{} is inaccessible" , msg) )
536- } ;
537- match self . tcx . map . find ( id) {
538- Some ( ast_map:: NodeItem ( item) ) => {
539- let desc = match item. node {
540- ast:: ItemMod ( ..) => "module" ,
541- ast:: ItemTrait ( ..) => "trait" ,
530+ let id = match self . def_privacy ( to_check) {
531+ ExternallyDenied => {
532+ return Some ( ( span, format ! ( "{} is private" , msg) , None ) )
533+ }
534+ Allowable => return None ,
535+ DisallowedBy ( id) => id,
536+ } ;
537+
538+ // If we're disallowed by a particular id, then we attempt to give a
539+ // nice error message to say why it was disallowed. It was either
540+ // because the item itself is private or because its parent is private
541+ // and its parent isn't in our ancestry.
542+ let ( err_span, err_msg) = if id == source_did. unwrap_or ( to_check) . node {
543+ return Some ( ( span, format ! ( "{} is private" , msg) , None ) ) ;
544+ } else {
545+ ( span, format ! ( "{} is inaccessible" , msg) )
546+ } ;
547+ let item = match self . tcx . map . find ( id) {
548+ Some ( ast_map:: NodeItem ( item) ) => {
549+ match item. node {
550+ // If an impl disallowed this item, then this is resolve's
551+ // way of saying that a struct/enum's static method was
552+ // invoked, and the struct/enum itself is private. Crawl
553+ // back up the chains to find the relevant struct/enum that
554+ // was private.
555+ ast:: ItemImpl ( _, _, ref ty, _) => {
556+ let id = match ty. node {
557+ ast:: TyPath ( _, _, id) => id,
542558 _ => return Some ( ( err_span, err_msg, None ) ) ,
543559 } ;
544- let msg = format ! ( "{} `{}` is private" ,
545- desc,
546- token:: get_ident( item. ident) ) ;
547- Some ( ( err_span, err_msg, Some ( ( span, msg) ) ) )
548- } ,
549- _ => Some ( ( err_span, err_msg, None ) ) ,
560+ let def = self . tcx . def_map . borrow ( ) . get_copy ( & id) ;
561+ let did = def_id_of_def ( def) ;
562+ assert ! ( is_local( did) ) ;
563+ match self . tcx . map . get ( did. node ) {
564+ ast_map:: NodeItem ( item) => item,
565+ _ => self . tcx . sess . span_bug ( item. span ,
566+ "path is not an item" )
567+ }
568+ }
569+ _ => item
550570 }
551- } ,
552- Allowable => None ,
553- }
571+ }
572+ Some ( ..) | None => return Some ( ( err_span, err_msg, None ) ) ,
573+ } ;
574+ let desc = match item. node {
575+ ast:: ItemMod ( ..) => "module" ,
576+ ast:: ItemTrait ( ..) => "trait" ,
577+ ast:: ItemStruct ( ..) => "struct" ,
578+ ast:: ItemEnum ( ..) => "enum" ,
579+ _ => return Some ( ( err_span, err_msg, None ) )
580+ } ;
581+ let msg = format ! ( "{} `{}` is private" , desc,
582+ token:: get_ident( item. ident) ) ;
583+ Some ( ( err_span, err_msg, Some ( ( span, msg) ) ) )
554584 }
555585
556586 // Checks that a field is in scope.
@@ -622,12 +652,8 @@ impl<'a> PrivacyVisitor<'a> {
622652 . unwrap ( )
623653 . identifier ) ;
624654 let origdid = def_id_of_def ( orig_def) ;
625- self . ensure_public ( span,
626- def,
627- Some ( origdid) ,
628- format ! ( "{} `{}`" ,
629- tyname,
630- name) )
655+ self . ensure_public ( span, def, Some ( origdid) ,
656+ format ! ( "{} `{}`" , tyname, name) )
631657 } ;
632658
633659 match * self . last_private_map . get ( & path_id) {
0 commit comments