Rollup merge of #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`
This commit is contained in:
commit
9df7f26b1b
5 changed files with 98 additions and 88 deletions
|
@ -688,6 +688,9 @@ pub enum Constructor<Cx: TypeCx> {
|
|||
/// Fake extra constructor for constructors that are not seen in the matrix, as explained at the
|
||||
/// top of the file.
|
||||
Missing,
|
||||
/// Fake extra constructor that indicates and empty field that is private. When we encounter one
|
||||
/// we skip the column entirely so we don't observe its emptiness. Only used for specialization.
|
||||
PrivateUninhabited,
|
||||
}
|
||||
|
||||
impl<Cx: TypeCx> Clone for Constructor<Cx> {
|
||||
|
@ -709,6 +712,7 @@ impl<Cx: TypeCx> Clone for Constructor<Cx> {
|
|||
Constructor::NonExhaustive => Constructor::NonExhaustive,
|
||||
Constructor::Hidden => Constructor::Hidden,
|
||||
Constructor::Missing => Constructor::Missing,
|
||||
Constructor::PrivateUninhabited => Constructor::PrivateUninhabited,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -763,6 +767,8 @@ impl<Cx: TypeCx> Constructor<Cx> {
|
|||
}
|
||||
// Wildcards cover anything
|
||||
(_, Wildcard) => true,
|
||||
// `PrivateUninhabited` skips everything.
|
||||
(PrivateUninhabited, _) => true,
|
||||
// Only a wildcard pattern can match these special constructors.
|
||||
(Missing { .. } | NonExhaustive | Hidden, _) => false,
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue