E3033
E3033 — A comptime block the evaluator could not finish. The block runs during compilation and leaves nothing behind, so one that cannot be run has no meaning — and used to be emitted as ordinary run-time code, which hid the fact entirely.
What the compiler reports
Error[E3033]{{.*}}cannot be evaluated
Error[E3033]{{.*}}writes to 'outside'
The fragments the test suite holds the compiler to. An ellipsis marks text the test does not constrain; the emitted message also carries a source location.
A program that triggers it
//
// Part of the Vx Project, under the Apache License v2.0 with LLVM Exceptions.
// See LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// A `comptime` block the evaluator cannot finish is refused.
//
// The block runs while compiling and leaves nothing behind, so there is no such thing as
// one that half-ran. Until this was an error such a block was emitted as ordinary
// run-time code, which is precisely what let a skipped loop or call go unnoticed.
//
// `held` calls a function through a bare call statement, which the evaluator does not
// run, so the block has no value for it.
//
fn noop() -> void {
return;
}
fn held() -> i64 {
let mut total : i64 = 0i64;
noop();
total = 5i64;
return total;
}
fn main() -> i32 {
let n = comptime {
let v : i64 = held();
v
};
// A block that writes to something declared outside it. The block disappears, so the
// write would have to disappear with it -- which is how this shape used to turn a
// program that printed 4 into one that printed 0, quietly.
let mut outside : i64 = 0i64;
comptime {
outside = 4i64;
}
return 0;
}
From tests/frontend/fail/comptime_block_cannot_be_evaluated.vx, which asserts this diagnostic on every commit.
Related
A tour of VxThe chapter covering the rule this code enforces.
All diagnosticsEvery code the compiler can emit, grouped by stage.
E3032A chain of generic instantiations that does not end —
f<N - 1>() whose base case is never reached. Reported here rather than left to run out of stack, which gave no file, no line and no message.
E3034A comptime block inside another one. The outer block already runs at compile time, so the inner one asks for nothing extra, and nesting them is what made a block's value depend on evaluating a closure defined inside another block.