Closed
Description
Compiler version
3.0.0-RC1
Minimized code
class Record(private val fields: Map[String, Any]) extends Selectable:
def this(elems: (String, Any)*) = this(elems.toMap)
def selectDynamic(name: String): Any = fields(name)
infix def ::[I <: Record, O >: this.type & I](record: I): O =
Record(fields ++ record.fields).asInstanceOf[O]
def debug() =
val elems = fields.map{ case (key, value) => s"${key}: ${value.getClass.getSimpleName.toString}" }
s"{ ${elems.mkString(", ")} }"
def toJson() =
val elems = fields.map{ case (key, value) => s"${key}: ${value}" }
s"{ ${elems.mkString(", ")} }"
object Record:
def of[T <: Record](elems: (String, Any)*) = Record(elems.toMap).asInstanceOf[T]
def obj[I <: Object](obj: I) = obj.asInstanceOf[Record]
extension [L <: Object](left: L)
infix def &[R <: Object, O >: L & R](right: R): O =
(left.asInstanceOf[Record] :: right.asInstanceOf[Record]).asInstanceOf[O]
@main def hello =
type One = { val one: Int }
type Two = { val two: Int }
type Extended = { val one: Int; val two: Int }
val one: One = Record.of("one" -> 1)
val two: Two = Record.of("two" -> 2)
val v1: One & Two = one & two
val v2 = one & two
val v3: Extended = v1
val v4: Extended = v2
val v5: Extended = one & two
val record = Record.obj(one & two)
println(Record.obj(v2).toJson())
Output
Found: (two : Two)
Required: Object{one: Int; two: Int}
Expectation
line 38: val v5: Extended = one & two
should work in the same way this works:
val v3: Extended = v1
val v4: Extended = v2