I tried to insert dyn but it returns me the error as follows: the size for values of type (dyn StdError + 'static) cannot be known at compilation time
if i remove dyn the compiler tells me that i have to insert dyn.
I'm confused.
Are you trying to pass along any errors that the two lines in your new function have? If so:
The first line is already handling errors with expect, and
The second line is only returning errors with expect_err.
So your new function probably doesn't work the way you want anyway.
My best suggestion for handling any errors that this function might cause is to depend on thiserror and make a new error enum:
#[derive(Debug, thiserror::Error)]
enum DataInfoError {
/// An IO error.
#[error(transparent)]
IO(#[from] std::io::Error),
/// An error associated with reading a file into a `DataInfo`.
#[error(transparent)]
FromReader(#[from] WhateverErrorFromReaderProduces)
}
This new error type handles all errors that could be coming out of new.
Now change your function to:
pub fn new(src: &File) -> Result<DataInfo, DataInfoError> {
let src = &File::open("Level.xml")?;
let datainfo: DataInfo = from_reader(src)?;
datainfo
}
You might still have compiler errors, but they should be independent of the error handling.
In your code, Error is referring to some trait called Error (perhaps the one in the standard library), and not to a type called Error.
Types which implement a trait can be coerced to a trait object.[1] The trait object is a distinct type, and when you name it, you name like like dyn Error. That's why you got the error about adding dyn: the compiler saw a trait name in a place it expected a type, and suggested you add dyn so that it was the name of the trait object type instead.
However, because different base types can be coerced to the trait object (dyn Error), the trait object doesn't have a size that's known at compile time. That is, it is dynamically sized. But in most places where you're moving or holding on to something by value, the compiler needs to know its size at compile time. And that's the case here:
Result doesn't support dynamically sized types (and Rust doesn't support returning dynamically sized types by value either). So that's why you get the error about the size not being known at compilation time.
When you do want to use dynamically sized types like dyn Error, you use them behind some sort of pointer type. In this case in your code, you probably want to use Box<dyn Error>. [2]
Alternatively, maybe you were trying to return a type called Error (like std::io::Error) and not a trait object. In that case you probably need to import the type name or refer to it by path (io::Error or std::io::Error).
If the trait is "dyn safe" or "object safe", which is another topic. ↩︎
or perhaps Box<dyn Error + Send + Sync> or such depending on your multithreaded situation. ↩︎