From dd9a03e8ff5dcf697466bb27945743eacae4bf99 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Sat, 25 Aug 2018 14:58:39 +0200 Subject: [PATCH] Properly prevent the promotion of unstable const fns --- src/librustc_mir/transform/qualify_consts.rs | 4 +--- src/librustc_passes/rvalue_promotion.rs | 3 --- .../dont_promote_unstable_const_fn.nll.stderr | 1 + .../dont_promote_unstable_const_fn.rs | 1 + .../dont_promote_unstable_const_fn.stderr | 13 +++++++++- .../consts/const-eval/auxiliary/stability.rs | 21 ++++++++++++++++ ...e_unstable_const_fn_cross_crate.nll.stderr | 13 ++++++++++ ...t_promote_unstable_const_fn_cross_crate.rs | 20 ++++++++++++++++ ...omote_unstable_const_fn_cross_crate.stderr | 24 +++++++++++++++++++ 9 files changed, 93 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/consts/const-eval/auxiliary/stability.rs create mode 100644 src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.nll.stderr create mode 100644 src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.rs create mode 100644 src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 8a12a604ef202..673cf6aa11c91 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -127,6 +127,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { mir: &'a Mir<'tcx>, mode: Mode) -> Qualifier<'a, 'tcx, 'tcx> { + assert!(def_id.is_local()); let mut rpo = traversal::reverse_postorder(mir); let temps = promote_consts::collect_temps(mir, &mut rpo); rpo.reset(); @@ -915,9 +916,6 @@ This does not pose a problem by itself because they can't be accessed directly." .iter() .any(|&(ref sym, _)| sym == feature_name) && - // this doesn't come from a crate with the feature-gate enabled, - self.def_id.is_local() && - // this doesn't come from a macro that has #[allow_internal_unstable] !self.span.allows_unstable() { diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 114fd8754a21f..7a64f8e2920a1 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -189,9 +189,6 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> { .iter() .any(|&(ref sym, _)| sym == feature_name) || - // this comes from a crate with the feature-gate enabled, - !def_id.is_local() || - // this comes from a macro that has #[allow_internal_unstable] span.allows_unstable(); if !stable_check { diff --git a/src/test/ui/const-eval/dont_promote_unstable_const_fn.nll.stderr b/src/test/ui/const-eval/dont_promote_unstable_const_fn.nll.stderr index 684fa1c997bf1..ed3e38486baf6 100644 --- a/src/test/ui/const-eval/dont_promote_unstable_const_fn.nll.stderr +++ b/src/test/ui/const-eval/dont_promote_unstable_const_fn.nll.stderr @@ -11,6 +11,7 @@ error[E0597]: borrowed value does not live long enough | LL | let x: &'static _ = &std::time::Duration::from_millis(42).subsec_millis(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough +LL | //~^ does not live long enough LL | } | - temporary value only lives until here | diff --git a/src/test/ui/const-eval/dont_promote_unstable_const_fn.rs b/src/test/ui/const-eval/dont_promote_unstable_const_fn.rs index a590e569947f8..623e99480a70a 100644 --- a/src/test/ui/const-eval/dont_promote_unstable_const_fn.rs +++ b/src/test/ui/const-eval/dont_promote_unstable_const_fn.rs @@ -31,4 +31,5 @@ fn a() { fn main() { let _: &'static u32 = &meh(); //~ ERROR does not live long enough let x: &'static _ = &std::time::Duration::from_millis(42).subsec_millis(); + //~^ does not live long enough } diff --git a/src/test/ui/const-eval/dont_promote_unstable_const_fn.stderr b/src/test/ui/const-eval/dont_promote_unstable_const_fn.stderr index 7963cbb4e4569..b9856d37b0ee1 100644 --- a/src/test/ui/const-eval/dont_promote_unstable_const_fn.stderr +++ b/src/test/ui/const-eval/dont_promote_unstable_const_fn.stderr @@ -21,12 +21,23 @@ error[E0597]: borrowed value does not live long enough | LL | let _: &'static u32 = &meh(); //~ ERROR does not live long enough | ^^^^^ temporary value does not live long enough +... +LL | } + | - temporary value only lives until here + | + = note: borrowed value must be valid for the static lifetime... + +error[E0597]: borrowed value does not live long enough + --> $DIR/dont_promote_unstable_const_fn.rs:33:26 + | LL | let x: &'static _ = &std::time::Duration::from_millis(42).subsec_millis(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough +LL | //~^ does not live long enough LL | } | - temporary value only lives until here | = note: borrowed value must be valid for the static lifetime... -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/consts/const-eval/auxiliary/stability.rs b/src/test/ui/consts/const-eval/auxiliary/stability.rs new file mode 100644 index 0000000000000..18c6b52fa7c21 --- /dev/null +++ b/src/test/ui/consts/const-eval/auxiliary/stability.rs @@ -0,0 +1,21 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Crate that exports a const fn. Used for testing cross-crate. + +#![crate_type="rlib"] +#![stable(feature = "rust1", since = "1.0.0")] + +#![feature(rustc_const_unstable, const_fn)] +#![feature(staged_api)] + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_const_unstable(feature="foo")] +pub const fn foo() -> u32 { 42 } diff --git a/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.nll.stderr b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.nll.stderr new file mode 100644 index 0000000000000..4c8f2f47d1e8d --- /dev/null +++ b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.nll.stderr @@ -0,0 +1,13 @@ +error[E0597]: borrowed value does not live long enough + --> $DIR/dont_promote_unstable_const_fn_cross_crate.rs:19:29 + | +LL | let _x: &'static u32 = &foo(); //~ ERROR does not live long enough + | ^^^^^ temporary value does not live long enough +LL | } + | - temporary value only lives until here + | + = note: borrowed value must be valid for the static lifetime... + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.rs b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.rs new file mode 100644 index 0000000000000..81be5d4fe1a38 --- /dev/null +++ b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.rs @@ -0,0 +1,20 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:stability.rs + +extern crate stability; + +use stability::foo; + +fn main() { + let _: &'static u32 = &foo(); //~ ERROR does not live long enough + let _x: &'static u32 = &foo(); //~ ERROR does not live long enough +} diff --git a/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr new file mode 100644 index 0000000000000..cea36a0fa36be --- /dev/null +++ b/src/test/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr @@ -0,0 +1,24 @@ +error[E0597]: borrowed value does not live long enough + --> $DIR/dont_promote_unstable_const_fn_cross_crate.rs:18:28 + | +LL | let _: &'static u32 = &foo(); //~ ERROR does not live long enough + | ^^^^^ temporary value does not live long enough +LL | let _x: &'static u32 = &foo(); //~ ERROR does not live long enough +LL | } + | - temporary value only lives until here + | + = note: borrowed value must be valid for the static lifetime... + +error[E0597]: borrowed value does not live long enough + --> $DIR/dont_promote_unstable_const_fn_cross_crate.rs:19:29 + | +LL | let _x: &'static u32 = &foo(); //~ ERROR does not live long enough + | ^^^^^ temporary value does not live long enough +LL | } + | - temporary value only lives until here + | + = note: borrowed value must be valid for the static lifetime... + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0597`.