@@ -1241,42 +1241,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1241
1241
tcx. sess . span_err ( span, "union expressions should have exactly one field" ) ;
1242
1242
}
1243
1243
} 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 ( ) ;
1250
1251
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 ) ;
1253
1254
} 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
+ }
1279
1257
}
1258
+
1280
1259
error_happened
1281
1260
}
1282
1261
@@ -1293,6 +1272,79 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1293
1272
}
1294
1273
}
1295
1274
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
+
1296
1348
fn report_unknown_field (
1297
1349
& self ,
1298
1350
ty : Ty < ' tcx > ,
0 commit comments