@@ -1241,42 +1241,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12411241 tcx. sess . span_err ( span, "union expressions should have exactly one field" ) ;
12421242 }
12431243 } else if check_completeness && !error_happened && !remaining_fields. is_empty ( ) {
1244- let len = remaining_fields. len ( ) ;
1245-
1246- let mut displayable_field_names =
1247- remaining_fields. keys ( ) . map ( |ident| ident. as_str ( ) ) . collect :: < Vec < _ > > ( ) ;
1248-
1249- displayable_field_names. sort ( ) ;
1244+ let no_accessible_remaining_fields = remaining_fields
1245+ . iter ( )
1246+ . filter ( |( _, ( _, field) ) | {
1247+ field. vis . is_accessible_from ( tcx. parent_module ( expr_id) . to_def_id ( ) , tcx)
1248+ } )
1249+ . next ( )
1250+ . is_none ( ) ;
12501251
1251- let truncated_fields_error = if len <= 3 {
1252- String :: new ( )
1252+ if no_accessible_remaining_fields {
1253+ self . report_no_accessible_fields ( adt_ty , span ) ;
12531254 } else {
1254- format ! ( " and {} other field{}" , ( len - 3 ) , if len - 3 == 1 { "" } else { "s" } )
1255- } ;
1256-
1257- let remaining_fields_names = displayable_field_names
1258- . iter ( )
1259- . take ( 3 )
1260- . map ( |n| format ! ( "`{}`" , n) )
1261- . collect :: < Vec < _ > > ( )
1262- . join ( ", " ) ;
1263-
1264- struct_span_err ! (
1265- tcx. sess,
1266- span,
1267- E0063 ,
1268- "missing field{} {}{} in initializer of `{}`" ,
1269- pluralize!( remaining_fields. len( ) ) ,
1270- remaining_fields_names,
1271- truncated_fields_error,
1272- adt_ty
1273- )
1274- . span_label (
1275- span,
1276- format ! ( "missing {}{}" , remaining_fields_names, truncated_fields_error) ,
1277- )
1278- . emit ( ) ;
1255+ self . report_missing_field ( adt_ty, span, remaining_fields) ;
1256+ }
12791257 }
1258+
12801259 error_happened
12811260 }
12821261
@@ -1293,6 +1272,79 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12931272 }
12941273 }
12951274
1275+ /// Report an error for a struct field expression when there are fields which aren't provided.
1276+ ///
1277+ /// ```ignore (diagnostic)
1278+ /// error: missing field `you_can_use_this_field` in initializer of `foo::Foo`
1279+ /// --> src/main.rs:8:5
1280+ /// |
1281+ /// 8 | foo::Foo {};
1282+ /// | ^^^^^^^^ missing `you_can_use_this_field`
1283+ ///
1284+ /// error: aborting due to previous error
1285+ /// ```
1286+ fn report_missing_field (
1287+ & self ,
1288+ adt_ty : Ty < ' tcx > ,
1289+ span : Span ,
1290+ remaining_fields : FxHashMap < Ident , ( usize , & ty:: FieldDef ) > ,
1291+ ) {
1292+ let tcx = self . tcx ;
1293+ let len = remaining_fields. len ( ) ;
1294+
1295+ let mut displayable_field_names =
1296+ remaining_fields. keys ( ) . map ( |ident| ident. as_str ( ) ) . collect :: < Vec < _ > > ( ) ;
1297+
1298+ displayable_field_names. sort ( ) ;
1299+
1300+ let truncated_fields_error = if len <= 3 {
1301+ String :: new ( )
1302+ } else {
1303+ format ! ( " and {} other field{}" , ( len - 3 ) , if len - 3 == 1 { "" } else { "s" } )
1304+ } ;
1305+
1306+ let remaining_fields_names = displayable_field_names
1307+ . iter ( )
1308+ . take ( 3 )
1309+ . map ( |n| format ! ( "`{}`" , n) )
1310+ . collect :: < Vec < _ > > ( )
1311+ . join ( ", " ) ;
1312+
1313+ struct_span_err ! (
1314+ tcx. sess,
1315+ span,
1316+ E0063 ,
1317+ "missing field{} {}{} in initializer of `{}`" ,
1318+ pluralize!( remaining_fields. len( ) ) ,
1319+ remaining_fields_names,
1320+ truncated_fields_error,
1321+ adt_ty
1322+ )
1323+ . span_label ( span, format ! ( "missing {}{}" , remaining_fields_names, truncated_fields_error) )
1324+ . emit ( ) ;
1325+ }
1326+
1327+ /// Report an error for a struct field expression when there are no visible fields.
1328+ ///
1329+ /// ```ignore (diagnostic)
1330+ /// error: cannot construct `Foo` with struct literal syntax due to inaccessible fields
1331+ /// --> src/main.rs:8:5
1332+ /// |
1333+ /// 8 | foo::Foo {};
1334+ /// | ^^^^^^^^
1335+ ///
1336+ /// error: aborting due to previous error
1337+ /// ```
1338+ fn report_no_accessible_fields ( & self , adt_ty : Ty < ' tcx > , span : Span ) {
1339+ self . tcx . sess . span_err (
1340+ span,
1341+ & format ! (
1342+ "cannot construct `{}` with struct literal syntax due to inaccessible fields" ,
1343+ adt_ty,
1344+ ) ,
1345+ ) ;
1346+ }
1347+
12961348 fn report_unknown_field (
12971349 & self ,
12981350 ty : Ty < ' tcx > ,
0 commit comments