Introduce the mismatched_lifetime_syntaxes lint

This commit is contained in:
Jake Goulding
2025-03-28 16:12:07 -04:00
parent d2bf16ad6d
commit 9a50cb4a0c
8 changed files with 1447 additions and 3 deletions

View File

@@ -3241,3 +3241,128 @@ pub(crate) struct ReservedMultihash {
#[suggestion(code = " ", applicability = "machine-applicable")]
pub suggestion: Span,
}
#[derive(Debug)]
pub(crate) struct MismatchedLifetimeSyntaxes {
pub lifetime_name: String,
pub inputs: Vec<Span>,
pub outputs: Vec<Span>,
pub suggestions: Vec<MismatchedLifetimeSyntaxesSuggestion>,
}
impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for MismatchedLifetimeSyntaxes {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
diag.primary_message(fluent::lint_mismatched_lifetime_syntaxes);
diag.arg("lifetime_name", self.lifetime_name);
diag.arg("n_inputs", self.inputs.len());
for input in self.inputs {
let a = diag.eagerly_translate(fluent::lint_label_mismatched_lifetime_syntaxes_inputs);
diag.span_label(input, a);
}
diag.arg("n_outputs", self.outputs.len());
for output in self.outputs {
let a = diag.eagerly_translate(fluent::lint_label_mismatched_lifetime_syntaxes_outputs);
diag.span_label(output, a);
}
let mut suggestions = self.suggestions.into_iter();
if let Some(s) = suggestions.next() {
diag.subdiagnostic(s);
for mut s in suggestions {
s.make_tool_only();
diag.subdiagnostic(s);
}
}
}
}
#[derive(Debug)]
pub(crate) enum MismatchedLifetimeSyntaxesSuggestion {
Implicit {
suggestions: Vec<Span>,
tool_only: bool,
},
Mixed {
implicit_suggestions: Vec<Span>,
explicit_anonymous_suggestions: Vec<(Span, String)>,
tool_only: bool,
},
Explicit {
lifetime_name: String,
suggestions: Vec<(Span, String)>,
tool_only: bool,
},
}
impl MismatchedLifetimeSyntaxesSuggestion {
fn make_tool_only(&mut self) {
use MismatchedLifetimeSyntaxesSuggestion::*;
let tool_only = match self {
Implicit { tool_only, .. } | Mixed { tool_only, .. } | Explicit { tool_only, .. } => {
tool_only
}
};
*tool_only = true;
}
}
impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion {
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
use MismatchedLifetimeSyntaxesSuggestion::*;
let style = |tool_only| {
if tool_only { SuggestionStyle::CompletelyHidden } else { SuggestionStyle::ShowAlways }
};
match self {
Implicit { suggestions, tool_only } => {
let suggestions = suggestions.into_iter().map(|s| (s, String::new())).collect();
diag.multipart_suggestion_with_style(
fluent::lint_mismatched_lifetime_syntaxes_suggestion_implicit,
suggestions,
Applicability::MachineApplicable,
style(tool_only),
);
}
Mixed { implicit_suggestions, explicit_anonymous_suggestions, tool_only } => {
let implicit_suggestions =
implicit_suggestions.into_iter().map(|s| (s, String::new()));
let suggestions =
implicit_suggestions.chain(explicit_anonymous_suggestions).collect();
diag.multipart_suggestion_with_style(
fluent::lint_mismatched_lifetime_syntaxes_suggestion_mixed,
suggestions,
Applicability::MachineApplicable,
style(tool_only),
);
}
Explicit { lifetime_name, suggestions, tool_only } => {
diag.arg("lifetime_name", lifetime_name);
let msg = diag.eagerly_translate(
fluent::lint_mismatched_lifetime_syntaxes_suggestion_explicit,
);
diag.multipart_suggestion_with_style(
msg,
suggestions,
Applicability::MachineApplicable,
style(tool_only),
);
}
}
}
}