Skip to content

Union singleton types weirdness with isInstanceOf #12796

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

Closed
Swoorup opened this issue Jun 12, 2021 · 1 comment · Fixed by #12799
Closed

Union singleton types weirdness with isInstanceOf #12796

Swoorup opened this issue Jun 12, 2021 · 1 comment · Fixed by #12799
Assignees
Milestone

Comments

@Swoorup
Copy link

Swoorup commented Jun 12, 2021

isInstanceOf has difference when run in compile time vs runtime. Here is an sbt example where a valid subtype isn't detected, when passed as method arg.

Compiler version

3.0.1-RC1

Minimized code

type Timeframe = "1m" | "2m" | "1H"

@main def main(input: String) = 
  val isTimeframe = input.isInstanceOf[Timeframe]
  val oneM: String = "1m"
  println(s"input is of Timeframe: $isTimeframe")
  println(s"1m is of Timeframe: ${oneM.isInstanceOf[Timeframe]}")

Output

Running with 1m which is a valid Timeframe type.

sbt:scala3-simple> run 1m
[info] running main 1m
input is of Timeframe: false
1m is of Timeframe: true

Expectation

sbt:scala3-simple> run 1m
[info] running main 1m
input is of Timeframe: true
1m is of Timeframe: true

Original motivation for doing this was to check if an input from untrusted source is of the specified type.

@Swoorup
Copy link
Author

Swoorup commented Jun 12, 2021

So somehow the compiler also knows about literals in the code being at the callsite, when you write code like this

type Timeframe = "1m" | "2m" | "1H"

def ok(input: String) = 
  val oneMinute: String = "1m"
  println(s"input: $input is of Timeframe: ${input.isInstanceOf[Timeframe]}")
  println(s"1m is of Timeframe: ${oneMinute.isInstanceOf[Timeframe]}")

@main def main(input: String) = 
  ok("1H")
  ok(input)

This is also a bit troubling.

sbt:scala3-simple> run 1m
input: 1H is of Timeframe: true
1m is of Timeframe: true
input: 1m is of Timeframe: false
1m is of Timeframe: true

odersky added a commit to dotty-staging/dotty that referenced this issue Jun 12, 2021
We used `eq` before, as for other objetc singletons. But this means
we are subject to the vagaries of string hashing.

Fixes scala#12796
@Kordyjan Kordyjan added this to the 3.0.2 milestone Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants