Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign up`catch` blocks are not `Ok`-wrapping their value #41414
Comments
nikomatsakis
added
the
T-lang
label
Apr 20, 2017
This comment has been minimized.
This comment has been minimized.
|
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 |
nikomatsakis
added
the
I-nominated
label
Apr 20, 2017
This comment has been minimized.
This comment has been minimized.
|
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
|
This comment has been minimized.
This comment has been minimized.
|
@scottmcm but then by the same token why shouldn't a function that returns a |
This comment has been minimized.
This comment has been minimized.
|
@withoutboats I think that'd be a win, yes. The And I strongly hope that |
This comment has been minimized.
This comment has been minimized.
|
I'm a bit sympathetic to the idea but wouldn't that be a very big & breaking change? |
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
|
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? |
This comment has been minimized.
This comment has been minimized.
|
I'm definitely interested. I'd been pondering what a solution could look like, but wouldn't have dared propose a new coercion. |
This comment has been minimized.
This comment has been minimized.
|
@scottmcm Great! Ping me or @nikomatsakis on email or IRC to get things cooking? |
nikomatsakis
removed
the
I-nominated
label
May 11, 2017
scottmcm
referenced this issue
Jun 28, 2017
Open
Tracking issue for `ops::Try` (`try_trait` feature) #42327
Mark-Simulacrum
added
the
C-feature-request
label
Jul 27, 2017
scottmcm
referenced this issue
Aug 14, 2017
Closed
Ok wrapping: Improved support for writing code from an error handling mindset #2107
scottmcm
referenced this issue
Aug 21, 2017
Closed
Add the `()` → `Result<(), _>` coercion rule, for removing `Ok(())` everywhere. #2120
pnkfelix
referenced this issue
Sep 27, 2017
Open
`catch` lacking both type annotation and trailing expr yields confusing diagnostic #44886
This comment has been minimized.
This comment has been minimized.
|
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:
|
This comment has been minimized.
This comment has been minimized.
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 |
nikomatsakis
referenced this issue
Mar 19, 2018
Open
document where various bits of rust are desugared #94
kennytm
added
the
E-mentor
label
Mar 19, 2018
This comment has been minimized.
This comment has been minimized.
|
I'm going to take a stab at this. |
scottmcm commentedApr 20, 2017
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)