Skip to content

Commit 6024f02

Browse files
Forbid term params for inline traits
This decision, approved by M. Odersky and N. Stucki, comes from the fact that traits cannot call the constructors of other traits. This creates a problem when inlining inner traits, because they need to extend their original counterpart. However, since it cannot pass arguments, the extension would need to be generated when inlining, which adds the need for param bindings. Example: ``` inline trait A: trait Inner(x: Int) /* * replaced by: * * trait Inner$trait(x: Int) * type Inner <: Inner$trait */ end A class B extends A: /* * generated: * * trait Inner(x: Int) extends Inner$trait // missing term x */ end B val b = B() class C extends B.Inner(1) // invalid: must declare extension of Inner$trait explicitly ```
1 parent 96941a0 commit 6024f02

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2688,6 +2688,18 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
26882688
)
26892689
)
26902690
val membersToInline = body1.filter(member => Inlines.isInlineableFromInlineTrait(cls, member))
2691+
membersToInline.foreach {
2692+
case tdef: TypeDef if tdef.symbol.isClass =>
2693+
def rec(paramss: List[List[Symbol]]): Unit = paramss match {
2694+
case (param :: _) :: _ if param.isTerm =>
2695+
report.error(em"Implementation restriction: inline traits cannot have term parameters", param.srcPos)
2696+
case _ :: paramss =>
2697+
rec(paramss)
2698+
case _ =>
2699+
}
2700+
rec(tdef.symbol.primaryConstructor.paramSymss)
2701+
case _ =>
2702+
}
26912703
val wrappedMembersToInline = Block(membersToInline, unitLiteral).withSpan(cdef.span)
26922704
PrepareInlineable.registerInlineInfo(cls, wrappedMembersToInline)
26932705

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
inline trait A[T]:
2+
trait InnerAType[T >: Int <: AnyVal]
3+
trait InnerATypes[T <: AnyVal, U <: T]
4+
trait InnerATerm(i: Int) // error
5+
trait InnerATerms(i: Int, j: Double) // error
6+
trait InnerATermsCurried(i: Int, j: Double)(k: String) // error
7+
trait InnerAAllCurried[T, U](i: T, j: U)(k: (T, U)) // error

0 commit comments

Comments
 (0)