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

ignore uninhabited non-exhaustive variant fields #65414

Merged

Conversation

davidtwco
Copy link
Member

@davidtwco davidtwco commented Oct 14, 2019

Fixes #65157.

This PR modifies the uninhabitedness checking so that the fields of
a non-exhaustive variant (which is not local) are ignored if they are
uninhabited. This is an improvement over the previous behaviour which
considered all non-local non-exhaustive variants useful because
unreachable patterns are now detected.

r? @arielb1
cc @varkor

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 14, 2019
@davidtwco
Copy link
Member Author

I'm not sure if this is the best way to fix this, so I'm happy to take an alternate approach if anyone has a better solution.

@Nadrieril
Copy link
Member

Yeah, I'd think there must be a better solution.
What was the original reason that tuple variants with non-exhaustive fields should be treated differently ? I couldn't understand why you originally added that line of code

@Centril
Copy link
Contributor

Centril commented Oct 15, 2019

What was the original reason that tuple variants with non-exhaustive fields should be treated differently ? I couldn't understand why you originally added that line of code

The idea is that with #![feature(exhaustive_patterns)], inhabitedness becomes structural rather than taking visibility into account (iirc). That is, for any type (sum or product), the inhabitedness of a type in crate A would leak to the external crate B which would be observable when matching on the type from A inside B. In #60529, the point was to make a #[non_exhaustive] be regarded as inhabited outside of the current crate no matter if it is an enum or a product type (see #60529 (comment)).

@Nadrieril
Copy link
Member

So this is about ignoring uninhabitedness when the variant is marked non_exhaustive and not local ? Then I think we should be able to find the code that checks whether a variant is inhabited and tweak that. I can't seem to find what part of the code does that however; I'll keep looking.

@Nadrieril
Copy link
Member

Okay I figured it out. I'll take this line as an example:

while let PartiallyInhabitedVariants::Struct { x, .. } = partially_inhabited_variant() {

That line would be detected as unreachable if the variant wasn't declared non_exhaustive. The reason for this behaviour is that we start with v = [PartiallyInhabitedVariants::Struct { x, .. }], then we specialize it by the PartiallyInhabitedVariants::Struct constructor. Then v = [_] where the wildcard has type !. So it is detected as unreachable.

We can't avoid expanding PartiallyInhabitedVariants::Struct into its fields altogether, otherwise we would incorrectly think the second branch is unreachable here: (Enum taken from #65157):

match Enum::Unit {
    Enum::Unit => {}
    Enum::Struct { x: true, .. } => {}
    Enum::Struct { x: false, .. } => {}
}

So I'd say a good solution might be to specifically ignore the fields of PartiallyInhabitedVariants::Struct that are of an uninhabited type.

Does that make sense ?

PS: @davidtwco would you mind waiting for #65160 to get merged before merging this PR ? Otherwise I'd have to rebase the fix and it will be a pain.

@davidtwco
Copy link
Member Author

Does that make sense ?

I haven’t read this yet, will do later.

PS: @davidtwco would you mind waiting for #65160 to get merged before merging this PR ? Otherwise I'd have to rebase the fix and it will be a pain.

No worries, I just wanted to put something up to get review.

@davidtwco davidtwco force-pushed the issue-65157-non-exhaustive-always-useful branch from 11a0114 to dd5bd7b Compare October 18, 2019 20:34
@davidtwco
Copy link
Member Author

Thanks @Nadrieril, I've updated the PR with your suggested approach.

@davidtwco davidtwco changed the title uninhabited: non-exhaustive variants useful once ignore uninhabited non-exhaustive variant fields Oct 18, 2019
@bors

This comment has been minimized.

@davidtwco davidtwco force-pushed the issue-65157-non-exhaustive-always-useful branch from dd5bd7b to 1bf1236 Compare October 20, 2019 15:18
@davidtwco
Copy link
Member Author

r? @varkor

@rust-highfive rust-highfive assigned varkor and unassigned arielb1 Oct 21, 2019
@varkor varkor added S-blocked Status: Marked as blocked ❌ on something else such as an RFC or other implementation work. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 21, 2019
This commit modifies the uninhabitedness checking so that the fields of
a non-exhaustive variant (which is not local) are ignored if they are
uninhabited. This is an improvement over the previous behaviour which
considered all non-local non-exhaustive variants useful because
unreachable patterns are now detected.

Signed-off-by: David Wood <david@davidtw.co>
@davidtwco davidtwco force-pushed the issue-65157-non-exhaustive-always-useful branch from 1bf1236 to 7ffbd62 Compare October 23, 2019 21:29
@davidtwco
Copy link
Member Author

@varkor perhaps we should consider this unblocked and proceed with review and merging? - #65160 is already conflicted, this PR is quite small, and this PR is blocking RFC 2008’s stabilisation in #64639.

@Centril Centril added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-blocked Status: Marked as blocked ❌ on something else such as an RFC or other implementation work. labels Oct 24, 2019
@Centril
Copy link
Contributor

Centril commented Oct 24, 2019

Sounds reasonable; it does enhance the rationale for @Nadrieril to split their PR into parts. ;)

@varkor
Copy link
Member

varkor commented Oct 24, 2019

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Oct 24, 2019

📌 Commit 7ffbd62 has been approved by varkor

@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 Oct 24, 2019
Centril added a commit to Centril/rust that referenced this pull request Oct 25, 2019
…e-always-useful, r=varkor

ignore uninhabited non-exhaustive variant fields

Fixes rust-lang#65157.

This PR modifies the uninhabitedness checking so that the fields of
a non-exhaustive variant (which is not local) are ignored if they are
uninhabited. This is an improvement over the previous behaviour which
considered all non-local non-exhaustive variants useful because
unreachable patterns are now detected.

r? @arielb1
cc @varkor
bors added a commit that referenced this pull request Oct 25, 2019
Rollup of 9 pull requests

Successful merges:

 - #62959 (Add by-value iterator for arrays )
 - #65390 (Add long error explanation for E0576)
 - #65408 (reorder config.toml.example options and add one missing option)
 - #65414 (ignore uninhabited non-exhaustive variant fields)
 - #65666 (Deprecated proc_macro doesn't trigger warning on build library)
 - #65742 (Pre-expansion gate most of the things)
 - #65747 (Adjust the tracking issue for `untagged_unions`.)
 - #65763 (Changed APIT with explicit generic args span to specific arg spans)
 - #65775 (Fix more `ReEmpty` ICEs)

Failed merges:

 - #65519 (trait-based structural match implementation)

r? @ghost
@bors bors merged commit 7ffbd62 into rust-lang:master Oct 25, 2019
@Centril Centril added the F-non_exhaustive `#![feature(non_exhaustive)]` label Oct 25, 2019
@davidtwco davidtwco deleted the issue-65157-non-exhaustive-always-useful branch October 25, 2019 08:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F-non_exhaustive `#![feature(non_exhaustive)]` S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

#[non_exhaustive] variants are not detected to be redundant
7 participants