@@ -17,6 +17,7 @@ use rustc_middle::{bug, span_bug};
17
17
use rustc_span:: def_id:: DefId ;
18
18
use rustc_span:: source_map:: Spanned ;
19
19
use rustc_span:: { DUMMY_SP , Span , Symbol , sym} ;
20
+ use rustc_trait_selection:: infer:: InferCtxtExt ;
20
21
use tracing:: { debug, instrument} ;
21
22
22
23
use crate :: builder:: Builder ;
@@ -450,7 +451,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
450
451
( _, expect) = coerce ( expect_ty, expect, * elem_ty) ;
451
452
}
452
453
453
- // Figure out the type on which we are calling `PartialEq` . This involves an extra wrapping
454
+ // Figure out the type we are searching for traits against . This involves an extra wrapping
454
455
// reference: we can only compare two `&T`, and then compare_ty will be `T`.
455
456
// Make sure that we do *not* call any user-defined code here.
456
457
// The only types that can end up here are string and byte literals,
@@ -466,10 +467,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
466
467
_ => span_bug ! ( source_info. span, "invalid type for non-scalar compare: {}" , ty) ,
467
468
} ;
468
469
469
- let eq_def_id =
470
+ let mut cmp_trait_def_id =
470
471
self . tcx . require_lang_item ( LangItem :: MatchLoweredCmp , Some ( source_info. span ) ) ;
471
- let method = trait_method ( self . tcx , eq_def_id, sym:: do_match, [ compare_ty, compare_ty] ) ;
472
472
473
+ let has_pattern_eq = self
474
+ . infcx
475
+ . type_implements_trait ( cmp_trait_def_id, [ compare_ty] , self . param_env )
476
+ . must_apply_modulo_regions ( ) ;
477
+ if !has_pattern_eq {
478
+ cmp_trait_def_id =
479
+ self . tcx . require_lang_item ( LangItem :: PartialEq , Some ( source_info. span ) ) ;
480
+ }
481
+
482
+ let method =
483
+ trait_method ( self . tcx , cmp_trait_def_id, sym:: do_match, [ compare_ty, compare_ty] ) ;
473
484
let bool_ty = self . tcx . types . bool ;
474
485
let eq_result = self . temp ( bool_ty, source_info. span ) ;
475
486
let eq_block = self . cfg . start_new_block ( ) ;
0 commit comments