-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Closed
Description
Scala Version
3.2.2
Minimized Code
trait A:
final class X
extension (x:X)
def next: A#X
def foo(ax:A#X) =
ax.nextResult
Compilation fails with value next is not a member of A#X.
Expectation
Would be elegant to let code compile.
For an inner projection P#T, (x:P#T).extensionMethod(args) would desugar into something similar to
{ val outer : P = x.$outer
outer.extensionMethod(inner:outer.T)(args)
}Rationale
In a pattern where the inner class is final but the outer class is open, it is elegant to create extensions which only make sense on the subclasses of the outer class.
class A:
class X
class B extends A:
extension (x:X) def foo : ...So that bx:B#Xs have a foo method, while ax:A#Xs do not.
Today, a significant boiler plate is necessary:
class A:
class X:
def deflect[T](f: (a:A.this.type) => a.X => T) : T = f(A.this)(this)
object B:
extension (x:B#X) def foo = x.deflect(_.foo)
class B extends A:
def foo(x:X) = ...- the
deflectmethod is present in the innerclass, and must be left public. - Each extension method is declared twice, once in the companion object as extension, and once in the class as implementation.
Metadata
Metadata
Assignees
Labels
No labels