@@ -820,7 +820,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
820820
821821 let fn_ty = func. ty ( self . mir , self . tcx ) ;
822822 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 ;
824826 if let ty:: FnDef ( def_id, _) = fn_ty. sty {
825827 callee_def_id = Some ( def_id) ;
826828 match self . tcx . fn_sig ( def_id) . abi ( ) {
@@ -881,6 +883,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
881883 // functions without #[rustc_promotable]
882884 if self . tcx . is_promotable_const_fn ( def_id) {
883885 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 ;
884889 }
885890 } else {
886891 // 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> {
982987 if !constant_arguments. contains ( & i) {
983988 return
984989 }
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 ( ) {
9861001 this. promotion_candidates . push ( candidate) ;
9871002 } else {
9881003 this. tcx . sess . span_err ( this. span ,
@@ -1011,7 +1026,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
10111026 // Be conservative about the returned value of a const fn.
10121027 let tcx = self . tcx ;
10131028 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+ }
10151034 self . add_type ( ty) ;
10161035 }
10171036 self . assign ( dest, location) ;
0 commit comments