@@ -369,33 +369,49 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
369369 tcx : TyCtxt < ' tcx > ,
370370 key : ty:: PseudoCanonicalInput < ' tcx , GlobalId < ' tcx > > ,
371371) -> :: rustc_middle:: mir:: interpret:: EvalToAllocationRawResult < ' tcx > {
372+ let ty:: PseudoCanonicalInput { typing_env, value } = key;
373+
372374 // This shouldn't be used for statics, since statics are conceptually places,
373375 // not values -- so what we do here could break pointer identity.
374376 assert ! ( key. value. promoted. is_some( ) || !tcx. is_static( key. value. instance. def_id( ) ) ) ;
375377
376- if cfg ! ( debug_assertions) {
377- match key. typing_env . typing_mode ( ) . assert_not_erased ( ) {
378- ty:: TypingMode :: PostAnalysis => { }
379- ty:: TypingMode :: Coherence
380- | ty:: TypingMode :: Analysis { .. }
381- | ty:: TypingMode :: Borrowck { .. }
382- | ty:: TypingMode :: PostBorrowckAnalysis { .. } => {
378+ match key. typing_env . typing_mode ( ) . assert_not_erased ( ) {
379+ ty:: TypingMode :: PostAnalysis => { }
380+ // We are in codegen. It's very likely this constant has been evaluated in PostAnalysis before.
381+ // Try to reuse this evaluation, and only re-run if we hit a `TooGeneric` error.
382+ ty:: TypingMode :: Codegen => {
383+ let with_postanalysis =
384+ ty:: TypingEnv :: new ( typing_env. param_env , ty:: TypingMode :: PostAnalysis ) ;
385+ let with_postanalysis =
386+ tcx. eval_to_allocation_raw ( with_postanalysis. as_query_input ( value) ) ;
387+ match with_postanalysis {
388+ Ok ( _) | Err ( ErrorHandled :: Reported ( ..) ) => return with_postanalysis,
389+ Err ( ErrorHandled :: TooGeneric ( _) ) => { }
390+ }
391+ }
392+ ty:: TypingMode :: Coherence
393+ | ty:: TypingMode :: Analysis { .. }
394+ | ty:: TypingMode :: Borrowck { .. }
395+ | ty:: TypingMode :: PostBorrowckAnalysis { .. } => {
396+ if cfg ! ( debug_assertions) {
383397 bug ! (
384- "Const eval should always happens in PostAnalysis mode. See the comment in `InterpCx::new` for more details."
398+ "Const eval should always happens in PostAnalysis or Codegen mode. See the comment in `InterpCx::new` for more details."
385399 )
386400 }
387401 }
402+ }
388403
404+ if cfg ! ( debug_assertions) {
389405 // Make sure we format the instance even if we do not print it.
390406 // This serves as a regression test against an ICE on printing.
391407 // The next two lines concatenated contain some discussion:
392408 // https://rust-lang.zulipchat.com/#narrow/stream/146212-t-compiler.2Fconst-eval/
393409 // subject/anon_const_instance_printing/near/135980032
394- let instance = with_no_trimmed_paths ! ( key . value. instance. to_string( ) ) ;
395- trace ! ( "const eval: {:?} ({})" , key , instance) ;
410+ let instance = with_no_trimmed_paths ! ( value. instance. to_string( ) ) ;
411+ trace ! ( "const eval: {:?} ({}) inside {:?} " , value , instance, typing_env ) ;
396412 }
397413
398- eval_in_interpreter ( tcx, key . value , key . typing_env )
414+ eval_in_interpreter ( tcx, value, typing_env)
399415}
400416
401417fn eval_in_interpreter < ' tcx , R : InterpretationResult < ' tcx > > (
0 commit comments