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

pattern_analysis: rework how we hide empty private fields #121000

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.

compiler/rustc_pattern_analysis/src/rustc.rs Outdated Show resolved Hide resolved
compiler/rustc_pattern_analysis/src/rustc.rs Outdated Show resolved Hide 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
Contributor

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
11 checks passed
@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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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