Description
If a value tasty
has abstract type T
and T
is marked as being a singleton type (that is, currently, T <: Singleton
), I’d expect tasty.type = T
, because both types are singleton that contain tasty
. This currently fails in Scalac and Dotty (the Scala report is scala/bug#10905 — this is a copy, with Scalac output swapped with Dotty output).
A minimized example:
scala> trait A { type T; val prod: T; val cons: T => Int = _ => 0 }; trait Foo { type U <: Singleton with A; val tasty: U }
// defined trait A
// defined trait Foo
scala> val v: A = new A { type T = Int; val prod: T = 1}; val u: Foo = new Foo { type U = v.type; val tasty: U = v }
val v: A = anon$1@5416f8db
val u: Foo = anon$2@64e1377c
scala> u.tasty.cons(u.tasty.prod: u.U#T)
1 |u.tasty.cons(u.tasty.prod: u.U#T)
| ^^^^^^^^^^^^^^^^^^^
| found: u.U#T
| required: u.tasty.T
|
/cc @milessabin
Background
I ran into this while prototyping a heavily path-dependent API in Dotty (an early version of Tasty reflection), in relation to https://github.com/lampepfl/dotty/pull/4577/files/b315dbfa9f2d206cc26da75779388fca98faaabd#r191016341; the workaround involved turning defs into vals, which I suspect is acceptable here but potentially annoying when trying to save memory.
Alternatives
For the example above, enabling the definition of idempotent methods might be more general, if we ever get there.
Soundness
Not formally investigated, since nobody yet added to DOT either singleton types, type projections or singleton type variables.