@@ -8,7 +8,7 @@ use crate::hir::def_id::DefId;
88use crate :: ty:: subst:: { GenericArg , GenericArgKind , SubstsRef } ;
99use crate :: ty:: { self , Ty , TyCtxt , TypeFoldable } ;
1010use 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 } ;
1212use std:: rc:: Rc ;
1313use std:: iter;
1414use rustc_target:: spec:: abi;
@@ -561,37 +561,47 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
561561 // implement both `PartialEq` and `Eq`, corresponding to
562562 // `structural_match` types.
563563 // 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) ) {
565565 ( ConstValue :: Infer ( _) , _) | ( _, ConstValue :: Infer ( _) ) => {
566566 // The caller should handle these cases!
567567 bug ! ( "var types encountered in super_relate_consts: {:?} {:?}" , a, b)
568568 }
569569 ( ConstValue :: Param ( a_p) , ConstValue :: Param ( b_p) ) if a_p. index == b_p. index => {
570- Ok ( a)
570+ return Ok ( a) ;
571571 }
572572 ( ConstValue :: Placeholder ( p1) , ConstValue :: Placeholder ( p2) ) if p1 == p2 => {
573- Ok ( a)
573+ return Ok ( a) ;
574574 }
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+ }
582598 }
583599
584- // FIXME(const_generics): we should either handle `Scalar::Ptr` or add a comment
585- // saying that we're not handling it intentionally.
586-
587600 ( a_val @ ConstValue :: Slice { .. } , b_val @ ConstValue :: Slice { .. } ) => {
588601 let a_bytes = get_slice_bytes ( & tcx, a_val) ;
589602 let b_bytes = get_slice_bytes ( & tcx, b_val) ;
590603 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)
595605 } else {
596606 Err ( TypeError :: ConstMismatch ( expected_found ( relation, & a, & b) ) )
597607 }
@@ -602,16 +612,16 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
602612 // FIXME(const_generics): this is wrong, as it is a projection
603613 ( ConstValue :: Unevaluated ( a_def_id, a_substs) ,
604614 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+ } ) )
615625}
616626
617627impl < ' tcx > Relate < ' tcx > for & ' tcx ty:: List < ty:: ExistentialPredicate < ' tcx > > {
0 commit comments