rust-lang / rust-lang/rfcs

Option<T> / Result<T, E> rewrap shorthand

Open
#3,225 14 comments 17 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Markdown
Stars
6.6k
Forks
1.7k
Avg merge
16h 14m
Merged PRs (30d)
1

Description

The problem

In code I find myself having to do a lot of:

let b = if let Some(a) = a {
    if let Some(b) = a.b {
        Some(b)
    }
} else {
    None
}

What's available right now

Currently I can do this:

let b = a?.b;

But I can only use the ? operator from a function that returns an Option<T>. In the vast majority of cases I'm returning a Result<T, E> so I can't use the existing shorthand. Additionally, this would trigger an early return where I might want to continue working with the unwrapped value.

The Proposal

A syntax shorthand that conditionally unwraps values to access deeply nested values behind myriad Option<T> and Result<T, E>. This syntax does not do an early return like the ? operator, it only produces a value. This behaves very similarly to JavaScript's optional chaining operator: ?.. An example of this could look like:

let b: Option<B> = a!.b!;

The behaviour for Option<T> and Result<T, E> follows like so:

Returning Option<T>

struct A {
    b: Option<B>
}

struct B {
    c: Option<C>
}

struct C;

fn get_c(a: Option<A>) -> Option<C> {
    a!.b!.c!
}

This example returns an Option<T> at the end where T is the field value. The field value can either be T or Option<T>.

Returning Result<T, E>

struct EA;
struct EB;
struct EC;

struct A {
    b: Result<B, ErrorB>
}

struct B {
    c: Result<C, EC>
}

struct C;

fn try_get_c(a: Result<A: EA>) -> Result<C: EA> {
    a!.b!.c!
}

In this scenario, the root level E type is always returned in the Result<T, E>, which in this case is EA. This is meant to behave exactly as the ? operator does in doing early returns in fn() -> Result<T, E> functions. Therefore, for this to not error we need to have the appropriate From<T> traits implemented for our error types like so:

impl From<EB> for EA { ... }
impl From<EC> for EB { ... }

Conclusion

I suspect there will be a few gaps or problems with implementing this that I have not been able to foresee but I believe a syntax shorthand like this will make working with Option<T> and Result<T, E> much more terse and a great deal quicker.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No implementation files, tests, or entry points are named in the issue. Start by reviewing the proposed ! syntax and its Option/Result propagation rules, then compare them with the existing ? operator. Done would require resolving the language-design questions and producing an accepted RFC or implementation plan.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.