The '?' operator

Hi guys,
i'm writing a rust code and when i write the code as follows i obtain this error:
The operator '?' can only be used in a function that returns Result or Option.
In my case it returns a Result<> type.
Anyone knows how i can fix it?

fn write_mem(path_dev: &Path, full_addr: [u8;3]){
      let file_buffer = File::create(_path_dev)?;
      let mut bytes =file_buffer.write(&full_addr);

I just want to write my file_buffer at the address &full_addr and it seems to me the easiest way. Other helps are welcome.

You did not share a full code example (and _path_dev is undefined), however it is clear that your write_mem function implicitly returns () as you did not specify a return type.

You can change your function to return a io::Result<()> and should be able to then use the ? operator, like this:

use std::io;

fn write_mem(path_dev: &Path, full_addr: [u8; 3]) -> io::Result<()> {
      let file_buffer = File::create(path_dev)?;
      let mut bytes = file_buffer.write(&full_addr);

If not all of the functions you want to use ? with are IO errors, you will either need to use a custom enum (optionally with thiserror) or use a pattern like anyhow.

1 Like

Ok, really clear, thank you.

For future questions, be aware that when you encounter an error and want to ask about it, it’s generally good and useful practice to include the error message you got with the question. It’s also useful to include complete and reproducable code examples in case that’s easily possible, for example if your code wasn’t all that long anyways, or it’s easy to isolate the problem you have to a small self-contained section of code (without changing or leaving out anything that’s relevant for the problem).

Unless you thought that write_mem’s return type needs not be specified, in which case @leob already provided the perfect answer… perhaps you simply mis-read the precise wording here? It doesn’t say

The operator '?' can only be used on a function that returns Result or Option

but

The operator '?' can only be used in a function that returns Result or Option

Well, the former is actually true as well, but that’s not what the error is referring to, not the return type of File::create, which would be the return type of the function that ? is used on, but the return type of the containing function you’re currently defining, write_mem, is relevant.

This is for the simple reason of what ? does. A (simplified) desugaring of

let file_buffer = File::create(path_dev)?;

looks like

let file_buffer = match File::create(path_def) {
    Ok(value) => value,
    Err(error) => return Err(error.into()),
};

For the match to work, File::create needs to return Result, but for the return Error(error) to work, the function we’re currently in needs to return a Result, too.

4 Likes

Reminder that the compiler can! If I paste what you wrote into playground and fix the imports and variable names https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=5108989c86e8d8dacd3ecc1a3cf486b6:

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
 --> src/lib.rs:4:45
  |
3 | fn write_mem(path_dev: &Path, full_addr: [u8; 3]) {
  | ------------------------------------------------- this function should return `Result` or `Option` to accept `?`
4 |     let file_buffer = File::create(path_dev)?;
  |                                             ^ cannot use the `?` operator in a function that returns `()`
  |
  = help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`

Note, in particular, the

this function should return Result or Option to accept ?

2 Likes