-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
catch
blocks are not Ok
-wrapping their value
#41414
Comments
cc @rust-lang/lang -- this is an interesting question. The fn main() {
let x: Result<i32, ()> = do catch { 22 };
} However, the catch blocks are implemented do not have this behavior, so one must do: fn main() {
let x: Result<i32, ()> = do catch { Ok(22) };
} What behavior do we want here? I think the currently implemented behavior is natural, in some respects, in that inserting a (Also, the |
To argue the opposite, I suspect the wrapping behaviour will be more convenient & consistent. Manufactured example where I think the wrapping provides a nice consistency:
That's certainly better than writing this:
But I also think it's better than this no-wrapping version, despite this being the shortest of the three:
That last call is obviously less consistent syntactically, but it's also less consistent semantically: it requires that As for convenience, I'd gladly write the second
in order to not have to write
|
@scottmcm but then by the same token why shouldn't a function that returns a |
@withoutboats I think that'd be a win, yes. The And I strongly hope that |
I'm a bit sympathetic to the idea but wouldn't that be a very big & breaking change? |
I would like some way to support "auto-wrapping", indeed, but I worry that the inconsistency will be confusing. I think it'll be hard to remember when you should have If we are going to have this, I think I would prefer some sort of syntactic "opt-in" that one can use on a fn or a Alternatively, the original RFC (IIRC) also did not have In other words, with try-catch, it would work something like this: let result_code = try {
write!(...)?;
0
} catch {
Err(e) => 1,
}; This doesn't really feel like autowrapping to me, though in some desugarings autowrapping may have been involved. |
We discussed in the @rust-lang/lang meeting, and I think the general feeling was that it is important to keep
@scottmcm -- would you be interested in working with a @rust-lang/lang member (probably myself) on an RFC to that effect? |
I'm definitely interested. I'd been pondering what a solution could look like, but wouldn't have dared propose a new coercion. |
@scottmcm Great! Ping me or @nikomatsakis on email or IRC to get things cooking? |
After the long discussion on internals, I've had a change of heart here. Earlier I wrote:
But now I think I was wrong to argue for that, and that we should revert to the original intent. Why, you ask? In short, given that our attempts to find more universal coercions have failed, it seems clear that if we are going to do some form of ok-wrapping, it has to have syntactic opt-in. And, in that case, I don't see a future where In more detailed form:
|
Mentoring instructionscatch blocks are processed during HIR lowering. This works by building on the HIR's support for a let x = do catch {
Ok(foo?)
}; desugars to: let x = 'a: {
Ok(match foo {
Ok(v) => v,
Err(e) => break 'a Err(e.into()),
})
}; The The code to desugar a catch block lives here: rust/src/librustc/hir/lowering.rs Lines 2772 to 2775 in aafe7d8
The rust/src/librustc/hir/lowering.rs Line 105 in aafe7d8
Then when we desugar the rust/src/librustc/hir/lowering.rs Lines 3197 to 3199 in aafe7d8
we can check this stack in the rust/src/librustc/hir/lowering.rs Lines 3273 to 3288 in aafe7d8
(We don't need to alter the What we want to change here is actually in the rust/src/librustc/hir/lowering.rs Lines 2772 to 2775 in aafe7d8
It seems like we want to lower:
to the equivalent of
This suggests that we want to take the return value from the function self.with_catch_scope(body.id, |this| {
let mut block = this.lower_block(body, true);
block.expr = wrap_in_from_ok_call(block.expr);
hir::ExprBlock(block)
}) then all we have to do is write this rust/src/librustc/hir/lowering.rs Lines 3264 to 3269 in aafe7d8
|
I'm going to take a stab at this. |
Add ok-wrapping to catch blocks, per RFC Updates the `catch{}` lowering to wrap the result in `Try::from_ok`. r? @nikomatsakis Fixes #41414 Fixes #43818
Opening as #39849 (linked from tracking issue #31436) is closed.
From https://github.com/rust-lang/rfcs/blob/master/text/0243-trait-based-exception-handling.md#catch-expressions
The current implementation does not; the following does not compile (2017-04-18):
Error message:
Runnable: https://play.integer32.com/?gist=4e589a7b8f2ffff23f507fb66ac7f662&version=nightly
cc @nikomatsakis, who mentioned this in rust-lang/rfcs#1859 (comment)
The text was updated successfully, but these errors were encountered: