-
Notifications
You must be signed in to change notification settings - Fork 353
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow error type conversions in ensure! and ensure_eq! #474
Conversation
} | ||
|
||
#[test] | ||
fn ensure_can_infer_error_type() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd love to understand why this works. How does Rust infer the error type in that case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woah, this compiles???
I guess it uses the matches!
segment to determine it is expected to compare with StdError, thus setting the Result<_, StdError>
. But this compiler is starting to get a bit too smart....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Amazed the tests requires such few changes, and the actual contracts could always infer the types.
This is strictly better. 👍
if $a != $b { | ||
return Err($e); | ||
} | ||
ensure!($a == $b, $e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better reuse of code 👍
} | ||
|
||
#[test] | ||
fn ensure_can_infer_error_type() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woah, this compiles???
I guess it uses the matches!
segment to determine it is expected to compare with StdError, thus setting the Result<_, StdError>
. But this compiler is starting to get a bit too smart....
#[derive(Debug)] | ||
struct ContractError; | ||
|
||
impl From<StdError> for ContractError { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice minimal case 👍
} | ||
} | ||
|
||
fn check(a: usize, b: usize) -> Result<(), ContractError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, here is the real test of the compiler's intelligence:
If you remove -> Result<(), ContractError>
, will the compiler infer it from line 97?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An fn
always needs a specific return type. Unset means ()
. So this is more realistic that the closure test case.
But yes, if you turn it into a closure and remove the return type, compiler can infer it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty good. Just noticed fail_if!
is missing these conversions. Maybe implement fail_if!
in terms of ensure!
?
Good point
I'm in favour of removing |
I second that. |
As discussed before.