提交 014333fb 编写于 作者: E Eduard-Mihai Burtescu

Stabilize rvalue promotion to 'static.

上级 c8862468
Subproject commit 1abfbaa70313fdf527cf799ffd9b9a096a62105c
Subproject commit 266d429a48468371d2d90669f6a30dd659bb4bdb
# `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);
}
```
......@@ -873,10 +873,10 @@ pub fn cat_rvalue_node(&self,
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
......
......@@ -345,9 +345,6 @@ pub fn new() -> 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 @@ pub fn new() -> 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
......
......@@ -11,10 +11,12 @@
// Test lifetimes are linked properly when we take reference
// to interior.
fn id<T>(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
}
......
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<u32> = &None; //~ error: does not live long enough
}
......@@ -10,7 +10,9 @@
// This file must never have a trailing newline
fn id<T>(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
}
......@@ -10,9 +10,11 @@
#![feature(fn_traits)]
fn id<T>(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() {}
......@@ -8,9 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn id<T>(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() {
......
......@@ -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 @@ fn write_str(&mut self, _s: &str) -> ::std::fmt::Result {
}
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
}
......@@ -12,6 +12,8 @@
// are treated as rvalues and their lifetime is not bounded to
// the static scope.
fn id<T>(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
}
......
......@@ -8,8 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn id<T>(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() {
......
......@@ -8,13 +8,15 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn id<T>(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);
}
}
......
......@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn id<T>(x: T) -> T { x }
struct StateMachineIter<'a> {
statefn: &'a StateMachineFunc<'a>
}
......@@ -23,19 +25,19 @@ fn next(&mut self) -> Option<&'static str> {
}
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
}
}
......
......@@ -10,11 +10,13 @@
#![feature(box_syntax)]
fn id<T>(x: T) -> T { x }
fn f<T:'static>(_: 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);
}
......@@ -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;
......
......@@ -9,7 +9,7 @@
// except according to those terms.
fn f() {
let x = [1].iter();
let x = vec![1].iter();
}
fn main() {
......
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
......@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn id<T>(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
......
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
......
......@@ -8,9 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn id<T>(x: T) -> T { x }
fn main() {
let v = vec![
&3
&id(3)
];
for &&x in &v {
......
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
......
......@@ -10,6 +10,8 @@
#![feature(box_syntax)]
fn id<T>(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<Foo>;
}
}
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<Foo>;
22 | }
22 | let ss: &isize = &id(1);
| ----- temporary value created here
23 | blah = box ss as Box<Foo>;
24 | }
| ^ temporary value dropped here while still borrowed
23 | }
25 | }
| - temporary value needs to live until here
error: aborting due to previous error
......
......@@ -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..];
}
}
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册