Skip to content

Commit

Permalink
Rollup merge of #56007 - RalfJung:non-const-call, r=oli-obk
Browse files Browse the repository at this point in the history
CTFE: dynamically make sure we do not call non-const-fn

I'd love to have a test case for this, but I don't know how.

I am also really surprised by this test case that changed behavior: Why did it even start execution if it already determined that it shouldn't?!?

r? @oli-obk
  • Loading branch information
pietroalbini authored and kennytm committed Nov 19, 2018
2 parents cc6473d + 0c0478d commit c0d48ce
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 11 deletions.
16 changes: 11 additions & 5 deletions src/librustc_mir/const_eval.rs
Expand Up @@ -365,13 +365,19 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
ret: Option<mir::BasicBlock>,
) -> EvalResult<'tcx, Option<&'mir mir::Mir<'tcx>>> {
debug!("eval_fn_call: {:?}", instance);
if !ecx.tcx.is_const_fn(instance.def_id()) {
// Execution might have wandered off into other crates, so we cannot to a stability-
// sensitive check here. But we can at least rule out functions that are not const
// at all.
if !ecx.tcx.is_const_fn_raw(instance.def_id()) {
// Some functions we support even if they are non-const -- but avoid testing
// that for const fn!
if ecx.hook_fn(instance, args, dest)? {
// that for const fn! We certainly do *not* want to actually call the fn
// though, so be sure we return here.
return if ecx.hook_fn(instance, args, dest)? {
ecx.goto_block(ret)?; // fully evaluated and done
return Ok(None);
}
Ok(None)
} else {
err!(MachineError(format!("calling non-const function `{}`", instance)))
};
}
// This is a const fn. Call it.
Ok(Some(match ecx.load_mir(instance.def) {
Expand Down
1 change: 1 addition & 0 deletions src/test/compile-fail/const-fn-error.rs
Expand Up @@ -19,6 +19,7 @@ const fn f(x: usize) -> usize {
for i in 0..x {
//~^ ERROR E0015
//~| ERROR E0019
//~| ERROR E0080
sum += i;
}
sum
Expand Down
1 change: 1 addition & 0 deletions src/test/compile-fail/issue-52443.rs
Expand Up @@ -14,4 +14,5 @@ fn main() {
[(); {while true {break}; 0}]; //~ ERROR constant contains unimplemented expression type
[(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
//~^ ERROR constant contains unimplemented expression type
//~| ERROR evaluation of constant value failed
}
1 change: 1 addition & 0 deletions src/test/ui/consts/const-call.rs
Expand Up @@ -15,4 +15,5 @@ fn f(x: usize) -> usize {
fn main() {
let _ = [0; f(2)];
//~^ ERROR calls in constants are limited to constant functions
//~| ERROR evaluation of constant value failed
}
11 changes: 9 additions & 2 deletions src/test/ui/consts/const-call.stderr
Expand Up @@ -4,6 +4,13 @@ error[E0015]: calls in constants are limited to constant functions, tuple struct
LL | let _ = [0; f(2)];
| ^^^^

error: aborting due to previous error
error[E0080]: evaluation of constant value failed
--> $DIR/const-call.rs:16:17
|
LL | let _ = [0; f(2)];
| ^^^^ calling non-const function `f`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0015`.
Some errors occurred: E0015, E0080.
For more information about an error, try `rustc --explain E0015`.
2 changes: 2 additions & 0 deletions src/test/ui/issues/issue-39559-2.rs
Expand Up @@ -23,6 +23,8 @@ impl Dim for Dim3 {
fn main() {
let array: [usize; Dim3::dim()]
//~^ ERROR E0015
//~| ERROR E0080
= [0; Dim3::dim()];
//~^ ERROR E0015
//~| ERROR E0080
}
19 changes: 16 additions & 3 deletions src/test/ui/issues/issue-39559-2.stderr
Expand Up @@ -4,12 +4,25 @@ error[E0015]: calls in constants are limited to constant functions, tuple struct
LL | let array: [usize; Dim3::dim()]
| ^^^^^^^^^^^

error[E0080]: evaluation of constant value failed
--> $DIR/issue-39559-2.rs:24:24
|
LL | let array: [usize; Dim3::dim()]
| ^^^^^^^^^^^ calling non-const function `<Dim3 as Dim>::dim`

error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
--> $DIR/issue-39559-2.rs:26:15
--> $DIR/issue-39559-2.rs:27:15
|
LL | = [0; Dim3::dim()];
| ^^^^^^^^^^^

error: aborting due to 2 previous errors
error[E0080]: evaluation of constant value failed
--> $DIR/issue-39559-2.rs:27:15
|
LL | = [0; Dim3::dim()];
| ^^^^^^^^^^^ calling non-const function `<Dim3 as Dim>::dim`

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0015`.
Some errors occurred: E0015, E0080.
For more information about an error, try `rustc --explain E0015`.
2 changes: 2 additions & 0 deletions src/test/ui/issues/issue-43105.rs
Expand Up @@ -12,10 +12,12 @@ fn xyz() -> u8 { 42 }

const NUM: u8 = xyz();
//~^ ERROR calls in constants are limited to constant functions, tuple structs and tuple variants
//~| ERROR any use of this value will cause an error [const_err]

fn main() {
match 1 {
NUM => unimplemented!(),
//~^ ERROR could not evaluate constant pattern
_ => unimplemented!(),
}
}
18 changes: 17 additions & 1 deletion src/test/ui/issues/issue-43105.stderr
Expand Up @@ -4,6 +4,22 @@ error[E0015]: calls in constants are limited to constant functions, tuple struct
LL | const NUM: u8 = xyz();
| ^^^^^

error: aborting due to previous error
error: any use of this value will cause an error
--> $DIR/issue-43105.rs:13:1
|
LL | const NUM: u8 = xyz();
| ^^^^^^^^^^^^^^^^-----^
| |
| calling non-const function `xyz`
|
= note: #[deny(const_err)] on by default

error: could not evaluate constant pattern
--> $DIR/issue-43105.rs:19:9
|
LL | NUM => unimplemented!(),
| ^^^

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0015`.

0 comments on commit c0d48ce

Please sign in to comment.