diff --git a/src/doc/reference b/src/doc/reference index 1abfbaa7031..266d429a484 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 1abfbaa70313fdf527cf799ffd9b9a096a62105c +Subproject commit 266d429a48468371d2d90669f6a30dd659bb4bdb diff --git a/src/doc/unstable-book/src/language-features/rvalue-static-promotion.md b/src/doc/unstable-book/src/language-features/rvalue-static-promotion.md deleted file mode 100644 index 2583d350ebe..00000000000 --- a/src/doc/unstable-book/src/language-features/rvalue-static-promotion.md +++ /dev/null @@ -1,23 +0,0 @@ -# `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 8919d0afc1d..c8a7f8c4aaf 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -873,10 +873,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { let promotable = self.tcx.rvalue_promotable_to_static.borrow().get(&id).cloned() .unwrap_or(false); - // When the corresponding feature isn't toggled, only promote `[T; 0]`. + // Always promote `[T; 0]` (even when e.g. borrowed mutably). let promotable = match expr_ty.sty { ty::TyArray(_, 0) => true, - _ => promotable && self.tcx.sess.features.borrow().rvalue_static_promotion, + _ => promotable, }; // 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 7b2a31b5705..801343689b7 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -345,9 +345,6 @@ declare_features! ( // Allows `repr(align(u16))` struct attribute (RFC 1358) (active, repr_align, "1.17.0", Some(33626)), - // See rust-lang/rfcs#1414. Allows code like `let x: &'static u32 = &42` to work. - (active, rvalue_static_promotion, "1.15.1", Some(38865)), - // Used to preserve symbols (see llvm.used) (active, used, "1.18.0", Some(40289)), @@ -457,6 +454,8 @@ declare_features! ( (accepted, associated_consts, "1.20.0", Some(29646)), // Usage of the `compile_error!` macro (accepted, compile_error, "1.20.0", Some(40872)), + // See rust-lang/rfcs#1414. Allows code like `let x: &'static u32 = &42` to work. + (accepted, rvalue_static_promotion, "1.21.0", Some(38865)), ); // If you change this, please modify src/doc/unstable-book as well. You must diff --git a/src/test/compile-fail/borrowck/borrowck-borrow-from-temporary.rs b/src/test/compile-fail/borrowck/borrowck-borrow-from-temporary.rs index fbb3824cd40..f7514df800d 100644 --- a/src/test/compile-fail/borrowck/borrowck-borrow-from-temporary.rs +++ b/src/test/compile-fail/borrowck/borrowck-borrow-from-temporary.rs @@ -11,10 +11,12 @@ // Test lifetimes are linked properly when we take reference // to interior. +fn id(x: T) -> T { x } + struct Foo(isize); fn foo<'a>() -> &'a isize { - let &Foo(ref x) = &Foo(3); //~ ERROR borrowed value does not live long enough + let &Foo(ref x) = &id(Foo(3)); //~ ERROR borrowed value does not live long enough x } diff --git a/src/test/compile-fail/feature-gate-rvalue_static_promotion.rs b/src/test/compile-fail/feature-gate-rvalue_static_promotion.rs deleted file mode 100644 index f33d0a71481..00000000000 --- a/src/test/compile-fail/feature-gate-rvalue_static_promotion.rs +++ /dev/null @@ -1,15 +0,0 @@ -// 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/compile-fail/issue-11493.rs b/src/test/compile-fail/issue-11493.rs index 333ff7118d4..3045c06ca4c 100644 --- a/src/test/compile-fail/issue-11493.rs +++ b/src/test/compile-fail/issue-11493.rs @@ -10,7 +10,9 @@ // This file must never have a trailing newline +fn id(x: T) -> T { x } + fn main() { let x = Some(3); - let y = x.as_ref().unwrap_or(&5); //~ ERROR: borrowed value does not live long enough + let y = x.as_ref().unwrap_or(&id(5)); //~ ERROR: borrowed value does not live long enough } diff --git a/src/test/compile-fail/issue-17545.rs b/src/test/compile-fail/issue-17545.rs index 45bc5ee07a5..9264305e6ea 100644 --- a/src/test/compile-fail/issue-17545.rs +++ b/src/test/compile-fail/issue-17545.rs @@ -10,9 +10,11 @@ #![feature(fn_traits)] +fn id(x: T) -> T { x } + pub fn foo<'a, F: Fn(&'a ())>(bar: F) { bar.call(( - &(), //~ ERROR borrowed value does not live long enough + &id(()), //~ ERROR borrowed value does not live long enough )); } fn main() {} diff --git a/src/test/compile-fail/issue-17718-constants-not-static.rs b/src/test/compile-fail/issue-17718-constants-not-static.rs index db56d2c6cf3..9b7ed463499 100644 --- a/src/test/compile-fail/issue-17718-constants-not-static.rs +++ b/src/test/compile-fail/issue-17718-constants-not-static.rs @@ -8,9 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +fn id(x: T) -> T { x } + const FOO: usize = 3; -fn foo() -> &'static usize { &FOO } +fn foo() -> &'static usize { &id(FOO) } //~^ ERROR: borrowed value does not live long enough fn main() { diff --git a/src/test/compile-fail/issue-27592.rs b/src/test/compile-fail/issue-27592.rs index ccf5eabc111..731d4fb2bf6 100644 --- a/src/test/compile-fail/issue-27592.rs +++ b/src/test/compile-fail/issue-27592.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Regression test for issue #27591. +// Regression test for issue #27592. fn write<'a, F: ::std::ops::FnOnce()->::std::fmt::Arguments<'a> + 'a>(fcn: F) { use std::fmt::Write; @@ -23,7 +23,7 @@ impl ::std::fmt::Write for Stream { } fn main() { - write(|| format_args!("{}", "Hello world")); + write(|| format_args!("{}", String::from("Hello world"))); //~^ ERROR borrowed value does not live long enough //~| ERROR borrowed value does not live long enough } diff --git a/src/test/compile-fail/regions-lifetime-of-struct-or-enum-variant.rs b/src/test/compile-fail/regions-lifetime-of-struct-or-enum-variant.rs index 9c985839c4d..46c486c63a3 100644 --- a/src/test/compile-fail/regions-lifetime-of-struct-or-enum-variant.rs +++ b/src/test/compile-fail/regions-lifetime-of-struct-or-enum-variant.rs @@ -12,6 +12,8 @@ // are treated as rvalues and their lifetime is not bounded to // the static scope. +fn id(x: T) -> T { x } + struct Test; enum MyEnum { @@ -19,12 +21,14 @@ enum MyEnum { } fn structLifetime<'a>() -> &'a Test { - let testValue = &Test; //~ ERROR borrowed value does not live long enough + let testValue = &id(Test); + //~^ ERROR borrowed value does not live long enough testValue } fn variantLifetime<'a>() -> &'a MyEnum { - let testValue = &MyEnum::Variant1; //~ ERROR borrowed value does not live long enough + let testValue = &id(MyEnum::Variant1); + //~^ ERROR borrowed value does not live long enough testValue } diff --git a/src/test/compile-fail/regions-ret.rs b/src/test/compile-fail/regions-ret.rs index 61c98d69d80..c7cd3ced98d 100644 --- a/src/test/compile-fail/regions-ret.rs +++ b/src/test/compile-fail/regions-ret.rs @@ -8,8 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +fn id(x: T) -> T { x } + fn f(_x: &isize) -> &isize { - return &3; //~ ERROR borrowed value does not live long enough + return &id(3); //~ ERROR borrowed value does not live long enough } fn main() { diff --git a/src/test/compile-fail/regions-var-type-out-of-scope.rs b/src/test/compile-fail/regions-var-type-out-of-scope.rs index 8955a26de0b..031091c4523 100644 --- a/src/test/compile-fail/regions-var-type-out-of-scope.rs +++ b/src/test/compile-fail/regions-var-type-out-of-scope.rs @@ -8,13 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +fn id(x: T) -> T { x } + fn foo(cond: bool) { // Here we will infer a type that uses the // region of the if stmt then block: let mut x; if cond { - x = &3; //~ ERROR borrowed value does not live long enough + x = &id(3); //~ ERROR borrowed value does not live long enough assert_eq!(*x, 3); } } diff --git a/src/test/compile-fail/static-reference-to-fn-2.rs b/src/test/compile-fail/static-reference-to-fn-2.rs index 460154f25d7..8d9f442b81d 100644 --- a/src/test/compile-fail/static-reference-to-fn-2.rs +++ b/src/test/compile-fail/static-reference-to-fn-2.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +fn id(x: T) -> T { x } + struct StateMachineIter<'a> { statefn: &'a StateMachineFunc<'a> } @@ -23,19 +25,19 @@ impl<'a> Iterator for StateMachineIter<'a> { } fn state1(self_: &mut StateMachineIter) -> Option<&'static str> { - self_.statefn = &(state2 as StateMachineFunc); + self_.statefn = &id(state2 as StateMachineFunc); //~^ ERROR borrowed value does not live long enough return Some("state1"); } fn state2(self_: &mut StateMachineIter) -> Option<(&'static str)> { - self_.statefn = &(state3 as StateMachineFunc); + self_.statefn = &id(state3 as StateMachineFunc); //~^ ERROR borrowed value does not live long enough return Some("state2"); } fn state3(self_: &mut StateMachineIter) -> Option<(&'static str)> { - self_.statefn = &(finished as StateMachineFunc); + self_.statefn = &id(finished as StateMachineFunc); //~^ ERROR borrowed value does not live long enough return Some("state3"); } @@ -46,7 +48,8 @@ fn finished(_: &mut StateMachineIter) -> Option<(&'static str)> { fn state_iter() -> StateMachineIter<'static> { StateMachineIter { - statefn: &(state1 as StateMachineFunc) //~ ERROR borrowed value does not live long enough + statefn: &id(state1 as StateMachineFunc) + //~^ ERROR borrowed value does not live long enough } } diff --git a/src/test/compile-fail/static-region-bound.rs b/src/test/compile-fail/static-region-bound.rs index eca22bfdda0..90ed401659c 100644 --- a/src/test/compile-fail/static-region-bound.rs +++ b/src/test/compile-fail/static-region-bound.rs @@ -10,11 +10,13 @@ #![feature(box_syntax)] +fn id(x: T) -> T { x } + fn f(_: T) {} fn main() { let x: Box<_> = box 3; f(x); - let x = &3; //~ ERROR borrowed value does not live long enough + let x = &id(3); //~ ERROR borrowed value does not live long enough f(x); } diff --git a/src/test/run-pass/rvalue-static-promotion.rs b/src/test/run-pass/rvalue-static-promotion.rs index 30643cfc3eb..e57491930a4 100644 --- a/src/test/run-pass/rvalue-static-promotion.rs +++ b/src/test/run-pass/rvalue-static-promotion.rs @@ -8,8 +8,6 @@ // 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; diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.rs b/src/test/ui/lifetimes/borrowck-let-suggestion.rs index eeafaab44c6..1c904648f9e 100644 --- a/src/test/ui/lifetimes/borrowck-let-suggestion.rs +++ b/src/test/ui/lifetimes/borrowck-let-suggestion.rs @@ -9,7 +9,7 @@ // except according to those terms. fn f() { - let x = [1].iter(); + let x = vec![1].iter(); } fn main() { diff --git a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr index d1ba9246588..6316c066660 100644 --- a/src/test/ui/lifetimes/borrowck-let-suggestion.stderr +++ b/src/test/ui/lifetimes/borrowck-let-suggestion.stderr @@ -1,14 +1,15 @@ error[E0597]: borrowed value does not live long enough - --> $DIR/borrowck-let-suggestion.rs:12:23 + --> $DIR/borrowck-let-suggestion.rs:12:27 | -12 | let x = [1].iter(); - | --- ^ temporary value dropped here while still borrowed +12 | let x = vec![1].iter(); + | ------- ^ temporary value dropped here while still borrowed | | | temporary value created here 13 | } | - temporary value needs to live until here | = note: consider using a `let` binding to increase its lifetime + = note: this error originates in a macro outside of the current crate error: aborting due to previous error diff --git a/src/test/ui/span/borrowck-let-suggestion-suffixes.rs b/src/test/ui/span/borrowck-let-suggestion-suffixes.rs index 1206d716672..9e316b989a4 100644 --- a/src/test/ui/span/borrowck-let-suggestion-suffixes.rs +++ b/src/test/ui/span/borrowck-let-suggestion-suffixes.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +fn id(x: T) -> T { x } + fn f() { let old = ['o']; // statement 0 let mut v1 = Vec::new(); // statement 1 @@ -21,7 +23,7 @@ fn f() { let mut v3 = Vec::new(); // statement 5 - v3.push(&'x'); // statement 6 + v3.push(&id('x')); // statement 6 //~^ ERROR borrowed value does not live long enough //~| NOTE temporary value created here //~| NOTE temporary value only lives until here @@ -31,7 +33,7 @@ fn f() { let mut v4 = Vec::new(); // (sub) statement 0 - v4.push(&'y'); + v4.push(&id('y')); //~^ ERROR borrowed value does not live long enough //~| NOTE temporary value created here //~| NOTE temporary value only lives until here @@ -42,7 +44,7 @@ fn f() { let mut v5 = Vec::new(); // statement 8 - v5.push(&'z'); + v5.push(&id('z')); //~^ ERROR borrowed value does not live long enough //~| NOTE temporary value created here //~| NOTE temporary value only lives until here diff --git a/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr index 6ed1b7c2622..86c6f28ef1c 100644 --- a/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr +++ b/src/test/ui/span/borrowck-let-suggestion-suffixes.stderr @@ -1,49 +1,49 @@ error[E0597]: `young[..]` does not live long enough - --> $DIR/borrowck-let-suggestion-suffixes.rs:52:1 + --> $DIR/borrowck-let-suggestion-suffixes.rs:54:1 | -19 | v2.push(&young[0]); // statement 4 +21 | v2.push(&young[0]); // statement 4 | -------- borrow occurs here ... -52 | } +54 | } | ^ `young[..]` dropped here while still borrowed | = note: values in a scope are dropped in the opposite order they are created error[E0597]: borrowed value does not live long enough - --> $DIR/borrowck-let-suggestion-suffixes.rs:24:18 + --> $DIR/borrowck-let-suggestion-suffixes.rs:26:22 | -24 | v3.push(&'x'); // statement 6 - | --- ^ temporary value dropped here while still borrowed +26 | v3.push(&id('x')); // statement 6 + | ------- ^ temporary value dropped here while still borrowed | | | temporary value created here ... -52 | } +54 | } | - temporary value needs to live until here | = note: consider using a `let` binding to increase its lifetime error[E0597]: borrowed value does not live long enough - --> $DIR/borrowck-let-suggestion-suffixes.rs:34:22 + --> $DIR/borrowck-let-suggestion-suffixes.rs:36:26 | -34 | v4.push(&'y'); - | --- ^ temporary value dropped here while still borrowed +36 | v4.push(&id('y')); + | ------- ^ temporary value dropped here while still borrowed | | | temporary value created here ... -40 | } // (statement 7) +42 | } // (statement 7) | - temporary value needs to live until here | = note: consider using a `let` binding to increase its lifetime error[E0597]: borrowed value does not live long enough - --> $DIR/borrowck-let-suggestion-suffixes.rs:45:18 + --> $DIR/borrowck-let-suggestion-suffixes.rs:47:22 | -45 | v5.push(&'z'); - | --- ^ temporary value dropped here while still borrowed +47 | v5.push(&id('z')); + | ------- ^ temporary value dropped here while still borrowed | | | temporary value created here ... -52 | } +54 | } | - temporary value needs to live until here | = note: consider using a `let` binding to increase its lifetime diff --git a/src/test/ui/span/issue-15480.rs b/src/test/ui/span/issue-15480.rs index ea5f4d3fe60..871e0af50bf 100644 --- a/src/test/ui/span/issue-15480.rs +++ b/src/test/ui/span/issue-15480.rs @@ -8,9 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +fn id(x: T) -> T { x } + fn main() { let v = vec![ - &3 + &id(3) ]; for &&x in &v { diff --git a/src/test/ui/span/issue-15480.stderr b/src/test/ui/span/issue-15480.stderr index ce1c6e81b96..7f4ca19241c 100644 --- a/src/test/ui/span/issue-15480.stderr +++ b/src/test/ui/span/issue-15480.stderr @@ -1,12 +1,12 @@ error[E0597]: borrowed value does not live long enough - --> $DIR/issue-15480.rs:14:6 + --> $DIR/issue-15480.rs:16:6 | -13 | &3 - | - temporary value created here -14 | ]; +15 | &id(3) + | ----- temporary value created here +16 | ]; | ^ temporary value dropped here while still borrowed ... -19 | } +21 | } | - temporary value needs to live until here | = note: consider using a `let` binding to increase its lifetime diff --git a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.rs b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.rs index a524562f2d9..99b0d6ed296 100644 --- a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.rs +++ b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.rs @@ -10,6 +10,8 @@ #![feature(box_syntax)] +fn id(x: T) -> T { x } + trait Foo { } impl<'a> Foo for &'a isize { } @@ -17,7 +19,7 @@ impl<'a> Foo for &'a isize { } fn main() { let blah; { - let ss: &isize = &1; + let ss: &isize = &id(1); blah = box ss as Box; } } diff --git a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr index e671f1daf61..6a3625441b4 100644 --- a/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr +++ b/src/test/ui/span/regions-close-over-borrowed-ref-in-obj.stderr @@ -1,12 +1,12 @@ error[E0597]: borrowed value does not live long enough - --> $DIR/regions-close-over-borrowed-ref-in-obj.rs:22:5 + --> $DIR/regions-close-over-borrowed-ref-in-obj.rs:24:5 | -20 | let ss: &isize = &1; - | - temporary value created here -21 | blah = box ss as Box; -22 | } +22 | let ss: &isize = &id(1); + | ----- temporary value created here +23 | blah = box ss as Box; +24 | } | ^ temporary value dropped here while still borrowed -23 | } +25 | } | - temporary value needs to live until here error: aborting due to previous error diff --git a/src/test/ui/span/slice-borrow.rs b/src/test/ui/span/slice-borrow.rs index 4ca0ccaa731..1b022f23246 100644 --- a/src/test/ui/span/slice-borrow.rs +++ b/src/test/ui/span/slice-borrow.rs @@ -13,7 +13,7 @@ fn main() { let y; { - let x: &[isize] = &[1, 2, 3, 4, 5]; + let x: &[isize] = &vec![1, 2, 3, 4, 5]; y = &x[1..]; } } diff --git a/src/test/ui/span/slice-borrow.stderr b/src/test/ui/span/slice-borrow.stderr index b60ccd0fbf3..5e8edf80df6 100644 --- a/src/test/ui/span/slice-borrow.stderr +++ b/src/test/ui/span/slice-borrow.stderr @@ -1,13 +1,15 @@ error[E0597]: borrowed value does not live long enough --> $DIR/slice-borrow.rs:18:5 | -16 | let x: &[isize] = &[1, 2, 3, 4, 5]; - | --------------- temporary value created here +16 | let x: &[isize] = &vec![1, 2, 3, 4, 5]; + | ------------------- temporary value created here 17 | y = &x[1..]; 18 | } | ^ temporary value dropped here while still borrowed 19 | } | - temporary value needs to live until here + | + = note: this error originates in a macro outside of the current crate error: aborting due to previous error