E3063
E3063 — A?that cannot pass its error up.x?takes aResult<T, E>. It gives theTof anOk, and it passes anErrup unchanged: to the function, which must return aResult<_, E>with the sameE, to its closure, which must return one, or to its task ortasksblock, which must give one. A?in a closure needs the closure's type written,|x| -> Result<T, E> { .. }.?does not convert the error..map_err(..)converts it.
What the compiler reports
Error[E3063] at {{.*}}.vx:[[@LINE+2]]:4: `?` takes a `Result<T, E>`. This value has the type 'i32'
Error[E3063] at {{.*}}.vx:[[@LINE+3]]:4: `?` takes a `Result<T, E>`. This value has the type 'Option<i32>'. For an `Option`, use a `match`, or `.ok_or(e)?` with an error `e`
Error[E3063] at {{.*}}.vx:[[@LINE+2]]:17: this `?` passes up an error of type 'i32', so the function must return a `Result<_, i32>`. It returns 'i32'
Error[E3063] at {{.*}}.vx:[[@LINE+2]]:18: this `?` passes up an error of type 'i64', so the function must return a `Result<_, i64>`. It returns 'Result<i32, i32>'
Error[E3063] at {{.*}}.vx:[[@LINE+3]]:20: this `?` passes up an error of type 'i32', so its `tasks` block must give a `Result<_, i32>`. The block gives 'Result<i32, i64>'
Error[E3063] at {{.*}}.vx:[[@LINE+4]]:14: this `?` passes up an error of type 'i32', so its task must give a `Result<_, i32>`. The task gives 'i32'
Error[E3063] at {{.*}}.vx:[[@LINE+2]]:28: a `?` in a closure needs the type that the closure returns. Write it: `|..| -> Result<T, i32> { .. }`
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
//
// `x?` passes the `Err` of a `Result` up unchanged, to the function or to its `tasks` block.
// Each function here uses `?` where it cannot do that.
//
import core::option;
import core::result;
fn plus(n : i32) -> Result<i32, i32> {
return Result<i32, i32>::Ok(n + 1);
}
fn wide(n : i32) -> Result<i32, i64> {
return Result<i32, i64>::Ok(n);
}
fn not_a_result(n : i32) -> Result<i32, i32> {
n?;
return Result<i32, i32>::Ok(n);
}
// A Rust programmer may write `?` on an `Option`.
fn on_an_option(n : i32) -> Result<i32, i32> {
let o = Option<i32>::Some(n);
o?;
return Result<i32, i32>::Ok(n);
}
fn returns_a_number(n : i32) -> i32 {
return plus(n)?;
}
// `?` does not convert an `i64` error to an `i32`.
fn other_error(n : i32) -> Result<i32, i32> {
let x = wide(n)?;
return Result<i32, i32>::Ok(x);
}
fn block_of_other_error(n : i32) -> Result<i32, i64> {
let r = tasks {
let x = plus(n)?;
Result<i32, i64>::Ok(x)
};
return r;
}
fn in_a_task_that_gives_no_result(n : i32) -> i32 {
let r = tasks {
let h = spawn {
plus(n)?
};
h.join()
};
return r;
}
fn in_a_closure_with_no_written_type(n : i32) -> Result<i32, i32> {
let f = |x : i32| plus(x)?;
return Result<i32, i32>::Ok(f(n));
}
fn main() -> i32 {
return 0;
}
From tests/frontend/fail/a_question_mark_that_cannot_pass_its_error_up.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.
E3062A struct literal that writes its fields in an order other than the struct's declaration. The fields run in the order the source writes them, so
P { y : f(), x : g() } would run f before g and store y before x. Write the fields in the order the struct declares them.