5

I have tried to reproduce the problem in a very tiny program (you can find it here Rust REPL)

#[macro_use]
extern crate quick_error;

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        SomeError{
            description("SomeError")
        }
    }
}


pub struct Version {
    foo: u8,
}

pub struct Bar();

impl Bar {
    pub fn version() -> Result<Version, Error> {
        Ok(Version{foo: 1})
    }
}

fn main() {
    let tmp = Bar::version()?;
}

when trying to compile, I get the following:

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:27:15
   |
27 |     let tmp = Bar::version()?;
   |               ^^^^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()`

HOWEVER, version is returning Result<Version, Error>. What is going on?

Juan Leni
  • 6,982
  • 5
  • 55
  • 87

1 Answers1

25

You misunderstand the function that the operator is talking about:

cannot use the ? operator in a function that returns ()

Is about the function in which the expression appears and not the expression on which ? is applied:

  • the function in which the expression appears is main.
  • the expression to which ? is applied is Bar::version()?.

Therefore, the compiler is complaining that you cannot use ? in main because the return type of main is ().


You can use -> Result<(), Box<dyn Error>> as a return type for main:

use std::error::Error;

fn main() -> Result<(), Box<dyn Error>> {
    let tmp = Bar::version()?;
    Ok(())
}
Jay
  • 9,314
  • 7
  • 33
  • 40
Matthieu M.
  • 287,565
  • 48
  • 449
  • 722