Skip to content

Commit fe01d7a

Browse files
committed
Add error message when trait parameter prefix is used in its parent
#1589
1 parent 45b6ebd commit fe01d7a

File tree

4 files changed

+38
-2
lines changed

4 files changed

+38
-2
lines changed

compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ enum ErrorMessageID extends java.lang.Enum[ErrorMessageID] {
145145
NoMatchingOverloadID,
146146
StableIdentPatternID,
147147
StaticFieldsShouldPrecedeNonStaticID,
148-
IllegalSuperAccessorID
148+
IllegalSuperAccessorID,
149+
TraitParameterUsedAsParentPrefixID
149150

150151
def errorNumber = ordinal - 2
151152
}

compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala

+16
Original file line numberDiff line numberDiff line change
@@ -2362,4 +2362,20 @@ object messages {
23622362
}
23632363
val explanation: String = ""
23642364
}
2365+
2366+
case class TraitParameterUsedAsParentPrefix(cls: Symbol)(implicit val ctx: Context)
2367+
extends Message(TraitParameterUsedAsParentPrefixID) {
2368+
val kind: String = "Reference"
2369+
val msg: String =
2370+
s"${cls.show} cannot extend from a parent that is derived via its own parameters"
2371+
val explanation: String =
2372+
ex"""
2373+
|The parent class/trait that ${cls.show} extends from is obtained from
2374+
|the parameter of ${cls.show}. This is disallowed in order to prevent
2375+
|outer-related Null Pointer Exceptions in Scala.
2376+
|
2377+
|In order to fix this issue consider directly extending from the parent rather
2378+
|than obtaining it from the parameters of ${cls.show}.
2379+
|""".stripMargin
2380+
}
23652381
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ object RefChecks {
116116
case TypeRef(ref: TermRef, _) =>
117117
val paramRefs = ref.namedPartsWith(ntp => ntp.symbol.enclosingClass == cls)
118118
if (paramRefs.nonEmpty)
119-
ctx.error("trait parameters cannot be used as parent prefixes", parent.sourcePos)
119+
ctx.error(TraitParameterUsedAsParentPrefix(cls), parent.sourcePos)
120120
case _ =>
121121
}
122122

compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala

+19
Original file line numberDiff line numberDiff line change
@@ -1638,4 +1638,23 @@ class ErrorMessagesTests extends ErrorMessagesTest {
16381638
message.msg
16391639
)
16401640
}
1641+
1642+
@Test def traitParametersUsedAsParentPrefix() =
1643+
checkMessagesAfter(RefChecks.name) {
1644+
"""
1645+
|class Outer {
1646+
| trait Inner
1647+
| trait Test(val outer: Outer) extends outer.Inner
1648+
|}
1649+
|""".stripMargin
1650+
}.expect {
1651+
(ictx, messages) =>
1652+
implicit val ctx: Context = ictx
1653+
val TraitParameterUsedAsParentPrefix(cls) :: Nil = messages
1654+
assertEquals("trait Test", cls.show)
1655+
assertEquals(
1656+
s"${cls.show} cannot extend from a parent that is derived via its own parameters",
1657+
messages.head.msg
1658+
)
1659+
}
16411660
}

0 commit comments

Comments
 (0)