# Labeled questionmark

**URL:** <https://internals.rust-lang.org/t/labeled-questionmark/9195>\
**Category:** Uncategorized\
**Created:** [January 12, 2019, 6:41pm UTC](https://internals.rust-lang.org/t/labeled-questionmark/9195 "2019-01-12T18:41:51Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [January 12, 2019, 6:41pm UTC](https://internals.rust-lang.org/t/labeled-questionmark/9195/1 "2019-01-12T18:41:51Z")

</div>

It would be useful to be able to label questionmarks, primarily for use with loops:

```rust
fn foo<T: Into<i32>>(op: fn(i8, i8) -> Option<T>) {
    for i in (0i8..=9i8) {
        'a: for j in (0i8..=9i8) {
            let k: i32 = op(i, j) 'a?.into();
            // do stuff with k
        }
    }
}

```

This labeled questionmark would cause the loop to continue/go to the next iteration if the result of `op(i, j)` is `None` - or anything that can be considered `Into<()>`. (is `NoneError` an `Into<()>`? I don’t remember)

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [January 12, 2019, 6:51pm UTC](https://internals.rust-lang.org/t/labeled-questionmark/9195/2 "2019-01-12T18:51:11Z")

</div>

There’s already such feature in the language: [https://github.com/rust-lang/rust/issues/50412](https://github.com/rust-lang/rust/issues/50412), specifically [https://github.com/rust-lang/rust/issues/31436](https://github.com/rust-lang/rust/issues/31436)

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [January 12, 2019, 6:53pm UTC](https://internals.rust-lang.org/t/labeled-questionmark/9195/3 "2019-01-12T18:53:34Z")

</div>

I believe that still adds another depth of indentation, which is really bad for readability. It also doesn’t tie in with the loops very well and you don’t have much control over where it goes (it just goes to the nearest, literally no control).

---

<div class="post-metadata">

**Author:** ![160R](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/160r/32/9502_2.png) [@160R](https://internals.rust-lang.org/u/160R)\
**Post date:** [January 12, 2019, 10:55pm UTC](https://internals.rust-lang.org/t/labeled-questionmark/9195/4 "2019-01-12T22:55:43Z")

</div>

This is interesting because with [labeled break value](https://github.com/rust-lang/rfcs/blob/master/text/2046-label-break-value.md) it could be a good alternative to `try` blocks:

```rust
// With `try` blocks
let z = try {
    let x = foo()?;
    let y = bar()?;
    x + y
}

// With this proposal
let z = 'a: {
    let x = foo() 'a ?;
    let y = bar() 'a ?;
    Ok(x + y)
}

```

I definitely would prefer this over `try`, since it seems to be easier to implement, easier to understand, and I’ve never seen too much use cases that worth to introduce `try` syntax.

Additionally, it seems to be more flexible:

```rust
let z = 'a: {
    let x = foo() 'a ?;
    let y = bar() 'a ?;
    validate(x, y)?;
    Ok(x + y)
}

```

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [January 13, 2019, 7:24am UTC](https://internals.rust-lang.org/t/labeled-questionmark/9195/5 "2019-01-13T07:24:43Z")

</div>

This was discussed in:

- [Design `?` to work on named blocks](https://internals.rust-lang.org/t/design-to-work-on-named-blocks/7312).
- [https://github.com/rust-lang/rfcs/pull/2388#issuecomment-381352575](https://github.com/rust-lang/rfcs/pull/2388#issuecomment-381352575)
- [https://github.com/rust-lang/rfcs/pull/2388#issuecomment-385136848](https://github.com/rust-lang/rfcs/pull/2388#issuecomment-385136848)

`try` (formerly `catch`) has been through 2 RFCs, unless new compelling arguments are presented I see no reason to go with `'label?`.

---

<div class="post-metadata">

**Author:** ![160R](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/160r/32/9502_2.png) [@160R](https://internals.rust-lang.org/u/160R)\
**Post date:** [January 13, 2019, 9:53am UTC](https://internals.rust-lang.org/t/labeled-questionmark/9195/6 "2019-01-13T09:53:23Z")

</div>

To be honest, now I don’t even see why both features should be conflicting when instead they could complement each other!

* * *

First we must update current implementation of `?` operator:

- It should by default bubble up errors to the nearest block prefixed with `'try:` label
- All functions should be implicitly marked with that label
- But it’s still shouldn’t be possible to specify manually because `try` is a reserved keyword

Then we must allow `?` operator to work on named blocks:

- This is what been proposed in current and preceding threads
- It also shouldn’t permit `try` label because it’s a reserved keyword

And finally we must allow to specify `'try:` label using `try` keyword

- This introduces similar syntax to `try` expression RFC
- Except it shouldn’t provide implicit `Ok` wrapping (I see it as feature, through)
- Rationale to use `try` keyword is that implicit return to `'try:` would be ugly and confusing

* * *

And how it would look:

```rust
fn example() -> Result<(), Box<Error>> 'a: {
    let z = try {
        let x = foo()?;
        let y = bar()?;
        validate(x, y) 'a ?;
        Ok(x + y)
    }
    ...
}

```

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [January 13, 2019, 10:14am UTC](https://internals.rust-lang.org/t/labeled-questionmark/9195/7 "2019-01-13T10:14:31Z")

</div>

I see “reducing indentation” as a huge new compelling arguments.

---

<div class="post-metadata">

**Author:** ![phaylon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/phaylon/32/62_2.png) [@phaylon](https://internals.rust-lang.org/u/phaylon)\
**Post date:** [January 13, 2019, 2:38pm UTC](https://internals.rust-lang.org/t/labeled-questionmark/9195/8 "2019-01-13T14:38:01Z")

</div>

> [@Centril](#):
>
> `try` (formerly `catch` ) has been through 2 RFCs, unless new compelling arguments are presented I see no reason to go with `'label?` .

It might be helpful to link to those 2 RFCs.

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [January 13, 2019, 2:50pm UTC](https://internals.rust-lang.org/t/labeled-questionmark/9195/9 "2019-01-13T14:50:08Z")

</div>

> [@phaylon](#):
>
> It might be helpful to link to those 2 RFCs.

- [First-class error handling with `?` and `catch` by glaebhoerl · Pull Request #243 · rust-lang/rfcs · GitHub](https://github.com/rust-lang/rfcs/pull/243)
- [https://github.com/rust-lang/rfcs/pull/2388](https://github.com/rust-lang/rfcs/pull/2388)

---

<div class="post-metadata">

**Author:** ![phaylon](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/phaylon/32/62_2.png) [@phaylon](https://internals.rust-lang.org/u/phaylon)\
**Post date:** [January 13, 2019, 3:06pm UTC](https://internals.rust-lang.org/t/labeled-questionmark/9195/10 "2019-01-13T15:06:40Z")

</div>

Thank you.

As someone who would have more use for a more general solution, I find it encouraging that other people are looking for it as well. It does keep coming up so I hope at some point something will come along, and that people keep discussing possibilities.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [April 13, 2019, 3:06pm UTC](https://internals.rust-lang.org/t/labeled-questionmark/9195/11 "2019-04-13T15:06:44Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
