@@ -4,7 +4,7 @@ use std::ops::ControlFlow;
4
4
use rustc_abi:: { BackendRepr , ExternAbi , TagEncoding , Variants , WrappingRange } ;
5
5
use rustc_data_structures:: fx:: FxHashSet ;
6
6
use rustc_errors:: DiagMessage ;
7
- use rustc_hir:: { Expr , ExprKind } ;
7
+ use rustc_hir:: { Expr , ExprKind , LangItem } ;
8
8
use rustc_middle:: bug;
9
9
use rustc_middle:: ty:: layout:: { LayoutOf , SizeSkeleton } ;
10
10
use rustc_middle:: ty:: {
@@ -445,7 +445,25 @@ fn lint_fn_pointer<'tcx>(
445
445
let ( l_ty, l_ty_refs) = peel_refs ( l_ty) ;
446
446
let ( r_ty, r_ty_refs) = peel_refs ( r_ty) ;
447
447
448
- if !l_ty. is_fn ( ) || !r_ty. is_fn ( ) {
448
+ if l_ty. is_fn ( ) && r_ty. is_fn ( ) {
449
+ // both operands are function pointers, fallthrough
450
+ } else if let ty:: Adt ( l_def, l_args) = l_ty. kind ( )
451
+ && let ty:: Adt ( r_def, r_args) = r_ty. kind ( )
452
+ && cx. tcx . is_lang_item ( l_def. did ( ) , LangItem :: Option )
453
+ && cx. tcx . is_lang_item ( r_def. did ( ) , LangItem :: Option )
454
+ && let Some ( l_some_arg) = l_args. get ( 0 )
455
+ && let Some ( r_some_arg) = r_args. get ( 0 )
456
+ && l_some_arg. expect_ty ( ) . is_fn ( )
457
+ && r_some_arg. expect_ty ( ) . is_fn ( )
458
+ {
459
+ // both operands are `Option<{function ptr}>`
460
+ return cx. emit_span_lint (
461
+ UNPREDICTABLE_FUNCTION_POINTER_COMPARISONS ,
462
+ e. span ,
463
+ UnpredictableFunctionPointerComparisons :: Warn ,
464
+ ) ;
465
+ } else {
466
+ // types are not function pointers, nothing to do
449
467
return ;
450
468
}
451
469
0 commit comments