@@ -17,6 +17,7 @@ use rustc_middle::{bug, span_bug};
1717use rustc_span:: def_id:: DefId ;
1818use rustc_span:: source_map:: Spanned ;
1919use rustc_span:: { DUMMY_SP , Span , Symbol , sym} ;
20+ use rustc_trait_selection:: infer:: InferCtxtExt ;
2021use tracing:: { debug, instrument} ;
2122
2223use crate :: builder:: Builder ;
@@ -450,7 +451,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
450451 ( _, expect) = coerce ( expect_ty, expect, * elem_ty) ;
451452 }
452453
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
454455 // reference: we can only compare two `&T`, and then compare_ty will be `T`.
455456 // Make sure that we do *not* call any user-defined code here.
456457 // The only types that can end up here are string and byte literals,
@@ -466,10 +467,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
466467 _ => span_bug ! ( source_info. span, "invalid type for non-scalar compare: {}" , ty) ,
467468 } ;
468469
469- let eq_def_id =
470+ let mut cmp_trait_def_id =
470471 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] ) ;
472472
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] ) ;
473484 let bool_ty = self . tcx . types . bool ;
474485 let eq_result = self . temp ( bool_ty, source_info. span ) ;
475486 let eq_block = self . cfg . start_new_block ( ) ;
0 commit comments