E3048

E3048 — An if with no else whose value is used, as in let u = if c { .. };. When the condition is false there is no branch to give a value. Add an else, or use the if as a statement.

What the compiler reports

Error[E3048] at [[@LINE+1]]:10: this `if` has no `else`
Error[E3048] at [[@LINE+1]]:5:
Error[E3048] at [[@LINE+1]]:5:
Error[E3048] at [[@LINE+1]]:11:
4 error(s) emitted

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
//
// An `if` with no `else` has no value when its condition is false, so its value cannot be
// used: not bound by `let`, returned, or given as the value of an enclosing `if` or
// `spawn`. As a statement, including the last one in a `void` function or in a `spawn`
// used as a statement, it is fine.
//

fn report(c: bool) -> void {
  if c {
    print("as a statement ");
  }
}

fn pick(c: bool) -> i32 {
  return if c {
    1
  };
}

fn nested(a: bool, b: bool) -> i32 {
  let n = if a {
    1
  } else {
    if b {
      2
    }
  };
  return n;
}

fn spawned(c: bool) -> i32 {
  spawn on(Topology::CPU) {
    if c {
      print("in a region ");
    }
  }
  let _v = spawn on(Topology::CPU) {
    if c {
      1
    }
  };
  return 0;
}

fn main() -> i32 {
  let x : i32 = 3;
  let u = if x > 2 {
    print("big");
  };
  report(true);
  return pick(true) + nested(true, false) + spawned(true);
}

From tests/frontend/fail/if_without_else_used_as_a_value.vx, which asserts this diagnostic on every commit.

Related