Reputation: 2561
I've got the following snippet:
pub fn init(&mut self, opts: InitOptions) -> Result<(), PostalError> {
let _ = self.mutex.lock();
unsafe {
if !libpostal_setup() {
Err(PostalError::LibpostalSetup);
}
}
self.setup_done = true;
if opts.expand_address {
unsafe {
if !libpostal_setup_language_classifier() {
Err(PostalError::LibpostalEnableExpansion);
}
}
self.expand_address_enabled = true;
}
Ok(())
}
which yields this error when compiling:
error[E0282]: type annotations needed
--> src/lib.rs:110:17
|
110 | Err(PostalError::LibpostalSetup);
| ^^^ cannot infer type for `T`
I've tried a number of things:
Adding type annotations to Err
, as suggested; e.g. Err::<(), PostalError>(PostalError::LibpostalSetup);
, which compiles but produces warnings and incorrect runtime behavior (i.e. a single unwrap()
no longer works on the returned Result
).
Changing from the unit type ()
to u8
(for testing).
Fiddling with enum variant signature changes in general in a variety of ways, to no avail.
What is curious is that I have another function on the same type, with a similar use of Result
for which the compiler has no trouble with:
pub fn expand_address(
&self,
a: &str,
opts: ExpandAddressOptions,
) -> Result<Expansions, PostalError> {
if self.setup_done && self.expand_address_enabled {
let _ = self.mutex.lock();
unsafe {
match CString::new(a) {
Ok(c_string) => {
let addr = c_string.as_ptr() as *mut c_char;
let mut num_expansions: usize = 0;
let raw = libpostal_expand_address(addr, opts.opts, &mut num_expansions);
Ok(Expansions::new(raw, num_expansions))
}
Err(e) => Err(PostalError::BadCString(e)),
}
}
} else {
Err(PostalError::LibpostalNotReady)
}
}
What exactly is the compiler is having issues with in the former example?
I could (and might) change to Option<PostalError>
, but that makes the match
/unwrap
/?
awkward to use. I'd rather not, if possible.
Upvotes: 3
Views: 11111
Reputation: 32063
110 | Err(PostalError::LibpostalSetup);
| ^^^ cannot infer type for `T`
You missed a return
.
Err(PostalError::LibpostalSetup);
is a useless statement, not a function's return value, so I guess Rust is saying it has no way of inferring T
in Result<T, PostalError>
you're trying to construct.
"Function Bodies Contain Statements and Expressions" explains how the return value of a function is determined and "Are semicolons optional in Rust?" explains the significance of semicolons, or lack thereof, in Rust.
Upvotes: 9