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:
commit
551de164e6
3 changed files with 75 additions and 34 deletions
|
@ -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> {
|
||||||
|
|
|
@ -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 },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
16
tests/ui/lint/fn-ptr-comparisons-134345.rs
Normal file
16
tests/ui/lint/fn-ptr-comparisons-134345.rs
Normal 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;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue