@@ -1681,41 +1681,81 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
1681
1681
// the struct literal syntax at all, as that will cause a subsequent error.
1682
1682
let fields = this. r . field_idents ( def_id) ;
1683
1683
let has_fields = fields. as_ref ( ) . is_some_and ( |f| !f. is_empty ( ) ) ;
1684
- let ( fields, applicability) = match fields {
1685
- Some ( fields) => {
1686
- let fields = if let Some ( old_fields) = old_fields {
1687
- fields
1688
- . iter ( )
1689
- . enumerate ( )
1690
- . map ( |( idx, new) | ( new, old_fields. get ( idx) ) )
1691
- . map ( |( new, old) | {
1692
- if let Some ( Some ( old) ) = old
1693
- && new. as_str ( ) != old
1694
- {
1695
- format ! ( "{new}: {old}" )
1696
- } else {
1697
- new. to_string ( )
1698
- }
1699
- } )
1700
- . collect :: < Vec < String > > ( )
1701
- } else {
1702
- fields
1703
- . iter ( )
1704
- . map ( |f| format ! ( "{f}{tail}" ) )
1705
- . collect :: < Vec < String > > ( )
1706
- } ;
1707
-
1708
- ( fields. join ( ", " ) , applicability)
1709
- }
1710
- None => ( "/* fields */" . to_string ( ) , Applicability :: HasPlaceholders ) ,
1711
- } ;
1712
- let pad = if has_fields { " " } else { "" } ;
1713
- err. span_suggestion (
1684
+
1685
+ if let PathSource :: Expr ( Some ( Expr {
1686
+ kind : ExprKind :: Call ( path, args) ,
1714
1687
span,
1715
- format ! ( "use struct {descr} syntax instead" ) ,
1716
- format ! ( "{path_str} {{{pad}{fields}{pad}}}" ) ,
1717
- applicability,
1718
- ) ;
1688
+ ..
1689
+ } ) ) = source
1690
+ && !args. is_empty ( )
1691
+ && let Some ( fields) = & fields
1692
+ && args. len ( ) == fields. len ( )
1693
+ // Make sure we have same number of args as fields
1694
+ {
1695
+ let path_span = path. span ;
1696
+ let mut parts = Vec :: new ( ) ;
1697
+
1698
+ // Start with the opening brace
1699
+ parts. push ( (
1700
+ path_span. shrink_to_hi ( ) . until ( args[ 0 ] . span ) ,
1701
+ "{" . to_owned ( ) ,
1702
+ ) ) ;
1703
+
1704
+ for ( field, arg) in fields. iter ( ) . zip ( args. iter ( ) ) {
1705
+ // Add the field name before the argument
1706
+ parts. push ( ( arg. span . shrink_to_lo ( ) , format ! ( "{}: " , field) ) ) ;
1707
+ }
1708
+
1709
+ // Add the closing brace
1710
+ parts. push ( (
1711
+ args. last ( ) . unwrap ( ) . span . shrink_to_hi ( ) . until ( span. shrink_to_hi ( ) ) ,
1712
+ "}" . to_owned ( ) ,
1713
+ ) ) ;
1714
+
1715
+ err. multipart_suggestion_verbose (
1716
+ format ! ( "use struct {descr} syntax instead of calling" ) ,
1717
+ parts,
1718
+ applicability,
1719
+ ) ;
1720
+ } else {
1721
+ let ( fields, applicability) = match fields {
1722
+ Some ( fields) => {
1723
+ let fields = if let Some ( old_fields) = old_fields {
1724
+ fields
1725
+ . iter ( )
1726
+ . enumerate ( )
1727
+ . map ( |( idx, new) | ( new, old_fields. get ( idx) ) )
1728
+ . map ( |( new, old) | {
1729
+ if let Some ( Some ( old) ) = old
1730
+ && new. as_str ( ) != old
1731
+ {
1732
+ format ! ( "{new}: {old}" )
1733
+ } else {
1734
+ new. to_string ( )
1735
+ }
1736
+ } )
1737
+ . collect :: < Vec < String > > ( )
1738
+ } else {
1739
+ fields
1740
+ . iter ( )
1741
+ . map ( |f| format ! ( "{f}{tail}" ) )
1742
+ . collect :: < Vec < String > > ( )
1743
+ } ;
1744
+
1745
+ ( fields. join ( ", " ) , applicability)
1746
+ }
1747
+ None => {
1748
+ ( "/* fields */" . to_string ( ) , Applicability :: HasPlaceholders )
1749
+ }
1750
+ } ;
1751
+ let pad = if has_fields { " " } else { "" } ;
1752
+ err. span_suggestion (
1753
+ span,
1754
+ format ! ( "use struct {descr} syntax instead" ) ,
1755
+ format ! ( "{path_str} {{{pad}{fields}{pad}}}" ) ,
1756
+ applicability,
1757
+ ) ;
1758
+ }
1719
1759
}
1720
1760
if let PathSource :: Expr ( Some ( Expr {
1721
1761
kind : ExprKind :: Call ( path, args) ,
0 commit comments