E3028
E3028 — A function with a non-void return type whose body can complete without returning. Reported here rather than left to codegen, where it surfaced as an MLIR verifier message naming an operation, with no source location.
What the compiler reports
E3028] at {{[1-9][0-9]*}}:{{[0-9]+}}: 'falls_off_the_end' returns i32 but its body can finish without returning a value
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
//
// A function that promises a value and can finish without producing one. This used to reach
// codegen: the emitter left a block with no terminator and the MLIR verifier reported it as
// `block with no terminator, has %1 = "arith.addi"(...)` -- an operation name, no source
// location, and no statement of what was wrong. For what is probably the most common mistake a
// newcomer makes.
//
// The location is the last statement, which is where the missing `return` belongs.
//
fn falls_off_the_end(x : i32) -> i32 {
let y : i32 = x + 1;
}
fn empty(x : i32) -> i32 {
}
// One branch returning is not enough -- the other path reaches the end.
fn only_one_branch(x : i32) -> i32 {
if x > 0 {
return 1;
}
}
fn main() -> i32 {
return 0;
}
From tests/frontend/fail/missing_return.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.
E3027A function whose return type is a closure. A closure value points into the frame that made it, so it cannot outlive that frame yet.
E3029A type name in a signature that names no declaration. An unknown name in type position parses as a user nominal, so without this a typo — or a type constructor removed from the language — compiled silently and did nothing.