@@ -895,145 +895,160 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
895
895
let mut is_shuffle = false ;
896
896
let mut is_const_fn = false ;
897
897
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
928
+ // from the 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
+ }
942
944
}
943
945
}
944
- }
945
946
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
+ }
949
950
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
+ _ => { }
963
952
}
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) {
975
960
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) {
992
963
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 ( ) ;
1002
964
}
1003
965
} 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`
973
+ // because that would make `panic!` insta stable in constants,
974
+ // since the 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 ( feat) = 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
990
+ // report 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
+ feat) ;
1002
+ err. emit ( ) ;
1003
+ }
1013
1004
} 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 ( ) ;
1029
1032
}
1030
- err. emit ( ) ;
1031
1033
}
1032
1034
}
1033
1035
}
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
1034
1048
}
1035
1049
}
1036
1050
1051
+
1037
1052
let constant_arguments = callee_def_id. and_then ( |id| {
1038
1053
args_required_const ( self . tcx , id)
1039
1054
} ) ;
0 commit comments