diff --git a/src/doc/unstable-book/src/SUMMARY.md b/src/doc/unstable-book/src/SUMMARY.md index 44eda204a3d29..7820d44920829 100644 --- a/src/doc/unstable-book/src/SUMMARY.md +++ b/src/doc/unstable-book/src/SUMMARY.md @@ -71,6 +71,7 @@ - [repr_simd](repr-simd.md) - [rustc_attrs](rustc-attrs.md) - [rustc_diagnostic_macros](rustc-diagnostic-macros.md) +- [rvalue_static_promotion](rvalue-static-promotion.md) - [sanitizer_runtime](sanitizer-runtime.md) - [simd](simd.md) - [simd_ffi](simd-ffi.md) diff --git a/src/doc/unstable-book/src/rvalue-static-promotion.md b/src/doc/unstable-book/src/rvalue-static-promotion.md new file mode 100644 index 0000000000000..2583d350ebe11 --- /dev/null +++ b/src/doc/unstable-book/src/rvalue-static-promotion.md @@ -0,0 +1,23 @@ +# `rvalue_static_promotion` + +The tracking issue for this feature is: [#38865] + +[#38865]: https://github.com/rust-lang/rust/issues/38865 + +------------------------ + +The `rvalue_static_promotion` feature allows directly creating `'static` references to +constant `rvalue`s, which in particular allowing for more concise code in the common case +in which a `'static` reference is all that's needed. + + +## Examples + +```rust +#![feature(rvalue_static_promotion)] + +fn main() { + let DEFAULT_VALUE: &'static u32 = &42; + assert_eq!(*DEFAULT_VALUE, 42); +} +``` diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index b0c85e2ef4cd4..a1deda0ab3ec1 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -843,11 +843,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { let promotable = self.tcx().rvalue_promotable_to_static.borrow().get(&id).cloned() .unwrap_or(false); - // Only promote `[T; 0]` before an RFC for rvalue promotions - // is accepted. + // When the corresponding feature isn't toggled, only promote `[T; 0]`. let promotable = match expr_ty.sty { ty::TyArray(_, 0) => true, - _ => promotable & false + _ => promotable && self.tcx().sess.features.borrow().rvalue_static_promotion, }; // Compute maximum lifetime of this rvalue. This is 'static if diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 1e06ee97e0bc7..d07069d030a1b 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -342,6 +342,9 @@ declare_features! ( // Allows the `catch {...}` expression (active, catch_expr, "1.17.0", Some(31436)), + + // See rust-lang/rfcs#1414. Allows code like `let x: &'static u32 = &42` to work. + (active, rvalue_static_promotion, "1.15.1", Some(38865)), ); declare_features! ( diff --git a/src/test/compile-fail/feature-gate-rvalue_static_promotion.rs b/src/test/compile-fail/feature-gate-rvalue_static_promotion.rs new file mode 100644 index 0000000000000..f33d0a71481d2 --- /dev/null +++ b/src/test/compile-fail/feature-gate-rvalue_static_promotion.rs @@ -0,0 +1,15 @@ +// Copyright 2017 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. + +#[allow(unused_variables)] +fn main() { + let x: &'static u32 = &42; //~ error: does not live long enough + let y: &'static Option = &None; //~ error: does not live long enough +} diff --git a/src/test/run-pass/rvalue-static-promotion.rs b/src/test/run-pass/rvalue-static-promotion.rs new file mode 100644 index 0000000000000..30643cfc3eb7d --- /dev/null +++ b/src/test/run-pass/rvalue-static-promotion.rs @@ -0,0 +1,17 @@ +// Copyright 2017 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. + +#![feature(rvalue_static_promotion)] + +#[allow(unused_variables)] +fn main() { + let x: &'static u32 = &42; + let y: &'static Option = &None; +}