Skip to content

Commit 425c8c1

Browse files
johnreganfelixmulder
johnregan
authored andcommitted
Combine modifiers not allowed with type, and combinations.This also simplifies logic. Adds more detail to explanation (#2807)
* Combine errors and simplifies logic. Adds more detail to explanation * refactor to DRY prinicpal * move method to local scope, replace paraphrasing with url to documentation
1 parent bf1082d commit 425c8c1

File tree

3 files changed

+28
-18
lines changed

3 files changed

+28
-18
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,18 +1680,13 @@ object Parsers {
16801680
)
16811681

16821682
def addFlag(mods: Modifiers, flag: FlagSet): Modifiers = {
1683-
def incompatible(kind: String) = {
1684-
syntaxError(ModifiersNotAllowed(mods.flags, kind))
1685-
Modifiers(flag)
1686-
}
1683+
def getPrintableTypeFromFlagSet =
1684+
Map(Trait -> "trait", Method -> "method", Mutable -> "variable").get(flag)
1685+
16871686
if (compatible(mods.flags, flag)) mods | flag
1688-
else flag match {
1689-
case Trait => incompatible("trait")
1690-
case Method => incompatible("method")
1691-
case Mutable => incompatible("variable")
1692-
case _ =>
1693-
syntaxError(s"illegal modifier combination: ${mods.flags} and $flag")
1694-
mods
1687+
else {
1688+
syntaxError(ModifiersNotAllowed(mods.flags, getPrintableTypeFromFlagSet))
1689+
Modifiers(flag)
16951690
}
16961691
}
16971692

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1648,18 +1648,23 @@ object messages {
16481648
val explanation = "Method inlining prohibits calling superclass methods, as it may lead to confusion about which super is being called."
16491649
}
16501650

1651-
case class ModifiersNotAllowed(flags: FlagSet, sort: String)(implicit ctx: Context)
1651+
case class ModifiersNotAllowed(flags: FlagSet, printableType: Option[String])(implicit ctx: Context)
16521652
extends Message(ModifiersNotAllowedID) {
16531653
val kind = "Syntax"
1654-
val msg = s"modifier(s) `$flags' not allowed for $sort"
1654+
val msg = s"modifier(s) `$flags' not allowed for ${printableType.getOrElse("combination")}"
16551655
val explanation = {
1656-
val code = "sealed def y: Int = 1"
1656+
val first = "sealed def y: Int = 1"
1657+
val second = "sealed lazy class z"
16571658
hl"""You tried to use a modifier that is inapplicable for the type of item under modification
16581659
|
1660+
| Please see the official Scala Language Specification section on modifiers:
1661+
| https://www.scala-lang.org/files/archive/spec/2.11/05-classes-and-objects.html#modifiers
16591662
|
16601663
|Consider the following example:
1661-
|$code
1664+
|$first
16621665
|In this instance, the modifier 'sealed' is not applicable to the item type 'def' (method)
1666+
|$second
1667+
|In this instance, the modifier combination is not supported
16631668
"""
16641669
}
16651670
}

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ package reporting
44

55
import core.Contexts.Context
66
import diagnostic.messages._
7+
import dotty.tools.dotc.core.Flags
8+
import dotty.tools.dotc.core.Flags.FlagSet
79
import dotty.tools.dotc.core.Types.WildcardType
810
import dotty.tools.dotc.parsing.Tokens
911
import org.junit.Assert._
@@ -841,14 +843,22 @@ class ErrorMessagesTests extends ErrorMessagesTest {
841843
}
842844

843845
@Test def modifiersNotAllowed =
844-
checkMessagesAfter("refchecks")("""lazy trait T""")
846+
verifyModifiersNotAllowed("lazy trait T", "lazy", Some("trait"))
847+
848+
@Test def modifiersOtherThanTraitMethodVariable =
849+
verifyModifiersNotAllowed("sealed lazy class x", "sealed")
850+
851+
private def verifyModifiersNotAllowed(code: String, modifierAssertion: String,
852+
typeAssertion: Option[String] = None) = {
853+
checkMessagesAfter("refchecks")(code)
845854
.expect { (ictx, messages) =>
846855
implicit val ctx: Context = ictx
847856
assertMessageCount(1, messages)
848857
val ModifiersNotAllowed(flags, sort) :: Nil = messages
849-
assertEquals("lazy", flags.toString)
850-
assertEquals("trait", sort)
858+
assertEquals(modifierAssertion, flags.toString)
859+
assertEquals(typeAssertion, sort)
851860
}
861+
}
852862

853863
@Test def wildcardOnTypeArgumentNotAllowedOnNew =
854864
checkMessagesAfter("refchecks") {

0 commit comments

Comments
 (0)