Skip to content

if clauses following an if let are compiled to match guards #41272

Closed

Description

@nox

https://is.gd/2ZnMND

is this code:

struct Foo;

impl Foo {
    fn bar(&mut self) -> bool { true }
}

fn error(foo: &mut Foo) {
    if let Some(_) = Some(true) {
    } else if foo.bar() {}
}

fn ok(foo: &mut Foo) {
    if let Some(_) = Some(true) {
    } else {
        if foo.bar() {}
    }
}

fn main() {}

yielding:

rustc 1.16.0 (30cf806ef 2017-03-10)
error[E0301]: cannot mutably borrow in a pattern guard
 --> <anon>:9:15
  |
9 |     } else if foo.bar() {}
  |               ^^^ borrowed mutably in pattern guard

Activity

  1. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Apr 13, 2017
  2. eddyb commented on Apr 13, 2017

    @eddyb
    Contributor

    Where this happens. I don't know why we do this, the "else" part of "if" or "if-let" is an arbitrary expression:

    if let pat = expr1 {...} else expr2
    // can be lowered to
    match expr1 {
        pat => {...}
        _ => expr2
    }

    This seems simpler, less error prone and it won't hit arbitrary limitations specific to match guards.

  3. nikomatsakis commented on Apr 13, 2017

    @nikomatsakis
    Contributor

    The RFC states:

    Optionally, one or more else if (not else if let) blocks can be placed in the same match using pattern guards on _. This could be done to simplify the code when pretty-printing the expansion result. Otherwise, this is an unnecessary transformation.

    This doesn't feel like a compelling reason, particularly since the desugaring is not otherwise user visible. I would call this a bug.

  4. nikomatsakis commented on Apr 13, 2017

    @nikomatsakis
    Contributor

    triage: P-medium

  5. added
    E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.
    E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.
    on Apr 13, 2017
  6. nikomatsakis commented on Apr 13, 2017

    @nikomatsakis
    Contributor

    This is a great mentoring bug! I'm going to write up some very quick pointers for now. Please reach out for more details. In short, the code that needs to be changed is in the "HIR lowering", which converts from the AST (what the user wrote) to the compiler's internal HIR (also an abstract syntax tree, but somewhat desugared). The code in question is in lowering.rs, specifically right around here. There is also some more logic. You'll want to change how it is desugaring along the lines that @eddyb suggested in this comment.

  7. cuviper commented on Apr 14, 2017

    @cuviper
    Member

    I'm interested in taking this bug.

  8. eddyb commented on Apr 14, 2017

    @eddyb
    Contributor

    @suchithjn225 Sure thing! Let us know how far you get with #41272 (comment). We're also on IRC.

  9. cuviper commented on Apr 14, 2017

    @cuviper
    Member

    @suchithjn225 I'll yield to you -- good luck!

  10. added a commit that references this issue on Apr 15, 2017
    c67cf5f
  11. added 3 commits that reference this issue on Feb 5, 2025
  12. added a commit that references this issue on Feb 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.P-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions