@@ -583,6 +583,70 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
583
583
}
584
584
}
585
585
586
+ /// The main "const relation" routine. Note that this does not handle
587
+ /// inference artifacts, so you should filter those out before calling
588
+ /// it.
589
+ pub fn super_relate_consts < ' a , ' gcx , ' tcx , R > (
590
+ relation : & mut R ,
591
+ a : & ' tcx ty:: LazyConst < ' tcx > ,
592
+ b : & ' tcx ty:: LazyConst < ' tcx >
593
+ ) -> RelateResult < ' tcx , & ' tcx ty:: LazyConst < ' tcx > >
594
+ where
595
+ R : TypeRelation < ' a , ' gcx , ' tcx > , ' gcx : ' a +' tcx , ' tcx : ' a
596
+ {
597
+ let tcx = relation. tcx ( ) ;
598
+
599
+ match ( a, b) {
600
+ ( ty:: LazyConst :: Evaluated ( a_eval) , ty:: LazyConst :: Evaluated ( b_eval) ) => {
601
+ // Only consts whose types are equal should be compared.
602
+ assert_eq ! ( a_eval. ty, b_eval. ty) ;
603
+
604
+ // Currently, the values that can be unified are those that
605
+ // implement both `PartialEq` and `Eq`, corresponding to
606
+ // `structural_match` types.
607
+ // FIXME(const_generics): check for `structural_match` synthetic attribute.
608
+ match ( a_eval. val , b_eval. val ) {
609
+ ( ConstValue :: Infer ( _) , _) | ( _, ConstValue :: Infer ( _) ) => {
610
+ // The caller should handle these cases!
611
+ bug ! ( "var types encountered in super_relate_consts: {:?} {:?}" , a, b)
612
+ }
613
+ ( ConstValue :: Param ( a_p) , ConstValue :: Param ( b_p) ) if a_p. index == b_p. index => {
614
+ Ok ( a)
615
+ }
616
+ ( ConstValue :: Scalar ( Scalar :: Bits { .. } ) , _) if a == b => {
617
+ Ok ( a)
618
+ }
619
+ ( ConstValue :: ByRef ( ..) , _) => {
620
+ bug ! (
621
+ "non-Scalar ConstValue encountered in super_relate_consts {:?} {:?}" ,
622
+ a,
623
+ b,
624
+ ) ;
625
+ }
626
+ _ => {
627
+ Err ( TypeError :: ConstError (
628
+ ConstError :: Mismatch ( expected_found ( relation, & a, & b) )
629
+ ) )
630
+ }
631
+ }
632
+ }
633
+ // FIXME(const_generics): this is probably wrong (regarding TyProjection)
634
+ (
635
+ ty:: LazyConst :: Unevaluated ( a_def_id, a_substs) ,
636
+ ty:: LazyConst :: Unevaluated ( b_def_id, b_substs) ,
637
+ ) if a_def_id == b_def_id => {
638
+ let substs =
639
+ relation. relate_with_variance ( ty:: Variance :: Invariant , a_substs, b_substs) ?;
640
+ Ok ( tcx. mk_lazy_const ( ty:: LazyConst :: Unevaluated ( * a_def_id, substs) ) )
641
+ }
642
+ _ => {
643
+ Err ( TypeError :: ConstError (
644
+ ConstError :: Mismatch ( expected_found ( relation, & a, & b) )
645
+ ) )
646
+ }
647
+ }
648
+ }
649
+
586
650
impl < ' tcx > Relate < ' tcx > for & ' tcx ty:: List < ty:: ExistentialPredicate < ' tcx > > {
587
651
fn relate < ' a , ' gcx , R > ( relation : & mut R ,
588
652
a : & Self ,
0 commit comments