diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_lint/src/types.rs | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 0c58c804353..c0371b1f606 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -4,7 +4,7 @@ use std::ops::ControlFlow; use rustc_abi::{BackendRepr, ExternAbi, TagEncoding, Variants, WrappingRange}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::DiagMessage; -use rustc_hir::{Expr, ExprKind}; +use rustc_hir::{Expr, ExprKind, LangItem}; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, SizeSkeleton}; use rustc_middle::ty::{ @@ -444,7 +444,25 @@ fn lint_fn_pointer<'tcx>( let (l_ty, l_ty_refs) = peel_refs(l_ty); let (r_ty, r_ty_refs) = peel_refs(r_ty); - if !l_ty.is_fn() || !r_ty.is_fn() { + if l_ty.is_fn() && r_ty.is_fn() { + // both operands are function pointers, fallthrough + } else if let ty::Adt(l_def, l_args) = l_ty.kind() + && let ty::Adt(r_def, r_args) = r_ty.kind() + && cx.tcx.is_lang_item(l_def.did(), LangItem::Option) + && cx.tcx.is_lang_item(r_def.did(), LangItem::Option) + && let Some(l_some_arg) = l_args.get(0) + && let Some(r_some_arg) = r_args.get(0) + && l_some_arg.expect_ty().is_fn() + && r_some_arg.expect_ty().is_fn() + { + // both operands are `Option<{function ptr}>` + return cx.emit_span_lint( + UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS, + e.span, + UnpredictableFunctionPointerComparisons::Warn, + ); + } else { + // types are not function pointers, nothing to do return; } |
