I have this rust method error message:
error[E0277]: the `?` operator can only be used on `Option`s,
not `Result`s, in an async function that returns `Option`
I must admit, I often encounter Rust error messages which appear confusing to me, while to most other coders they make absolute sense.
So, I apologize in advance for posting this question.
First of all: what does that second comma in the error message mean? Should I read it as the following:
"If an async function call [within another function] returns an enum of the type Result
then the ?
operator can only be applied if, and only if, the respective [other] function also returns an enum of type Result
and not an enum of type Option
"
Pardon my verbose language. I hope I got my point across.
What also got me confused was the error message with that very same Reference i.e. error[E0277] , which is listed in the official rust error codes index, states:
"You tried to use a type which doesn’t implement some trait in a place which expected that trait."
In which universe do these two error messages have anything in common, except for the identical reference number?
And here’s the entire error block, which Rust produced:
error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in an async function that returns `Option`
--> src/utils/tokenizer.rs:72:73
|
70 | pub async fn clear(&self) -> Option<String> {
| _________________________________________________-
71 | | let mut conn = self.pool.get().await.unwrap();
72 | | let mut iter: redis::AsyncIter<i32> = conn.sscan("my_set").await?;
| | ^ use `.ok()?` if you want to discard the `Result<Infallible, Red
Error>` error information
73 | | while let Some(element) = iter.next_item().await {
... |
79 | | Some(String::from("A"))
80 | | }
| |_____- this function returns an `Option`
|
= help: the trait `FromResidual<Result<Infallible, RedisError>>` is not implemented for `std::option::Option<std::string::String>`
= help: the following other types implement trait `FromResidual<R>`:
<std::option::Option<T> as FromResidual<Yeet<()>>>
<std::option::Option<T> as FromResidual>
For more information about this error, try `rustc --explain E0277`.
What is the canonical error message, the one from the error code index page or the one, the compiler produces?
2
Answers
Your function
clear
returnsOption<String>
but the functionconn.sscan("my_set").await?;
returns a Result. You cannot use?
to propagate the result because that doesn’t match the return type ofclear(&self) -> Option<String>
.You will need explicitly handle the
Result
or convert it to anOption<String>
. You could also try adding.ok()?
per the compiler hint and see what that gets you.Whatever you pick the important thing is just to make sure that the return type matches what your
?
operator is unwrapping.Yes, your interpretation is correct, although to be pedantic the error says the opposite:
"If an async function returns
Option
then the ? operator can only be applied to expressions that has the typeOption
, and notResult
".And if you ask why on earth this has error code E0277? Well, this is because in order to be propagated using
?
a type has to implement the (experimental)Try
trait with some combination of type parameters and associated types corresponding to some other combination of the return type of the function. So, in essence, an incompatible type in?
boils down to an unsatisfied trait bound. But unless you’re interested in the inner workings of?
, this is not really important.