@@ -30,12 +30,14 @@ impl<'db> ExprCollector<'db> {
3030 ) -> ExprId {
3131 let mut args = FormatArgumentsCollector :: default ( ) ;
3232 f. args ( ) . for_each ( |arg| {
33+ let expr = arg. expr ( ) ;
3334 args. add ( FormatArgument {
3435 kind : match arg. arg_name ( ) {
3536 Some ( name) => FormatArgumentKind :: Named ( Name :: new_root ( name. name ( ) . text ( ) ) ) ,
3637 None => FormatArgumentKind :: Normal ,
3738 } ,
38- expr : self . collect_expr_opt ( arg. expr ( ) ) ,
39+ syntax : expr. as_ref ( ) . map ( AstPtr :: new) ,
40+ expr : self . collect_expr_opt ( expr) ,
3941 } ) ;
4042 } ) ;
4143 let template = f. template ( ) ;
@@ -53,8 +55,10 @@ impl<'db> ExprCollector<'db> {
5355 Some ( ( ( s, is_direct_literal) , template) ) => {
5456 let call_ctx = SyntaxContext :: root ( self . def_map . edition ( ) ) ;
5557 let hygiene = self . hygiene_id_for ( s. syntax ( ) . text_range ( ) ) ;
58+ let template_ptr = AstPtr :: new ( & template) ;
5659 let fmt = format_args:: parse (
5760 & s,
61+ template_ptr,
5862 fmt_snippet,
5963 args,
6064 is_direct_literal,
@@ -65,10 +69,7 @@ impl<'db> ExprCollector<'db> {
6569 . template_map
6670 . get_or_insert_with ( Default :: default)
6771 . implicit_capture_to_source
68- . insert (
69- expr_id,
70- self . expander . in_file ( ( AstPtr :: new ( & template) , range) ) ,
71- ) ;
72+ . insert ( expr_id, self . expander . in_file ( ( template_ptr, range) ) ) ;
7273 }
7374 if !hygiene. is_root ( ) {
7475 self . store . ident_hygiene . insert ( expr_id. into ( ) , hygiene) ;
@@ -340,7 +341,8 @@ impl<'db> ExprCollector<'db> {
340341 expr : args_ident_expr,
341342 name : Name :: new_tuple_field ( arg_index) ,
342343 } ) ;
343- self . make_argument ( arg, ty)
344+ let arg_ptr = arguments. get ( arg_index) . and_then ( |it| it. syntax ) ;
345+ self . make_argument ( arg_ptr, arg, ty)
344346 } )
345347 . collect ( ) ;
346348 let args =
@@ -557,7 +559,8 @@ impl<'db> ExprCollector<'db> {
557559 rawness : Rawness :: Ref ,
558560 mutability : Mutability :: Shared ,
559561 } ) ;
560- self . make_argument ( arg, ty)
562+ let arg_ptr = arguments. get ( arg_index) . and_then ( |it| it. syntax ) ;
563+ self . make_argument ( arg_ptr, arg, ty)
561564 } )
562565 . collect ( ) ;
563566 let array =
@@ -649,7 +652,8 @@ impl<'db> ExprCollector<'db> {
649652 rawness : Rawness :: Ref ,
650653 mutability : Mutability :: Shared ,
651654 } ) ;
652- self . make_argument ( ref_arg, ty)
655+ let arg_ptr = arguments. get ( arg_index) . and_then ( |it| it. syntax ) ;
656+ self . make_argument ( arg_ptr, ref_arg, ty)
653657 } )
654658 . collect ( ) ;
655659 let args =
@@ -716,7 +720,8 @@ impl<'db> ExprCollector<'db> {
716720 expr : args_ident_expr,
717721 name : Name :: new_tuple_field ( arg_index) ,
718722 } ) ;
719- self . make_argument ( arg, ty)
723+ let arg_ptr = arguments. get ( arg_index) . and_then ( |it| it. syntax ) ;
724+ self . make_argument ( arg_ptr, arg, ty)
720725 } )
721726 . collect ( ) ;
722727 let array =
@@ -976,11 +981,16 @@ impl<'db> ExprCollector<'db> {
976981 /// ```text
977982 /// <core::fmt::Argument>::new_…(arg)
978983 /// ```
979- fn make_argument ( & mut self , arg : ExprId , ty : ArgumentType ) -> ExprId {
984+ fn make_argument (
985+ & mut self ,
986+ arg_ptr : Option < AstPtr < ast:: Expr > > ,
987+ arg : ExprId ,
988+ ty : ArgumentType ,
989+ ) -> ExprId {
980990 use ArgumentType :: * ;
981991 use FormatTrait :: * ;
982992
983- let new_fn = self . ty_rel_lang_path_desugared_expr (
993+ let new_fn = self . ty_rel_lang_path (
984994 self . lang_items ( ) . FormatArgument ,
985995 match ty {
986996 Format ( Display ) => sym:: new_display,
@@ -995,6 +1005,22 @@ impl<'db> ExprCollector<'db> {
9951005 Usize => sym:: from_usize,
9961006 } ,
9971007 ) ;
1008+ let new_fn = match new_fn {
1009+ Some ( new_fn) => {
1010+ let new_fn = self . store . exprs . alloc ( Expr :: Path ( new_fn) ) ;
1011+ if let Some ( arg_ptr) = arg_ptr {
1012+ // Trait errors (the argument does not implement the expected fmt trait) will show
1013+ // on this path, so to not end up with synthetic syntax we insert this mapping. We
1014+ // don't want to insert the other way's mapping in order to not override the source
1015+ // for the argument.
1016+ self . store
1017+ . expr_map_back
1018+ . insert ( new_fn, self . expander . in_file ( arg_ptr. wrap_left ( ) ) ) ;
1019+ }
1020+ new_fn
1021+ }
1022+ None => self . missing_expr ( ) ,
1023+ } ;
9981024 self . alloc_expr_desugared ( Expr :: Call { callee : new_fn, args : Box :: new ( [ arg] ) } )
9991025 }
10001026
0 commit comments