@@ -917,54 +917,71 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
917
917
self . suggest_using_enum_variant ( err, source, def_id, span) ;
918
918
}
919
919
( Res :: Def ( DefKind :: Struct , def_id) , _) if ns == ValueNS => {
920
- if let Some ( ( ctor_def, ctor_vis, fields) ) =
921
- self . r . struct_constructors . get ( & def_id) . cloned ( )
920
+ let ( ctor_def, ctor_vis, fields) =
921
+ if let Some ( struct_ctor) = self . r . struct_constructors . get ( & def_id) . cloned ( ) {
922
+ struct_ctor
923
+ } else {
924
+ bad_struct_syntax_suggestion ( def_id) ;
925
+ return true ;
926
+ } ;
927
+
928
+ let is_accessible = self . r . is_accessible_from ( ctor_vis, self . parent_scope . module ) ;
929
+ if !is_expected ( ctor_def) || is_accessible {
930
+ return true ;
931
+ }
932
+
933
+ let field_spans = match source {
934
+ // e.g. `if let Enum::TupleVariant(field1, field2) = _`
935
+ PathSource :: TupleStruct ( _, pattern_spans) => {
936
+ err. set_primary_message (
937
+ "cannot match against a tuple struct which contains private fields" ,
938
+ ) ;
939
+
940
+ // Use spans of the tuple struct pattern.
941
+ Some ( Vec :: from ( pattern_spans) )
942
+ }
943
+ // e.g. `let _ = Enum::TupleVariant(field1, field2);`
944
+ _ if source. is_call ( ) => {
945
+ err. set_primary_message (
946
+ "cannot initialize a tuple struct which contains private fields" ,
947
+ ) ;
948
+
949
+ // Use spans of the tuple struct definition.
950
+ self . r
951
+ . field_names
952
+ . get ( & def_id)
953
+ . map ( |fields| fields. iter ( ) . map ( |f| f. span ) . collect :: < Vec < _ > > ( ) )
954
+ }
955
+ _ => None ,
956
+ } ;
957
+
958
+ if let Some ( spans) =
959
+ field_spans. filter ( |spans| spans. len ( ) > 0 && fields. len ( ) == spans. len ( ) )
922
960
{
923
- let accessible_ctor =
924
- self . r . is_accessible_from ( ctor_vis, self . parent_scope . module ) ;
925
- if is_expected ( ctor_def) && !accessible_ctor {
926
- let mut better_diag = false ;
927
- if let PathSource :: TupleStruct ( _, pattern_spans) = source {
928
- if pattern_spans. len ( ) > 0 && fields. len ( ) == pattern_spans. len ( ) {
929
- let non_visible_spans: Vec < Span > = fields
930
- . iter ( )
931
- . zip ( pattern_spans. iter ( ) )
932
- . filter_map ( |( vis, span) | {
933
- match self
934
- . r
935
- . is_accessible_from ( * vis, self . parent_scope . module )
936
- {
937
- true => None ,
938
- false => Some ( * span) ,
939
- }
940
- } )
941
- . collect ( ) ;
942
- // Extra check to be sure
943
- if non_visible_spans. len ( ) > 0 {
944
- let mut m: rustc_span:: MultiSpan =
945
- non_visible_spans. clone ( ) . into ( ) ;
946
- non_visible_spans. into_iter ( ) . for_each ( |s| {
947
- m. push_span_label ( s, "private field" . to_string ( ) )
948
- } ) ;
949
- err. span_note (
950
- m,
951
- "constructor is not visible here due to private fields" ,
952
- ) ;
953
- better_diag = true ;
954
- }
955
- }
956
- }
961
+ let non_visible_spans: Vec < Span > = fields
962
+ . iter ( )
963
+ . zip ( spans. iter ( ) )
964
+ . filter ( |( vis, _) | {
965
+ !self . r . is_accessible_from ( * * vis, self . parent_scope . module )
966
+ } )
967
+ . map ( |( _, span) | * span)
968
+ . collect ( ) ;
957
969
958
- if !better_diag {
959
- err . span_label (
960
- span ,
961
- "constructor is not visible here due to private fields" . to_string ( ) ,
962
- ) ;
963
- }
970
+ if non_visible_spans . len ( ) > 0 {
971
+ let mut m : rustc_span :: MultiSpan = non_visible_spans . clone ( ) . into ( ) ;
972
+ non_visible_spans
973
+ . into_iter ( )
974
+ . for_each ( |s| m . push_span_label ( s , "private field" . to_string ( ) ) ) ;
975
+ err . span_note ( m , "constructor is not visible here due to private fields" ) ;
964
976
}
965
- } else {
966
- bad_struct_syntax_suggestion ( def_id ) ;
977
+
978
+ return true ;
967
979
}
980
+
981
+ err. span_label (
982
+ span,
983
+ "constructor is not visible here due to private fields" . to_string ( ) ,
984
+ ) ;
968
985
}
969
986
(
970
987
Res :: Def (
0 commit comments