From 8b097c4ce92869b012c36ba0c7c0a2a096a17849 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Thu, 4 Oct 2018 16:23:22 +0200 Subject: [PATCH 01/41] Don't try to promote already promoted out temporaries --- src/librustc_mir/transform/promote_consts.rs | 2 ++ src/librustc_mir/transform/qualify_consts.rs | 18 ++++++++++++++---- .../ui/consts/const-eval/double_promotion.rs | 17 +++++++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/consts/const-eval/double_promotion.rs diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 34339b0634194..bba9260f2b829 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -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!() } } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 17fe78d325cf1..4808f02c1dff4 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -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() { @@ -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 @@ -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, @@ -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( @@ -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); diff --git a/src/test/ui/consts/const-eval/double_promotion.rs b/src/test/ui/consts/const-eval/double_promotion.rs new file mode 100644 index 0000000000000..0e75ea8e66b3c --- /dev/null +++ b/src/test/ui/consts/const-eval/double_promotion.rs @@ -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)); +} From 7d3d835c58e789127744076c97110664ea9c6087 Mon Sep 17 00:00:00 2001 From: Philip Munksgaard Date: Thu, 4 Oct 2018 22:17:01 +0200 Subject: [PATCH 02/41] replace escape-rust-expr test with dont-show-const-contents The old test was supposed to check for proper html escaping when showing the contents of constants. This was changed as part of #53409. The revised test asserts that the contents of the constant is not shown as part of the generated documentation. --- .../{escape-rust-expr.rs => dont-show-const-contents.rs} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename src/test/rustdoc/{escape-rust-expr.rs => dont-show-const-contents.rs} (64%) diff --git a/src/test/rustdoc/escape-rust-expr.rs b/src/test/rustdoc/dont-show-const-contents.rs similarity index 64% rename from src/test/rustdoc/escape-rust-expr.rs rename to src/test/rustdoc/dont-show-const-contents.rs index 4594eb95ea18e..1392c62b4abb1 100644 --- a/src/test/rustdoc/escape-rust-expr.rs +++ b/src/test/rustdoc/dont-show-const-contents.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test that we HTML-escape Rust expressions, where HTML special chars -// can occur, and we know it's definitely not markup. +// Test that the contents of constants are not displayed as part of the +// documentation. -// @!has escape_rust_expr/constant.CONST_S.html '//pre[@class="rust const"]' '"