@@ -7,7 +7,7 @@ use rustc_hir::def::DefKind;
77use rustc_middle:: mir:: interpret:: { AllocId , ErrorHandled , InterpErrorInfo , ReportedErrorInfo } ;
88use rustc_middle:: mir:: { self , ConstAlloc , ConstValue } ;
99use rustc_middle:: query:: TyCtxtAt ;
10- use rustc_middle:: ty:: layout:: HasTypingEnv ;
10+ use rustc_middle:: ty:: layout:: { HasTypingEnv , TyAndLayout } ;
1111use rustc_middle:: ty:: print:: with_no_trimmed_paths;
1212use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
1313use rustc_middle:: { bug, throw_inval} ;
@@ -24,13 +24,11 @@ use crate::interpret::{
2424} ;
2525use crate :: { CTRL_C_RECEIVED , errors} ;
2626
27- // Returns a pointer to where the result lives
28- #[ instrument( level = "trace" , skip( ecx, body) ) ]
29- fn eval_body_using_ecx < ' tcx , R : InterpretationResult < ' tcx > > (
27+ fn setup_for_eval < ' tcx > (
3028 ecx : & mut CompileTimeInterpCx < ' tcx > ,
3129 cid : GlobalId < ' tcx > ,
32- body : & ' tcx mir :: Body < ' tcx > ,
33- ) -> InterpResult < ' tcx , R > {
30+ layout : TyAndLayout < ' tcx > ,
31+ ) -> InterpResult < ' tcx , ( InternKind , MPlaceTy < ' tcx > ) > {
3432 let tcx = * ecx. tcx ;
3533 assert ! (
3634 cid. promoted. is_some( )
@@ -46,7 +44,6 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
4644 "Unexpected DefKind: {:?}" ,
4745 ecx. tcx. def_kind( cid. instance. def_id( ) )
4846 ) ;
49- let layout = ecx. layout_of ( body. bound_return_ty ( ) . instantiate ( tcx, cid. instance . args ) ) ?;
5047 assert ! ( layout. is_sized( ) ) ;
5148
5249 let intern_kind = if cid. promoted . is_some ( ) {
@@ -58,12 +55,25 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
5855 }
5956 } ;
6057
61- let ret = if let InternKind :: Static ( _) = intern_kind {
62- create_static_alloc ( ecx, cid. instance . def_id ( ) . expect_local ( ) , layout) ?
58+ let return_place = if let InternKind :: Static ( _) = intern_kind {
59+ create_static_alloc ( ecx, cid. instance . def_id ( ) . expect_local ( ) , layout)
6360 } else {
64- ecx. allocate ( layout, MemoryKind :: Stack ) ?
61+ ecx. allocate ( layout, MemoryKind :: Stack )
6562 } ;
6663
64+ return_place. map ( |ret| ( intern_kind, ret) )
65+ }
66+
67+ #[ instrument( level = "trace" , skip( ecx, body) ) ]
68+ fn eval_body_using_ecx < ' tcx , R : InterpretationResult < ' tcx > > (
69+ ecx : & mut CompileTimeInterpCx < ' tcx > ,
70+ cid : GlobalId < ' tcx > ,
71+ body : & ' tcx mir:: Body < ' tcx > ,
72+ ) -> InterpResult < ' tcx , R > {
73+ let tcx = * ecx. tcx ;
74+ let layout = ecx. layout_of ( body. bound_return_ty ( ) . instantiate ( tcx, cid. instance . args ) ) ?;
75+ let ( intern_kind, ret) = setup_for_eval ( ecx, cid, layout) ?;
76+
6777 trace ! (
6878 "eval_body_using_ecx: pushing stack frame for global: {}{}" ,
6979 with_no_trimmed_paths!( ecx. tcx. def_path_str( cid. instance. def_id( ) ) ) ,
@@ -87,6 +97,31 @@ fn eval_body_using_ecx<'tcx, R: InterpretationResult<'tcx>>(
8797 }
8898 }
8999
100+ intern_and_validate ( ecx, cid, intern_kind, ret)
101+ }
102+
103+ #[ instrument( level = "trace" , skip( ecx) ) ]
104+ fn eval_trivial_const_using_ecx < ' tcx , R : InterpretationResult < ' tcx > > (
105+ ecx : & mut CompileTimeInterpCx < ' tcx > ,
106+ cid : GlobalId < ' tcx > ,
107+ val : ConstValue ,
108+ ty : Ty < ' tcx > ,
109+ ) -> InterpResult < ' tcx , R > {
110+ let layout = ecx. layout_of ( ty) ?;
111+ let ( intern_kind, return_place) = setup_for_eval ( ecx, cid, layout) ?;
112+
113+ let opty = ecx. const_val_to_op ( val, ty, Some ( layout) ) ?;
114+ ecx. copy_op ( & opty, & return_place) ?;
115+
116+ intern_and_validate ( ecx, cid, intern_kind, return_place)
117+ }
118+
119+ fn intern_and_validate < ' tcx , R : InterpretationResult < ' tcx > > (
120+ ecx : & mut CompileTimeInterpCx < ' tcx > ,
121+ cid : GlobalId < ' tcx > ,
122+ intern_kind : InternKind ,
123+ ret : MPlaceTy < ' tcx > ,
124+ ) -> InterpResult < ' tcx , R > {
90125 // Intern the result
91126 let intern_result = intern_const_alloc_recursive ( ecx, intern_kind, & ret) ;
92127
@@ -292,6 +327,9 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
292327 tcx : TyCtxt < ' tcx > ,
293328 key : ty:: PseudoCanonicalInput < ' tcx , GlobalId < ' tcx > > ,
294329) -> :: rustc_middle:: mir:: interpret:: EvalToConstValueResult < ' tcx > {
330+ if let Some ( ( value, _ty) ) = tcx. trivial_const ( key. value . instance . def_id ( ) ) {
331+ return Ok ( value) ;
332+ }
295333 tcx. eval_to_allocation_raw ( key) . map ( |val| turn_into_const_value ( tcx, val, key) )
296334}
297335
@@ -368,10 +406,14 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
368406 // so we have to reject reading mutable global memory.
369407 CompileTimeMachine :: new ( CanAccessMutGlobal :: from ( is_static) , CheckAlignment :: Error ) ,
370408 ) ;
371- let res = ecx. load_mir ( cid. instance . def , cid. promoted ) ;
372- res. and_then ( |body| eval_body_using_ecx ( & mut ecx, cid, body) )
373- . report_err ( )
374- . map_err ( |error| report_eval_error ( & ecx, cid, error) )
409+
410+ let result = if let Some ( ( value, ty) ) = tcx. trivial_const ( def) {
411+ eval_trivial_const_using_ecx ( & mut ecx, cid, value, ty)
412+ } else {
413+ ecx. load_mir ( cid. instance . def , cid. promoted )
414+ . and_then ( |body| eval_body_using_ecx ( & mut ecx, cid, body) )
415+ } ;
416+ result. report_err ( ) . map_err ( |error| report_eval_error ( & ecx, cid, error) )
375417}
376418
377419#[ inline( always) ]
0 commit comments