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

[SR-13521] Improve diagnostic when exhaustiveness checking fails due to custom match functions #55957

Open
typesanitizer opened this issue Sep 8, 2020 · 6 comments
Labels
compiler The Swift compiler in itself improvement

Comments

@typesanitizer
Copy link

Previous ID SR-13521
Radar rdar://problem/68532714
Original Reporter @typesanitizer
Type Improvement
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Improvement
Assignee None
Priority Medium

md5: d6cd00bf3c67667514e251b4587cc376

Issue Description:

For example:

https://bugs.swift.org/browse/SR-13516

The wording "switch must be exhaustive" makes it sound like the switch is not exhaustive. However, that's not the case. The problem is that the compiler is not able to reason about exhaustiveness here. We should clarify the diagnostic to have wording like (say) "is not known to be exhaustive" when we see custom match functions (i.e. ~= overloads) being used. Similarly, if there are where clauses, we should emit the new wording, only using the current wording we were able to compute the pattern subspace that is not covered by the existing patterns.

@typesanitizer
Copy link
Author

@swift-ci create

@WowbaggersLiquidLunch
Copy link
Collaborator

I want to try to work on this, if no one has claimed it yet. I will need some help pointing me to the right direction first, though.

I searched for the string "switch must be exhaustive" in Swift's repository, and it didn't give me much helpful information. It will be great if someone could show me where the diagnostics messages are produced, and which files are responsible for checking switch cases' exhaustiveness.

@typesanitizer
Copy link
Author

I searched for the string "switch must be exhaustive" in Swift's repository, and it didn't give me much helpful information.

Generally what I end up doing is something like

git grep 'switch must be exhaustive' -- 'include/**' 'lib/**'

In this case, it gives 4 hits; the error message is present in include/swift/AST/DiagnosticsSema.def with the name non_exhaustive_switch. You can follow the error name to see places in Sema which emit this error.

That said, before hacking at the code, it may be helpful to first discuss what cases should/shouldn't emit the new diagnostic, to gain some clarity (you may still want to read through Pattern.h and ). As I linked in the original post, the "base" case of having ranges being immediately matched should emit the clearer warning.

Now consider the following example:

switch (x as Optional<Int>) {
case .some(0): break;
}

We probably want to continue having "switch must be exhaustive" here, having the "is not known to be exhaustive" warning would make it seem like the compiler doesn't even understand that there's a missing nil case. However, this does have an implicit ~= even though it's not written in the source code. It's equivalent to the following:

switch (x as Optional<Int>) {
case .some(let tmp): tmp ~= 0;
}

If you use -dump-ast on this, you'll see that there's a pattern_expr (i.e. ExprPattern) which reflects this.

This means that the most straightforward solution of checking if any of the patterns contains an ExprPattern (which can be taken as a marker for =) is not going to work, as the match with = may be happening at an "irrelevant" position.

I'm still trying to precisely formulate the condition that we should be checking here... I need to think some more.

I don't think this bug really qualifies as a StarterBug, it's more complicated than that. That said, if you are still interested, we can try working through this together.

cc @hborla

@WowbaggersLiquidLunch
Copy link
Collaborator

I don't think this bug really qualifies as a StarterBug, it's more complicated than that. That said, if you are still interested, we can try working through this together.

Yep, I'm still interested. Even if I can't do much, I would still like to follow along and learn.

In addition to the Optional<Int> example, I think the code snippet provided in SR-13516's description is also an example where the compiler should be able to prove exhaustiveness, because there is a finite number of Int values (integers are countable, and Int has .min and .max). I'm not sure if it is outside of the scope of this issue, though.

Newbie question:

I tried to access Pattern.h and DiagnosticsSema.def in Xcode, but couldn't find them. I can only find TypeCheckSwitchStmt.cpp in Xcode. Do I must use other IDEs/editors when working with some of the files, or is there a way to edit all source files in Xcode?

@typesanitizer
Copy link
Author

I think the code snippet provided in SR-13516's description is also an example where the compiler should be able to prove exhaustiveness, because there is a finite number of Int values

The compiler does exhaustiveness checking for enum cases, not for arbitrary types. Since Int is not an enum, the compiler cannot do exhaustiveness checking. So yeah, that's out of scope here.

I tried to access Pattern.h and DiagnosticsSema.def in Xcode, but couldn't find them. I can only find TypeCheckSwitchStmt.cpp in Xcode. Do I must use other IDEs/editors when working with some of the files, or is there a way to edit all source files in Xcode?

That's strange, those files should open fine in Xcode. Are you working with a fresh build/did Xcode finish indexing? You may want to run a build of swift-frontend, I think that forces creation/update of the index.

@WowbaggersLiquidLunch
Copy link
Collaborator

Are you working with a fresh build/did Xcode finish indexing? You may want to run a build of swift-frontend, I think that forces creation/update of the index.

I re-cloned and re-built the project for a few times, and the problem persists. I'm going to ask about it on the forums, instead of polluting this thread.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler The Swift compiler in itself improvement
Projects
None yet
Development

No branches or pull requests

2 participants