Do not simplify isInstanceOf if unrelated types might be subtypes at run-time#25535
Conversation
|
|
||
| if foundEffectiveClass.isPrimitiveValueClass && !testCls.isPrimitiveValueClass then | ||
| if foundEffectiveClass.isPrimitiveValueClass && !testCls.isPrimitiveValueClass && !ctx.platform.typeMightSubtypeAtRuntime(foundEffectiveClass, testCls) then | ||
| report.error(em"cannot test if value of $exprType is a reference of $testCls", tree.srcPos) |
There was a problem hiding this comment.
This change does not seem right. The platform should not influence whether code compiles or not.
There was a problem hiding this comment.
there's 1 Scala.js test failing because I commented this out, I'll figure it out on Monday
There was a problem hiding this comment.
@sjrd I think this is a case of the compiler being a little over-eager with an error. This report could be a warning, there's nothing inherently broken with testing whether A is a subtype of B when we know it's unrelated. I pushed a commit with a comment explaining why we need to call the platform here.
There was a problem hiding this comment.
Hum. IMO in that case we must either
a) emit the compile error on JS as well, or
b) make it platform-dependent warning.
It makes no sense to have a platform-dependent compile error (unless there are interop features involved).
a) seems the most conservative here. IMO it's not nonsensical. One can argue that it's just a language rule that we forbid prim.isInstanceOf[NonPrim]. It doesn't need to have anything to do with the platform behavior.
There was a problem hiding this comment.
OK. Unfortunately the way we get here is not by a direct check in the code but by another part of this file doing some widening (what else? :) ) so let me figure this out...
There was a problem hiding this comment.
@sjrd so it turns out a few lines above there already was the infra to do basically (b), the unreachable function, so I used it.
However it's not strictly a platform-dependent warning because if we're in a pattern match we instead error with "unreachable case". Why that's an error and not a warning I don't know, but I don't think this PR should change that.
447c0ef to
f30fed2
Compare
| lazy val sjsJUnitTests = project.in(file("tests/sjs-junit")). | ||
| enablePlugins(DottyJSPlugin). | ||
| dependsOn(`scala-library-sjs`). | ||
| dependsOn(`scala-library-sjs`, `scala3-compiler-bootstrapped`). |
There was a problem hiding this comment.
since these unit tests also depend on the compiler...
There was a problem hiding this comment.
I'm afraid that's wrong. That puts the compiler code on the classpath of sjsJUnitTests ! (also fixing this should be a separate PR anyway)
| dependsOn(`scala-library-sjs`, `scala3-compiler-bootstrapped`). | ||
| settings( | ||
| regularScalaJSProjectSettings, | ||
| bspEnabled := false, |
There was a problem hiding this comment.
for the deleted file below, I changed it to a "warn" test since that aligns with how the compiler was handling other such issues
There was a problem hiding this comment.
GitHub tip: you can comment on a whole file with the comment icon in the top right corner of a file's diff. This is true even for deleted files.
50cfe64 to
8f2b599
Compare
| lazy val sjsJUnitTests = project.in(file("tests/sjs-junit")). | ||
| enablePlugins(DottyJSPlugin). | ||
| dependsOn(`scala-library-sjs`). | ||
| dependsOn(`scala-library-sjs`, `scala3-compiler-bootstrapped`). |
There was a problem hiding this comment.
I'm afraid that's wrong. That puts the compiler code on the classpath of sjsJUnitTests ! (also fixing this should be a separate PR anyway)
| -- Warning: tests/warn/typetest.scala:5:10 ----------------------------------------------------------------------------- | ||
| 5 | println(i.isInstanceOf[Object]) // warning | ||
| | ^ | ||
| | this will always yield false since type Int is a primitive and class Object is a reference |
There was a problem hiding this comment.
It's going to say true if you actually run it, though, isn't it?
If it's meant as a progression test, say so in a comment on the test.
There was a problem hiding this comment.
no, it does say false, at least running on the JVM
There was a problem hiding this comment.
Well, that would then be a bug, because (1: Any).isInstanceOf[Object] definitely answers true today. It would be inconsistent for 1.isInstanceOf[Object] to return false.
There was a problem hiding this comment.
It makes sense to me thinking of : Any as a boxing operation, a value type instance isn't an instance of Object until you box it.
There was a problem hiding this comment.
No. Boxing is supposed to be transparent in Scala. There's no "boxing operation".
For example, you can still reproduce the result true without ever upcasting to Any:
scala> def test[T](x: T): Boolean = x.isInstanceOf[Object]; test[Int](5)
def test[T](x: T): Boolean
val res90: Boolean = trueThere was a problem hiding this comment.
.. could you say in the PR description what this PR changes? I wanted to take a quick look to understand, having a summary would really help.
There was a problem hiding this comment.
Will do as soon as we agree on what that is 😂
There was a problem hiding this comment.
To be clear this test currently fails to compile on main: https://github.com/scala/scala3/blob/main/tests/neg/typetest.scala
There was a problem hiding this comment.
It was more of a general remark; you know what you changed, the thoughts behind it, the research you did. It saves reviewers a lot of time if you can summarize it in the PR description and commit message.
| dependsOn(`scala-library-sjs`, `scala3-compiler-bootstrapped`). | ||
| settings( | ||
| regularScalaJSProjectSettings, | ||
| bspEnabled := false, |
There was a problem hiding this comment.
GitHub tip: you can comment on a whole file with the comment icon in the top right corner of a file's diff. This is true even for deleted files.
|
@sjrd I pushed a silly commit that comments out this warning/error entirely and... the only test that fails in the compiler is this |
|
Let's do that, yes. |
fe36f98 to
ed998a6
Compare
…run-time (scala#25535) Fixes scala#25037 Fixes scala#25097 Introduce `typeMightBeSubtypeAtRuntime` in `Platform`, and use it in `TypeTestCasts` to avoid simplifying type tests that may have different behavior at runtime on a specific platform. Implement this method for the JVM, where everything is `Serializable`, and Scala.js, where integer semantics are a little funny due to JS's "everything is a double" model. Drop the "a value type cannot be an instance of a reference type" error as it's wrong, `1.isInstanceOf[Object]` is `true`, and move the neg test to a run test ensuring this. ## How much have your relied on LLM-based tools in this contribution? not ## How was the solution tested? new automated tests [Cherry-picked e0dd739][modified]
Fixes #25037
Fixes #25097
Introduce
typeMightBeSubtypeAtRuntimeinPlatform, and use it inTypeTestCaststo avoid simplifying type tests that may have different behavior at runtime on a specific platform.Implement this method for the JVM, where everything is
Serializable, and Scala.js, where integer semantics are a little funny due to JS's "everything is a double" model.Drop the "a value type cannot be an instance of a reference type" error as it's wrong,
1.isInstanceOf[Object]istrue, and move the neg test to a run test ensuring this.How much have your relied on LLM-based tools in this contribution?
not
How was the solution tested?
new automated tests