Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/expr_store/lower/format_args.rs')
-rw-r--r--crates/hir-def/src/expr_store/lower/format_args.rs48
1 files changed, 37 insertions, 11 deletions
diff --git a/crates/hir-def/src/expr_store/lower/format_args.rs b/crates/hir-def/src/expr_store/lower/format_args.rs
index beb1267173..b058ad6d9a 100644
--- a/crates/hir-def/src/expr_store/lower/format_args.rs
+++ b/crates/hir-def/src/expr_store/lower/format_args.rs
@@ -30,12 +30,14 @@ impl<'db> ExprCollector<'db> {
) -> ExprId {
let mut args = FormatArgumentsCollector::default();
f.args().for_each(|arg| {
+ let expr = arg.expr();
args.add(FormatArgument {
kind: match arg.arg_name() {
Some(name) => FormatArgumentKind::Named(Name::new_root(name.name().text())),
None => FormatArgumentKind::Normal,
},
- expr: self.collect_expr_opt(arg.expr()),
+ syntax: expr.as_ref().map(AstPtr::new),
+ expr: self.collect_expr_opt(expr),
});
});
let template = f.template();
@@ -53,8 +55,10 @@ impl<'db> ExprCollector<'db> {
Some(((s, is_direct_literal), template)) => {
let call_ctx = SyntaxContext::root(self.def_map.edition());
let hygiene = self.hygiene_id_for(s.syntax().text_range());
+ let template_ptr = AstPtr::new(&template);
let fmt = format_args::parse(
&s,
+ template_ptr,
fmt_snippet,
args,
is_direct_literal,
@@ -65,10 +69,7 @@ impl<'db> ExprCollector<'db> {
.template_map
.get_or_insert_with(Default::default)
.implicit_capture_to_source
- .insert(
- expr_id,
- self.expander.in_file((AstPtr::new(&template), range)),
- );
+ .insert(expr_id, self.expander.in_file((template_ptr, range)));
}
if !hygiene.is_root() {
self.store.ident_hygiene.insert(expr_id.into(), hygiene);
@@ -340,7 +341,8 @@ impl<'db> ExprCollector<'db> {
expr: args_ident_expr,
name: Name::new_tuple_field(arg_index),
});
- self.make_argument(arg, ty)
+ let arg_ptr = arguments.get(arg_index).and_then(|it| it.syntax);
+ self.make_argument(arg_ptr, arg, ty)
})
.collect();
let args =
@@ -557,7 +559,8 @@ impl<'db> ExprCollector<'db> {
rawness: Rawness::Ref,
mutability: Mutability::Shared,
});
- self.make_argument(arg, ty)
+ let arg_ptr = arguments.get(arg_index).and_then(|it| it.syntax);
+ self.make_argument(arg_ptr, arg, ty)
})
.collect();
let array =
@@ -649,7 +652,8 @@ impl<'db> ExprCollector<'db> {
rawness: Rawness::Ref,
mutability: Mutability::Shared,
});
- self.make_argument(ref_arg, ty)
+ let arg_ptr = arguments.get(arg_index).and_then(|it| it.syntax);
+ self.make_argument(arg_ptr, ref_arg, ty)
})
.collect();
let args =
@@ -716,7 +720,8 @@ impl<'db> ExprCollector<'db> {
expr: args_ident_expr,
name: Name::new_tuple_field(arg_index),
});
- self.make_argument(arg, ty)
+ let arg_ptr = arguments.get(arg_index).and_then(|it| it.syntax);
+ self.make_argument(arg_ptr, arg, ty)
})
.collect();
let array =
@@ -976,11 +981,16 @@ impl<'db> ExprCollector<'db> {
/// ```text
/// <core::fmt::Argument>::new_…(arg)
/// ```
- fn make_argument(&mut self, arg: ExprId, ty: ArgumentType) -> ExprId {
+ fn make_argument(
+ &mut self,
+ arg_ptr: Option<AstPtr<ast::Expr>>,
+ arg: ExprId,
+ ty: ArgumentType,
+ ) -> ExprId {
use ArgumentType::*;
use FormatTrait::*;
- let new_fn = self.ty_rel_lang_path_desugared_expr(
+ let new_fn = self.ty_rel_lang_path(
self.lang_items().FormatArgument,
match ty {
Format(Display) => sym::new_display,
@@ -995,6 +1005,22 @@ impl<'db> ExprCollector<'db> {
Usize => sym::from_usize,
},
);
+ let new_fn = match new_fn {
+ Some(new_fn) => {
+ let new_fn = self.store.exprs.alloc(Expr::Path(new_fn));
+ if let Some(arg_ptr) = arg_ptr {
+ // Trait errors (the argument does not implement the expected fmt trait) will show
+ // on this path, so to not end up with synthetic syntax we insert this mapping. We
+ // don't want to insert the other way's mapping in order to not override the source
+ // for the argument.
+ self.store
+ .expr_map_back
+ .insert(new_fn, self.expander.in_file(arg_ptr.wrap_left()));
+ }
+ new_fn
+ }
+ None => self.missing_expr(),
+ };
self.alloc_expr_desugared(Expr::Call { callee: new_fn, args: Box::new([arg]) })
}