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