diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 044c9413f0b..2133fd25b67 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -415,14 +415,17 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::Item<'_>) { impl LateLintPass<'_> for Diagnostics { fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { + let collect_args_tys_and_spans = |args: &[Expr<'_>], reserve_one_extra: bool| { + let mut result = Vec::with_capacity(args.len() + usize::from(reserve_one_extra)); + result.extend(args.iter().map(|arg| (cx.typeck_results().expr_ty(arg), arg.span))); + result + }; // Only check function calls and method calls. - let (span, def_id, fn_gen_args, call_tys) = match expr.kind { + let (span, def_id, fn_gen_args, arg_tys_and_spans) = match expr.kind { ExprKind::Call(callee, args) => { match cx.typeck_results().node_type(callee.hir_id).kind() { &ty::FnDef(def_id, fn_gen_args) => { - let call_tys: Vec<_> = - args.iter().map(|arg| cx.typeck_results().expr_ty(arg)).collect(); - (callee.span, def_id, fn_gen_args, call_tys) + (callee.span, def_id, fn_gen_args, collect_args_tys_and_spans(args, false)) } _ => return, // occurs for fns passed as args } @@ -432,10 +435,9 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { else { return; }; - let mut call_tys: Vec<_> = - args.iter().map(|arg| cx.typeck_results().expr_ty(arg)).collect(); - call_tys.insert(0, cx.tcx.types.self_param); // dummy inserted for `self` - (span, def_id, fn_gen_args, call_tys) + let mut args = collect_args_tys_and_spans(args, true); + args.insert(0, (cx.tcx.types.self_param, _recv.span)); // dummy inserted for `self` + (span, def_id, fn_gen_args, args) } _ => return, }; @@ -525,11 +527,11 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { // `UNTRANSLATABLE_DIAGNOSTIC` lint. for (param_i, param_i_p_name) in impl_into_diagnostic_message_params { // Is the arg type `{Sub,D}iagMessage`or `impl Into<{Sub,D}iagMessage>`? - let arg_ty = call_tys[param_i]; + let (arg_ty, arg_span) = arg_tys_and_spans[param_i]; let is_translatable = is_diag_message(arg_ty) || matches!(arg_ty.kind(), ty::Param(p) if p.name == param_i_p_name); if !is_translatable { - cx.emit_span_lint(UNTRANSLATABLE_DIAGNOSTIC, span, UntranslatableDiag); + cx.emit_span_lint(UNTRANSLATABLE_DIAGNOSTIC, arg_span, UntranslatableDiag); } } } diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.stderr b/tests/ui-fulldeps/internal-lints/diagnostics.stderr index c23da981ea2..36dd3cf4be7 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.stderr +++ b/tests/ui-fulldeps/internal-lints/diagnostics.stderr @@ -1,8 +1,8 @@ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:43:9 + --> $DIR/diagnostics.rs:43:31 | LL | Diag::new(dcx, level, "untranslatable diagnostic") - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the lint level is defined here --> $DIR/diagnostics.rs:7:9 @@ -11,16 +11,16 @@ LL | #![deny(rustc::untranslatable_diagnostic)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:64:14 + --> $DIR/diagnostics.rs:64:19 | LL | diag.note("untranslatable diagnostic"); - | ^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:85:14 + --> $DIR/diagnostics.rs:85:19 | LL | diag.note("untranslatable diagnostic"); - | ^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls --> $DIR/diagnostics.rs:99:21 @@ -41,36 +41,34 @@ LL | let _diag = dcx.struct_err("untranslatable diagnostic"); | ^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:102:21 + --> $DIR/diagnostics.rs:102:32 | LL | let _diag = dcx.struct_err("untranslatable diagnostic"); - | ^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:120:5 + --> $DIR/diagnostics.rs:120:7 | LL | f("untranslatable diagnostic", crate::fluent_generated::no_crate_example); - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:122:5 + --> $DIR/diagnostics.rs:122:50 | LL | f(crate::fluent_generated::no_crate_example, "untranslatable diagnostic"); - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:124:5 + --> $DIR/diagnostics.rs:124:7 | LL | f("untranslatable diagnostic", "untranslatable diagnostic"); - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:124:5 + --> $DIR/diagnostics.rs:124:36 | LL | f("untranslatable diagnostic", "untranslatable diagnostic"); - | ^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 10 previous errors