-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Regression: "temporary value does not live long enough" in a static
item in Servo
#54846
Comments
Hmm, this diff does not seem to have any effect on the 275 occurrences of this error in Servo, am I missing something: diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs
index 210e9ae557..7632d341b1 100644
--- a/components/script/dom/bindings/interface.rs
+++ b/components/script/dom/bindings/interface.rs
@@ -88,6 +88,7 @@ pub struct InterfaceConstructorBehavior(ClassOps);
impl InterfaceConstructorBehavior {
/// An interface constructor that unconditionally throws a type error.
+ #[rustc_promotable]
pub const fn throw() -> Self {
InterfaceConstructorBehavior(ClassOps {
addProperty: None,
@@ -105,6 +106,7 @@ impl InterfaceConstructorBehavior {
}
/// An interface constructor that calls a native Rust function.
+ #[rustc_promotable]
pub const fn call(hook: ConstructorClassHook) -> Self {
InterfaceConstructorBehavior(ClassOps {
addProperty: None,
diff --git a/components/script/lib.rs b/components/script/lib.rs
index 097f69d780..a5355a3937 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -7,6 +7,7 @@
#![feature(const_fn)]
#![feature(drain_filter)]
#![feature(plugin)]
+#![feature(rustc_attrs)]
#![feature(try_from)]
#![deny(unsafe_code)]
#![allow(non_snake_case)] Sample error in non-reduced code: error[E0597]: borrowed value does not live long enough
--> /home/simon/servo2/target/debug/build/script-1105d98fbcf10485/out/Bindings/AnalyserNodeBinding.rs:1522:10
|
1522 | &InterfaceConstructorBehavior::call(_constructor),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
...
1525 | 2);
| - temporary value only lives until here
|
= note: borrowed value must be valid for the static lifetime... |
hmm... I thought Or you can always use an intermediate constant.
|
I can hack the |
I’d forgotten this was an option! It works for Servo here. However it’s not really discoverable… |
Upgrade to rustc 1.31.0-nightly (8c4ad4e9e 2018-10-04) CC rust-lang/rust#54846 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/21872) <!-- Reviewable:end -->
Upgrade to rustc 1.31.0-nightly (8c4ad4e9e 2018-10-04) CC rust-lang/rust#54846 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/21872) <!-- Reviewable:end -->
Any suggestions for how to make it more discoverable? The reason promotion is so cautious is that you didn't ask for a static lifetime, and if we promote too aggressively and then CTFE fails we broke your code. With a |
I would say make the error message suggest the intermediate-
Didn’t I? This borrow is immediately passed to a ( |
yea, we could totally promote any I personally think that we should even accept static FOO: &u32 = {
let x = 42;
&x
}; But that's a different discussion. |
Oh, that context wasn't clear to me. Yeah that's a different game, we can be less careful there.
Let's do this after we kill the HIR-based promotion code and rewrite the other, shall we?^^ |
I also wish code like this would work: struct Foo(u32);
impl Foo {
const fn new(x: u32) -> Self {
Foo(x)
}
}
fn bar() -> &'static Foo {
&Foo(42) // works because of rvalue promotion
}
fn baz() -> &'static Foo {
&Foo::new(42) // error: temporary value does not live long enough
} Because right now I have to create a lot of intermediate constants..
Why would CTFE fail (after upgrading the nightly) for expressions that it used to work for (in the previous nightly)? Won't the set of expressions that CTFE works for just expand over time? |
Imagine we did promotion for a I think @oli-obk's idea here is to introduce some kind of syntax for asking for promotion. Basically, some leight-weight alternative to { const FOO = &Foo::new(42); FOO } Maybe it could be If you want to help, the const-eval/CTFE work is happening at https://github.com/rust-rfcs/const-eval/ :) |
This happened because we did in fact expand the set of expression that work in CTFE: we added fn baz() -> &'static Foo {
&unimplemented!()
} If we promote that, you suddenly get a compile-time error instead of a runtime panic. There are many similar things that we need to consider. So yes, I'd prefer if we could move to some sort of anonymous constant expressions, but I haven't gotten around to writing an RFC about it. |
@oli-obk I think I've found a bug in static rvalue promotion but I'm not sure if it belongs in its own issue: Given: struct Value;
impl Value {
const fn new() -> Self { Value }
}
struct StaticContainer(&'static [Value]); This doesn't work: // "Borrowed value does not live long enough" pointing to the slice
static CONTAINER: StaticContainer = StaticContainer(&[Value::new()]); However, this does: static VALUES: &'static [Value] = &[Value::new()];
static CONTAINER: StaticContainer = StaticContainer(VALUES); The former has been accepted on nightly for quite some time now with no additional feature flags but still fails to compile on stable. |
cc @eddyb |
Hmm... I just did some testing, and it works on the playground on all channels: https://play.rust-lang.org/?version=beta&mode=debug&edition=2018&gist=8a2ec5bda8c8b08034490c1b1d0f6c76 What's your stable version? |
@oli-obk I'm using 2015 edition which explains why it works on stable in 2018 but why then does it work on nightly in 2015? |
probably because nightly has nll enabled since recently |
jep, works on beta, too |
Nightly has NLL enabled even on 2015 edition? |
yes, in migration mode, just like 2018 |
That explains it, thanks. |
Reduced test case:
rustc 1.31.0-nightly (5597ee8 2018-10-03): OK
rustc 1.31.0-nightly (8c4ad4e 2018-10-04):
Commit range: 5597ee8...8c4ad4e. #53851 seems relevant. @oli-obk, should we use
#[rustc_promotable]
in unstable code, despite therustc_
prefix in its name?The text was updated successfully, but these errors were encountered: