@@ -15,6 +15,7 @@ use rustc::ty::{self, Ty, TyCtxt, subst::Subst};
1515use rustc:: ty:: layout:: { self , LayoutOf , VariantIdx } ;
1616use rustc:: traits:: Reveal ;
1717use rustc_data_structures:: fx:: FxHashMap ;
18+ use crate :: interpret:: eval_nullary_intrinsic;
1819
1920use syntax:: source_map:: { Span , DUMMY_SP } ;
2021
@@ -604,6 +605,23 @@ pub fn const_eval_provider<'tcx>(
604605 other => return other,
605606 }
606607 }
608+
609+ // We call `const_eval` for zero arg intrinsics, too, in order to cache their value.
610+ // Catch such calls and evaluate them instead of trying to load a constant's MIR.
611+ if let ty:: InstanceDef :: Intrinsic ( def_id) = key. value . instance . def {
612+ let ty = key. value . instance . ty ( tcx) ;
613+ let substs = match ty. sty {
614+ ty:: FnDef ( _, substs) => substs,
615+ _ => bug ! ( "intrinsic with type {:?}" , ty) ,
616+ } ;
617+ return eval_nullary_intrinsic ( tcx, key. param_env , def_id, substs)
618+ . map_err ( |error| {
619+ let span = tcx. def_span ( def_id) ;
620+ let error = ConstEvalErr { error : error. kind , stacktrace : vec ! [ ] , span } ;
621+ error. report_as_error ( tcx. at ( span) , "could not evaluate nullary intrinsic" )
622+ } )
623+ }
624+
607625 tcx. const_eval_raw ( key) . and_then ( |val| {
608626 validate_and_turn_into_const ( tcx, val, key)
609627 } )
@@ -666,63 +684,63 @@ pub fn const_eval_raw_provider<'tcx>(
666684 } )
667685 } ) . map_err ( |error| {
668686 let err = error_to_const_error ( & ecx, error) ;
669- // errors in statics are always emitted as fatal errors
670- if tcx. is_static ( def_id) {
671- // Ensure that if the above error was either `TooGeneric` or `Reported`
672- // an error must be reported.
687+ // errors in statics are always emitted as fatal errors
688+ if tcx. is_static ( def_id) {
689+ // Ensure that if the above error was either `TooGeneric` or `Reported`
690+ // an error must be reported.
673691 let v = err. report_as_error ( ecx. tcx , "could not evaluate static initializer" ) ;
674- tcx. sess . delay_span_bug (
675- err. span ,
676- & format ! ( "static eval failure did not emit an error: {:#?}" , v)
677- ) ;
678- v
679- } else if def_id. is_local ( ) {
680- // constant defined in this crate, we can figure out a lint level!
681- match tcx. def_kind ( def_id) {
682- // constants never produce a hard error at the definition site. Anything else is
683- // a backwards compatibility hazard (and will break old versions of winapi for sure)
684- //
685- // note that validation may still cause a hard error on this very same constant,
686- // because any code that existed before validation could not have failed validation
687- // thus preventing such a hard error from being a backwards compatibility hazard
688- Some ( DefKind :: Const ) | Some ( DefKind :: AssocConst ) => {
689- let hir_id = tcx. hir ( ) . as_local_hir_id ( def_id) . unwrap ( ) ;
692+ tcx. sess . delay_span_bug (
693+ err. span ,
694+ & format ! ( "static eval failure did not emit an error: {:#?}" , v)
695+ ) ;
696+ v
697+ } else if def_id. is_local ( ) {
698+ // constant defined in this crate, we can figure out a lint level!
699+ match tcx. def_kind ( def_id) {
700+ // constants never produce a hard error at the definition site. Anything else is
701+ // a backwards compatibility hazard (and will break old versions of winapi for sure)
702+ //
703+ // note that validation may still cause a hard error on this very same constant,
704+ // because any code that existed before validation could not have failed validation
705+ // thus preventing such a hard error from being a backwards compatibility hazard
706+ Some ( DefKind :: Const ) | Some ( DefKind :: AssocConst ) => {
707+ let hir_id = tcx. hir ( ) . as_local_hir_id ( def_id) . unwrap ( ) ;
708+ err. report_as_lint (
709+ tcx. at ( tcx. def_span ( def_id) ) ,
710+ "any use of this value will cause an error" ,
711+ hir_id,
712+ Some ( err. span ) ,
713+ )
714+ } ,
715+ // promoting runtime code is only allowed to error if it references broken constants
716+ // any other kind of error will be reported to the user as a deny-by-default lint
717+ _ => if let Some ( p) = cid. promoted {
718+ let span = tcx. promoted_mir ( def_id) [ p] . span ;
719+ if let err_inval ! ( ReferencedConstant ) = err. error {
720+ err. report_as_error (
721+ tcx. at ( span) ,
722+ "evaluation of constant expression failed" ,
723+ )
724+ } else {
690725 err. report_as_lint (
691- tcx. at ( tcx . def_span ( def_id ) ) ,
692- "any use of this value will cause an error " ,
693- hir_id ,
726+ tcx. at ( span ) ,
727+ "reaching this expression at runtime will panic or abort " ,
728+ tcx . hir ( ) . as_local_hir_id ( def_id ) . unwrap ( ) ,
694729 Some ( err. span ) ,
695730 )
696- } ,
697- // promoting runtime code is only allowed to error if it references broken constants
698- // any other kind of error will be reported to the user as a deny-by-default lint
699- _ => if let Some ( p) = cid. promoted {
700- let span = tcx. promoted_mir ( def_id) [ p] . span ;
701- if let err_inval ! ( ReferencedConstant ) = err. error {
702- err. report_as_error (
703- tcx. at ( span) ,
704- "evaluation of constant expression failed" ,
705- )
706- } else {
707- err. report_as_lint (
708- tcx. at ( span) ,
709- "reaching this expression at runtime will panic or abort" ,
710- tcx. hir ( ) . as_local_hir_id ( def_id) . unwrap ( ) ,
711- Some ( err. span ) ,
712- )
713- }
714- // anything else (array lengths, enum initializers, constant patterns) are reported
715- // as hard errors
716- } else {
717- err. report_as_error (
731+ }
732+ // anything else (array lengths, enum initializers, constant patterns) are reported
733+ // as hard errors
734+ } else {
735+ err. report_as_error (
718736 ecx. tcx ,
719- "evaluation of constant value failed" ,
720- )
721- } ,
722- }
723- } else {
724- // use of broken constant from other crate
725- err. report_as_error ( ecx. tcx , "could not evaluate constant" )
737+ "evaluation of constant value failed" ,
738+ )
739+ } ,
726740 }
741+ } else {
742+ // use of broken constant from other crate
743+ err. report_as_error ( ecx. tcx , "could not evaluate constant" )
744+ }
727745 } )
728746}
0 commit comments