@@ -405,7 +405,8 @@ impl<'a> PrivacyVisitor<'a> {
405
405
} ;
406
406
}
407
407
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) ) ;
409
410
// return quickly for things in the same module
410
411
if self . parents . find ( & did. node ) == self . parents . find ( & self . curitem ) {
411
412
debug ! ( "privacy - same parent, we're done here" ) ;
@@ -526,31 +527,60 @@ impl<'a> PrivacyVisitor<'a> {
526
527
/// If the result is `None`, no errors were found.
527
528
fn ensure_public ( & self , span : Span , to_check : ast:: DefId ,
528
529
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,
542
558
_ => return Some ( ( err_span, err_msg, None ) ) ,
543
559
} ;
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
550
570
}
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) ) ) )
554
584
}
555
585
556
586
// Checks that a field is in scope.
@@ -622,12 +652,8 @@ impl<'a> PrivacyVisitor<'a> {
622
652
. unwrap ( )
623
653
. identifier ) ;
624
654
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) )
631
657
} ;
632
658
633
659
match * self . last_private_map . get ( & path_id) {
0 commit comments