diff options
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/promote_consts.rs | 14 | ||||
| -rw-r--r-- | src/test/ui/consts/promoted_const_call.rs | 19 | ||||
| -rw-r--r-- | src/test/ui/consts/promoted_const_call.stderr | 65 | ||||
| -rw-r--r-- | src/test/ui/consts/promoted_const_call2.rs | 14 | ||||
| -rw-r--r-- | src/test/ui/consts/promoted_const_call2.stderr | 50 | ||||
| -rw-r--r-- | src/test/ui/consts/promoted_const_call3.rs | 26 | ||||
| -rw-r--r-- | src/test/ui/consts/promoted_const_call3.stderr | 105 | ||||
| -rw-r--r-- | src/test/ui/consts/promoted_const_call4.rs | 18 | ||||
| -rw-r--r-- | src/test/ui/consts/promoted_const_call5.rs | 42 | ||||
| -rw-r--r-- | src/test/ui/consts/promoted_const_call5.stderr | 74 |
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`. |
