Skip to content

Prevent matching into or out of an opaque type #7314

Closed
@LPTK

Description

@LPTK

One of the stated goals of opaque types is to statically enforce invariants about some values without wrapping them. To achieve this, we must control what values are allowed to get converted into and out of the opaque type.

Matching on opaque types is currently allowed, and break this. For instance, it is possible to convert an immutable array into a mutable one by matching on it, which defeats its purpose.

minimized code

@main def main = {
  
  // conversion into the opaque type:
  val arr = Array(1,2,3)
  val imm0: IArray[Int] // supposedly immutable
    = oops(arr)
  println(imm0(0)) // 1
  arr(0) = 0
  println(imm0(0)) // 0, the value has changed!
  
  // conversion out of the opaque type:
  val imm1 = IArray(1,2,3) // supposedly immutable
  println(imm1(0)) // 1
  imm1 match {
    case a: Array[Int] =>
      a(0) = 0
  }
  println(imm1(0)) // 0
  
}

def oops(a: Array[Int]): IArray[Int] = a match {
  case a: IArray[Int] => a
}

https://scastie.scala-lang.org/hV46dfNWR6iTP2uLIMfS2g

expectation

Both matches should be rejected, or at the very least give warnings.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions