Wait, so what do you want to behaviour to be when using ??
Try blocks act as a closure; they return an Option/Result:
let x: Option<usize> = try {
Some(3)?
};
x is still an Option, and the ? operator just broke out of the try block instead of the most local function.
Additionally, if you want this to work:
fn foo() { // -> () implicitly
None?;
println!("Hello, World");
}
And print Hello, World, then what would be needed is to implement From<NoneError> for ().
The behaviour of ? on a type is dictated by std::ops::Try, which when used on an Option, its Err type is NoneError.
As stated in the docs:
The error type that results from applying the try operator ( ? ) to a None value. If you wish to allow x? (where x is an Option<T> ) to be converted into your error type, you can implement impl From<NoneError> for YourErrorType . In that case, x? within a function that returns Result<_, YourErrorType> will translate a None value into an Err result.
Hence, if you want to be able to use ? on a None variant to return early out of a () returning function, std would have to add an implementation for From<NoneError> for ().
Unfortunately, that might cause even more ambiguity errors:
fn foo() -> Option<()> {
(|| None?)()
}
Works fine, however lets introduce a mock Unit type to replace () upon which we can implement our own traits:
#![feature(try_trait)]
use std::option::NoneError;
struct Unit;
impl From<NoneError> for Unit {
fn from(x: NoneError) -> Self {
Unit
}
}
fn foo() -> Unit {
(|| None?)()?;
Unit
}
However, even this produces an error:
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
--> src/main.rs:14:5
|
13 | / fn foo() -> Unit {
14 | | (|| None?)()?;
| | ^^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `Unit`
15 | |
16 | | Unit
17 | | }
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `std::ops::Try` is not implemented for `Unit`
= note: required by `std::ops::Try::from_error`
Which points out that the function's return type must also implement Try.