Skip to content

Commit 8660e18

Browse files
Forbid defining inline traits inside inline traits
When inlining the body of an inline trait, trying to inline another inline trait creates typing issues. For example, with the following code: ``` inline trait A[T]: inline trait InnerA[U]: val x: (T, U) = ??? class B extends A[Int]: class InnerB extends InnerA[String] ``` when the Inlining phase tries to inline InnerA inside of InnerB, it should try to change A#T to B#T but does not know that A exists in a higher scope. An idea to solve this would be to inline everything from A inside of B before inlining InnerA inside of InnerB, but this adds quite a bit of complexity. Another one would be to keep track, when inlining a trait, of all the type parameters like we do for term parameters. This could be done more easily. This will be left as future work for the time being.
1 parent 383e771 commit 8660e18

File tree

3 files changed

+13
-7
lines changed

3 files changed

+13
-7
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2675,6 +2675,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
26752675
val body1 = addAccessorDefs(cls, typedStats(impl.body, dummy)(using ctx.inClassContext(self1.symbol))._1)
26762676

26772677
if !ctx.isAfterTyper && cls.isInlineTrait then
2678+
body1.map(_.symbol).filter(_.isInlineTrait).foreach(innerInlTrait =>
2679+
report.error(
2680+
em"Implementation restriction: an inline trait cannot be defined inside of another inline trait",
2681+
innerInlTrait.srcPos
2682+
)
2683+
)
26782684
val membersToInline = body1.filter(member => Inlines.isInlineableFromInlineTrait(cls, member))
26792685
val wrappedMembersToInline = Block(membersToInline, unitLiteral).withSpan(cdef.span)
26802686
PrepareInlineable.registerInlineInfo(cls, wrappedMembersToInline)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
inline trait A[T]:
2+
inline trait InnerA[U]: // error
3+
val x: (T, U) = ???
4+
5+
class B extends A[Int]:
6+
class InnerB extends InnerA[String]
7+
def f: (Int, String) = InnerB().x

tests/pos/inline-trait-body-trait-inline.scala

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)