@@ -8,7 +8,7 @@ use crate::hir::def_id::DefId;
8
8
use crate :: ty:: subst:: { GenericArg , GenericArgKind , SubstsRef } ;
9
9
use crate :: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
10
10
use crate :: ty:: error:: { ExpectedFound , TypeError } ;
11
- use crate :: mir:: interpret:: { ConstValue , get_slice_bytes, Scalar } ;
11
+ use crate :: mir:: interpret:: { ConstValue , get_slice_bytes, Scalar , GlobalAlloc } ;
12
12
use std:: rc:: Rc ;
13
13
use std:: iter;
14
14
use rustc_target:: spec:: abi;
@@ -561,37 +561,47 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
561
561
// implement both `PartialEq` and `Eq`, corresponding to
562
562
// `structural_match` types.
563
563
// FIXME(const_generics): check for `structural_match` synthetic attribute.
564
- match ( eagerly_eval ( a) , eagerly_eval ( b) ) {
564
+ let new_const_val = match ( eagerly_eval ( a) , eagerly_eval ( b) ) {
565
565
( ConstValue :: Infer ( _) , _) | ( _, ConstValue :: Infer ( _) ) => {
566
566
// The caller should handle these cases!
567
567
bug ! ( "var types encountered in super_relate_consts: {:?} {:?}" , a, b)
568
568
}
569
569
( ConstValue :: Param ( a_p) , ConstValue :: Param ( b_p) ) if a_p. index == b_p. index => {
570
- Ok ( a)
570
+ return Ok ( a) ;
571
571
}
572
572
( ConstValue :: Placeholder ( p1) , ConstValue :: Placeholder ( p2) ) if p1 == p2 => {
573
- Ok ( a)
573
+ return Ok ( a) ;
574
574
}
575
- ( a_val @ ConstValue :: Scalar ( Scalar :: Raw { .. } ) , b_val @ _)
576
- if a. ty == b. ty && a_val == b_val =>
577
- {
578
- Ok ( tcx. mk_const ( ty:: Const {
579
- val : a_val,
580
- ty : a. ty ,
581
- } ) )
575
+ ( ConstValue :: Scalar ( a_val) , ConstValue :: Scalar ( b_val) ) if a. ty == b. ty => {
576
+ if a_val == b_val {
577
+ Ok ( ConstValue :: Scalar ( a_val) )
578
+ } else if let ty:: FnPtr ( _) = a. ty . kind {
579
+ let alloc_map = tcx. alloc_map . lock ( ) ;
580
+ let get_fn_instance = |val : Scalar | {
581
+ let ptr = val. to_ptr ( ) . unwrap ( ) ;
582
+ if let Some ( GlobalAlloc :: Function ( instance) ) = alloc_map. get ( ptr. alloc_id ) {
583
+ instance
584
+ } else {
585
+ bug ! ( "Allocation for FnPtr isn't a function" ) ;
586
+ }
587
+ } ;
588
+ let a_instance = get_fn_instance ( a_val) ;
589
+ let b_instance = get_fn_instance ( b_val) ;
590
+ if a_instance == b_instance {
591
+ Ok ( ConstValue :: Scalar ( a_val) )
592
+ } else {
593
+ Err ( TypeError :: ConstMismatch ( expected_found ( relation, & a, & b) ) )
594
+ }
595
+ } else {
596
+ Err ( TypeError :: ConstMismatch ( expected_found ( relation, & a, & b) ) )
597
+ }
582
598
}
583
599
584
- // FIXME(const_generics): we should either handle `Scalar::Ptr` or add a comment
585
- // saying that we're not handling it intentionally.
586
-
587
600
( a_val @ ConstValue :: Slice { .. } , b_val @ ConstValue :: Slice { .. } ) => {
588
601
let a_bytes = get_slice_bytes ( & tcx, a_val) ;
589
602
let b_bytes = get_slice_bytes ( & tcx, b_val) ;
590
603
if a_bytes == b_bytes {
591
- Ok ( tcx. mk_const ( ty:: Const {
592
- val : a_val,
593
- ty : a. ty ,
594
- } ) )
604
+ Ok ( a_val)
595
605
} else {
596
606
Err ( TypeError :: ConstMismatch ( expected_found ( relation, & a, & b) ) )
597
607
}
@@ -602,16 +612,16 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
602
612
// FIXME(const_generics): this is wrong, as it is a projection
603
613
( ConstValue :: Unevaluated ( a_def_id, a_substs) ,
604
614
ConstValue :: Unevaluated ( b_def_id, b_substs) ) if a_def_id == b_def_id => {
605
- let substs =
606
- relation. relate_with_variance ( ty:: Variance :: Invariant , & a_substs, & b_substs) ?;
607
- Ok ( tcx . mk_const ( ty :: Const {
608
- val : ConstValue :: Unevaluated ( a_def_id , & substs ) ,
609
- ty : a . ty ,
610
- } ) )
611
- }
612
-
613
- _ => Err ( TypeError :: ConstMismatch ( expected_found ( relation , & a , & b ) ) ) ,
614
- }
615
+ let substs =
616
+ relation. relate_with_variance ( ty:: Variance :: Invariant , & a_substs, & b_substs) ?;
617
+ Ok ( ConstValue :: Unevaluated ( a_def_id , & substs ) )
618
+ }
619
+ _ => Err ( TypeError :: ConstMismatch ( expected_found ( relation , & a , & b ) ) ) ,
620
+ } ;
621
+ new_const_val . map ( |val| tcx . mk_const ( ty :: Const {
622
+ val ,
623
+ ty : a . ty ,
624
+ } ) )
615
625
}
616
626
617
627
impl < ' tcx > Relate < ' tcx > for & ' tcx ty:: List < ty:: ExistentialPredicate < ' tcx > > {
0 commit comments