From 303dbccf040de2f61434dc7d716c5feed817fbdc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 16 Nov 2018 18:05:08 +0100 Subject: [PATCH 1/2] CTFE: dynamically make sure we do not call non-const-fn --- src/librustc_mir/const_eval.rs | 16 +++++++++++----- src/test/ui/consts/const-call.rs | 1 + src/test/ui/consts/const-call.stderr | 11 +++++++++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 7bff76f948e57..51046399ec201 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -365,13 +365,19 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx> ret: Option, ) -> 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) { diff --git a/src/test/ui/consts/const-call.rs b/src/test/ui/consts/const-call.rs index 18476494300b2..bd407192cd7a1 100644 --- a/src/test/ui/consts/const-call.rs +++ b/src/test/ui/consts/const-call.rs @@ -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 } diff --git a/src/test/ui/consts/const-call.stderr b/src/test/ui/consts/const-call.stderr index 81be93e916e8b..219fcec51b386 100644 --- a/src/test/ui/consts/const-call.stderr +++ b/src/test/ui/consts/const-call.stderr @@ -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`. From 0c0478d57a5bc3a85fb695b84c06d38494f70529 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 16 Nov 2018 18:38:28 +0100 Subject: [PATCH 2/2] adjust remaining tests --- src/test/compile-fail/const-fn-error.rs | 1 + src/test/compile-fail/issue-52443.rs | 1 + src/test/ui/issues/issue-39559-2.rs | 2 ++ src/test/ui/issues/issue-39559-2.stderr | 19 ++++++++++++++++--- src/test/ui/issues/issue-43105.rs | 2 ++ src/test/ui/issues/issue-43105.stderr | 18 +++++++++++++++++- 6 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/test/compile-fail/const-fn-error.rs b/src/test/compile-fail/const-fn-error.rs index 83f2735aa9d8e..17dc9f94fe19c 100644 --- a/src/test/compile-fail/const-fn-error.rs +++ b/src/test/compile-fail/const-fn-error.rs @@ -19,6 +19,7 @@ const fn f(x: usize) -> usize { for i in 0..x { //~^ ERROR E0015 //~| ERROR E0019 + //~| ERROR E0080 sum += i; } sum diff --git a/src/test/compile-fail/issue-52443.rs b/src/test/compile-fail/issue-52443.rs index fc42f87ccbfda..1ed513033fd5d 100644 --- a/src/test/compile-fail/issue-52443.rs +++ b/src/test/compile-fail/issue-52443.rs @@ -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 } diff --git a/src/test/ui/issues/issue-39559-2.rs b/src/test/ui/issues/issue-39559-2.rs index 2e480a29774ce..f01fd1fd8f144 100644 --- a/src/test/ui/issues/issue-39559-2.rs +++ b/src/test/ui/issues/issue-39559-2.rs @@ -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 } diff --git a/src/test/ui/issues/issue-39559-2.stderr b/src/test/ui/issues/issue-39559-2.stderr index ca9da096b6c16..57e9f23e0b33c 100644 --- a/src/test/ui/issues/issue-39559-2.stderr +++ b/src/test/ui/issues/issue-39559-2.stderr @@ -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 `::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 `::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`. diff --git a/src/test/ui/issues/issue-43105.rs b/src/test/ui/issues/issue-43105.rs index 2bddc443d5baf..60b18a66f1a38 100644 --- a/src/test/ui/issues/issue-43105.rs +++ b/src/test/ui/issues/issue-43105.rs @@ -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!(), } } diff --git a/src/test/ui/issues/issue-43105.stderr b/src/test/ui/issues/issue-43105.stderr index 67a6008cd8ebc..f26447ed2b9f0 100644 --- a/src/test/ui/issues/issue-43105.stderr +++ b/src/test/ui/issues/issue-43105.stderr @@ -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`.