@@ -820,7 +820,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
820
820
821
821
let fn_ty = func. ty ( self . mir , self . tcx ) ;
822
822
let mut callee_def_id = None ;
823
- let ( mut is_shuffle, mut is_const_fn) = ( false , false ) ;
823
+ let mut is_shuffle = false ;
824
+ let mut is_const_fn = false ;
825
+ let mut is_promotable_const_fn = false ;
824
826
if let ty:: FnDef ( def_id, _) = fn_ty. sty {
825
827
callee_def_id = Some ( def_id) ;
826
828
match self . tcx . fn_sig ( def_id) . abi ( ) {
@@ -881,6 +883,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
881
883
// functions without #[rustc_promotable]
882
884
if self . tcx . is_promotable_const_fn ( def_id) {
883
885
is_const_fn = true ;
886
+ is_promotable_const_fn = true ;
887
+ } else if self . tcx . is_const_fn ( def_id) {
888
+ is_const_fn = true ;
884
889
}
885
890
} else {
886
891
// stable const fn or unstable const fns with their feature gate
@@ -982,7 +987,17 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
982
987
if !constant_arguments. contains ( & i) {
983
988
return
984
989
}
985
- if this. qualif . is_empty ( ) {
990
+ // Since the argument is required to be constant,
991
+ // we care about constness, not promotability.
992
+ // If we checked for promotability, we'd miss out on
993
+ // the results of function calls (which are never promoted
994
+ // in runtime code)
995
+ // This is not a problem, because the argument explicitly
996
+ // requests constness, in contrast to regular promotion
997
+ // which happens even without the user requesting it.
998
+ // We can error out with a hard error if the argument is not
999
+ // constant here.
1000
+ if ( this. qualif - Qualif :: NOT_PROMOTABLE ) . is_empty ( ) {
986
1001
this. promotion_candidates . push ( candidate) ;
987
1002
} else {
988
1003
this. tcx . sess . span_err ( this. span ,
@@ -1011,7 +1026,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
1011
1026
// Be conservative about the returned value of a const fn.
1012
1027
let tcx = self . tcx ;
1013
1028
let ty = dest. ty ( self . mir , tcx) . to_ty ( tcx) ;
1014
- self . qualif = Qualif :: empty ( ) ;
1029
+ if is_const_fn && !is_promotable_const_fn && self . mode == Mode :: Fn {
1030
+ self . qualif = Qualif :: NOT_PROMOTABLE ;
1031
+ } else {
1032
+ self . qualif = Qualif :: empty ( ) ;
1033
+ }
1015
1034
self . add_type ( ty) ;
1016
1035
}
1017
1036
self . assign ( dest, location) ;
0 commit comments