Skip to content
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

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: 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: 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
# for free to join this conversation on GitHub. Already have an account? # 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