Skip to content

Commit

Permalink
Auto merge of #105085 - oli-obk:stop_promoting_all_the_things, r=Ralf…
Browse files Browse the repository at this point in the history
…Jung

Stop promoting all the things

fixes #91009

r? `@RalfJung`
  • Loading branch information
bors committed Dec 24, 2022
2 parents 8766bbd + b4a6047 commit f5c3dfd
Show file tree
Hide file tree
Showing 10 changed files with 419 additions and 8 deletions.
14 changes: 6 additions & 8 deletions compiler/rustc_const_eval/src/transform/promote_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(),
Expand Down Expand Up @@ -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];
Expand Down
19 changes: 19 additions & 0 deletions src/test/ui/consts/promoted_const_call.rs
Original file line number Diff line number Diff line change
@@ -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
}
65 changes: 65 additions & 0 deletions src/test/ui/consts/promoted_const_call.stderr
Original file line number Diff line number Diff line change
@@ -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`.
14 changes: 14 additions & 0 deletions src/test/ui/consts/promoted_const_call2.rs
Original file line number Diff line number Diff line change
@@ -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
}
50 changes: 50 additions & 0 deletions src/test/ui/consts/promoted_const_call2.stderr
Original file line number Diff line number Diff line change
@@ -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`.
26 changes: 26 additions & 0 deletions src/test/ui/consts/promoted_const_call3.rs
Original file line number Diff line number Diff line change
@@ -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
}
105 changes: 105 additions & 0 deletions src/test/ui/consts/promoted_const_call3.stderr
Original file line number Diff line number Diff line change
@@ -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`.
18 changes: 18 additions & 0 deletions src/test/ui/consts/promoted_const_call4.rs
Original file line number Diff line number Diff line change
@@ -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));
}
42 changes: 42 additions & 0 deletions src/test/ui/consts/promoted_const_call5.rs
Original file line number Diff line number Diff line change
@@ -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
}
Loading

0 comments on commit f5c3dfd

Please sign in to comment.