@@ -789,10 +789,10 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
789789 }
790790 }
791791
792+ #[ instrument( skip( self ) ) ]
792793 fn visit_terminator ( & mut self , terminator : & Terminator < ' tcx > , location : Location ) {
793794 use rustc_target:: spec:: abi:: Abi :: RustIntrinsic ;
794795
795- trace ! ( "visit_terminator: terminator={:?} location={:?}" , terminator, location) ;
796796 self . super_terminator ( terminator, location) ;
797797
798798 match & terminator. kind {
@@ -816,6 +816,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
816816
817817 // Attempting to call a trait method?
818818 if let Some ( trait_id) = tcx. trait_of_item ( callee) {
819+ trace ! ( "attempting to call a trait method" ) ;
819820 if !self . tcx . features ( ) . const_trait_impl {
820821 self . check_op ( ops:: FnCallNonConst ) ;
821822 return ;
@@ -871,13 +872,13 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
871872 return ;
872873 }
873874
875+ let is_intrinsic = tcx. fn_sig ( callee) . abi ( ) == RustIntrinsic ;
876+
874877 // HACK: This is to "unstabilize" the `transmute` intrinsic
875878 // within const fns. `transmute` is allowed in all other const contexts.
876879 // This won't really scale to more intrinsics or functions. Let's allow const
877880 // 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 {
881882 self . check_op ( ops:: Transmute ) ;
882883 return ;
883884 }
@@ -890,6 +891,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
890891 // If the `const fn` we are trying to call is not const-stable, ensure that we have
891892 // the proper feature gate enabled.
892893 if let Some ( gate) = is_unstable_const_fn ( tcx, callee) {
894+ trace ! ( ?gate, "calling unstable const fn" ) ;
893895 if self . span . allows_unstable ( gate) {
894896 return ;
895897 }
@@ -904,12 +906,14 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
904906 // If this crate is not using stability attributes, or the caller is not claiming to be a
905907 // stable `const fn`, that is all that is required.
906908 if !self . ccx . is_const_stable_const_fn ( ) {
909+ trace ! ( "crate not using stability attributes or caller not stably const" ) ;
907910 return ;
908911 }
909912
910913 // Otherwise, we are something const-stable calling a const-unstable fn.
911914
912915 if super :: rustc_allow_const_fn_unstable ( tcx, caller, gate) {
916+ trace ! ( "rustc_allow_const_fn_unstable gate active" ) ;
913917 return ;
914918 }
915919
@@ -923,10 +927,16 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
923927 let callee_is_unstable_unmarked = tcx. lookup_const_stability ( callee) . is_none ( )
924928 && tcx. lookup_stability ( callee) . map_or ( false , |s| s. level . is_unstable ( ) ) ;
925929 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 {
927935 self . check_op ( ops:: FnCallUnstable ( callee, None ) ) ;
936+ return ;
928937 }
929938 }
939+ trace ! ( "permitting call" ) ;
930940 }
931941
932942 // Forbid all `Drop` terminators unless the place being dropped is a local with no
0 commit comments