@@ -24,6 +24,7 @@ use crate::lifetimes::{ElisionFailureInfo, LifetimeContext};
24
24
use crate :: path_names_to_string;
25
25
use crate :: { AmbiguityError , AmbiguityErrorMisc , AmbiguityKind } ;
26
26
use crate :: { BindingError , CrateLint , HasGenericParams , LegacyScope , Module , ModuleOrUniformRoot } ;
27
+ use crate :: { ModuleData , ModuleKind } ;
27
28
use crate :: { NameBinding , NameBindingKind , PrivacyError , VisResolutionError } ;
28
29
use crate :: { ParentScope , PathResult , ResolutionError , Resolver , Scope , ScopeSet , Segment } ;
29
30
@@ -419,8 +420,7 @@ impl<'a> Resolver<'a> {
419
420
self . session,
420
421
span,
421
422
E0128 ,
422
- "type parameters with a default cannot use \
423
- forward declared identifiers"
423
+ "type parameters with a default cannot use forward declared identifiers"
424
424
) ;
425
425
err. span_label (
426
426
span,
@@ -952,8 +952,7 @@ impl<'a> Resolver<'a> {
952
952
err. emit ( ) ;
953
953
}
954
954
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 < ' _ > ) {
957
956
let session = & self . session ;
958
957
let mk_struct_span_error = |is_constructor| {
959
958
let mut descr = binding. res ( ) . descr ( ) . to_string ( ) ;
@@ -966,13 +965,7 @@ impl<'a> Resolver<'a> {
966
965
967
966
let mut err =
968
967
struct_span_err ! ( session, ident. span, E0603 , "{} `{}` is private" , descr, ident) ;
969
-
970
968
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
-
976
969
err
977
970
} ;
978
971
@@ -997,6 +990,109 @@ impl<'a> Resolver<'a> {
997
990
mk_struct_span_error ( false )
998
991
} ;
999
992
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
+
1000
1096
err. emit ( ) ;
1001
1097
}
1002
1098
}
0 commit comments