@@ -15,6 +15,8 @@ use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToTy
15
15
use rustc:: middle:: free_region:: RegionRelations ;
16
16
use rustc:: middle:: lang_items;
17
17
use rustc:: middle:: region;
18
+ use rustc:: mir;
19
+ use rustc:: mir:: interpret:: ConstEvalResult ;
18
20
use rustc:: session:: config:: BorrowckMode ;
19
21
use rustc:: ty:: error:: { ExpectedFound , TypeError , UnconstrainedNumeric } ;
20
22
use rustc:: ty:: fold:: { TypeFoldable , TypeFolder } ;
@@ -63,6 +65,7 @@ pub mod resolve;
63
65
mod sub;
64
66
pub mod type_variable;
65
67
68
+ use crate :: infer:: canonical:: OriginalQueryValues ;
66
69
pub use rustc:: infer:: unify_key;
67
70
68
71
#[ must_use]
@@ -1565,6 +1568,35 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1565
1568
self . universe . set ( u) ;
1566
1569
u
1567
1570
}
1571
+
1572
+ /// Resolves and evaluates a constant.
1573
+ ///
1574
+ /// The constant can be located on a trait like `<A as B>::C`, in which case the given
1575
+ /// substitutions and environment are used to resolve the constant. Alternatively if the
1576
+ /// constant has generic parameters in scope the substitutions are used to evaluate the value of
1577
+ /// the constant. For example in `fn foo<T>() { let _ = [0; bar::<T>()]; }` the repeat count
1578
+ /// constant `bar::<T>()` requires a substitution for `T`, if the substitution for `T` is still
1579
+ /// too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is
1580
+ /// returned.
1581
+ ///
1582
+ /// This handles inferences variables within both `param_env` and `substs` by
1583
+ /// performing the operation on their respective canonical forms.
1584
+ pub fn const_eval_resolve (
1585
+ & self ,
1586
+ param_env : ty:: ParamEnv < ' tcx > ,
1587
+ def_id : DefId ,
1588
+ substs : SubstsRef < ' tcx > ,
1589
+ promoted : Option < mir:: Promoted > ,
1590
+ span : Option < Span > ,
1591
+ ) -> ConstEvalResult < ' tcx > {
1592
+ let mut original_values = OriginalQueryValues :: default ( ) ;
1593
+ let canonical = self . canonicalize_query ( & ( param_env, substs) , & mut original_values) ;
1594
+
1595
+ let ( param_env, substs) = canonical. value ;
1596
+ // The return value is the evaluated value which doesn't contain any reference to inference
1597
+ // variables, thus we don't need to substitute back the original values.
1598
+ self . tcx . const_eval_resolve ( param_env, def_id, substs, promoted, span)
1599
+ }
1568
1600
}
1569
1601
1570
1602
pub struct ShallowResolver < ' a , ' tcx > {
0 commit comments