@@ -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 ;
@@ -362,7 +363,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
362363 ) ;
363364 }
364365
365- /// Compare two values using `<T as std::compare::pattern::MatchLoweredCmp >::do_match `.
366+ /// Compare two values using `<T as std::compare::pattern::PatternConstEq >::eq `.
366367 /// If the values are already references, just call it directly, otherwise
367368 /// take a reference to the values first and then call it.
368369 fn non_scalar_compare (
@@ -456,19 +457,30 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
456457 // The only types that can end up here are str and ScalarInt slices,
457458 // which have their comparison defined in `core`.
458459 // (Interestingly this means that exhaustiveness analysis relies, for soundness,
459- // on the `MatchLoweredCmp ` impls for `str` and `[T]` to be correct!)
460+ // on the `PatternConstEq` and `PartialEq ` impls for `str` and `[T]` to be correct!)
460461 let compare_ty = match * ty. kind ( ) {
461462 ty:: Ref ( _, deref_ty, _) if deref_ty == self . tcx . types . str_ || deref_ty. is_slice ( ) => {
462463 deref_ty
463464 }
464465 _ => span_bug ! ( source_info. span, "invalid type for non-scalar compare: {}" , ty) ,
465466 } ;
466467
467- let cmp_trait_def_id =
468- self . tcx . require_lang_item ( LangItem :: MatchLoweredCmp , Some ( source_info. span ) ) ;
469- let method =
470- trait_method ( self . tcx , cmp_trait_def_id, sym:: do_match, [ compare_ty, compare_ty] ) ;
468+ let const_cmp_trait_def =
469+ self . tcx . require_lang_item ( LangItem :: PatternConstEq , Some ( source_info. span ) ) ;
470+ let fallback_cmp_trait_def =
471+ self . tcx . require_lang_item ( LangItem :: PartialEq , Some ( source_info. span ) ) ;
472+
473+ let cmp_trait_def = if self
474+ . infcx
475+ . type_implements_trait ( const_cmp_trait_def, [ compare_ty, compare_ty] , self . param_env )
476+ . must_apply_modulo_regions ( )
477+ {
478+ const_cmp_trait_def
479+ } else {
480+ fallback_cmp_trait_def
481+ } ;
471482
483+ let method = trait_method ( self . tcx , cmp_trait_def, sym:: eq, [ compare_ty, compare_ty] ) ;
472484 let bool_ty = self . tcx . types . bool ;
473485 let eq_result = self . temp ( bool_ty, source_info. span ) ;
474486 let eq_block = self . cfg . start_new_block ( ) ;
0 commit comments