summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_const_eval/src/transform/promote_consts.rs14
-rw-r--r--src/test/ui/consts/promoted_const_call.rs19
-rw-r--r--src/test/ui/consts/promoted_const_call.stderr65
-rw-r--r--src/test/ui/consts/promoted_const_call2.rs14
-rw-r--r--src/test/ui/consts/promoted_const_call2.stderr50
-rw-r--r--src/test/ui/consts/promoted_const_call3.rs26
-rw-r--r--src/test/ui/consts/promoted_const_call3.stderr105
-rw-r--r--src/test/ui/consts/promoted_const_call4.rs18
-rw-r--r--src/test/ui/consts/promoted_const_call5.rs42
-rw-r--r--src/test/ui/consts/promoted_const_call5.stderr74
10 files changed, 419 insertions, 8 deletions
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index 6777fae74f1..04ce701452b 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -216,12 +216,6 @@ impl<'tcx> Validator<'_, 'tcx> {
return Err(Unpromotable);
}
- // We cannot promote things that need dropping, since the promoted value
- // would not get dropped.
- if self.qualif_local::<qualifs::NeedsDrop>(place.local) {
- return Err(Unpromotable);
- }
-
Ok(())
}
_ => bug!(),
@@ -262,13 +256,17 @@ impl<'tcx> Validator<'_, 'tcx> {
}
}
} else {
- let span = self.body.local_decls[local].source_info.span;
- span_bug!(span, "{:?} not promotable, qualif_local shouldn't have been called", local);
+ false
}
}
fn validate_local(&mut self, local: Local) -> Result<(), Unpromotable> {
if let TempState::Defined { location: loc, uses, valid } = self.temps[local] {
+ // We cannot promote things that need dropping, since the promoted value
+ // would not get dropped.
+ if self.qualif_local::<qualifs::NeedsDrop>(local) {
+ return Err(Unpromotable);
+ }
valid.or_else(|_| {
let ok = {
let block = &self.body[loc.block];
diff --git a/src/test/ui/consts/promoted_const_call.rs b/src/test/ui/consts/promoted_const_call.rs
new file mode 100644
index 00000000000..30ae730535c
--- /dev/null
+++ b/src/test/ui/consts/promoted_const_call.rs
@@ -0,0 +1,19 @@
+#![feature(const_mut_refs)]
+#![feature(const_trait_impl)]
+struct Panic;
+impl const Drop for Panic { fn drop(&mut self) { panic!(); } }
+pub const fn id<T>(x: T) -> T { x }
+pub const C: () = {
+ let _: &'static _ = &id(&Panic);
+ //~^ ERROR: temporary value dropped while borrowed
+ //~| ERROR: temporary value dropped while borrowed
+};
+
+fn main() {
+ let _: &'static _ = &id(&Panic);
+ //~^ ERROR: temporary value dropped while borrowed
+ //~| ERROR: temporary value dropped while borrowed
+ let _: &'static _ = &&(Panic, 0).1;
+ //~^ ERROR: temporary value dropped while borrowed
+ //~| ERROR: temporary value dropped while borrowed
+}
diff --git a/src/test/ui/consts/promoted_const_call.stderr b/src/test/ui/consts/promoted_const_call.stderr
new file mode 100644
index 00000000000..83cc16f6f94
--- /dev/null
+++ b/src/test/ui/consts/promoted_const_call.stderr
@@ -0,0 +1,65 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call.rs:7:26
+ |
+LL | let _: &'static _ = &id(&Panic);
+ | ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | };
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call.rs:7:30
+ |
+LL | let _: &'static _ = &id(&Panic);
+ | ---------- ^^^^^ - temporary value is freed at the end of this statement
+ | | |
+ | | creates a temporary value which is freed while still in use
+ | type annotation requires that borrow lasts for `'static`
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call.rs:13:26
+ |
+LL | let _: &'static _ = &id(&Panic);
+ | ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call.rs:13:30
+ |
+LL | let _: &'static _ = &id(&Panic);
+ | ---------- ^^^^^ - temporary value is freed at the end of this statement
+ | | |
+ | | creates a temporary value which is freed while still in use
+ | type annotation requires that borrow lasts for `'static`
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call.rs:16:26
+ |
+LL | let _: &'static _ = &&(Panic, 0).1;
+ | ---------- ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call.rs:16:27
+ |
+LL | let _: &'static _ = &&(Panic, 0).1;
+ | ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/src/test/ui/consts/promoted_const_call2.rs b/src/test/ui/consts/promoted_const_call2.rs
new file mode 100644
index 00000000000..f332cd18cea
--- /dev/null
+++ b/src/test/ui/consts/promoted_const_call2.rs
@@ -0,0 +1,14 @@
+#![feature(const_precise_live_drops)]
+pub const fn id<T>(x: T) -> T { x }
+pub const C: () = {
+ let _: &'static _ = &id(&String::new());
+ //~^ ERROR: temporary value dropped while borrowed
+ //~| ERROR: temporary value dropped while borrowed
+ //~| ERROR: destructor of `String` cannot be evaluated at compile-time
+};
+
+fn main() {
+ let _: &'static _ = &id(&String::new());
+ //~^ ERROR: temporary value dropped while borrowed
+ //~| ERROR: temporary value dropped while borrowed
+}
diff --git a/src/test/ui/consts/promoted_const_call2.stderr b/src/test/ui/consts/promoted_const_call2.stderr
new file mode 100644
index 00000000000..13d864ed3db
--- /dev/null
+++ b/src/test/ui/consts/promoted_const_call2.stderr
@@ -0,0 +1,50 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call2.rs:4:26
+ |
+LL | let _: &'static _ = &id(&String::new());
+ | ---------- ^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | };
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call2.rs:4:30
+ |
+LL | let _: &'static _ = &id(&String::new());
+ | ---------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
+ | | |
+ | | creates a temporary value which is freed while still in use
+ | type annotation requires that borrow lasts for `'static`
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call2.rs:11:26
+ |
+LL | let _: &'static _ = &id(&String::new());
+ | ---------- ^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call2.rs:11:30
+ |
+LL | let _: &'static _ = &id(&String::new());
+ | ---------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
+ | | |
+ | | creates a temporary value which is freed while still in use
+ | type annotation requires that borrow lasts for `'static`
+
+error[E0493]: destructor of `String` cannot be evaluated at compile-time
+ --> $DIR/promoted_const_call2.rs:4:30
+ |
+LL | let _: &'static _ = &id(&String::new());
+ | ^^^^^^^^^^^^^ the destructor for this type cannot be evaluated in constants
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0493, E0716.
+For more information about an error, try `rustc --explain E0493`.
diff --git a/src/test/ui/consts/promoted_const_call3.rs b/src/test/ui/consts/promoted_const_call3.rs
new file mode 100644
index 00000000000..6d68a2de70e
--- /dev/null
+++ b/src/test/ui/consts/promoted_const_call3.rs
@@ -0,0 +1,26 @@
+pub const fn id<T>(x: T) -> T { x }
+pub const C: () = {
+ let _: &'static _ = &String::new();
+ //~^ ERROR: destructor of `String` cannot be evaluated at compile-time
+ //~| ERROR: temporary value dropped while borrowed
+
+ let _: &'static _ = &id(&String::new());
+ //~^ ERROR: destructor of `String` cannot be evaluated at compile-time
+ //~| ERROR: temporary value dropped while borrowed
+ //~| ERROR: temporary value dropped while borrowed
+
+ let _: &'static _ = &std::mem::ManuallyDrop::new(String::new());
+ //~^ ERROR: temporary value dropped while borrowed
+};
+
+fn main() {
+ let _: &'static _ = &String::new();
+ //~^ ERROR: temporary value dropped while borrowed
+
+ let _: &'static _ = &id(&String::new());
+ //~^ ERROR: temporary value dropped while borrowed
+ //~| ERROR: temporary value dropped while borrowed
+
+ let _: &'static _ = &std::mem::ManuallyDrop::new(String::new());
+ //~^ ERROR: temporary value dropped while borrowed
+}
diff --git a/src/test/ui/consts/promoted_const_call3.stderr b/src/test/ui/consts/promoted_const_call3.stderr
new file mode 100644
index 00000000000..af17457a10a
--- /dev/null
+++ b/src/test/ui/consts/promoted_const_call3.stderr
@@ -0,0 +1,105 @@
+error[E0493]: destructor of `String` cannot be evaluated at compile-time
+ --> $DIR/promoted_const_call3.rs:7:30
+ |
+LL | let _: &'static _ = &id(&String::new());
+ | ^^^^^^^^^^^^^ - value is dropped here
+ | |
+ | the destructor for this type cannot be evaluated in constants
+
+error[E0493]: destructor of `String` cannot be evaluated at compile-time
+ --> $DIR/promoted_const_call3.rs:3:26
+ |
+LL | let _: &'static _ = &String::new();
+ | ^^^^^^^^^^^^^ the destructor for this type cannot be evaluated in constants
+...
+LL | };
+ | - value is dropped here
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call3.rs:3:26
+ |
+LL | let _: &'static _ = &String::new();
+ | ---------- ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | };
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call3.rs:7:26
+ |
+LL | let _: &'static _ = &id(&String::new());
+ | ---------- ^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | };
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call3.rs:7:30
+ |
+LL | let _: &'static _ = &id(&String::new());
+ | ---------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
+ | | |
+ | | creates a temporary value which is freed while still in use
+ | type annotation requires that borrow lasts for `'static`
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call3.rs:12:26
+ |
+LL | let _: &'static _ = &std::mem::ManuallyDrop::new(String::new());
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+LL |
+LL | };
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call3.rs:17:26
+ |
+LL | let _: &'static _ = &String::new();
+ | ---------- ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call3.rs:20:26
+ |
+LL | let _: &'static _ = &id(&String::new());
+ | ---------- ^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call3.rs:20:30
+ |
+LL | let _: &'static _ = &id(&String::new());
+ | ---------- ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
+ | | |
+ | | creates a temporary value which is freed while still in use
+ | type annotation requires that borrow lasts for `'static`
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call3.rs:24:26
+ |
+LL | let _: &'static _ = &std::mem::ManuallyDrop::new(String::new());
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+LL |
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error: aborting due to 10 previous errors
+
+Some errors have detailed explanations: E0493, E0716.
+For more information about an error, try `rustc --explain E0493`.
diff --git a/src/test/ui/consts/promoted_const_call4.rs b/src/test/ui/consts/promoted_const_call4.rs
new file mode 100644
index 00000000000..82a17b7bf86
--- /dev/null
+++ b/src/test/ui/consts/promoted_const_call4.rs
@@ -0,0 +1,18 @@
+// run-pass
+
+use std::sync::atomic::*;
+
+static FLAG: AtomicBool = AtomicBool::new(false);
+
+struct NoisyDrop(&'static str);
+impl Drop for NoisyDrop {
+ fn drop(&mut self) {
+ FLAG.store(true, Ordering::SeqCst);
+ }
+}
+fn main() {
+ {
+ let _val = &&(NoisyDrop("drop!"), 0).1;
+ }
+ assert!(FLAG.load(Ordering::SeqCst));
+}
diff --git a/src/test/ui/consts/promoted_const_call5.rs b/src/test/ui/consts/promoted_const_call5.rs
new file mode 100644
index 00000000000..3ac8d358ce4
--- /dev/null
+++ b/src/test/ui/consts/promoted_const_call5.rs
@@ -0,0 +1,42 @@
+#![feature(rustc_attrs)]
+#![feature(staged_api)]
+#![stable(feature = "a", since = "1.0.0")]
+
+#[rustc_promotable]
+#[stable(feature = "a", since = "1.0.0")]
+#[rustc_const_stable(feature = "a", since = "1.0.0")]
+pub const fn id<T>(x: &'static T) -> &'static T { x }
+
+#[rustc_promotable]
+#[stable(feature = "a", since = "1.0.0")]
+#[rustc_const_stable(feature = "a", since = "1.0.0")]
+pub const fn new_string() -> String {
+ String::new()
+}
+
+#[rustc_promotable]
+#[stable(feature = "a", since = "1.0.0")]
+#[rustc_const_stable(feature = "a", since = "1.0.0")]
+pub const fn new_manually_drop<T>(t: T) -> std::mem::ManuallyDrop<T> {
+ std::mem::ManuallyDrop::new(t)
+}
+
+
+const C: () = {
+ let _: &'static _ = &id(&new_string());
+ //~^ ERROR destructor of `String` cannot be evaluated at compile-time
+ //~| ERROR: temporary value dropped while borrowed
+ //~| ERROR: temporary value dropped while borrowed
+
+ let _: &'static _ = &new_manually_drop(new_string());
+ //~^ ERROR: temporary value dropped while borrowed
+};
+
+fn main() {
+ let _: &'static _ = &id(&new_string());
+ //~^ ERROR: temporary value dropped while borrowed
+ //~| ERROR: temporary value dropped while borrowed
+
+ let _: &'static _ = &new_manually_drop(new_string());
+ //~^ ERROR: temporary value dropped while borrowed
+}
diff --git a/src/test/ui/consts/promoted_const_call5.stderr b/src/test/ui/consts/promoted_const_call5.stderr
new file mode 100644
index 00000000000..f736220b183
--- /dev/null
+++ b/src/test/ui/consts/promoted_const_call5.stderr
@@ -0,0 +1,74 @@
+error[E0493]: destructor of `String` cannot be evaluated at compile-time
+ --> $DIR/promoted_const_call5.rs:26:30
+ |
+LL | let _: &'static _ = &id(&new_string());
+ | ^^^^^^^^^^^^ - value is dropped here
+ | |
+ | the destructor for this type cannot be evaluated in constants
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call5.rs:26:26
+ |
+LL | let _: &'static _ = &id(&new_string());
+ | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | };
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call5.rs:26:30
+ |
+LL | let _: &'static _ = &id(&new_string());
+ | ----^^^^^^^^^^^^-- temporary value is freed at the end of this statement
+ | | |
+ | | creates a temporary value which is freed while still in use
+ | argument requires that borrow lasts for `'static`
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call5.rs:31:26
+ |
+LL | let _: &'static _ = &new_manually_drop(new_string());
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+LL |
+LL | };
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call5.rs:36:26
+ |
+LL | let _: &'static _ = &id(&new_string());
+ | ---------- ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call5.rs:36:30
+ |
+LL | let _: &'static _ = &id(&new_string());
+ | ----^^^^^^^^^^^^-- temporary value is freed at the end of this statement
+ | | |
+ | | creates a temporary value which is freed while still in use
+ | argument requires that borrow lasts for `'static`
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_call5.rs:40:26
+ |
+LL | let _: &'static _ = &new_manually_drop(new_string());
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+LL |
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error: aborting due to 7 previous errors
+
+Some errors have detailed explanations: E0493, E0716.
+For more information about an error, try `rustc --explain E0493`.