@@ -15,6 +15,7 @@ use rustc::ty::{self, Ty, TyCtxt, subst::Subst};
15
15
use rustc:: ty:: layout:: { self , LayoutOf , VariantIdx } ;
16
16
use rustc:: traits:: Reveal ;
17
17
use rustc_data_structures:: fx:: FxHashMap ;
18
+ use crate :: interpret:: eval_nullary_intrinsic;
18
19
19
20
use syntax:: source_map:: { Span , DUMMY_SP } ;
20
21
@@ -604,6 +605,23 @@ pub fn const_eval_provider<'tcx>(
604
605
other => return other,
605
606
}
606
607
}
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
+
607
625
tcx. const_eval_raw ( key) . and_then ( |val| {
608
626
validate_and_turn_into_const ( tcx, val, key)
609
627
} )
@@ -666,63 +684,63 @@ pub fn const_eval_raw_provider<'tcx>(
666
684
} )
667
685
} ) . map_err ( |error| {
668
686
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.
673
691
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 {
690
725
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 ( ) ,
694
729
Some ( err. span ) ,
695
730
)
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 (
718
736
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
+ } ,
726
740
}
741
+ } else {
742
+ // use of broken constant from other crate
743
+ err. report_as_error ( ecx. tcx , "could not evaluate constant" )
744
+ }
727
745
} )
728
746
}
0 commit comments