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