Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

There should be a shorthand for foo: ref foo in struct field patterns. #6137

Closed
jld opened this issue Apr 30, 2013 · 2 comments · Fixed by #10833
Closed

There should be a shorthand for foo: ref foo in struct field patterns. #6137

jld opened this issue Apr 30, 2013 · 2 comments · Fixed by #10833
Labels
A-parser Area: The parsing of Rust source code to an AST

Comments

@jld
Copy link
Contributor

jld commented Apr 30, 2013

In a pattern matching a struct (or struct-like enum variant), a field can be bound to a variable of the same name by using Thing { foo, ... } as a shorthand for Thing { foo: foo, ... }. It would be nice if there were a similar shorthand for Thing { foo: ref foo, ... }, when the field can't or shouldn't be copied; possibly Thing { ref foo, ... }, unless that's ambiguous.

Not a big issue, but it would help lower the activation energy for using struct-like variants instead staying with tuple-like variants after the point where they need comments in the definition to keep track of which bool/int/whatever means what (comments which are, of course, not available to the type checker).

@huonw
Copy link
Member

huonw commented Aug 14, 2013

Visiting for triage: still valid (doesn't parse). A testcase for the proposed feature:

fn main() {
    enum Foo {
        Bar { bar: ~str },
        Baz { baz: int }
    }
    match Bar(~"bar") {
        Bar { ref bar } => { println(*bar) } // should print `bar`
        _ => {}
    }

    let mut baz = Baz { baz: 0 };
    match baz {
        Baz { ref mut baz } => { *baz += 1 }
        _ => {}
    }
    printfln!(baz); // the `baz` field should be 1
}

Nominating for production ready (this is strictly more permissive that the current language, so not a backwards-compat feature).

@graydon
Copy link
Contributor

graydon commented Aug 22, 2013

just a bug, removing milestone/nomination.

bors added a commit that referenced this issue Dec 11, 2013
Previously, if you wanted to bind a field mutably or by ref, you had to
do something like Foo { x: ref mut x }. You can now just do
Foo { ref mut x }.

Closes #6137
@bors bors closed this as completed in 8240faf Dec 11, 2013
flip1995 pushed a commit to flip1995/rust that referenced this issue Sep 3, 2021
Downgrade option_if_let_else to nursery

I believe that this lint's loose understanding of ownership (rust-lang#5822, rust-lang#6737) makes it unsuitable to be enabled by default in its current state, even as a pedantic lint.

Additionally the lint has known problems with type inference (rust-lang#6137), though I may be willing to consider this a non-blocker in isolation if it weren't for the ownership false positives.

A fourth false positive involving const fn: rust-lang#7567.

But on top of these, for me the biggest issue is I basically fully agree with rust-lang/rust-clippy#6137 (comment). In my experience this lint universally makes code worse even when the resulting code does compile.

---

changelog: remove [`option_if_let_else`] from default set of enabled lints
flip1995 pushed a commit to flip1995/rust that referenced this issue Sep 3, 2021
Fix `option_if_let_else`

fixes: rust-lang#5822
fixes: rust-lang#6737
fixes: rust-lang#7567

The inference from rust-lang#6137 still exists so I'm not sure if this should be moved from the nursery. Before doing that though I'd almost want to see this split into two lints. One suggesting `map_or` and the other suggesting `map_or_else`.

`map_or_else` tends to have longer expressions for both branches so it doesn't end up much shorter than a match expression in practice. It also seems most people find it harder to read. `map_or` at least has the terseness benefit of being on one line most of the time, especially when the `None` branch is just a literal or path expression.

changelog: `break` and `continue` statments local to the would-be closure are allowed in `option_if_let_else`
changelog: don't lint in const contexts  in `option_if_let_else`
changelog: don't lint when yield expressions are used  in `option_if_let_else`
changelog: don't lint when the captures made by the would-be closure conflict with the other branch  in `option_if_let_else`
changelog: don't lint when a field of a local is used when the type could be pontentially moved from  in `option_if_let_else`
changelog: in some cases, don't lint when scrutinee expression conflicts with the captures of the would-be closure  in `option_if_let_else`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-parser Area: The parsing of Rust source code to an AST
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants