2

I am trying to chain an if let condition with a regular boolean condition.

if let Some(char_first_index) = char_info.first_index_in_string && !char_info.repeats_in_string

However, when I try to run this I get a compiler issue redirecting me to https://github.com/rust-lang/rust/issues/53667. This rfc mainly deals with chaining if let's. Although there is an issue mentioned here https://github.com/rust-lang/rfcs/blob/master/text/2497-if-let-chains.md#dealing-with-ambiguity which mentions dealing with ambiguity in the case of chaining if lets and booleans.

if let PAT = EXPR && EXPR { .. }
// It can either be parsed as (1):

if let PAT = (EXPR && EXPR) { .. }
// or instead as (2):

if (let PAT = EXPR) && EXPR { .. }

Re-ordering to avoid this ambiguity:

if !char_info.repeats_in_string && let Some(char_first_index) = char_info.first_index_in_string

or adding brackets:

if !char_info.repeats_in_string && (let Some(char_first_index) = char_info.first_index_in_string) 

Does not solve the issue and I still get the same compiler error. I'm not sure if the mentioned rfc has been pulled (apologies I'm not all that experienced with github). However, at the moment the only solutions I can find are either to use two separate if conditions:

if !char_info.repeats_in_string {
    if let Some(char_first_index) = char_info.first_index_in_string {

or to use a match block

match (char_info.repeats_in_string, char_info.first_index_in_string) {
    (false, Some(char_first_index)) => { 
        // former contents of if block
    },
    _ => {}
}

is there a way or make the if block work that I am missing or a more elegant solution than the multiple ifs / one-arm match block? Thanks,

4
  • RFCs are made before things are added to the language. But they're often written as if things are already implemented so that they stay accurate in the future.
    – drewtato
    Commented Feb 5 at 6:18
  • @drewtato thanks. That was my understanding too but I've seen "merged" next to a few of them and that one has a thing saying 8/14 tasks so I wasn't sure if that meant they had been merged and were now part of the language.
    – Pioneer_11
    Commented Feb 5 at 8:10
  • 1
    The RFC PR is merged when the RFC is accepted, which is a statement of intent to implement this in the language. Usually there's a link to a tracking issue from the RFC PR. That issue tracks the implementation of the RFC. If the tracking issue is merged, the feature is fully implemented in nightly, and will make it into beta and then release relatively soon. Commented Feb 5 at 8:47
  • 1
    @Pioneer_11 I checked and this one is currently in the nightly version of rust under the let_chains feature. It looks pretty complete, but it doesn't seem high-priority so no idea when it will be stable.
    – drewtato
    Commented Feb 5 at 18:54

1 Answer 1

4

You can turn your match version into an if-let expression:

if let (false, Some(char_first_index)) =
    (char_info.repeats_in_string, char_info.first_index_in_string)
{
    // former contents of if block
}

In fact, Clippy will suggest this exact transformation when given the match:

warning: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
  --> src\lib.rs:7:5
   |
7  | /     match (char_info.repeats_in_string, char_info.first_index_in_string) {
8  | |         (false, Some(char_first_index)) => {
9  | |             // former contents of if block
10 | |         }
11 | |         _ => {}
12 | |     }
   | |_____^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_match
   = note: `#[warn(clippy::single_match)]` on by default
help: try
   |
7  ~     if let (false, Some(char_first_index)) = (char_info.repeats_in_string, char_info.first_index_in_string) {
8  +         // former contents of if block
9  +     }
   |
1
  • Thanks, I keep meaning to set up clippy but putting it off. Guess I better set it up
    – Pioneer_11
    Commented Feb 5 at 8:08

Not the answer you're looking for? Browse other questions tagged or ask your own question.