1
Fork 0

Rollup merge of #134357 - Urgau:fn-ptr-134345, r=compiler-errors

Fix `trimmed_def_paths` ICE in the function ptr comparison lint

This PR fixes an ICE with `trimmed_def_paths` ICE in the function ptr comparison lint, specifically when pretty-printing user types but then not using the resulting pretty-printing.

Fixes #134345
r? `@saethlin`
This commit is contained in:
Matthias Krüger 2024-12-16 08:03:33 +01:00 committed by GitHub
commit 551de164e6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 75 additions and 34 deletions

View file

@ -1816,14 +1816,14 @@ pub(crate) enum AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
}
#[derive(LintDiagnostic)]
pub(crate) enum UnpredictableFunctionPointerComparisons<'a> {
pub(crate) enum UnpredictableFunctionPointerComparisons<'a, 'tcx> {
#[diag(lint_unpredictable_fn_pointer_comparisons)]
#[note(lint_note_duplicated_fn)]
#[note(lint_note_deduplicated_fn)]
#[note(lint_note_visit_fn_addr_eq)]
Suggestion {
#[subdiagnostic]
sugg: UnpredictableFunctionPointerComparisonsSuggestion<'a>,
sugg: UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx>,
},
#[diag(lint_unpredictable_fn_pointer_comparisons)]
#[note(lint_note_duplicated_fn)]
@ -1833,22 +1833,40 @@ pub(crate) enum UnpredictableFunctionPointerComparisons<'a> {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(
lint_fn_addr_eq_suggestion,
style = "verbose",
applicability = "maybe-incorrect"
)]
pub(crate) struct UnpredictableFunctionPointerComparisonsSuggestion<'a> {
pub ne: &'a str,
pub cast_right: String,
pub deref_left: &'a str,
pub deref_right: &'a str,
#[suggestion_part(code = "{ne}std::ptr::fn_addr_eq({deref_left}")]
pub left: Span,
#[suggestion_part(code = ", {deref_right}")]
pub middle: Span,
#[suggestion_part(code = "{cast_right})")]
pub right: Span,
pub(crate) enum UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx> {
#[multipart_suggestion(
lint_fn_addr_eq_suggestion,
style = "verbose",
applicability = "maybe-incorrect"
)]
FnAddrEq {
ne: &'a str,
deref_left: &'a str,
deref_right: &'a str,
#[suggestion_part(code = "{ne}std::ptr::fn_addr_eq({deref_left}")]
left: Span,
#[suggestion_part(code = ", {deref_right}")]
middle: Span,
#[suggestion_part(code = ")")]
right: Span,
},
#[multipart_suggestion(
lint_fn_addr_eq_suggestion,
style = "verbose",
applicability = "maybe-incorrect"
)]
FnAddrEqWithCast {
ne: &'a str,
deref_left: &'a str,
deref_right: &'a str,
fn_sig: rustc_middle::ty::PolyFnSig<'tcx>,
#[suggestion_part(code = "{ne}std::ptr::fn_addr_eq({deref_left}")]
left: Span,
#[suggestion_part(code = ", {deref_right}")]
middle: Span,
#[suggestion_part(code = " as {fn_sig})")]
right: Span,
},
}
pub(crate) struct ImproperCTypes<'a> {

View file

@ -483,29 +483,36 @@ fn lint_fn_pointer<'tcx>(
let middle = l_span.shrink_to_hi().until(r_span.shrink_to_lo());
let right = r_span.shrink_to_hi().until(e.span.shrink_to_hi());
// We only check for a right cast as `FnDef` == `FnPtr` is not possible,
// only `FnPtr == FnDef` is possible.
let cast_right = if !r_ty.is_fn_ptr() {
let fn_sig = r_ty.fn_sig(cx.tcx);
format!(" as {fn_sig}")
} else {
String::new()
};
let sugg =
// We only check for a right cast as `FnDef` == `FnPtr` is not possible,
// only `FnPtr == FnDef` is possible.
if !r_ty.is_fn_ptr() {
let fn_sig = r_ty.fn_sig(cx.tcx);
cx.emit_span_lint(
UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS,
e.span,
UnpredictableFunctionPointerComparisons::Suggestion {
sugg: UnpredictableFunctionPointerComparisonsSuggestion {
UnpredictableFunctionPointerComparisonsSuggestion::FnAddrEqWithCast {
ne,
fn_sig,
deref_left,
deref_right,
left,
middle,
right,
}
} else {
UnpredictableFunctionPointerComparisonsSuggestion::FnAddrEq {
ne,
deref_left,
deref_right,
left,
middle,
right,
cast_right,
},
},
}
};
cx.emit_span_lint(
UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS,
e.span,
UnpredictableFunctionPointerComparisons::Suggestion { sugg },
);
}