Stream: t-lang

Topic: Try-trait wishlist, pre-meeting


scottmcm (May 01 2020 at 22:17, on Zulip):

I wanted to start collecting goals and similar talking before next week's design meeting. Here's a quick brainstorm:

Wishes:

Non-wishes:

Please reply with other things you come up with. Let's try to keep to scoping and avoid solutioning in this topic for now, though.

Josh Triplett (May 01 2020 at 22:45, on Zulip):

I'm in complete agreement with everything you've said in both lists.

Josh Triplett (May 01 2020 at 22:45, on Zulip):

I definitely want to be able to write things like let x = try { ... }.with_context(|| ...)? without any extra type annotations.

Josh Triplett (May 01 2020 at 22:46, on Zulip):

Or let x = try { ... }; do_something(); x?

scottmcm (May 02 2020 at 00:29, on Zulip):

More difficult goals:

scottmcm (May 02 2020 at 00:34, on Zulip):

Future extensability:

Amanieu (May 02 2020 at 00:52, on Zulip):

I've been using Err(x)? in my code to return an error and it works pretty well. If we do decide to add yeet e in the future, should it just be a shorthand for Err(x)? with the same error conversion semantics? I personally feel that adding new syntax for this is unnecessary since Err(e)? works just fine.

Josh Triplett (May 02 2020 at 00:53, on Zulip):

That's one possible desugar. But that desugar would potentially necessitate a lot of type annotations.

Josh Triplett (May 02 2020 at 00:54, on Zulip):

You wouldn't be able to capture the output of try and then use ? on it again later, because inference wouldn't know what type to make the intermediate.

scottmcm (May 02 2020 at 00:55, on Zulip):

I think it also only would work with Result. I'm not sure what the correct syntax/semantics would be (assuming for now that it's needed) to return an error in code that's generic over the actual error carrier type

scottmcm (May 02 2020 at 00:57, on Zulip):

In the simple case, Err(e)? is return Err(From::from(e));, and it's not obvious to me whether the from should be there if we added syntax. It seems like one might rather than yeet e; is just return Err(e);, since you can always write yeet e.into(); if you want.

scottmcm (May 02 2020 at 01:00, on Zulip):

Oh, that reminds me:

Possible goal:

Josh Triplett (May 02 2020 at 01:02, on Zulip):

Note that yeet e; is not equivalent to anything involving return, because return bypasses a try block, but yeet doesn't.

scottmcm (May 02 2020 at 01:02, on Zulip):

Yes, that's why I put "in the simple case". break 'nearest_try Err(e);, if you prefer.

rpjohnst (May 02 2020 at 13:47, on Zulip):

scottmcm said:

Future extensability:

For some context, the original RFC included try { x? } catch e { compute_fallback() } with exactly those semantics- the Ok-wrapping try {} version was originally specified as sugar for pass-through catches like catch e { Err(e) }

Jane Lusby (May 02 2020 at 16:37, on Zulip):

How would this interact with theoretical return traces? It seems like removing implicit from altogether in try blocks would basically torpedo that feature.

Jane Lusby (May 02 2020 at 17:24, on Zulip):

Oh wait no, it's the try trait that matters, not the from, this is fine

Sebastian Malton (May 04 2020 at 13:21, on Zulip):

Do we really want:

Wouldn't it be better to not allow this? Since NoneError (as we have currently) seems very cludgey and not very useful since it doesn't really point to where the non was.

RalfJ (May 04 2020 at 13:58, on Zulip):

AFAIK this is possible on stable already... unfortunately.

Sebastian Malton (May 04 2020 at 14:14, on Zulip):

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=a15c8ee2e8d9334aa95035d4b23e3c0a

This produces the error: use of unstable library feature 'try_trait'. So not actually on stable

scottmcm (May 04 2020 at 16:01, on Zulip):

Sebastian Malton said:

Do we really want:

  • Blocks using option? in a result-returning function and blocks using result? in an option-returning function.

Wouldn't it be better to not allow this? Since NoneError (as we have currently) seems very cludgey and not very useful since it doesn't really point to where the non was.

Oops, bad ambiguity on my part. I meant "blocks" as a verb, not as a noun there. I should have written "Prevent using ..."

nikomatsakis (May 04 2020 at 16:06, on Zulip):

see #t-lang > Design meeting: try, oh my!

cuviper (May 04 2020 at 16:07, on Zulip):

option? to Result can be used on stable without naming NoneError:
https://github.com/rust-lang/rust/issues/42327#issuecomment-469359526
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=bf6ef506f2e26fc9a77f7bad76eee8d2

Sebastian Malton (May 04 2020 at 16:11, on Zulip):

Yes but that isn't using NoneError it is using a debug trait object.

Sebastian Malton (May 04 2020 at 16:11, on Zulip):

Ah I see, well then we are in agreement

Taylor Cramer (May 04 2020 at 17:08, on Zulip):

@cuviper ah, thanks for the example. I'm sort of relieved to know that it's not just my Poll impls that cause this issue.

cuviper (May 04 2020 at 17:10, on Zulip):

I don't know if anyone does that in practice though, but I think it's plausible

Taylor Cramer (May 04 2020 at 17:10, on Zulip):

Based on that, I'd expect let x: Result<&str, Error> = try { Some(5)?; "foo" }; to work

Taylor Cramer (May 04 2020 at 17:10, on Zulip):

@scottmcm @Josh Triplett ^

cuviper (May 04 2020 at 17:11, on Zulip):

Taylor Cramer said:

Based on that, I'd expect let x: Result<&str, Error> = try { Some(5)?; "foo" }; to work

yep: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=e7f100dca6cb0bf4d1adf0968cb5a96f

Joshua Nelson (May 19 2020 at 14:13, on Zulip):

Hmm, that isn't what I expected by 'returning option? in function returning Result' - I have a lot of Option<Result> in my code and it would be great to have a way for the Some to get there automatically on error

nikomatsakis (May 19 2020 at 16:53, on Zulip):

It seems to me that our ability to tweak the existing Try trait is just very limited

nikomatsakis (May 19 2020 at 16:53, on Zulip):

I'm not sure how I feel about it but I guess I can live with it

nikomatsakis (May 19 2020 at 16:54, on Zulip):

It's nice that it narrows the range of options at least :)

Josh Triplett (May 19 2020 at 17:06, on Zulip):

@nikomatsakis What limits that? The Try trait itself (and thus any third-party impls) are not standard, right?

Josh Triplett (May 19 2020 at 17:06, on Zulip):

We have to provide compatibility with the observable behavior of ?; are there any other limitations?

cuviper (May 19 2020 at 17:14, on Zulip):

We also have to support the behavior of stable interfaces that use Try, namely try_fold, which means for example something like Try::from_ok is needed

cuviper (May 19 2020 at 17:15, on Zulip):

(but it doesn't have to be called that exactly)

Josh Triplett (May 19 2020 at 17:17, on Zulip):

Ah, true.

nikomatsakis (May 19 2020 at 22:15, on Zulip):

@Josh Triplett I mostly meant the observable behavior of ?

nikomatsakis (May 19 2020 at 22:15, on Zulip):

but also e.g. the impls that @Taylor Cramer pointed out

Last update: Jun 05 2020 at 23:10UTC