Skip to content

Commit

Permalink
Don't try to promote already promoted out temporaries
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Oct 4, 2018
1 parent 088fc73 commit 8b097c4
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/librustc_mir/transform/promote_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
let operand = Operand::Copy(promoted_place(ty, span));
mem::replace(&mut args[index], operand)
}
// already promoted out
TerminatorKind::Goto { .. } => return,
_ => bug!()
}
}
Expand Down
18 changes: 14 additions & 4 deletions src/librustc_mir/transform/qualify_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {

let fn_ty = func.ty(self.mir, self.tcx);
let mut callee_def_id = None;
let (mut is_shuffle, mut is_const_fn) = (false, false);
let mut is_shuffle = false;
let mut is_const_fn = false;
let mut is_promotable_const_fn = false;
if let ty::FnDef(def_id, _) = fn_ty.sty {
callee_def_id = Some(def_id);
match self.tcx.fn_sig(def_id).abi() {
Expand Down Expand Up @@ -873,6 +875,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
// functions without #[rustc_promotable]
if self.tcx.is_promotable_const_fn(def_id) {
is_const_fn = true;
is_promotable_const_fn = true;
} else if self.tcx.is_const_fn(def_id) {
is_const_fn = true;
}
} else {
// stable const fn or unstable const fns with their feature gate
Expand Down Expand Up @@ -974,7 +979,9 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
if !constant_arguments.contains(&i) {
return
}
if this.qualif.is_empty() {
// if the argument requires a constant, we care about constness, not
// promotability
if (this.qualif - Qualif::NOT_PROMOTABLE).is_empty() {
this.promotion_candidates.push(candidate);
} else {
this.tcx.sess.span_err(this.span,
Expand All @@ -985,7 +992,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
}

// non-const fn calls.
if !is_const_fn {
if is_const_fn {
if !is_promotable_const_fn && self.mode == Mode::Fn {
self.qualif = Qualif::NOT_PROMOTABLE;
}
} else {
self.qualif = Qualif::NOT_CONST;
if self.mode != Mode::Fn {
self.tcx.sess.delay_span_bug(
Expand All @@ -1003,7 +1014,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
// Be conservative about the returned value of a const fn.
let tcx = self.tcx;
let ty = dest.ty(self.mir, tcx).to_ty(tcx);
self.qualif = Qualif::empty();
self.add_type(ty);
}
self.assign(dest, location);
Expand Down
17 changes: 17 additions & 0 deletions src/test/ui/consts/const-eval/double_promotion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// compile-pass

#![feature(const_fn, rustc_attrs)]

#[rustc_args_required_const(0)]
pub const fn a(value: u8) -> u8 {
value
}

#[rustc_args_required_const(0)]
pub fn b(_: u8) {
unimplemented!()
}

fn main() {
let _ = b(a(0));
}

0 comments on commit 8b097c4

Please sign in to comment.