Closed
Description
Compiler version
3.0.0-RC3
Minimized code
object Html {
final opaque type Tag[+N] = String
def apply[N](name: String): Tag[N] = name
}
object HtmlTags {
final def br: Html.Tag[Int] = Html("br")
final def p = Html[Long]("p")
}
object Test {
type Expect = Html.Tag[Any]
val x = List[Expect](HtmlTags.br, HtmlTags.p) // ok
val y = List(HtmlTags.br, HtmlTags.p)
y: List[Expect] // error
}
Output
[error] 17 | y: List[Expect] // error
[error] | ^
[error] | Found: (Test.y : List[Any])
[error] | Required: List[Test.Expect]
Expectation
Success.
Without opaque types
If we replace the opaque type with a case class and type alias, everything compiles successfully.
case class Html[+N](name: String)
object Html {
type Tag[+N] = Html[N]
}
// object Html {
// final opaque type Tag[+N] = String
// def apply[N](name: String): Tag[N] = name
// }
// Code below is unchanged
object HtmlTags {
final def br: Html.Tag[Int] = Html("br")
final def p = Html[Long]("p")
}
object Test {
type Expect = Html.Tag[Any]
val x = List[Expect](HtmlTags.br, HtmlTags.p) // ok
val y = List(HtmlTags.br, HtmlTags.p)
y: List[Expect] // ok now
}