@@ -1681,41 +1681,81 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
16811681 // the struct literal syntax at all, as that will cause a subsequent error.
16821682 let fields = this. r . field_idents ( def_id) ;
16831683 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) ,
17141687 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+ }
17191759 }
17201760 if let PathSource :: Expr ( Some ( Expr {
17211761 kind : ExprKind :: Call ( path, args) ,
0 commit comments