@@ -895,145 +895,160 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
895895 let mut is_shuffle = false ;
896896 let mut is_const_fn = false ;
897897 let mut is_promotable_const_fn = false ;
898- if let ty:: FnDef ( def_id, _) = fn_ty. sty {
899- callee_def_id = Some ( def_id) ;
900- match self . tcx . fn_sig ( def_id) . abi ( ) {
901- Abi :: RustIntrinsic |
902- Abi :: PlatformIntrinsic => {
903- assert ! ( !self . tcx. is_const_fn( def_id) ) ;
904- match & self . tcx . item_name ( def_id) . as_str ( ) [ ..] {
905- | "size_of"
906- | "min_align_of"
907- | "needs_drop"
908- | "type_id"
909- | "bswap"
910- | "bitreverse"
911- | "ctpop"
912- | "cttz"
913- | "cttz_nonzero"
914- | "ctlz"
915- | "ctlz_nonzero"
916- | "overflowing_add"
917- | "overflowing_sub"
918- | "overflowing_mul"
919- | "unchecked_shl"
920- | "unchecked_shr"
921- | "rotate_left"
922- | "rotate_right"
923- | "add_with_overflow"
924- | "sub_with_overflow"
925- | "mul_with_overflow"
926- // no need to check feature gates, intrinsics are only callable from the
927- // libstd or with forever unstable feature gates
928- => is_const_fn = true ,
929- // special intrinsic that can be called diretly without an intrinsic
930- // feature gate needs a language feature gate
931- "transmute" => {
932- // never promote transmute calls
933- if self . mode != Mode :: Fn {
934- is_const_fn = true ;
935- // const eval transmute calls only with the feature gate
936- if !self . tcx . features ( ) . const_transmute {
937- emit_feature_err (
938- & self . tcx . sess . parse_sess , "const_transmute" ,
939- self . span , GateIssue :: Language ,
940- & format ! ( "The use of std::mem::transmute() \
941- is gated in {}s", self . mode) ) ;
898+ match fn_ty. sty {
899+ ty:: FnDef ( def_id, _) => {
900+ callee_def_id = Some ( def_id) ;
901+ match self . tcx . fn_sig ( def_id) . abi ( ) {
902+ Abi :: RustIntrinsic |
903+ Abi :: PlatformIntrinsic => {
904+ assert ! ( !self . tcx. is_const_fn( def_id) ) ;
905+ match & self . tcx . item_name ( def_id) . as_str ( ) [ ..] {
906+ | "size_of"
907+ | "min_align_of"
908+ | "needs_drop"
909+ | "type_id"
910+ | "bswap"
911+ | "bitreverse"
912+ | "ctpop"
913+ | "cttz"
914+ | "cttz_nonzero"
915+ | "ctlz"
916+ | "ctlz_nonzero"
917+ | "overflowing_add"
918+ | "overflowing_sub"
919+ | "overflowing_mul"
920+ | "unchecked_shl"
921+ | "unchecked_shr"
922+ | "rotate_left"
923+ | "rotate_right"
924+ | "add_with_overflow"
925+ | "sub_with_overflow"
926+ | "mul_with_overflow"
927+ // no need to check feature gates, intrinsics are only callable from the
928+ // libstd or with forever unstable feature gates
929+ => is_const_fn = true ,
930+ // special intrinsic that can be called diretly without an intrinsic
931+ // feature gate needs a language feature gate
932+ "transmute" => {
933+ // never promote transmute calls
934+ if self . mode != Mode :: Fn {
935+ is_const_fn = true ;
936+ // const eval transmute calls only with the feature gate
937+ if !self . tcx . features ( ) . const_transmute {
938+ emit_feature_err (
939+ & self . tcx . sess . parse_sess , "const_transmute" ,
940+ self . span , GateIssue :: Language ,
941+ & format ! ( "The use of std::mem::transmute() \
942+ is gated in {}s", self . mode) ) ;
943+ }
942944 }
943945 }
944- }
945946
946- name if name. starts_with ( "simd_shuffle" ) => {
947- is_shuffle = true ;
948- }
947+ name if name. starts_with ( "simd_shuffle" ) => {
948+ is_shuffle = true ;
949+ }
949950
950- _ => { }
951- }
952- }
953- _ => {
954- // in normal functions we only care about promotion
955- if self . mode == Mode :: Fn {
956- // never promote const fn calls of
957- // functions without #[rustc_promotable]
958- if self . tcx . is_promotable_const_fn ( def_id) {
959- is_const_fn = true ;
960- is_promotable_const_fn = true ;
961- } else if self . tcx . is_const_fn ( def_id) {
962- is_const_fn = true ;
951+ _ => { }
963952 }
964- } else {
965- // stable const fn or unstable const fns with their feature gate
966- // active
967- if self . tcx . is_const_fn ( def_id) {
968- is_const_fn = true ;
969- } else if self . is_const_panic_fn ( def_id) {
970- // check the const_panic feature gate
971- // FIXME: cannot allow this inside `allow_internal_unstable` because
972- // that would make `panic!` insta stable in constants, since the
973- // macro is marked with the attr
974- if self . tcx . features ( ) . const_panic {
953+ }
954+ _ => {
955+ // in normal functions we only care about promotion
956+ if self . mode == Mode :: Fn {
957+ // never promote const fn calls of
958+ // functions without #[rustc_promotable]
959+ if self . tcx . is_promotable_const_fn ( def_id) {
975960 is_const_fn = true ;
976- } else {
977- // don't allow panics in constants without the feature gate
978- emit_feature_err (
979- & self . tcx . sess . parse_sess ,
980- "const_panic" ,
981- self . span ,
982- GateIssue :: Language ,
983- & format ! ( "panicking in {}s is unstable" , self . mode) ,
984- ) ;
985- }
986- } else if let Some ( feature) = self . tcx . is_unstable_const_fn ( def_id) {
987- // check `#[unstable]` const fns or `#[rustc_const_unstable]`
988- // functions without the feature gate active in this crate to report
989- // a better error message than the one below
990- if self . span . allows_unstable ( ) {
991- // `allow_internal_unstable` can make such calls stable
961+ is_promotable_const_fn = true ;
962+ } else if self . tcx . is_const_fn ( def_id) {
992963 is_const_fn = true ;
993- } else {
994- let mut err = self . tcx . sess . struct_span_err ( self . span ,
995- & format ! ( "`{}` is not yet stable as a const fn" ,
996- self . tcx. item_path_str( def_id) ) ) ;
997- help ! ( & mut err,
998- "in Nightly builds, add `#![feature({})]` \
999- to the crate attributes to enable",
1000- feature) ;
1001- err. emit ( ) ;
1002964 }
1003965 } else {
1004- // FIXME(#24111) Remove this check when const fn stabilizes
1005- let ( msg, note) = if let UnstableFeatures :: Disallow =
1006- self . tcx . sess . opts . unstable_features {
1007- ( format ! ( "calls in {}s are limited to \
1008- tuple structs and tuple variants",
1009- self . mode) ,
1010- Some ( "a limited form of compile-time function \
1011- evaluation is available on a nightly \
1012- compiler via `const fn`") )
966+ // stable const fn or unstable const fns with their feature gate
967+ // active
968+ if self . tcx . is_const_fn ( def_id) {
969+ is_const_fn = true ;
970+ } else if self . is_const_panic_fn ( def_id) {
971+ // check the const_panic feature gate
972+ // FIXME: cannot allow this inside `allow_internal_unstable` because
973+ // that would make `panic!` insta stable in constants, since the
974+ // macro is marked with the attr
975+ if self . tcx . features ( ) . const_panic {
976+ is_const_fn = true ;
977+ } else {
978+ // don't allow panics in constants without the feature gate
979+ emit_feature_err (
980+ & self . tcx . sess . parse_sess ,
981+ "const_panic" ,
982+ self . span ,
983+ GateIssue :: Language ,
984+ & format ! ( "panicking in {}s is unstable" , self . mode) ,
985+ ) ;
986+ }
987+ } else if let Some ( feature) = self . tcx . is_unstable_const_fn ( def_id) {
988+ // check `#[unstable]` const fns or `#[rustc_const_unstable]`
989+ // functions without the feature gate active in this crate to report
990+ // a better error message than the one below
991+ if self . span . allows_unstable ( ) {
992+ // `allow_internal_unstable` can make such calls stable
993+ is_const_fn = true ;
994+ } else {
995+ let mut err = self . tcx . sess . struct_span_err ( self . span ,
996+ & format ! ( "`{}` is not yet stable as a const fn" ,
997+ self . tcx. item_path_str( def_id) ) ) ;
998+ help ! ( & mut err,
999+ "in Nightly builds, add `#![feature({})]` \
1000+ to the crate attributes to enable",
1001+ feature) ;
1002+ err. emit ( ) ;
1003+ }
10131004 } else {
1014- ( format ! ( "calls in {}s are limited \
1015- to constant functions, \
1016- tuple structs and tuple variants",
1017- self . mode) ,
1018- None )
1019- } ;
1020- let mut err = struct_span_err ! (
1021- self . tcx. sess,
1022- self . span,
1023- E0015 ,
1024- "{}" ,
1025- msg,
1026- ) ;
1027- if let Some ( note) = note {
1028- err. span_note ( self . span , note) ;
1005+ // FIXME(#24111) Remove this check when const fn stabilizes
1006+ let ( msg, note) = if let UnstableFeatures :: Disallow =
1007+ self . tcx . sess . opts . unstable_features {
1008+ ( format ! ( "calls in {}s are limited to \
1009+ tuple structs and tuple variants",
1010+ self . mode) ,
1011+ Some ( "a limited form of compile-time function \
1012+ evaluation is available on a nightly \
1013+ compiler via `const fn`") )
1014+ } else {
1015+ ( format ! ( "calls in {}s are limited \
1016+ to constant functions, \
1017+ tuple structs and tuple variants",
1018+ self . mode) ,
1019+ None )
1020+ } ;
1021+ let mut err = struct_span_err ! (
1022+ self . tcx. sess,
1023+ self . span,
1024+ E0015 ,
1025+ "{}" ,
1026+ msg,
1027+ ) ;
1028+ if let Some ( note) = note {
1029+ err. span_note ( self . span , note) ;
1030+ }
1031+ err. emit ( ) ;
10291032 }
1030- err. emit ( ) ;
10311033 }
10321034 }
10331035 }
1036+ } ,
1037+ ty:: FnPtr ( _) => {
1038+ if self . mode != Mode :: Fn {
1039+ let mut err = self . tcx . sess . struct_span_err (
1040+ self . span ,
1041+ & format ! ( "function pointers are not allowed in const fn" ) ) ;
1042+ err. emit ( ) ;
1043+ }
1044+ } ,
1045+ _ => {
1046+ self . not_const ( ) ;
1047+ return
10341048 }
10351049 }
10361050
1051+
10371052 let constant_arguments = callee_def_id. and_then ( |id| {
10381053 args_required_const ( self . tcx , id)
10391054 } ) ;
0 commit comments