Note that if you do want to use ? for this, you'll need to make a repr(transparent) wrapper for i32, because you're not allowed to impl Try for i32 (as you're not the standard library).
A transparent wrapper is something I did for HRESULT while experimenting with Windows FFI, which is just a typedef for i32 in C. Though I've been wondering if Result<(),NonZeroI32> could have the same layout.
Given S_FALSE, I'm not sure that's semantically correct.
Certainly some sort of Result<NonNegativeI32, StrictlyNegativeI32>could be made to work, but I'm pretty sure Rust's current layout doesn't support overlaying things like that.
S_FALSE indicates success. It's not often used but when it is it usually means that the function returned successfully but it may not have needed to actually do anything.
As you say, Result<(),NonZeroI32> is still wrong for HRESULT.
Yes, something like Result<i32,HRESULT> or an equivalent is just as usable, and I wrote a method .result() to return that, so I could write .result()? and also impl Error for HRESULT.
Along the way I ended up trying to understand variants, before deciding I had better things to do.
Yeah, the correct way to handle this would to use a hypothetical Result<PositiveI32, NegativeI32> (where 0 is positive). But that's not currently possible. Or at least it's not currently possible to have the layout optimized to a single i32.
I guess the main problem is that the Result type is special but it is limited in terms of specifying the layout. The Try trait mention above will help but doesn't totally address the issue.