4
4
//! types or regions but can be other things. Examples of type relations are
5
5
//! subtyping, type equality, etc.
6
6
7
- use crate :: mir:: interpret:: { get_slice_bytes, ConstValue } ;
7
+ use crate :: mir:: interpret:: { get_slice_bytes, ConstValue , GlobalAlloc , Scalar } ;
8
8
use crate :: ty:: error:: { ExpectedFound , TypeError } ;
9
9
use crate :: ty:: subst:: { GenericArg , GenericArgKind , SubstsRef } ;
10
10
use crate :: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
11
11
use rustc_hir as ast;
12
12
use rustc_hir:: def_id:: DefId ;
13
- use rustc_span:: DUMMY_SP ;
14
13
use rustc_target:: spec:: abi;
15
14
use std:: iter;
16
15
@@ -513,93 +512,71 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
513
512
// Currently, the values that can be unified are primitive types,
514
513
// and those that derive both `PartialEq` and `Eq`, corresponding
515
514
// to structural-match types.
516
- match ( a. val , b. val ) {
515
+ let is_match = match ( a. val , b. val ) {
517
516
( ty:: ConstKind :: Infer ( _) , _) | ( _, ty:: ConstKind :: Infer ( _) ) => {
518
517
// The caller should handle these cases!
519
518
bug ! ( "var types encountered in super_relate_consts: {:?} {:?}" , a, b)
520
519
}
521
520
522
- ( ty:: ConstKind :: Error ( _) , _) => Ok ( a) ,
523
- ( _, ty:: ConstKind :: Error ( _) ) => Ok ( b) ,
521
+ ( ty:: ConstKind :: Error ( _) , _) => return Ok ( a) ,
522
+ ( _, ty:: ConstKind :: Error ( _) ) => return Ok ( b) ,
524
523
525
- ( ty:: ConstKind :: Param ( a_p) , ty:: ConstKind :: Param ( b_p) ) if a_p. index == b_p. index => {
526
- return Ok ( a) ;
527
- }
528
- ( ty:: ConstKind :: Placeholder ( p1) , ty:: ConstKind :: Placeholder ( p2) ) if p1 == p2 => {
529
- return Ok ( a) ;
530
- }
524
+ ( ty:: ConstKind :: Param ( a_p) , ty:: ConstKind :: Param ( b_p) ) => a_p. index == b_p. index ,
525
+ ( ty:: ConstKind :: Placeholder ( p1) , ty:: ConstKind :: Placeholder ( p2) ) => p1 == p2,
531
526
( ty:: ConstKind :: Value ( a_val) , ty:: ConstKind :: Value ( b_val) ) => {
532
527
match ( a_val, b_val) {
533
- ( ConstValue :: Scalar ( a_val) , ConstValue :: Scalar ( b_val) ) => {
534
- if a_val == b_val {
535
- Ok ( a)
536
- } else if let ty:: FnPtr ( _) = a. ty . kind ( ) {
537
- let a_instance = tcx. global_alloc ( a_val. assert_ptr ( ) . alloc_id ) . unwrap_fn ( ) ;
538
- let b_instance = tcx. global_alloc ( b_val. assert_ptr ( ) . alloc_id ) . unwrap_fn ( ) ;
539
- if a_instance == b_instance {
540
- Ok ( a)
541
- } else {
542
- Err ( TypeError :: ConstMismatch ( expected_found ( relation, a, b) ) )
528
+ (
529
+ ConstValue :: Scalar ( Scalar :: Int ( a_val) ) ,
530
+ ConstValue :: Scalar ( Scalar :: Int ( b_val) ) ,
531
+ ) => a_val == b_val,
532
+ (
533
+ ConstValue :: Scalar ( Scalar :: Ptr ( a_val) ) ,
534
+ ConstValue :: Scalar ( Scalar :: Ptr ( b_val) ) ,
535
+ ) => {
536
+ a_val == b_val
537
+ || match (
538
+ tcx. global_alloc ( a_val. alloc_id ) ,
539
+ tcx. global_alloc ( b_val. alloc_id ) ,
540
+ ) {
541
+ (
542
+ GlobalAlloc :: Function ( a_instance) ,
543
+ GlobalAlloc :: Function ( b_instance) ,
544
+ ) => a_instance == b_instance,
545
+ _ => false ,
543
546
}
544
- } else {
545
- Err ( TypeError :: ConstMismatch ( expected_found ( relation, a, b) ) )
546
- }
547
547
}
548
548
549
549
( ConstValue :: Slice { .. } , ConstValue :: Slice { .. } ) => {
550
- let a_bytes = get_slice_bytes ( & tcx, a_val) ;
551
- let b_bytes = get_slice_bytes ( & tcx, b_val) ;
552
- if a_bytes == b_bytes {
553
- Ok ( a)
554
- } else {
555
- Err ( TypeError :: ConstMismatch ( expected_found ( relation, a, b) ) )
556
- }
550
+ get_slice_bytes ( & tcx, a_val) == get_slice_bytes ( & tcx, b_val)
557
551
}
558
552
559
553
( ConstValue :: ByRef { .. } , ConstValue :: ByRef { .. } ) => {
560
- match a. ty . kind ( ) {
561
- ty:: Array ( ..) | ty:: Adt ( ..) | ty:: Tuple ( ..) => {
562
- let a_destructured = tcx. destructure_const ( relation. param_env ( ) . and ( a) ) ;
563
- let b_destructured = tcx. destructure_const ( relation. param_env ( ) . and ( b) ) ;
564
-
565
- // Both the variant and each field have to be equal.
566
- if a_destructured. variant == b_destructured. variant {
567
- for ( a_field, b_field) in
568
- a_destructured. fields . iter ( ) . zip ( b_destructured. fields . iter ( ) )
569
- {
570
- relation. consts ( a_field, b_field) ?;
571
- }
572
-
573
- Ok ( a)
574
- } else {
575
- Err ( TypeError :: ConstMismatch ( expected_found ( relation, a, b) ) )
576
- }
577
- }
578
- // FIXME(const_generics): There are probably some `TyKind`s
579
- // which should be handled here.
580
- _ => {
581
- tcx. sess . delay_span_bug (
582
- DUMMY_SP ,
583
- & format ! ( "unexpected consts: a: {:?}, b: {:?}" , a, b) ,
584
- ) ;
585
- Err ( TypeError :: ConstMismatch ( expected_found ( relation, a, b) ) )
554
+ let a_destructured = tcx. destructure_const ( relation. param_env ( ) . and ( a) ) ;
555
+ let b_destructured = tcx. destructure_const ( relation. param_env ( ) . and ( b) ) ;
556
+
557
+ // Both the variant and each field have to be equal.
558
+ if a_destructured. variant == b_destructured. variant {
559
+ for ( a_field, b_field) in
560
+ a_destructured. fields . iter ( ) . zip ( b_destructured. fields . iter ( ) )
561
+ {
562
+ relation. consts ( a_field, b_field) ?;
586
563
}
564
+
565
+ true
566
+ } else {
567
+ false
587
568
}
588
569
}
589
570
590
- _ => Err ( TypeError :: ConstMismatch ( expected_found ( relation , a , b ) ) ) ,
571
+ _ => false ,
591
572
}
592
573
}
593
574
594
575
(
595
576
ty:: ConstKind :: Unevaluated ( a_def, a_substs, None ) ,
596
577
ty:: ConstKind :: Unevaluated ( b_def, b_substs, None ) ,
597
578
) if tcx. features ( ) . const_evaluatable_checked && !relation. visit_ct_substs ( ) => {
598
- if tcx. try_unify_abstract_consts ( ( ( a_def, a_substs) , ( b_def, b_substs) ) ) {
599
- Ok ( a)
600
- } else {
601
- Err ( TypeError :: ConstMismatch ( expected_found ( relation, a, b) ) )
602
- }
579
+ tcx. try_unify_abstract_consts ( ( ( a_def, a_substs) , ( b_def, b_substs) ) )
603
580
}
604
581
605
582
// While this is slightly incorrect, it shouldn't matter for `min_const_generics`
@@ -611,13 +588,14 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
611
588
) if a_def == b_def && a_promoted == b_promoted => {
612
589
let substs =
613
590
relation. relate_with_variance ( ty:: Variance :: Invariant , a_substs, b_substs) ?;
614
- Ok ( tcx. mk_const ( ty:: Const {
591
+ return Ok ( tcx. mk_const ( ty:: Const {
615
592
val : ty:: ConstKind :: Unevaluated ( a_def, substs, a_promoted) ,
616
593
ty : a. ty ,
617
- } ) )
594
+ } ) ) ;
618
595
}
619
- _ => Err ( TypeError :: ConstMismatch ( expected_found ( relation, a, b) ) ) ,
620
- }
596
+ _ => false ,
597
+ } ;
598
+ if is_match { Ok ( a) } else { Err ( TypeError :: ConstMismatch ( expected_found ( relation, a, b) ) ) }
621
599
}
622
600
623
601
impl < ' tcx > Relate < ' tcx > for & ' tcx ty:: List < ty:: Binder < ty:: ExistentialPredicate < ' tcx > > > {
0 commit comments