@@ -3,7 +3,7 @@ use rustc_hir::def_id::DefId;
3
3
use rustc_index:: Idx ;
4
4
use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
5
5
use rustc_infer:: traits:: Obligation ;
6
- use rustc_middle:: mir;
6
+ use rustc_middle:: mir:: { self , ConstValue } ;
7
7
use rustc_middle:: thir:: { FieldPat , Pat , PatKind } ;
8
8
use rustc_middle:: ty:: { self , Ty , TyCtxt , ValTree } ;
9
9
use rustc_session:: lint;
@@ -198,7 +198,7 @@ impl<'tcx> ConstToPat<'tcx> {
198
198
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
199
199
let kind = PatKind :: Error ( e) ;
200
200
return Box :: new ( Pat { span : self . span , ty : cv. ty ( ) , kind } ) ;
201
- } else if let ty:: Adt ( ..) = cv. ty ( ) . kind ( ) && matches ! ( cv , mir:: Const :: Val ( .. ) ) {
201
+ } else if let ty:: Adt ( ..) = cv. ty ( ) . kind ( ) && let mir:: Const :: Val ( const_val , const_ty ) = cv && self . is_ty_included_by_const_val ( const_val , const_ty , non_sm_ty ) {
202
202
// This branch is only entered when the current `cv` is `mir::Const::Val`.
203
203
// This is because `mir::Const::ty` has already been handled by `Self::recur`
204
204
// and the invalid types may be ignored.
@@ -266,6 +266,34 @@ impl<'tcx> ConstToPat<'tcx> {
266
266
inlined_const_as_pat
267
267
}
268
268
269
+ // Check if `child` is included within the const value.
270
+ fn is_ty_included_by_const_val (
271
+ & self ,
272
+ const_val : ConstValue < ' tcx > ,
273
+ parent : Ty < ' tcx > ,
274
+ child : Ty < ' tcx > ,
275
+ ) -> bool {
276
+ if parent == self . tcx ( ) . normalize_erasing_regions ( self . param_env , child) {
277
+ return true ;
278
+ }
279
+ match parent. kind ( ) {
280
+ ty:: Adt ( ..) | ty:: Tuple ( _) | ty:: Array ( ..) => {
281
+ let destructured = self
282
+ . tcx ( )
283
+ . try_destructure_mir_constant_for_user_output (
284
+ const_val,
285
+ self . tcx ( ) . normalize_erasing_regions ( self . param_env , parent) ,
286
+ )
287
+ . unwrap ( ) ;
288
+ destructured
289
+ . fields
290
+ . iter ( )
291
+ . any ( |field| self . is_ty_included_by_const_val ( field. 0 , field. 1 , child) )
292
+ }
293
+ _ => false ,
294
+ }
295
+ }
296
+
269
297
#[ instrument( level = "trace" , skip( self ) , ret) ]
270
298
fn type_has_partial_eq_impl ( & self , ty : Ty < ' tcx > ) -> bool {
271
299
// double-check there even *is* a semantic `PartialEq` to dispatch to.
0 commit comments