@@ -24,6 +24,7 @@ use crate::lifetimes::{ElisionFailureInfo, LifetimeContext};
2424use crate :: path_names_to_string;
2525use crate :: { AmbiguityError , AmbiguityErrorMisc , AmbiguityKind } ;
2626use crate :: { BindingError , CrateLint , HasGenericParams , LegacyScope , Module , ModuleOrUniformRoot } ;
27+ use crate :: { ModuleData , ModuleKind } ;
2728use crate :: { NameBinding , NameBindingKind , PrivacyError , VisResolutionError } ;
2829use crate :: { ParentScope , PathResult , ResolutionError , Resolver , Scope , ScopeSet , Segment } ;
2930
@@ -419,8 +420,7 @@ impl<'a> Resolver<'a> {
419420 self . session,
420421 span,
421422 E0128 ,
422- "type parameters with a default cannot use \
423- forward declared identifiers"
423+ "type parameters with a default cannot use forward declared identifiers"
424424 ) ;
425425 err. span_label (
426426 span,
@@ -952,8 +952,7 @@ impl<'a> Resolver<'a> {
952952 err. emit ( ) ;
953953 }
954954
955- crate fn report_privacy_error ( & self , privacy_error : & PrivacyError < ' _ > ) {
956- let PrivacyError { ident, binding, .. } = * privacy_error;
955+ crate fn report_privacy_error ( & self , PrivacyError { ident, binding, .. } : & PrivacyError < ' _ > ) {
957956 let session = & self . session ;
958957 let mk_struct_span_error = |is_constructor| {
959958 let mut descr = binding. res ( ) . descr ( ) . to_string ( ) ;
@@ -966,13 +965,7 @@ impl<'a> Resolver<'a> {
966965
967966 let mut err =
968967 struct_span_err ! ( session, ident. span, E0603 , "{} `{}` is private" , descr, ident) ;
969-
970968 err. span_label ( ident. span , & format ! ( "this {} is private" , descr) ) ;
971- err. span_note (
972- session. source_map ( ) . def_span ( binding. span ) ,
973- & format ! ( "the {} `{}` is defined here" , descr, ident) ,
974- ) ;
975-
976969 err
977970 } ;
978971
@@ -997,6 +990,109 @@ impl<'a> Resolver<'a> {
997990 mk_struct_span_error ( false )
998991 } ;
999992
993+ // Display the chain of re-exports through to the original def for cases where the
994+ // `use` is private but the def is public.
995+ let mut imported = false ;
996+ let mut binding = * binding;
997+ loop {
998+ let binding_span = session. source_map ( ) . def_span ( binding. span ) ;
999+ match binding. kind {
1000+ NameBindingKind :: Res ( res, _is_macro_export) => {
1001+ match ( res, imported, binding. vis ) {
1002+ ( Res :: Def ( _, def_id) , true , ty:: Visibility :: Public ) => {
1003+ // FIXME: we should verify that this def is actually
1004+ // reachable from the user's crate, as the parent modules
1005+ // of this ADT might be private.
1006+ if def_id. is_local ( ) {
1007+ err. span_help (
1008+ binding_span,
1009+ & format ! (
1010+ "consider importing {} `{}` directly" ,
1011+ res. descr( ) ,
1012+ self . definitions
1013+ . def_path( def_id. index)
1014+ . to_string_no_crate( ) ,
1015+ ) ,
1016+ ) ;
1017+ } else {
1018+ err. span_help (
1019+ binding_span,
1020+ & format ! (
1021+ "consider importing {} `{}` directly" ,
1022+ res. descr( ) ,
1023+ ident. name
1024+ ) ,
1025+ ) ;
1026+ }
1027+ }
1028+ ( Res :: Def ( _, def_id) , true , _) if def_id. is_local ( ) => {
1029+ err. span_help (
1030+ binding_span,
1031+ & format ! ( "consider making {} `{}` public" , res. descr( ) , ident. name) ,
1032+ ) ;
1033+ }
1034+ _ => {
1035+ err. span_note (
1036+ binding_span,
1037+ & format ! (
1038+ "the {}{} `{}` is defined here" ,
1039+ if imported { "re-exported " } else { "" } ,
1040+ res. descr( ) ,
1041+ ident. name
1042+ ) ,
1043+ ) ;
1044+ }
1045+ }
1046+ break ;
1047+ }
1048+ NameBindingKind :: Module ( ModuleData {
1049+ kind : ModuleKind :: Def ( DefKind :: Mod , def_id, _) ,
1050+ ..
1051+ } ) if def_id. index == CRATE_DEF_INDEX && def_id. krate != LOCAL_CRATE => {
1052+ // Do not point at `extern crate foo;` twice.
1053+ break ;
1054+ }
1055+ NameBindingKind :: Module ( ModuleData {
1056+ kind : ModuleKind :: Def ( kind, def_id, _) ,
1057+ ..
1058+ } ) => {
1059+ err. span_note (
1060+ binding_span,
1061+ & format ! (
1062+ "the {}{} `{}` is defined here" ,
1063+ if imported { "re-exported " } else { "" } ,
1064+ kind. descr( * def_id) ,
1065+ ident. name,
1066+ ) ,
1067+ ) ;
1068+ break ;
1069+ }
1070+ NameBindingKind :: Module ( _) => break ,
1071+ NameBindingKind :: Import { binding : inner_binding, .. } => {
1072+ err. span_note (
1073+ binding_span,
1074+ & format ! (
1075+ "{} {} re-export of `{}`{}" ,
1076+ if imported { "...through this" } else { "the used" } ,
1077+ if binding. vis == ty:: Visibility :: Public {
1078+ "public"
1079+ } else {
1080+ "restricted"
1081+ } ,
1082+ ident. name,
1083+ if let NameBindingKind :: Import { .. } = inner_binding. kind {
1084+ "..."
1085+ } else {
1086+ ""
1087+ } ,
1088+ ) ,
1089+ ) ;
1090+ binding = inner_binding;
1091+ imported = true ;
1092+ }
1093+ }
1094+ }
1095+
10001096 err. emit ( ) ;
10011097 }
10021098}
0 commit comments