1
1
use super :: { ConstEvalResult , ErrorHandled , GlobalId } ;
2
2
3
+ use crate :: infer:: canonical:: { Canonical , OriginalQueryValues } ;
4
+ use crate :: infer:: InferCtxt ;
3
5
use crate :: mir;
4
6
use crate :: ty:: subst:: { InternalSubsts , SubstsRef } ;
5
7
use crate :: ty:: { self , TyCtxt } ;
@@ -19,7 +21,7 @@ impl<'tcx> TyCtxt<'tcx> {
19
21
let instance = ty:: Instance :: new ( def_id, substs) ;
20
22
let cid = GlobalId { instance, promoted : None } ;
21
23
let param_env = self . param_env ( def_id) . with_reveal_all ( ) ;
22
- self . const_eval_validated ( param_env. and ( cid) )
24
+ self . const_eval_validated ( Canonical :: empty ( param_env. and ( cid) ) )
23
25
}
24
26
25
27
/// Resolves and evaluates a constant.
@@ -38,25 +40,23 @@ impl<'tcx> TyCtxt<'tcx> {
38
40
substs : SubstsRef < ' tcx > ,
39
41
span : Option < Span > ,
40
42
) -> ConstEvalResult < ' tcx > {
41
- let instance = ty:: Instance :: resolve ( self , param_env, def_id, substs) ;
42
- if let Some ( instance) = instance {
43
- self . const_eval_instance ( param_env, instance, span)
44
- } else {
45
- Err ( ErrorHandled :: TooGeneric )
46
- }
43
+ self . infer_ctxt ( )
44
+ . enter ( |ref infcx| infcx. const_eval_resolve ( param_env, def_id, substs, span) )
47
45
}
48
46
47
+ /// Evaluates the constant represented by the instance.
49
48
pub fn const_eval_instance (
50
49
self ,
51
50
param_env : ty:: ParamEnv < ' tcx > ,
52
51
instance : ty:: Instance < ' tcx > ,
53
52
span : Option < Span > ,
54
53
) -> ConstEvalResult < ' tcx > {
55
54
let cid = GlobalId { instance, promoted : None } ;
55
+ let canonical = Canonical :: empty ( param_env. and ( cid) ) ;
56
56
if let Some ( span) = span {
57
- self . at ( span) . const_eval_validated ( param_env . and ( cid ) )
57
+ self . at ( span) . const_eval_validated ( canonical )
58
58
} else {
59
- self . const_eval_validated ( param_env . and ( cid ) )
59
+ self . const_eval_validated ( canonical )
60
60
}
61
61
}
62
62
@@ -68,6 +68,55 @@ impl<'tcx> TyCtxt<'tcx> {
68
68
) -> ConstEvalResult < ' tcx > {
69
69
let cid = GlobalId { instance, promoted : Some ( promoted) } ;
70
70
let param_env = ty:: ParamEnv :: reveal_all ( ) ;
71
- self . const_eval_validated ( param_env. and ( cid) )
71
+ self . const_eval_validated ( Canonical :: empty ( param_env. and ( cid) ) )
72
+ }
73
+ }
74
+
75
+ impl < ' a , ' tcx > InferCtxt < ' a , ' tcx > {
76
+ /// Evaluates the constant represented by the instance.
77
+ ///
78
+ /// The given `ParamEnv` and `Instance` can contain inference variables from this inference
79
+ /// context.
80
+ pub fn const_eval_instance (
81
+ & self ,
82
+ param_env : ty:: ParamEnv < ' tcx > ,
83
+ instance : ty:: Instance < ' tcx > ,
84
+ span : Option < Span > ,
85
+ ) -> ConstEvalResult < ' tcx > {
86
+ let cid = GlobalId { instance, promoted : None } ;
87
+ let mut orig_values = OriginalQueryValues :: default ( ) ;
88
+ let canonical = self . canonicalize_query ( & param_env. and ( cid) , & mut orig_values) ;
89
+ if let Some ( span) = span {
90
+ self . tcx . at ( span) . const_eval_validated ( canonical)
91
+ } else {
92
+ self . tcx . const_eval_validated ( canonical)
93
+ }
94
+ }
95
+
96
+ /// Resolves and evaluates a constant.
97
+ ///
98
+ /// The constant can be located on a trait like `<A as B>::C`, in which case the given
99
+ /// substitutions and environment are used to resolve the constant. Alternatively if the
100
+ /// constant has generic parameters in scope the substitutions are used to evaluate the value of
101
+ /// the constant. For example in `fn foo<T>() { let _ = [0; bar::<T>()]; }` the repeat count
102
+ /// constant `bar::<T>()` requires a substitution for `T`, if the substitution for `T` is still
103
+ /// too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is
104
+ /// returned.
105
+ ///
106
+ /// The given `ParamEnv` and `substs` can contain inference variables from this inference
107
+ /// context.
108
+ pub fn const_eval_resolve (
109
+ & self ,
110
+ param_env : ty:: ParamEnv < ' tcx > ,
111
+ def_id : DefId ,
112
+ substs : SubstsRef < ' tcx > ,
113
+ span : Option < Span > ,
114
+ ) -> ConstEvalResult < ' tcx > {
115
+ let instance = ty:: Instance :: resolve ( self , param_env, def_id, substs) ;
116
+ if let Some ( instance) = instance {
117
+ self . const_eval_instance ( param_env, instance, span)
118
+ } else {
119
+ Err ( ErrorHandled :: TooGeneric )
120
+ }
72
121
}
73
122
}
0 commit comments