@@ -2342,29 +2342,36 @@ impl<'tcx> ConstantKind<'tcx> {
23422342 }
23432343
23442344 #[ inline]
2345- pub fn eval ( self , tcx : TyCtxt < ' tcx > , param_env : ty:: ParamEnv < ' tcx > ) -> Self {
2346- match self {
2347- Self :: Ty ( c) => {
2348- if let Some ( val) = c. try_eval_for_mir ( tcx, param_env) {
2349- match val {
2350- Ok ( val) => Self :: Val ( val, c. ty ( ) ) ,
2351- Err ( guar) => Self :: Ty ( ty:: Const :: new_error ( tcx, guar, self . ty ( ) ) ) ,
2352- }
2345+ pub fn eval (
2346+ self ,
2347+ tcx : TyCtxt < ' tcx > ,
2348+ param_env : ty:: ParamEnv < ' tcx > ,
2349+ span : Option < Span > ,
2350+ ) -> Result < interpret:: ConstValue < ' tcx > , ErrorHandled > {
2351+ let uneval = match self {
2352+ ConstantKind :: Ty ( c) => {
2353+ if let ty:: ConstKind :: Unevaluated ( uv) = c. kind ( ) {
2354+ // Avoid the round-trip via valtree, evaluate directly to ConstValue.
2355+ uv. expand ( )
23532356 } else {
2354- self
2355- }
2356- }
2357- Self :: Val ( _, _) => self ,
2358- Self :: Unevaluated ( uneval, ty) => {
2359- // FIXME: We might want to have a `try_eval`-like function on `Unevaluated`
2360- match tcx. const_eval_resolve ( param_env, uneval, None ) {
2361- Ok ( val) => Self :: Val ( val, ty) ,
2362- Err ( ErrorHandled :: TooGeneric ) => self ,
2363- Err ( ErrorHandled :: Reported ( guar) ) => {
2364- Self :: Ty ( ty:: Const :: new_error ( tcx, guar. into ( ) , ty) )
2365- }
2357+ // It's already a valtree, or an error.
2358+ let val = c. eval ( tcx, param_env, span) ?;
2359+ return Ok ( tcx. valtree_to_const_val ( ( self . ty ( ) , val) ) ) ;
23662360 }
23672361 }
2362+ ConstantKind :: Unevaluated ( uneval, _) => uneval,
2363+ ConstantKind :: Val ( val, _) => return Ok ( val) ,
2364+ } ;
2365+ // FIXME: We might want to have a `try_eval`-like function on `Unevaluated`
2366+ tcx. const_eval_resolve ( param_env, uneval, span)
2367+ }
2368+
2369+ /// Normalizes the constant to a value if possible.
2370+ #[ inline]
2371+ pub fn normalize ( self , tcx : TyCtxt < ' tcx > , param_env : ty:: ParamEnv < ' tcx > ) -> Self {
2372+ match self . eval ( tcx, param_env, None ) {
2373+ Ok ( val) => Self :: Val ( val, self . ty ( ) ) ,
2374+ Err ( _) => self ,
23682375 }
23692376 }
23702377
@@ -2406,35 +2413,35 @@ impl<'tcx> ConstantKind<'tcx> {
24062413 }
24072414
24082415 #[ inline]
2409- pub fn try_eval_bool ( & self , tcx : TyCtxt < ' tcx > , param_env : ty:: ParamEnv < ' tcx > ) -> Option < bool > {
2410- match self {
2411- Self :: Ty ( ct) => ct. try_eval_bool ( tcx, param_env) ,
2412- Self :: Val ( val, _) => val. try_to_bool ( ) ,
2413- Self :: Unevaluated ( uneval, _) => {
2414- match tcx. const_eval_resolve ( param_env, * uneval, None ) {
2415- Ok ( val) => val. try_to_bool ( ) ,
2416- Err ( _) => None ,
2417- }
2418- }
2419- }
2416+ pub fn try_eval_scalar (
2417+ self ,
2418+ tcx : TyCtxt < ' tcx > ,
2419+ param_env : ty:: ParamEnv < ' tcx > ,
2420+ ) -> Option < Scalar > {
2421+ self . eval ( tcx, param_env, None ) . ok ( ) ?. try_to_scalar ( )
2422+ }
2423+
2424+ #[ inline]
2425+ pub fn try_eval_scalar_int (
2426+ self ,
2427+ tcx : TyCtxt < ' tcx > ,
2428+ param_env : ty:: ParamEnv < ' tcx > ,
2429+ ) -> Option < ScalarInt > {
2430+ self . try_eval_scalar ( tcx, param_env) ?. try_to_int ( ) . ok ( )
2431+ }
2432+
2433+ #[ inline]
2434+ pub fn try_eval_bool ( self , tcx : TyCtxt < ' tcx > , param_env : ty:: ParamEnv < ' tcx > ) -> Option < bool > {
2435+ self . try_eval_scalar_int ( tcx, param_env) ?. try_into ( ) . ok ( )
24202436 }
24212437
24222438 #[ inline]
24232439 pub fn try_eval_target_usize (
2424- & self ,
2440+ self ,
24252441 tcx : TyCtxt < ' tcx > ,
24262442 param_env : ty:: ParamEnv < ' tcx > ,
24272443 ) -> Option < u64 > {
2428- match self {
2429- Self :: Ty ( ct) => ct. try_eval_target_usize ( tcx, param_env) ,
2430- Self :: Val ( val, _) => val. try_to_target_usize ( tcx) ,
2431- Self :: Unevaluated ( uneval, _) => {
2432- match tcx. const_eval_resolve ( param_env, * uneval, None ) {
2433- Ok ( val) => val. try_to_target_usize ( tcx) ,
2434- Err ( _) => None ,
2435- }
2436- }
2437- }
2444+ self . try_eval_scalar_int ( tcx, param_env) ?. try_to_target_usize ( tcx) . ok ( )
24382445 }
24392446
24402447 #[ inline]
@@ -2610,6 +2617,11 @@ impl<'tcx> UnevaluatedConst<'tcx> {
26102617 pub fn new ( def : DefId , args : GenericArgsRef < ' tcx > ) -> UnevaluatedConst < ' tcx > {
26112618 UnevaluatedConst { def, args, promoted : Default :: default ( ) }
26122619 }
2620+
2621+ #[ inline]
2622+ pub fn from_instance ( instance : ty:: Instance < ' tcx > ) -> Self {
2623+ UnevaluatedConst :: new ( instance. def_id ( ) , instance. args )
2624+ }
26132625}
26142626
26152627/// A collection of projections into user types.
0 commit comments