E3060

E3060 — A task that can fail, used in a way that could lose its failure. A task whose body gives Result<T, E> can fail, and its join() gives the T. When the task failed, the join leaves the tasks block, and the block gives the Err. So the task needs a handle, let h = spawn { .. };, and a join in its own block that always runs after the spawn. The block must give a Result<U, E> with the same E.

What the compiler reports

Error[E3060] at {{.*}}.vx:[[@LINE+3]]:5: this task can fail with 'i32', so it needs a handle that the `tasks` block joins: `let h = spawn { .. };` and then `h.join()`

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 `return` in a task gives the value of the task, so it must have the type of the last value
// of the task. A `?` in a task makes a task that can fail, so the task needs a handle.
//

import core::result;

fn plus(n : i32) -> Result<i32, i32> {
  return Result<i32, i32>::Ok(n + 1);
}

fn return_of_another_type(c : bool) -> bool {
  let r = tasks {
    let h = spawn {
      if c {
        return 1;
      }
      true
    };
    h.join()
  };
  return r;
}

fn question_mark_in_a_task_with_no_handle(n : i32) -> void {
  tasks {
    spawn {
      plus(n)?;
    };
  }
}

fn main() -> i32 {
  return 0;
}

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

Related