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)] #[derive(LintDiagnostic)]
pub(crate) enum UnpredictableFunctionPointerComparisons<'a> { pub(crate) enum UnpredictableFunctionPointerComparisons<'a, 'tcx> {
#[diag(lint_unpredictable_fn_pointer_comparisons)] #[diag(lint_unpredictable_fn_pointer_comparisons)]
#[note(lint_note_duplicated_fn)] #[note(lint_note_duplicated_fn)]
#[note(lint_note_deduplicated_fn)] #[note(lint_note_deduplicated_fn)]
#[note(lint_note_visit_fn_addr_eq)] #[note(lint_note_visit_fn_addr_eq)]
Suggestion { Suggestion {
#[subdiagnostic] #[subdiagnostic]
sugg: UnpredictableFunctionPointerComparisonsSuggestion<'a>, sugg: UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx>,
}, },
#[diag(lint_unpredictable_fn_pointer_comparisons)] #[diag(lint_unpredictable_fn_pointer_comparisons)]
#[note(lint_note_duplicated_fn)] #[note(lint_note_duplicated_fn)]
@ -1833,22 +1833,40 @@ pub(crate) enum UnpredictableFunctionPointerComparisons<'a> {
} }
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]
pub(crate) enum UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx> {
#[multipart_suggestion( #[multipart_suggestion(
lint_fn_addr_eq_suggestion, lint_fn_addr_eq_suggestion,
style = "verbose", style = "verbose",
applicability = "maybe-incorrect" applicability = "maybe-incorrect"
)] )]
pub(crate) struct UnpredictableFunctionPointerComparisonsSuggestion<'a> { FnAddrEq {
pub ne: &'a str, ne: &'a str,
pub cast_right: String, deref_left: &'a str,
pub deref_left: &'a str, deref_right: &'a str,
pub deref_right: &'a str,
#[suggestion_part(code = "{ne}std::ptr::fn_addr_eq({deref_left}")] #[suggestion_part(code = "{ne}std::ptr::fn_addr_eq({deref_left}")]
pub left: Span, left: Span,
#[suggestion_part(code = ", {deref_right}")] #[suggestion_part(code = ", {deref_right}")]
pub middle: Span, middle: Span,
#[suggestion_part(code = "{cast_right})")] #[suggestion_part(code = ")")]
pub right: Span, 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> { 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 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()); let right = r_span.shrink_to_hi().until(e.span.shrink_to_hi());
let sugg =
// We only check for a right cast as `FnDef` == `FnPtr` is not possible, // We only check for a right cast as `FnDef` == `FnPtr` is not possible,
// only `FnPtr == FnDef` is possible. // only `FnPtr == FnDef` is possible.
let cast_right = if !r_ty.is_fn_ptr() { if !r_ty.is_fn_ptr() {
let fn_sig = r_ty.fn_sig(cx.tcx); let fn_sig = r_ty.fn_sig(cx.tcx);
format!(" as {fn_sig}")
} else {
String::new()
};
cx.emit_span_lint( UnpredictableFunctionPointerComparisonsSuggestion::FnAddrEqWithCast {
UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS, ne,
e.span, fn_sig,
UnpredictableFunctionPointerComparisons::Suggestion { deref_left,
sugg: UnpredictableFunctionPointerComparisonsSuggestion { deref_right,
left,
middle,
right,
}
} else {
UnpredictableFunctionPointerComparisonsSuggestion::FnAddrEq {
ne, ne,
deref_left, deref_left,
deref_right, deref_right,
left, left,
middle, middle,
right, right,
cast_right, }
}, };
},
cx.emit_span_lint(
UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS,
e.span,
UnpredictableFunctionPointerComparisons::Suggestion { sugg },
); );
} }

View file

@ -0,0 +1,16 @@
// This check veifies that we do not ICE when not showing a user type
// in the suggestions/diagnostics.
//
// cf. https://github.com/rust-lang/rust/issues/134345
//
//@ check-pass
struct A;
fn fna(_a: A) {}
#[allow(unpredictable_function_pointer_comparisons)]
fn main() {
let fa: fn(A) = fna;
let _ = fa == fna;
}