@@ -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
@@ -612,6 +613,23 @@ pub fn const_eval_provider<'tcx>(
612
613
other => return other,
613
614
}
614
615
}
616
+
617
+ // We call `const_eval` for zero arg intrinsics, too, in order to cache their value.
618
+ // Catch such calls and evaluate them instead of trying to load a constant's MIR.
619
+ if let ty:: InstanceDef :: Intrinsic ( def_id) = key. value . instance . def {
620
+ let ty = key. value . instance . ty ( tcx) ;
621
+ let substs = match ty. sty {
622
+ ty:: FnDef ( _, substs) => substs,
623
+ _ => bug ! ( "intrinsic with type {:?}" , ty) ,
624
+ } ;
625
+ return eval_nullary_intrinsic ( tcx, key. param_env , def_id, substs)
626
+ . map_err ( |error| {
627
+ let span = tcx. def_span ( def_id) ;
628
+ let error = ConstEvalErr { error : error. kind , stacktrace : vec ! [ ] , span } ;
629
+ error. report_as_error ( tcx. at ( span) , "could not evaluate nullary intrinsic" )
630
+ } )
631
+ }
632
+
615
633
tcx. const_eval_raw ( key) . and_then ( |val| {
616
634
validate_and_turn_into_const ( tcx, val, key)
617
635
} )
@@ -680,63 +698,63 @@ pub fn const_eval_raw_provider<'tcx>(
680
698
} )
681
699
} ) . map_err ( |error| {
682
700
let err = error_to_const_error ( & ecx, error) ;
683
- // errors in statics are always emitted as fatal errors
684
- if tcx. is_static ( def_id) {
685
- // Ensure that if the above error was either `TooGeneric` or `Reported`
686
- // an error must be reported.
701
+ // errors in statics are always emitted as fatal errors
702
+ if tcx. is_static ( def_id) {
703
+ // Ensure that if the above error was either `TooGeneric` or `Reported`
704
+ // an error must be reported.
687
705
let v = err. report_as_error ( ecx. tcx , "could not evaluate static initializer" ) ;
688
- tcx. sess . delay_span_bug (
689
- err. span ,
690
- & format ! ( "static eval failure did not emit an error: {:#?}" , v)
691
- ) ;
692
- v
693
- } else if def_id. is_local ( ) {
694
- // constant defined in this crate, we can figure out a lint level!
695
- match tcx. def_kind ( def_id) {
696
- // constants never produce a hard error at the definition site. Anything else is
697
- // a backwards compatibility hazard (and will break old versions of winapi for sure)
698
- //
699
- // note that validation may still cause a hard error on this very same constant,
700
- // because any code that existed before validation could not have failed validation
701
- // thus preventing such a hard error from being a backwards compatibility hazard
702
- Some ( DefKind :: Const ) | Some ( DefKind :: AssocConst ) => {
703
- let hir_id = tcx. hir ( ) . as_local_hir_id ( def_id) . unwrap ( ) ;
706
+ tcx. sess . delay_span_bug (
707
+ err. span ,
708
+ & format ! ( "static eval failure did not emit an error: {:#?}" , v)
709
+ ) ;
710
+ v
711
+ } else if def_id. is_local ( ) {
712
+ // constant defined in this crate, we can figure out a lint level!
713
+ match tcx. def_kind ( def_id) {
714
+ // constants never produce a hard error at the definition site. Anything else is
715
+ // a backwards compatibility hazard (and will break old versions of winapi for sure)
716
+ //
717
+ // note that validation may still cause a hard error on this very same constant,
718
+ // because any code that existed before validation could not have failed validation
719
+ // thus preventing such a hard error from being a backwards compatibility hazard
720
+ Some ( DefKind :: Const ) | Some ( DefKind :: AssocConst ) => {
721
+ let hir_id = tcx. hir ( ) . as_local_hir_id ( def_id) . unwrap ( ) ;
722
+ err. report_as_lint (
723
+ tcx. at ( tcx. def_span ( def_id) ) ,
724
+ "any use of this value will cause an error" ,
725
+ hir_id,
726
+ Some ( err. span ) ,
727
+ )
728
+ } ,
729
+ // promoting runtime code is only allowed to error if it references broken constants
730
+ // any other kind of error will be reported to the user as a deny-by-default lint
731
+ _ => if let Some ( p) = cid. promoted {
732
+ let span = tcx. promoted_mir ( def_id) [ p] . span ;
733
+ if let err_inval ! ( ReferencedConstant ) = err. error {
734
+ err. report_as_error (
735
+ tcx. at ( span) ,
736
+ "evaluation of constant expression failed" ,
737
+ )
738
+ } else {
704
739
err. report_as_lint (
705
- tcx. at ( tcx . def_span ( def_id ) ) ,
706
- "any use of this value will cause an error " ,
707
- hir_id ,
740
+ tcx. at ( span ) ,
741
+ "reaching this expression at runtime will panic or abort " ,
742
+ tcx . hir ( ) . as_local_hir_id ( def_id ) . unwrap ( ) ,
708
743
Some ( err. span ) ,
709
744
)
710
- } ,
711
- // promoting runtime code is only allowed to error if it references broken constants
712
- // any other kind of error will be reported to the user as a deny-by-default lint
713
- _ => if let Some ( p) = cid. promoted {
714
- let span = tcx. promoted_mir ( def_id) [ p] . span ;
715
- if let err_inval ! ( ReferencedConstant ) = err. error {
716
- err. report_as_error (
717
- tcx. at ( span) ,
718
- "evaluation of constant expression failed" ,
719
- )
720
- } else {
721
- err. report_as_lint (
722
- tcx. at ( span) ,
723
- "reaching this expression at runtime will panic or abort" ,
724
- tcx. hir ( ) . as_local_hir_id ( def_id) . unwrap ( ) ,
725
- Some ( err. span ) ,
726
- )
727
- }
728
- // anything else (array lengths, enum initializers, constant patterns) are reported
729
- // as hard errors
730
- } else {
731
- err. report_as_error (
745
+ }
746
+ // anything else (array lengths, enum initializers, constant patterns) are reported
747
+ // as hard errors
748
+ } else {
749
+ err. report_as_error (
732
750
ecx. tcx ,
733
- "evaluation of constant value failed" ,
734
- )
735
- } ,
736
- }
737
- } else {
738
- // use of broken constant from other crate
739
- err. report_as_error ( ecx. tcx , "could not evaluate constant" )
751
+ "evaluation of constant value failed" ,
752
+ )
753
+ } ,
740
754
}
755
+ } else {
756
+ // use of broken constant from other crate
757
+ err. report_as_error ( ecx. tcx , "could not evaluate constant" )
758
+ }
741
759
} )
742
760
}
0 commit comments