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

Add a lint for not using field pattern shorthands #17813

Merged
merged 1 commit into from
Oct 24, 2014

Conversation

ftxqxd
Copy link
Contributor

@ftxqxd ftxqxd commented Oct 6, 2014

Closes #17792.

match fieldpat.node.pat.node {
ast::PatIdent(_, ident, None) if ident.node.as_str()
== fieldpat.node.ident.as_str()
&& !fieldpat.node.is_shorthand => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be more efficient with the is_shorthand check first.

@ftxqxd
Copy link
Contributor Author

ftxqxd commented Oct 6, 2014

@huonw Comments addressed.

for fieldpat in v.iter() {
if fieldpat.node.is_shorthand { continue }
match fieldpat.node.pat.node {
ast::PatIdent(_, ident, None) if ident.node.as_str()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a small subtlety here, which the following example demonstrates:

struct Struct { x: uint }
const x: uint = 42u;
fn main() {
    match (Struct { x: 1u }) {
        Struct { x: x } => (),
        Struct { x: _ } => ()
    }
}

We need to check that the PatIdent here is not resolved to any definition (it can be a constant but I think in some weird cross-crate situations it could also be a variant or a unit struct).

I think this would read well:

        let def_map = cx.tcx.def_map.borrow();
        match pat.node {
            ast::PatStruct(_, ref v, _) => {
                for fieldpat in v.iter()
                    .filter(|fieldpat| !fieldpat.node.is_shorthand)
                    .filter(|fieldpat| !def_map.contains_key(fieldpat.node.pat.id)) {
                    match fieldpat.node.pat.node {
                        ast::PatIdent(_, ident, None) if ident.node.as_str()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that and it looks like the lint just stopped triggering for anything. I’m thinking of trying something like this:

                for fieldpat in v.iter()
                    .filter(|fieldpat| !fieldpat.node.is_shorthand)
                    .filter(|fieldpat| match def_map.find(&fieldpat.node.pat.id) {
                        Some(&def::DefConst(_)) => false,
                        Some(&def::DefVariant(_)) => false,
                        _ => true,
                    }) {

but I’m not sure if that will work, and if it does how I’ll handle the tuple/unit struct case.

@ghost
Copy link

ghost commented Oct 15, 2014

@P1start This looks great. I think if you rebased and addressed the def_map issue, we could get someone to r+ it. :)

@ftxqxd
Copy link
Contributor Author

ftxqxd commented Oct 16, 2014

OK, I’ve made an attempt (that seems to work) at fixing the issue with const and so on. r? someone?

}
_ => true,
}) {
if fieldpat.node.is_shorthand { continue }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@P1start I see! My bad, I completely forgot about DefLocal. I think this should work:

for fieldpat in v.iter().
                                 .filter(|fieldpat| def_map.find(&fieldpat.node.pat.id) == Some(&def::DefLocal(fieldpat.node.pat.id)))
                                 .filter(|fieldpat| !fieldpat.node.is_shorthand)
{
                    match fieldpat.node.pat.node {

(no need for if fieldpat.node.is_shorthand { continue }).

@ghost
Copy link

ghost commented Oct 16, 2014

@P1start r=me with the last two changes pending @huonw's approval.

@ftxqxd ftxqxd force-pushed the lint-field-shorthand branch 2 times, most recently from e518478 to 1478d0a Compare October 17, 2014 22:47
@ghost
Copy link

ghost commented Oct 18, 2014

I'm happy. @huonw?

@ghost
Copy link

ghost commented Oct 20, 2014

@P1start This will need another rebase. :(

@ghost
Copy link

ghost commented Oct 23, 2014

@P1start Sorry, will need another rebase. Please ping someone on IRC as soon as you rebase so that we can get the PR in ASAP as it's really prone to bitrotting. :)

bors added a commit that referenced this pull request Oct 24, 2014
@bors bors closed this Oct 24, 2014
@bors bors merged commit ead6c4b into rust-lang:master Oct 24, 2014
kevinmehall added a commit to kevinmehall/rust that referenced this pull request Oct 27, 2014
Use the `is_shorthand` field introduced by rust-lang#17813 (ead6c4b) to make the
prettyprinter output the shorthand form. Fixes a few places that set
`is_shorthand: true` when the pattern is not a PatIdent with the same
name as the field.
lnicola pushed a commit to lnicola/rust that referenced this pull request Aug 13, 2024
fix: tyck for non-ADT types when searching refs for `Self` kw

See https://github.com/rust-lang/rust-analyzer/pull/15864/files/e0276dc5ddc38c65240edb408522bb869f15afb4#r1389848845

For ADTs, to handle `{error}` in generic args, we should to convert them to ADT for comparisons; for others, we can directly compare the types.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Lint for not using field pattern shorthands where applicable.
3 participants