@@ -5,6 +5,7 @@ use rustc_middle::mir::*;
55use rustc_middle:: span_bug;
66use rustc_middle:: thir:: * ;
77use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeVisitableExt } ;
8+ use rustc_span:: sym;
89
910use crate :: builder:: Builder ;
1011use crate :: builder:: expr:: as_place:: { PlaceBase , PlaceBuilder } ;
@@ -40,6 +41,19 @@ fn try_reconstruct_aggregate_constant<'tcx>(
4041}
4142
4243impl < ' a , ' tcx > Builder < ' a , ' tcx > {
44+ /// Check if we can use aggregate `PartialEq::eq` comparisons for constant array/slice patterns.
45+ /// This is not possible in const contexts unless `#![feature(const_cmp, const_trait_impl)]` are enabled,
46+ /// because`PartialEq` is not const-stable.
47+ fn can_use_aggregate_eq ( & self ) -> bool {
48+ let const_partial_eq_enabled = {
49+ let features = self . tcx . features ( ) ;
50+ features. enabled ( sym:: const_trait_impl) && features. enabled ( sym:: const_cmp)
51+ } ;
52+ let in_const_context = self . tcx . is_const_fn ( self . def_id . to_def_id ( ) )
53+ || !self . tcx . hir_body_owner_kind ( self . def_id ) . is_fn_or_closure ( ) ;
54+ !in_const_context || const_partial_eq_enabled
55+ }
56+
4357 /// Builds and pushes [`MatchPairTree`] subtrees, one for each pattern in
4458 /// `subpatterns`, representing the fields of a [`PatKind::Variant`] or
4559 /// [`PatKind::Leaf`].
@@ -271,6 +285,7 @@ impl<'tcx> MatchPairTree<'tcx> {
271285 // `PartialEq::eq` rather than element by element.
272286 if slice. is_none ( )
273287 && suffix. is_empty ( )
288+ && cx. can_use_aggregate_eq ( )
274289 && let Some ( aggregate_value) =
275290 try_reconstruct_aggregate_constant ( cx. tcx , pattern. ty , prefix)
276291 {
@@ -310,6 +325,7 @@ impl<'tcx> MatchPairTree<'tcx> {
310325 // is performed after the length check.
311326 if slice. is_none ( )
312327 && suffix. is_empty ( )
328+ && cx. can_use_aggregate_eq ( )
313329 && let Some ( aggregate_value) =
314330 try_reconstruct_aggregate_constant ( cx. tcx , pattern. ty , prefix)
315331 {
0 commit comments