@@ -2342,29 +2342,39 @@ 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
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) ) ) ;
23552360 }
23562361 }
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- }
2366- }
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 or an error 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 ( ErrorHandled :: Reported ( guar) ) => {
2375+ Self :: Ty ( ty:: Const :: new_error ( tcx, guar. into ( ) , self . ty ( ) ) )
23672376 }
2377+ Err ( ErrorHandled :: TooGeneric ) => self ,
23682378 }
23692379 }
23702380
@@ -2406,35 +2416,35 @@ impl<'tcx> ConstantKind<'tcx> {
24062416 }
24072417
24082418 #[ 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- }
2419+ pub fn try_eval_scalar (
2420+ self ,
2421+ tcx : TyCtxt < ' tcx > ,
2422+ param_env : ty:: ParamEnv < ' tcx > ,
2423+ ) -> Option < Scalar > {
2424+ self . eval ( tcx, param_env, None ) . ok ( ) ?. try_to_scalar ( )
2425+ }
2426+
2427+ #[ inline]
2428+ pub fn try_eval_scalar_int (
2429+ self ,
2430+ tcx : TyCtxt < ' tcx > ,
2431+ param_env : ty:: ParamEnv < ' tcx > ,
2432+ ) -> Option < ScalarInt > {
2433+ self . try_eval_scalar ( tcx, param_env) ?. try_to_int ( ) . ok ( )
2434+ }
2435+
2436+ #[ inline]
2437+ pub fn try_eval_bool ( self , tcx : TyCtxt < ' tcx > , param_env : ty:: ParamEnv < ' tcx > ) -> Option < bool > {
2438+ self . try_eval_scalar_int ( tcx, param_env) ?. try_into ( ) . ok ( )
24202439 }
24212440
24222441 #[ inline]
24232442 pub fn try_eval_target_usize (
2424- & self ,
2443+ self ,
24252444 tcx : TyCtxt < ' tcx > ,
24262445 param_env : ty:: ParamEnv < ' tcx > ,
24272446 ) -> 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- }
2447+ self . try_eval_scalar_int ( tcx, param_env) ?. try_to_target_usize ( tcx) . ok ( )
24382448 }
24392449
24402450 #[ inline]
@@ -2610,6 +2620,11 @@ impl<'tcx> UnevaluatedConst<'tcx> {
26102620 pub fn new ( def : DefId , args : GenericArgsRef < ' tcx > ) -> UnevaluatedConst < ' tcx > {
26112621 UnevaluatedConst { def, args, promoted : Default :: default ( ) }
26122622 }
2623+
2624+ #[ inline]
2625+ pub fn from_instance ( instance : ty:: Instance < ' tcx > ) -> Self {
2626+ UnevaluatedConst :: new ( instance. def_id ( ) , instance. args )
2627+ }
26132628}
26142629
26152630/// A collection of projections into user types.
0 commit comments