Skip to content

Weird opaque types behaviour #15050

Open
Open
@jmgimeno

Description

@jmgimeno

Compiler version

I'be tested this on scala 3.0.0 and scala 3.1.2

Example 1

//> using scala "3.1.2"
import OpaqueBug.*
def g(n: Counter): Counter = n
object OpaqueBug:
  opaque type Counter = Int
  val initial: Counter = 42
  def f(n: Int): Int = g(n) + initial
  @main def run = println(f(21))

And the compiler complains with:

[error] ./OpaqueBug.scala:13:24: value + is not a member of OpaqueBug.Counter, but could be made available as an extension method.
[error] 
[error] One of the following imports might fix the problem:
[error] 
[error]   import Int.int2double
[error]   import Int.int2float
[error]   import Int.int2long
[error]   import math.BigDecimal.int2bigDecimal
[error]   import math.BigInt.int2bigInt
[error]   import math.Numeric.IntIsIntegral.mkNumericOps
[error] 
[error]   def f(n: Int): Int = g(n) + initial
[error]   

I'd would expect this code to compile because when we do the + the compiler should know than Counter is simply an Int.

Example 2

If I move the opaque definition outside of the object:

//> using scala "3.1.2"
opaque type Counter = Int
def g(n: Counter): Counter = n
object OpaqueBug:
  val initial: Counter = 42
  def f(n: Int): Int = g(n) + initial
  @main def run = println(f(21))

Then the compiler complains with

[error] ./OpaqueBug.scala:11:26: Found:    (42 : Int)
[error] Required: Counter
[error]   val initial: Counter = 42
[error]                          ^^
[error] ./OpaqueBug.scala:13:26: Found:    (n : Int)
[error] Required: Counter
[error]   def f(n: Int): Int = g(n) + initial
[error]   

And I'd expect this code to compile without problems.

So, is this a bug or a feature (and it's me that I do not understand how opaque types should work)?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions