0

I am trying to return an error with a formatted message.

let msg = format!("wrong num of dimensions: {}", dimensions.len()).to_string();
return Err(msg);

dimensions is a Vec<i32> that is supposed to have a length of 3. If it doesn't, I want to raise this error. However, I am getting this compiler error:

   Compiling advent02 v0.1.0 (file:///home/garrett/notes/rust/advent/advent02)
src/main.rs:19:24: 19:27 error: mismatched types:
 expected `&str`,
    found `collections::string::String`
(expected &-ptr,
    found struct `collections::string::String`) [E0308]
src/main.rs:19             return Err(msg);
                                  ^~~

It looks to me like it wants an &str type when I am giving it a String type. I have tried to do this from this example but get borrow errors because the returned string borrow goes out of scope.

I don't understand because this page is littered with examples that do Err(err.to_string()), and they don't seem to have a problem.

Community
  • 1
  • 1
vitiral
  • 8,446
  • 8
  • 29
  • 43
  • It would be best if you can provide an [MCVE](http://stackoverflow.com/help/mcve). Then people trying to answer it just have to edit your code to get it to compile instead of creating totally new code from scratch. – David Grayson Jan 10 '16 at 08:43
  • will do in the future, thankyou! – vitiral Jan 10 '16 at 15:12

2 Answers2

2

The return type of your function is Result<T, &str>, that's why the compiler is complaining. You create a String instance, take a reference to it and try to return. When the function returns, the String instance is freed and your returned reference would be invalid (a dangling pointer).

I'd change the signature of the function to return a Result<T, String>. That way, you move the string out of the function without freeing it.

Tibor Benke
  • 1,164
  • 11
  • 9
  • That was totally it! Thanks a lot. I'm accepting the other answer because it has a better example (someting I should have done in the first place...) – vitiral Jan 10 '16 at 15:13
1

Here is a complete Rust program that shows the behavior you wanted:

fn test() -> Result<u32, String> {
    let msg = format!("Error code {}.", 123).to_string();
    return Err(msg);
}

fn main() {
    match test() {
        Ok(num) => println!("Okay: {}", num),
        Err(msg) => println!("Error: {}", msg),
    };
}

This compiles without warnings or errors and prints "Error: Error code 123." when run.

The important thing here is to declare the return type of the function that is returning the error code. If you don't declare the return type, then the Rust compiler apparently does a bad job of figuring out what the return type should be, and you get errors (but the errors I get from rustc 1.5.0 are different from yours). This might actually be a bug in the Rust compiler; you could report this to the developers of the language and see what they have to say.

The Err thing that you used is just a type constructor for std::result::Result. So the return type of the function should be some type of Result.

David Grayson
  • 84,103
  • 24
  • 152
  • 189
  • I should have posted the whole code. Of course this was my fault for declaring the return type as `Result` (I feel pretty dumb typing that now). I'm so new to polymorphism that I don't think I am reading the right code to find where something goes wrong. – vitiral Jan 10 '16 at 15:15