@@ -30,24 +30,24 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
3030 span : Span ,
3131) -> Result < ( ) , ErrorHandled > {
3232 debug ! ( "is_const_evaluatable({:?}, {:?})" , def, substs) ;
33- if infcx . tcx . features ( ) . const_evaluatable_checked {
34- if let Some ( ct ) = AbstractConst :: new ( infcx . tcx , def , substs ) {
35- for pred in param_env . caller_bounds ( ) {
36- match pred . skip_binders ( ) {
37- ty :: PredicateAtom :: ConstEvaluatable ( b_def , b_substs ) => {
38- debug ! ( "is_const_evaluatable: caller_bound={:?}, {:?}" , b_def, b_substs) ;
39- if b_def == def && b_substs == substs {
40- debug ! ( "is_const_evaluatable: caller_bound ~~> ok" ) ;
41- return Ok ( ( ) ) ;
42- } else if AbstractConst :: new ( infcx . tcx , b_def , b_substs )
43- . map_or ( false , |b_ct| try_unify ( infcx. tcx , ct , b_ct ) )
44- {
45- debug ! ( "is_const_evaluatable: abstract_const ~~> ok" ) ;
46- return Ok ( ( ) ) ;
47- }
33+ // `AbstractConst::new` already returns `None` if ` const_evaluatable_checked`
34+ // is not active, so we don't have to explicitly check for this here.
35+ if let Some ( ct ) = AbstractConst :: new ( infcx . tcx , def , substs ) {
36+ for pred in param_env . caller_bounds ( ) {
37+ match pred . skip_binders ( ) {
38+ ty :: PredicateAtom :: ConstEvaluatable ( b_def, b_substs) => {
39+ debug ! ( "is_const_evaluatable: caller_bound={:?}, {:?}" , b_def, b_substs) ;
40+ if b_def == def && b_substs == substs {
41+ debug ! ( "is_const_evaluatable: caller_bound ~~> ok" ) ;
42+ return Ok ( ( ) ) ;
43+ } else if AbstractConst :: new ( infcx. tcx , b_def , b_substs )
44+ . map_or ( false , |b_ct| try_unify ( infcx . tcx , ct , b_ct ) )
45+ {
46+ debug ! ( "is_const_evaluatable: abstract_const ~~> ok" ) ;
47+ return Ok ( ( ) ) ;
4848 }
49- _ => { } // don't care
5049 }
50+ _ => { } // don't care
5151 }
5252 }
5353 }
@@ -394,14 +394,17 @@ pub(super) fn try_unify<'tcx>(
394394 let a_ct = a_ct. subst ( tcx, a. substs ) ;
395395 let b_ct = b_ct. subst ( tcx, b. substs ) ;
396396 match ( a_ct. val , b_ct. val ) {
397+ // We can just unify errors with everything to reduce the amount of
398+ // emitted errors here.
399+ ( ty:: ConstKind :: Error ( _) , _) | ( _, ty:: ConstKind :: Error ( _) ) => true ,
397400 ( ty:: ConstKind :: Param ( a_param) , ty:: ConstKind :: Param ( b_param) ) => {
398401 a_param == b_param
399402 }
400403 ( ty:: ConstKind :: Value ( a_val) , ty:: ConstKind :: Value ( b_val) ) => a_val == b_val,
401404 // If we have `fn a<const N: usize>() -> [u8; N + 1]` and `fn b<const M: usize>() -> [u8; 1 + M]`
402405 // we do not want to use `assert_eq!(a(), b())` to infer that `N` and `M` have to be `1`. This
403- // means that we can't do anything with inference variables here .
404- ( ty:: ConstKind :: Infer ( _ ) , _ ) | ( _ , ty:: ConstKind :: Infer ( _ ) ) => false ,
406+ // means that we only allow inference variables if they are equal .
407+ ( ty:: ConstKind :: Infer ( a_val ) , ty:: ConstKind :: Infer ( b_val ) ) => a_val == b_val ,
405408 // FIXME(const_evaluatable_checked): We may want to either actually try
406409 // to evaluate `a_ct` and `b_ct` if they are are fully concrete or something like
407410 // this, for now we just return false here.
0 commit comments