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)]
|
||||
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> {
|
||||
|
|
|
@ -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 },
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue