@@ -789,10 +789,10 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
789
789
}
790
790
}
791
791
792
+ #[ instrument( skip( self ) ) ]
792
793
fn visit_terminator ( & mut self , terminator : & Terminator < ' tcx > , location : Location ) {
793
794
use rustc_target:: spec:: abi:: Abi :: RustIntrinsic ;
794
795
795
- trace ! ( "visit_terminator: terminator={:?} location={:?}" , terminator, location) ;
796
796
self . super_terminator ( terminator, location) ;
797
797
798
798
match & terminator. kind {
@@ -816,6 +816,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
816
816
817
817
// Attempting to call a trait method?
818
818
if let Some ( trait_id) = tcx. trait_of_item ( callee) {
819
+ trace ! ( "attempting to call a trait method" ) ;
819
820
if !self . tcx . features ( ) . const_trait_impl {
820
821
self . check_op ( ops:: FnCallNonConst ) ;
821
822
return ;
@@ -871,13 +872,13 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
871
872
return ;
872
873
}
873
874
875
+ let is_intrinsic = tcx. fn_sig ( callee) . abi ( ) == RustIntrinsic ;
876
+
874
877
// HACK: This is to "unstabilize" the `transmute` intrinsic
875
878
// within const fns. `transmute` is allowed in all other const contexts.
876
879
// This won't really scale to more intrinsics or functions. Let's allow const
877
880
// transmutes in const fn before we add more hacks to this.
878
- if tcx. fn_sig ( callee) . abi ( ) == RustIntrinsic
879
- && tcx. item_name ( callee) == sym:: transmute
880
- {
881
+ if is_intrinsic && tcx. item_name ( callee) == sym:: transmute {
881
882
self . check_op ( ops:: Transmute ) ;
882
883
return ;
883
884
}
@@ -890,6 +891,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
890
891
// If the `const fn` we are trying to call is not const-stable, ensure that we have
891
892
// the proper feature gate enabled.
892
893
if let Some ( gate) = is_unstable_const_fn ( tcx, callee) {
894
+ trace ! ( ?gate, "calling unstable const fn" ) ;
893
895
if self . span . allows_unstable ( gate) {
894
896
return ;
895
897
}
@@ -904,12 +906,14 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
904
906
// If this crate is not using stability attributes, or the caller is not claiming to be a
905
907
// stable `const fn`, that is all that is required.
906
908
if !self . ccx . is_const_stable_const_fn ( ) {
909
+ trace ! ( "crate not using stability attributes or caller not stably const" ) ;
907
910
return ;
908
911
}
909
912
910
913
// Otherwise, we are something const-stable calling a const-unstable fn.
911
914
912
915
if super :: rustc_allow_const_fn_unstable ( tcx, caller, gate) {
916
+ trace ! ( "rustc_allow_const_fn_unstable gate active" ) ;
913
917
return ;
914
918
}
915
919
@@ -923,10 +927,16 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
923
927
let callee_is_unstable_unmarked = tcx. lookup_const_stability ( callee) . is_none ( )
924
928
&& tcx. lookup_stability ( callee) . map_or ( false , |s| s. level . is_unstable ( ) ) ;
925
929
if callee_is_unstable_unmarked {
926
- if self . ccx . is_const_stable_const_fn ( ) {
930
+ trace ! ( "callee_is_unstable_unmarked" ) ;
931
+ // We do not use `const` modifiers for intrinsic "functions", as intrinsics are
932
+ // `extern` funtions, and these have way to get marked `const`. So instead we
933
+ // use `rustc_const_(un)stable` attributes to mean that the intrinsic is `const`
934
+ if self . ccx . is_const_stable_const_fn ( ) || is_intrinsic {
927
935
self . check_op ( ops:: FnCallUnstable ( callee, None ) ) ;
936
+ return ;
928
937
}
929
938
}
939
+ trace ! ( "permitting call" ) ;
930
940
}
931
941
932
942
// Forbid all `Drop` terminators unless the place being dropped is a local with no
0 commit comments