@@ -1449,44 +1449,73 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
1449
1449
) ,
1450
1450
_ => ( ": val" , "literal" , Applicability :: HasPlaceholders , None ) ,
1451
1451
} ;
1452
- let field_ids = self . r . field_def_ids ( def_id) ;
1453
- let ( fields, applicability) = match field_ids {
1454
- Some ( field_ids) => {
1455
- let fields = field_ids. iter ( ) . map ( |& id| self . r . tcx . item_name ( id) ) ;
1456
-
1457
- let fields = if let Some ( old_fields) = old_fields {
1458
- fields
1459
- . enumerate ( )
1460
- . map ( |( idx, new) | ( new, old_fields. get ( idx) ) )
1461
- . map ( |( new, old) | {
1462
- let new = new. to_ident_string ( ) ;
1463
- if let Some ( Some ( old) ) = old
1464
- && new != * old
1465
- {
1466
- format ! ( "{new}: {old}" )
1467
- } else {
1468
- new
1469
- }
1470
- } )
1471
- . collect :: < Vec < String > > ( )
1472
- } else {
1473
- fields. map ( |f| format ! ( "{f}{tail}" ) ) . collect :: < Vec < String > > ( )
1474
- } ;
1475
1452
1476
- ( fields. join ( ", " ) , applicability)
1453
+ let fields = match def_id. as_local ( ) {
1454
+ Some ( def_id) => {
1455
+ self . r . struct_constructors . get ( & def_id) . cloned ( ) . map ( |( _, _, f) | f)
1477
1456
}
1478
- None => ( "/* fields */" . to_string ( ) , Applicability :: HasPlaceholders ) ,
1479
- } ;
1480
- let pad = match field_ids {
1481
- Some ( field_ids) if field_ids. is_empty ( ) => "" ,
1482
- _ => " " ,
1457
+ None => Some (
1458
+ self . r
1459
+ . tcx
1460
+ . associated_item_def_ids ( def_id)
1461
+ . iter ( )
1462
+ . map ( |field_id| self . r . tcx . visibility ( field_id) )
1463
+ . collect ( ) ,
1464
+ ) ,
1483
1465
} ;
1484
- err. span_suggestion (
1485
- span,
1486
- format ! ( "use struct {descr} syntax instead" ) ,
1487
- format ! ( "{path_str} {{{pad}{fields}{pad}}}" ) ,
1488
- applicability,
1489
- ) ;
1466
+
1467
+ let hidden_fields = fields. map_or ( false , |fields| {
1468
+ fields
1469
+ . iter ( )
1470
+ . filter ( |vis| {
1471
+ !self . r . is_accessible_from ( * * vis, self . parent_scope . module )
1472
+ } )
1473
+ . next ( )
1474
+ . is_some ( )
1475
+ } ) ;
1476
+
1477
+ if !hidden_fields {
1478
+ // If the fields of the type are private, we shouldn't be suggesting using
1479
+ // the struct literal syntax at all, as that will cause a subsequent error.
1480
+ let field_ids = self . r . field_def_ids ( def_id) ;
1481
+ let ( fields, applicability) = match field_ids {
1482
+ Some ( field_ids) => {
1483
+ let fields = field_ids. iter ( ) . map ( |& id| self . r . tcx . item_name ( id) ) ;
1484
+
1485
+ let fields = if let Some ( old_fields) = old_fields {
1486
+ fields
1487
+ . enumerate ( )
1488
+ . map ( |( idx, new) | ( new, old_fields. get ( idx) ) )
1489
+ . map ( |( new, old) | {
1490
+ let new = new. to_ident_string ( ) ;
1491
+ if let Some ( Some ( old) ) = old
1492
+ && new != * old
1493
+ {
1494
+ format ! ( "{new}: {old}" )
1495
+ } else {
1496
+ new
1497
+ }
1498
+ } )
1499
+ . collect :: < Vec < String > > ( )
1500
+ } else {
1501
+ fields. map ( |f| format ! ( "{f}{tail}" ) ) . collect :: < Vec < String > > ( )
1502
+ } ;
1503
+
1504
+ ( fields. join ( ", " ) , applicability)
1505
+ }
1506
+ None => ( "/* fields */" . to_string ( ) , Applicability :: HasPlaceholders ) ,
1507
+ } ;
1508
+ let pad = match field_ids {
1509
+ Some ( field_ids) if field_ids. is_empty ( ) => "" ,
1510
+ _ => " " ,
1511
+ } ;
1512
+ err. span_suggestion (
1513
+ span,
1514
+ format ! ( "use struct {descr} syntax instead" ) ,
1515
+ format ! ( "{path_str} {{{pad}{fields}{pad}}}" ) ,
1516
+ applicability,
1517
+ ) ;
1518
+ }
1490
1519
}
1491
1520
_ => {
1492
1521
err. span_label ( span, fallback_label. to_string ( ) ) ;
0 commit comments