Skip to content

Commit

Permalink
Add error message when trait parameter prefixes are used for its parent
Browse files Browse the repository at this point in the history
lampepfl#1589
  • Loading branch information
harpresing committed Oct 8, 2019
1 parent 45b6ebd commit 76e1453
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ enum ErrorMessageID extends java.lang.Enum[ErrorMessageID] {
NoMatchingOverloadID,
StableIdentPatternID,
StaticFieldsShouldPrecedeNonStaticID,
IllegalSuperAccessorID
IllegalSuperAccessorID,
TraitParameterUsedAsParentPrefixID

def errorNumber = ordinal - 2
}
16 changes: 16 additions & 0 deletions compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2362,4 +2362,20 @@ object messages {
}
val explanation: String = ""
}

case class TraitParameterUsedAsParentPrefix(typ: NamedType)(implicit val ctx: Context)
extends Message(TraitParameterUsedAsParentPrefixID) {
val kind: String = "Reference"
val msg: String =
s"${typ.symbol.show} cannot extend from a parent that is derived via its own parameters"
val explanation: String =
ex"""
|The parent class/trait that ${typ.symbol.show} extends from is obtained from
|the parameter of ${typ.symbol.show}. This is disallowed in order to prevent
|outer-related Null Pointer Exceptions in Scala.
|
|In order to fix this issue consider directly extending from the parent rather
|than obtaining it from the parameters of ${typ.symbol.show}.
|""".stripMargin
}
}
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ object RefChecks {
case TypeRef(ref: TermRef, _) =>
val paramRefs = ref.namedPartsWith(ntp => ntp.symbol.enclosingClass == cls)
if (paramRefs.nonEmpty)
ctx.error("trait parameters cannot be used as parent prefixes", parent.sourcePos)
ctx.error(TraitParameterUsedAsParentPrefix(paramRefs.tail.head), parent.sourcePos)
case _ =>
}

Expand Down
20 changes: 20 additions & 0 deletions compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1638,4 +1638,24 @@ class ErrorMessagesTests extends ErrorMessagesTest {
message.msg
)
}

@Test def traitParametersUsedAsParentPrefix() =
checkMessagesAfter(RefChecks.name) {
"""
|class Outer {
| trait Inner
| trait Test(val outer: Outer) extends outer.Inner
|}
|""".stripMargin
}.expect {
(ictx, messages) =>
implicit val ctx: Context = ictx
val TraitParameterUsedAsParentPrefix(typ) :: Nil = messages
assertEquals(1, messages.size)
assertEquals("trait Test", typ.symbol.show)
assertEquals(
s"${typ.symbol.show} cannot extend from a parent that is derived via its own parameters",
messages.head.msg
)
}
}

0 comments on commit 76e1453

Please sign in to comment.