Skip to content

Commit 0eb1d11

Browse files
committed
Allow multiple impl Into<{D,Subd}iagMessage> parameters in a function.
The internal diagnostic lint currently only allows one, because that was all that occurred in practice. But rust-lang/rust-clippy/pull/12453 wants to introduce functions with more than one, and this limitation is getting in the way.
1 parent af69f4c commit 0eb1d11

File tree

2 files changed

+13
-14
lines changed

2 files changed

+13
-14
lines changed

compiler/rustc_lint/src/internal.rs

+5-12
Original file line numberDiff line numberDiff line change
@@ -410,9 +410,8 @@ impl LateLintPass<'_> for Diagnostics {
410410
}
411411
};
412412

413-
// Does the callee have a `impl Into<{D,Subd}iagMessage>` parameter? (There should be at
414-
// most one.)
415-
let mut impl_into_diagnostic_message_param = None;
413+
// Does the callee have one or more `impl Into<{D,Subd}iagMessage>` parameters?
414+
let mut impl_into_diagnostic_message_params = vec![];
416415
let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
417416
let predicates = cx.tcx.predicates_of(def_id).instantiate_identity(cx.tcx).predicates;
418417
for (i, &param_ty) in fn_sig.inputs().iter().enumerate() {
@@ -426,20 +425,14 @@ impl LateLintPass<'_> for Diagnostics {
426425
&& let ty1 = trait_ref.args.type_at(1)
427426
&& is_diag_message(ty1)
428427
{
429-
if impl_into_diagnostic_message_param.is_some() {
430-
cx.tcx.dcx().span_bug(
431-
span,
432-
"can't handle multiple `impl Into<{D,Sub}iagMessage>` params",
433-
);
434-
}
435-
impl_into_diagnostic_message_param = Some((i, p.name));
428+
impl_into_diagnostic_message_params.push((i, p.name));
436429
}
437430
}
438431
}
439432
}
440433

441434
// Is the callee interesting?
442-
if !has_attr && impl_into_diagnostic_message_param.is_none() {
435+
if !has_attr && impl_into_diagnostic_message_params.is_empty() {
443436
return;
444437
}
445438

@@ -485,7 +478,7 @@ impl LateLintPass<'_> for Diagnostics {
485478
// Calls to methods with an `impl Into<{D,Subd}iagMessage>` parameter must be passed an arg
486479
// with type `{D,Subd}iagMessage` or `impl Into<{D,Subd}iagMessage>`. Otherwise, emit an
487480
// `UNTRANSLATABLE_DIAGNOSTIC` lint.
488-
if let Some((param_i, param_i_p_name)) = impl_into_diagnostic_message_param {
481+
for (param_i, param_i_p_name) in impl_into_diagnostic_message_params {
489482
// Is the arg type `{Sub,D}iagMessage`or `impl Into<{Sub,D}iagMessage>`?
490483
let arg_ty = call_tys[param_i];
491484
let is_translatable = is_diag_message(arg_ty)

tests/ui-fulldeps/internal-lints/diagnostics.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ extern crate rustc_span;
1515

1616
use rustc_errors::{
1717
AddToDiagnostic, DecorateLint, Diag, DiagCtxt, DiagInner, DiagMessage, EmissionGuarantee,
18-
IntoDiagnostic, Level, SubdiagMessageOp,
18+
IntoDiagnostic, Level, SubdiagMessage, SubdiagMessageOp,
1919
};
2020
use rustc_macros::{Diagnostic, Subdiagnostic};
2121
use rustc_span::Span;
@@ -114,9 +114,15 @@ pub fn make_diagnostics<'a>(dcx: &'a DiagCtxt) {
114114

115115
// Check that `rustc_lint_diagnostics`-annotated functions aren't themselves linted for
116116
// `diagnostic_outside_of_impl`.
117-
118117
#[rustc_lint_diagnostics]
119118
pub fn skipped_because_of_annotation<'a>(dcx: &'a DiagCtxt) {
120119
#[allow(rustc::untranslatable_diagnostic)]
121120
let _diag = dcx.struct_err("untranslatable diagnostic"); // okay!
122121
}
122+
123+
// Check that multiple translatable params are allowed in a single function (at one point they
124+
// weren't).
125+
fn f(_x: impl Into<DiagMessage>, _y: impl Into<SubdiagMessage>) {}
126+
fn g() {
127+
f(crate::fluent_generated::no_crate_example, crate::fluent_generated::no_crate_example);
128+
}

0 commit comments

Comments
 (0)