@@ -30,24 +30,24 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
30
30
span : Span ,
31
31
) -> Result < ( ) , ErrorHandled > {
32
32
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 ( ( ) ) ;
48
48
}
49
- _ => { } // don't care
50
49
}
50
+ _ => { } // don't care
51
51
}
52
52
}
53
53
}
@@ -394,14 +394,17 @@ pub(super) fn try_unify<'tcx>(
394
394
let a_ct = a_ct. subst ( tcx, a. substs ) ;
395
395
let b_ct = b_ct. subst ( tcx, b. substs ) ;
396
396
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 ,
397
400
( ty:: ConstKind :: Param ( a_param) , ty:: ConstKind :: Param ( b_param) ) => {
398
401
a_param == b_param
399
402
}
400
403
( ty:: ConstKind :: Value ( a_val) , ty:: ConstKind :: Value ( b_val) ) => a_val == b_val,
401
404
// If we have `fn a<const N: usize>() -> [u8; N + 1]` and `fn b<const M: usize>() -> [u8; 1 + M]`
402
405
// 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 ,
405
408
// FIXME(const_evaluatable_checked): We may want to either actually try
406
409
// to evaluate `a_ct` and `b_ct` if they are are fully concrete or something like
407
410
// this, for now we just return false here.
0 commit comments