-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Error in -Ycheck:typer
when refining String on StringOps defs
#17465
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
Labels
Milestone
Comments
Minimizationimport reflect.Selectable.reflectiveSelectable
def f[T](x: T{ def *(y: Int): T }): T = x * 2
def test = f[scala.collection.StringOps | String]("Hello") |
Maybe it is because |
This issue was picked for the Issue Spree No. 31 of 30 May 2023 which takes place in 2 days. @Linyxus, @hamzaremmal, @TheElectronWill will be working on it. If you have any insight into the issue or guidance on how to fix it, please leave it here. |
Relevant documentation: |
Closed
Linyxus
added a commit
that referenced
this issue
Jul 20, 2023
Fixes #17465. In TypeComparer, `fourthTry` calls `isNewSubType` and `isCovered` to detect the subtype queries that have been covered by previous attempts and prune them. However, the pruning is spurious when both sides contain union types, as exemplified by the following subtype trace before the PR: ``` ==> isSubType (test1 : (Int | String){def foo(x: Int): Int}) <:< Int | String? ==> isSubType (Int | String){def foo(x: Int): Int} <:< Int | String? ==> isSubType (Int | String){def foo(x: Int): Int} <:< Int? <== isSubType (Int | String){def foo(x: Int): Int} <:< Int = false ==> isSubType (Int | String){def foo(x: Int): Int} <:< String? ==> isSubType (Int | String){def foo(x: Int): Int} <:< String? <== isSubType (Int | String){def foo(x: Int): Int} <:< String = false <== isSubType (Int | String){def foo(x: Int): Int} <:< String = false // (1): follow-up subtype checks are pruned here by isNewSubType <== isSubType (Int | String){def foo(x: Int): Int} <:< Int | String = false <== isSubType (test1 : (Int | String){def foo(x: Int): Int}) <:< Int | String = false ``` At `(1)`, the pruning condition is met, and follow-up recursions are skipped. However, in this case, only after `(1)` are the refinement on LHS dropped and the subtype between two identical OrTypes are accepted. The pruning is spurious. This PR tempers the pruning conditions specified in `isCovered` and `isNewSubType` to fix these false negatives.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Compiler version
3.3.0-RC4
Minimized code
Compile this code with the
-Ycheck:typer
flag.Edit: further minimization (thanks to @nicolasstucki):
Output
Expectation
The code compiles both with and without the
-Ycheck:typer
flag.More information
This seems to be related to the widening of
String
toscala.collection.StringOps | String
, as this issue does not arise with a homemade class: the following code passes the check.The text was updated successfully, but these errors were encountered: