@@ -15,6 +15,8 @@ use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToTy
1515use rustc:: middle:: free_region:: RegionRelations ;
1616use rustc:: middle:: lang_items;
1717use rustc:: middle:: region;
18+ use rustc:: mir;
19+ use rustc:: mir:: interpret:: ConstEvalResult ;
1820use rustc:: session:: config:: BorrowckMode ;
1921use rustc:: ty:: error:: { ExpectedFound , TypeError , UnconstrainedNumeric } ;
2022use rustc:: ty:: fold:: { TypeFoldable , TypeFolder } ;
@@ -63,6 +65,7 @@ pub mod resolve;
6365mod sub;
6466pub mod type_variable;
6567
68+ use crate :: infer:: canonical:: OriginalQueryValues ;
6669pub use rustc:: infer:: unify_key;
6770
6871#[ must_use]
@@ -1565,6 +1568,35 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
15651568 self . universe . set ( u) ;
15661569 u
15671570 }
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+ }
15681600}
15691601
15701602pub struct ShallowResolver < ' a , ' tcx > {
0 commit comments