44//! types or regions but can be other things. Examples of type relations are
55//! subtyping, type equality, etc.
66
7- use crate :: mir:: interpret:: { get_slice_bytes, ConstValue } ;
7+ use crate :: mir:: interpret:: { get_slice_bytes, ConstValue , GlobalAlloc , Scalar } ;
88use crate :: ty:: error:: { ExpectedFound , TypeError } ;
99use crate :: ty:: subst:: { GenericArg , GenericArgKind , SubstsRef } ;
1010use crate :: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
1111use rustc_hir as ast;
1212use rustc_hir:: def_id:: DefId ;
13- use rustc_span:: DUMMY_SP ;
1413use rustc_target:: spec:: abi;
1514use std:: iter;
1615
@@ -513,93 +512,71 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
513512 // Currently, the values that can be unified are primitive types,
514513 // and those that derive both `PartialEq` and `Eq`, corresponding
515514 // to structural-match types.
516- match ( a. val , b. val ) {
515+ let is_match = match ( a. val , b. val ) {
517516 ( ty:: ConstKind :: Infer ( _) , _) | ( _, ty:: ConstKind :: Infer ( _) ) => {
518517 // The caller should handle these cases!
519518 bug ! ( "var types encountered in super_relate_consts: {:?} {:?}" , a, b)
520519 }
521520
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) ,
524523
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,
531526 ( ty:: ConstKind :: Value ( a_val) , ty:: ConstKind :: Value ( b_val) ) => {
532527 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 ,
543546 }
544- } else {
545- Err ( TypeError :: ConstMismatch ( expected_found ( relation, a, b) ) )
546- }
547547 }
548548
549549 ( 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)
557551 }
558552
559553 ( 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) ?;
586563 }
564+
565+ true
566+ } else {
567+ false
587568 }
588569 }
589570
590- _ => Err ( TypeError :: ConstMismatch ( expected_found ( relation , a , b ) ) ) ,
571+ _ => false ,
591572 }
592573 }
593574
594575 (
595576 ty:: ConstKind :: Unevaluated ( a_def, a_substs, None ) ,
596577 ty:: ConstKind :: Unevaluated ( b_def, b_substs, None ) ,
597578 ) 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) ) )
603580 }
604581
605582 // 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>>(
611588 ) if a_def == b_def && a_promoted == b_promoted => {
612589 let substs =
613590 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 {
615592 val : ty:: ConstKind :: Unevaluated ( a_def, substs, a_promoted) ,
616593 ty : a. ty ,
617- } ) )
594+ } ) ) ;
618595 }
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) ) ) }
621599}
622600
623601impl < ' tcx > Relate < ' tcx > for & ' tcx ty:: List < ty:: Binder < ty:: ExistentialPredicate < ' tcx > > > {
0 commit comments