Skip to content

pattern_analysis: rework how we hide empty private fields #121000

New issue

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

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

Already on GitHub? # to your account

Merged
merged 6 commits into from
Feb 29, 2024

Conversation

Nadrieril
Copy link
Member

@Nadrieril Nadrieril commented Feb 13, 2024

Consider this:

mod foo {
  pub struct Bar {
    pub a: bool,
    b: !,
  }
}

fn match_a_bar(bar: foo::Bar) -> bool {
  match bar {
    Bar { a, .. } => a,
  }
}

Because the field b is private, matches outside the module are not allowed to observe the fact that Bar is empty. In particular match bar {} is valid within the module foo but an error outside (assuming exhaustive_patterns).

We currently handle this by hiding the field b when it's both private and empty. This means that the pattern Bar { a, .. } is lowered to Bar(a, _) if we're inside of foo and to Bar(a) outside. This involves a bit of a dance to keep field indices straight. But most importantly this makes pattern lowering depend on the module.

In this PR, I instead do nothing special when lowering. Only during analysis do we track whether a place must be skipped.

r? @compiler-errors

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 13, 2024
@bors

This comment was marked as resolved.

/// Fake extra constructor that indicates that we should skip the column entirely. This is used
/// when a private field is empty, so that we don't observe its emptiness. Only used for
/// specialization.
Skip,
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we should give this a more descriptive name (PrivateUninhabited) or something

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah I like that, will rename

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@compiler-errors

This comment was marked as off-topic.

@bors

This comment was marked as off-topic.

@compiler-errors
Copy link
Member

@bors r+

@bors
Copy link
Collaborator

bors commented Feb 28, 2024

📌 Commit c918893 has been approved by compiler-errors

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 28, 2024
@Nadrieril
Copy link
Member Author

Ty!

bors added a commit to rust-lang-ci/rust that referenced this pull request Feb 29, 2024
…llaumeGomez

Rollup of 7 pull requests

Successful merges:

 - rust-lang#119748 (Increase visibility of `join_path` and `split_paths`)
 - rust-lang#120820 (Enable CMPXCHG16B, SSE3, SAHF/LAHF and 128-bit Atomics (in nightly) in Windows x64)
 - rust-lang#121000 (pattern_analysis: rework how we hide empty private fields)
 - rust-lang#121376 (Skip unnecessary comparison with half-open range patterns)
 - rust-lang#121596 (Use volatile access instead of `#[used]` for `on_tls_callback`)
 - rust-lang#121669 (Count stashed errors again)
 - rust-lang#121783 (Emitter cleanups)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 9df7f26 into rust-lang:master Feb 29, 2024
@rustbot rustbot added this to the 1.78.0 milestone Feb 29, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Feb 29, 2024
Rollup merge of rust-lang#121000 - Nadrieril:keep_all_fields, r=compiler-errors

pattern_analysis: rework how we hide empty private fields

Consider this:
```rust
mod foo {
  pub struct Bar {
    pub a: bool,
    b: !,
  }
}

fn match_a_bar(bar: foo::Bar) -> bool {
  match bar {
    Bar { a, .. } => a,
  }
}
```

Because the field `b` is private, matches outside the module are not allowed to observe the fact that `Bar` is empty. In particular `match bar {}` is valid within the module `foo` but an error outside (assuming `exhaustive_patterns`).

We currently handle this by hiding the field `b` when it's both private and empty. This means that the pattern `Bar { a, .. }` is lowered to `Bar(a, _)` if we're inside of `foo` and to `Bar(a)` outside. This involves a bit of a dance to keep field indices straight. But most importantly this makes pattern lowering depend on the module.

In this PR, I instead do nothing special when lowering. Only during analysis do we track whether a place must be skipped.

r? `@compiler-errors`
@Nadrieril Nadrieril deleted the keep_all_fields branch February 29, 2024 21:21
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants