Auto merge of #53851 - oli-obk:local_promotion, r=eddyb

Limit the promotion of const fns to the libstd and the `rustc_promotable` attribute

There are so many questions around promoting const fn calls... it seems saner to try to limit automatic promotion to const fns which were explicitly opted in for promotion.

I added the attribute to all public stable const fns that were already promotable (e.g. not Cell::new) in order to not cause any breakage

r? @eddyb

cc @nikomatsakis
This commit is contained in:
bors 2018-10-04 06:48:13 +00:00
commit 088fc7384c
45 changed files with 484 additions and 335 deletions

View file

@ -14,7 +14,8 @@
// compile-flags: -C debug_assertions=yes
#![feature(const_fn, libc)]
#![stable(feature = "rustc", since = "1.0.0")]
#![feature(const_fn, libc, staged_api, rustc_attrs)]
#![allow(const_err)]
extern crate libc;
@ -23,6 +24,8 @@ use std::env;
use std::process::{Command, Stdio};
// this will panic in debug mode and overflow in release mode
#[stable(feature = "rustc", since = "1.0.0")]
#[rustc_promotable]
const fn bar() -> usize { 0 - 1 }
fn foo() {

View file

@ -13,13 +13,15 @@
use std::cell::Cell;
const FIVE: Cell<i32> = Cell::new(5);
#[inline(never)]
fn tuple_field() -> &'static u32 {
// This test is MIR-borrowck-only because the old borrowck
// doesn't agree that borrows of "frozen" (i.e. without any
// interior mutability) fields of non-frozen temporaries,
// should be promoted, while MIR promotion does promote them.
&(Cell::new(5), 42).1
&(FIVE, 42).1
}
fn main() {

View file

@ -15,5 +15,4 @@ fn f(x: usize) -> usize {
fn main() {
let _ = [0; f(2)];
//~^ ERROR calls in constants are limited to constant functions
//~| E0080
}

View file

@ -4,13 +4,6 @@ error[E0015]: calls in constants are limited to constant functions, tuple struct
LL | let _ = [0; f(2)];
| ^^^^
error[E0080]: could not evaluate repeat length
--> $DIR/const-call.rs:16:17
|
LL | let _ = [0; f(2)];
| ^^^^ calling non-const fn `f`
error: aborting due to previous error
error: aborting due to 2 previous errors
Some errors occurred: E0015, E0080.
For more information about an error, try `rustc --explain E0015`.
For more information about this error, try `rustc --explain E0015`.

View file

@ -32,7 +32,7 @@ error[E0716]: temporary value dropped while borrowed
|
LL | let x: &'static _ = &std::time::Duration::from_millis(42).subsec_millis();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
LL | //~^ does not live long enough
LL | //~^ ERROR does not live long enough
LL | }
| - temporary value is freed at the end of this statement
|

View file

@ -31,5 +31,5 @@ fn a() {
fn main() {
let _: &'static u32 = &meh(); //~ ERROR does not live long enough
let x: &'static _ = &std::time::Duration::from_millis(42).subsec_millis();
//~^ does not live long enough
//~^ ERROR does not live long enough
}

View file

@ -32,7 +32,7 @@ error[E0597]: borrowed value does not live long enough
|
LL | let x: &'static _ = &std::time::Duration::from_millis(42).subsec_millis();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ temporary value does not live long enough
LL | //~^ does not live long enough
LL | //~^ ERROR does not live long enough
LL | }
| - temporary value only lives until here
|

View file

@ -1,51 +0,0 @@
error[E0308]: mismatched types
--> $DIR/issue-52443.rs:12:10
|
LL | [(); & { loop { continue } } ]; //~ ERROR mismatched types
| ^^^^^^^^^^^^^^^^^^^^^^^
| |
| expected usize, found reference
| help: consider removing the borrow: `{ loop { continue } }`
|
= note: expected type `usize`
found type `&_`
error[E0308]: mismatched types
--> $DIR/issue-52443.rs:13:17
|
LL | [(); loop { break }]; //~ ERROR mismatched types
| ^^^^^ expected (), found usize
|
= note: expected type `()`
found type `usize`
error[E0019]: constant contains unimplemented expression type
--> $DIR/issue-52443.rs:14:11
|
LL | [(); {while true {break}; 0}]; //~ ERROR constant contains unimplemented expression type
| ^^^^^^^^^^^^^^^^^^
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
--> $DIR/issue-52443.rs:15:21
|
LL | [(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
| ^^^^^^^^
error[E0019]: constant contains unimplemented expression type
--> $DIR/issue-52443.rs:15:21
|
LL | [(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
| ^^^^^^^^
error[E0080]: could not evaluate repeat length
--> $DIR/issue-52443.rs:15:10
|
LL | [(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
| ^^^^^^^^^^^--------^^^^^^^
| |
| calling non-const fn `<I as std::iter::IntoIterator><std::ops::RangeFrom<usize>>::into_iter`
error: aborting due to 6 previous errors
Some errors occurred: E0015, E0019, E0080, E0308.
For more information about an error, try `rustc --explain E0015`.

View file

@ -0,0 +1,14 @@
error[E0716]: temporary value dropped while borrowed
--> $DIR/promoted_const_fn_fail.rs:30:27
|
LL | let x: &'static u8 = &(bar() + 1); //~ ERROR does not live long enough
| ^^^^^^^^^^^ creates a temporary which is freed while still in use
...
LL | }
| - temporary value is freed at the end of this statement
|
= note: borrowed value must be valid for the static lifetime...
error: aborting due to previous error
For more information about this error, try `rustc --explain E0716`.

View file

@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// compile-pass
#![feature(const_fn, const_fn_union)]
#![deny(const_err)]
@ -29,10 +27,7 @@ const fn bar() -> u8 {
}
fn main() {
// FIXME(oli-obk): this should panic at runtime
// this will actually compile, but then
// abort at runtime (not panic, hard abort).
let x: &'static u8 = &(bar() + 1);
let x: &'static u8 = &(bar() + 1); //~ ERROR does not live long enough
let y = *x;
unreachable!();
}

View file

@ -0,0 +1,14 @@
error[E0597]: borrowed value does not live long enough
--> $DIR/promoted_const_fn_fail.rs:30:27
|
LL | let x: &'static u8 = &(bar() + 1); //~ ERROR does not live long enough
| ^^^^^^^^^^^ temporary value does not live long enough
...
LL | }
| - temporary value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
error: aborting due to previous error
For more information about this error, try `rustc --explain E0597`.

View file

@ -1,43 +0,0 @@
error[E0658]: let bindings in constant functions are unstable (see issue #48821)
--> $DIR/const-fn-error.rs:16:19
|
LL | let mut sum = 0;
| ^
|
= help: add #![feature(const_let)] to the crate attributes to enable
error[E0658]: statements in constant functions are unstable (see issue #48821)
--> $DIR/const-fn-error.rs:16:19
|
LL | let mut sum = 0;
| ^
|
= help: add #![feature(const_let)] to the crate attributes to enable
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
--> $DIR/const-fn-error.rs:19:14
|
LL | for i in 0..x {
| ^^^^
error[E0019]: constant function contains unimplemented expression type
--> $DIR/const-fn-error.rs:19:14
|
LL | for i in 0..x {
| ^^^^
error[E0080]: could not evaluate constant expression
--> $DIR/const-fn-error.rs:29:13
|
LL | for i in 0..x {
| ---- calling non-const fn `<I as std::iter::IntoIterator><std::ops::Range<usize>>::into_iter`
...
LL | let a : [i32; f(X)]; //~ ERROR E0080
| ^^^^^^----^
| |
| inside call to `f`
error: aborting due to 5 previous errors
Some errors occurred: E0015, E0019, E0080, E0658.
For more information about an error, try `rustc --explain E0015`.

View file

@ -0,0 +1,68 @@
error[E0716]: temporary value dropped while borrowed
--> $DIR/promotion.rs:13:27
|
LL | let x: &'static () = &foo1(); //~ ERROR does not live long enough
| ^^^^^^ creates a temporary which is freed while still in use
...
LL | }
| - temporary value is freed at the end of this statement
|
= note: borrowed value must be valid for the static lifetime...
error[E0716]: temporary value dropped while borrowed
--> $DIR/promotion.rs:14:28
|
LL | let y: &'static i32 = &foo2(42); //~ ERROR does not live long enough
| ^^^^^^^^ creates a temporary which is freed while still in use
...
LL | }
| - temporary value is freed at the end of this statement
|
= note: borrowed value must be valid for the static lifetime...
error[E0716]: temporary value dropped while borrowed
--> $DIR/promotion.rs:15:28
|
LL | let z: &'static i32 = &foo3(); //~ ERROR does not live long enough
| ^^^^^^ creates a temporary which is freed while still in use
...
LL | }
| - temporary value is freed at the end of this statement
|
= note: borrowed value must be valid for the static lifetime...
error[E0716]: temporary value dropped while borrowed
--> $DIR/promotion.rs:16:34
|
LL | let a: &'static Cell<i32> = &foo4(); //~ ERROR does not live long enough
| ^^^^^^ creates a temporary which is freed while still in use
...
LL | }
| - temporary value is freed at the end of this statement
|
= note: borrowed value must be valid for the static lifetime...
error[E0716]: temporary value dropped while borrowed
--> $DIR/promotion.rs:17:42
|
LL | let a: &'static Option<Cell<i32>> = &foo5(); //~ ERROR does not live long enough
| ^^^^^^ creates a temporary which is freed while still in use
LL | let a: &'static Option<Cell<i32>> = &foo6(); //~ ERROR does not live long enough
LL | }
| - temporary value is freed at the end of this statement
|
= note: borrowed value must be valid for the static lifetime...
error[E0716]: temporary value dropped while borrowed
--> $DIR/promotion.rs:18:42
|
LL | let a: &'static Option<Cell<i32>> = &foo6(); //~ ERROR does not live long enough
| ^^^^^^ creates a temporary which is freed while still in use
LL | }
| - temporary value is freed at the end of this statement
|
= note: borrowed value must be valid for the static lifetime...
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0716`.

View file

@ -0,0 +1,19 @@
#![feature(min_const_fn)]
use std::cell::Cell;
const fn foo1() {}
const fn foo2(x: i32) -> i32 { x }
const fn foo3() -> i32 { 42 }
const fn foo4() -> Cell<i32> { Cell::new(42) }
const fn foo5() -> Option<Cell<i32>> { Some(Cell::new(42)) }
const fn foo6() -> Option<Cell<i32>> { None }
fn main() {
let x: &'static () = &foo1(); //~ ERROR does not live long enough
let y: &'static i32 = &foo2(42); //~ ERROR does not live long enough
let z: &'static i32 = &foo3(); //~ ERROR does not live long enough
let a: &'static Cell<i32> = &foo4(); //~ ERROR does not live long enough
let a: &'static Option<Cell<i32>> = &foo5(); //~ ERROR does not live long enough
let a: &'static Option<Cell<i32>> = &foo6(); //~ ERROR does not live long enough
}

View file

@ -0,0 +1,68 @@
error[E0597]: borrowed value does not live long enough
--> $DIR/promotion.rs:13:27
|
LL | let x: &'static () = &foo1(); //~ ERROR does not live long enough
| ^^^^^^ temporary value does not live long enough
...
LL | }
| - temporary value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
error[E0597]: borrowed value does not live long enough
--> $DIR/promotion.rs:14:28
|
LL | let y: &'static i32 = &foo2(42); //~ ERROR does not live long enough
| ^^^^^^^^ temporary value does not live long enough
...
LL | }
| - temporary value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
error[E0597]: borrowed value does not live long enough
--> $DIR/promotion.rs:15:28
|
LL | let z: &'static i32 = &foo3(); //~ ERROR does not live long enough
| ^^^^^^ temporary value does not live long enough
...
LL | }
| - temporary value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
error[E0597]: borrowed value does not live long enough
--> $DIR/promotion.rs:16:34
|
LL | let a: &'static Cell<i32> = &foo4(); //~ ERROR does not live long enough
| ^^^^^^ temporary value does not live long enough
...
LL | }
| - temporary value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
error[E0597]: borrowed value does not live long enough
--> $DIR/promotion.rs:17:42
|
LL | let a: &'static Option<Cell<i32>> = &foo5(); //~ ERROR does not live long enough
| ^^^^^^ temporary value does not live long enough
LL | let a: &'static Option<Cell<i32>> = &foo6(); //~ ERROR does not live long enough
LL | }
| - temporary value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
error[E0597]: borrowed value does not live long enough
--> $DIR/promotion.rs:18:42
|
LL | let a: &'static Option<Cell<i32>> = &foo6(); //~ ERROR does not live long enough
| ^^^^^^ temporary value does not live long enough
LL | }
| - temporary value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0597`.

View file

@ -23,8 +23,6 @@ impl Dim for Dim3 {
fn main() {
let array: [usize; Dim3::dim()]
//~^ ERROR E0015
//~| ERROR E0080
= [0; Dim3::dim()];
//~^ ERROR E0015
//~| ERROR E0080
}

View file

@ -5,26 +5,11 @@ LL | let array: [usize; Dim3::dim()]
| ^^^^^^^^^^^
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
--> $DIR/issue-39559-2.rs:27:15
--> $DIR/issue-39559-2.rs:26:15
|
LL | = [0; Dim3::dim()];
| ^^^^^^^^^^^
error[E0080]: could not evaluate repeat length
--> $DIR/issue-39559-2.rs:27:15
|
LL | = [0; Dim3::dim()];
| ^^^^^^^^^^^ calling non-const fn `<Dim3 as Dim>::dim`
error: aborting due to 2 previous errors
error[E0080]: could not evaluate constant expression
--> $DIR/issue-39559-2.rs:24:16
|
LL | let array: [usize; Dim3::dim()]
| ^^^^^^^^-----------^
| |
| calling non-const fn `<Dim3 as Dim>::dim`
error: aborting due to 4 previous errors
Some errors occurred: E0015, E0080.
For more information about an error, try `rustc --explain E0015`.
For more information about this error, try `rustc --explain E0015`.

View file

@ -16,7 +16,6 @@ const NUM: u8 = xyz();
fn main() {
match 1 {
NUM => unimplemented!(),
//~^ ERROR could not evaluate constant pattern
_ => unimplemented!(),
}
}

View file

@ -4,16 +4,6 @@ error[E0015]: calls in constants are limited to constant functions, tuple struct
LL | const NUM: u8 = xyz();
| ^^^^^
error[E0080]: could not evaluate constant pattern
--> $DIR/issue-43105.rs:18:9
|
LL | const NUM: u8 = xyz();
| ----- calling non-const fn `xyz`
...
LL | NUM => unimplemented!(),
| ^^^
error: aborting due to previous error
error: aborting due to 2 previous errors
Some errors occurred: E0015, E0080.
For more information about an error, try `rustc --explain E0015`.
For more information about this error, try `rustc --explain E0015`.

View file

@ -27,7 +27,8 @@ const fn baz() -> i32 {
fn main() {
foo(2);
foo(2 + 3);
foo(baz());
const BAZ: i32 = baz();
foo(BAZ);
let a = 4;
foo(A);
foo(a); //~ ERROR: argument 1 is required to be a constant

View file

@ -1,11 +1,11 @@
error: argument 1 is required to be a constant
--> $DIR/rustc-args-required-const.rs:33:5
--> $DIR/rustc-args-required-const.rs:34:5
|
LL | foo(a); //~ ERROR: argument 1 is required to be a constant
| ^^^^^^
error: argument 2 is required to be a constant
--> $DIR/rustc-args-required-const.rs:35:5
--> $DIR/rustc-args-required-const.rs:36:5
|
LL | bar(a, a); //~ ERROR: argument 2 is required to be a constant
| ^^^^^^^^^