aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala160
1 files changed, 117 insertions, 43 deletions
diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
index 4d61f21cf..7fccebef9 100644
--- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
+++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -4,12 +4,20 @@ package reporting
package diagnostic
import dotc.core._
-import Contexts.Context, Decorators._, Symbols._, Names._, NameOps._, Types._
+import Contexts.Context
+import Decorators._
+import Symbols._
+import Names._
+import NameOps._
+import Types._
import util.SourcePosition
import config.Settings.Setting
-import interfaces.Diagnostic.{ERROR, WARNING, INFO}
+import interfaces.Diagnostic.{ERROR, INFO, WARNING}
+import dotc.parsing.Scanners.Token
+import dotc.parsing.Tokens
import printing.Highlighting._
import printing.Formatting
+import ErrorMessageID._
object messages {
@@ -87,8 +95,8 @@ object messages {
// Syntax Errors ---------------------------------------------------------- //
- abstract class EmptyCatchOrFinallyBlock(tryBody: untpd.Tree, errNo: Int)(implicit ctx: Context)
- extends Message(errNo) {
+ abstract class EmptyCatchOrFinallyBlock(tryBody: untpd.Tree, errNo: ErrorMessageID)(implicit ctx: Context)
+ extends Message(EmptyCatchOrFinallyBlockID) {
val explanation = {
val tryString = tryBody match {
case Block(Nil, untpd.EmptyTree) => "{}"
@@ -124,7 +132,7 @@ object messages {
}
case class EmptyCatchBlock(tryBody: untpd.Tree)(implicit ctx: Context)
- extends EmptyCatchOrFinallyBlock(tryBody, 1) {
+ extends EmptyCatchOrFinallyBlock(tryBody, EmptyCatchBlockID) {
val kind = "Syntax"
val msg =
hl"""|The ${"catch"} block does not contain a valid expression, try
@@ -132,7 +140,7 @@ object messages {
}
case class EmptyCatchAndFinallyBlock(tryBody: untpd.Tree)(implicit ctx: Context)
- extends EmptyCatchOrFinallyBlock(tryBody, 2) {
+ extends EmptyCatchOrFinallyBlock(tryBody, EmptyCatchAndFinallyBlockID) {
val kind = "Syntax"
val msg =
hl"""|A ${"try"} without ${"catch"} or ${"finally"} is equivalent to putting
@@ -140,7 +148,7 @@ object messages {
}
case class DeprecatedWithOperator()(implicit ctx: Context)
- extends Message(3) {
+ extends Message(DeprecatedWithOperatorID) {
val kind = "Syntax"
val msg =
hl"""${"with"} as a type operator has been deprecated; use `&' instead"""
@@ -151,7 +159,7 @@ object messages {
}
case class CaseClassMissingParamList(cdef: untpd.TypeDef)(implicit ctx: Context)
- extends Message(4) {
+ extends Message(CaseClassMissingParamListID) {
val kind = "Syntax"
val msg =
hl"""|A ${"case class"} must have at least one parameter list"""
@@ -165,7 +173,7 @@ object messages {
// Type Errors ------------------------------------------------------------ //
case class DuplicateBind(bind: untpd.Bind, tree: untpd.CaseDef)(implicit ctx: Context)
- extends Message(5) {
+ extends Message(DuplicateBindID) {
val kind = "Naming"
val msg = em"duplicate pattern variable: `${bind.name}`"
@@ -192,7 +200,7 @@ object messages {
}
case class MissingIdent(tree: untpd.Ident, treeKind: String, name: String)(implicit ctx: Context)
- extends Message(6) {
+ extends Message(MissingIdentID) {
val kind = "Unbound Identifier"
val msg = em"not found: $treeKind$name"
@@ -205,7 +213,7 @@ object messages {
}
case class TypeMismatch(found: Type, expected: Type, whyNoMatch: String = "", implicitFailure: String = "")(implicit ctx: Context)
- extends Message(7) {
+ extends Message(TypeMismatchID) {
val kind = "Type Mismatch"
val msg = {
val (where, printCtx) = Formatting.disambiguateTypes(found, expected)
@@ -220,7 +228,7 @@ object messages {
}
case class NotAMember(site: Type, name: Name, selected: String)(implicit ctx: Context)
- extends Message(8) {
+ extends Message(NotAMemberID) {
val kind = "Member Not Found"
//println(i"site = $site, decls = ${site.decls}, source = ${site.widen.typeSymbol.sourceFile}") //DEBUG
@@ -286,7 +294,7 @@ object messages {
}
case class EarlyDefinitionsNotSupported()(implicit ctx: Context)
- extends Message(9) {
+ extends Message(EarlyDefinitionsNotSupportedID) {
val kind = "Syntax"
val msg = "early definitions are not supported; use trait parameters instead"
@@ -332,7 +340,7 @@ object messages {
}
case class TopLevelImplicitClass(cdef: untpd.TypeDef)(implicit ctx: Context)
- extends Message(10) {
+ extends Message(TopLevelImplicitClassID) {
val kind = "Syntax"
val msg = hl"""An ${"implicit class"} may not be top-level"""
@@ -362,7 +370,7 @@ object messages {
}
case class ImplicitCaseClass(cdef: untpd.TypeDef)(implicit ctx: Context)
- extends Message(11) {
+ extends Message(ImplicitCaseClassID) {
val kind = "Syntax"
val msg = hl"""A ${"case class"} may not be defined as ${"implicit"}"""
@@ -375,7 +383,7 @@ object messages {
}
case class ObjectMayNotHaveSelfType(mdef: untpd.ModuleDef)(implicit ctx: Context)
- extends Message(12) {
+ extends Message(ObjectMayNotHaveSelfTypeID) {
val kind = "Syntax"
val msg = hl"""${"object"}s must not have a self ${"type"}"""
@@ -393,7 +401,7 @@ object messages {
}
case class TupleTooLong(ts: List[untpd.Tree])(implicit ctx: Context)
- extends Message(13) {
+ extends Message(TupleTooLongID) {
import Definitions.MaxTupleArity
val kind = "Syntax"
val msg = hl"""A ${"tuple"} cannot have more than ${MaxTupleArity} members"""
@@ -409,7 +417,7 @@ object messages {
}
case class RepeatedModifier(modifier: String)(implicit ctx:Context)
- extends Message(14) {
+ extends Message(RepeatedModifierID) {
val kind = "Syntax"
val msg = hl"""repeated modifier $modifier"""
@@ -431,7 +439,7 @@ object messages {
}
case class InterpolatedStringError()(implicit ctx:Context)
- extends Message(15) {
+ extends Message(InterpolatedStringErrorID) {
val kind = "Syntax"
val msg = "error in interpolated string: identifier or block expected"
val explanation = {
@@ -449,7 +457,7 @@ object messages {
}
case class UnboundPlaceholderParameter()(implicit ctx:Context)
- extends Message(16) {
+ extends Message(UnboundPlaceholderParameterID) {
val kind = "Syntax"
val msg = "unbound placeholder parameter; incorrect use of `_`"
val explanation =
@@ -482,7 +490,7 @@ object messages {
}
case class IllegalStartSimpleExpr(illegalToken: String)(implicit ctx: Context)
- extends Message(17) {
+ extends Message(IllegalStartSimpleExprID) {
val kind = "Syntax"
val msg = "illegal start of simple expression"
val explanation = {
@@ -500,7 +508,8 @@ object messages {
}
}
- case class MissingReturnType()(implicit ctx:Context) extends Message(18) {
+ case class MissingReturnType()(implicit ctx:Context)
+ extends Message(MissingReturnTypeID) {
val kind = "Syntax"
val msg = "missing return type"
val explanation =
@@ -512,7 +521,7 @@ object messages {
}
case class YieldOrDoExpectedInForComprehension()(implicit ctx: Context)
- extends Message(19) {
+ extends Message(YieldOrDoExpectedInForComprehensionID) {
val kind = "Syntax"
val msg = hl"${"yield"} or ${"do"} expected"
@@ -545,7 +554,7 @@ object messages {
}
case class ProperDefinitionNotFound()(implicit ctx: Context)
- extends Message(20) {
+ extends Message(ProperDefinitionNotFoundID) {
val kind = "Definition Not Found"
val msg = hl"""Proper definition was not found in ${"@usecase"}"""
@@ -584,7 +593,7 @@ object messages {
}
case class ByNameParameterNotSupported()(implicit ctx: Context)
- extends Message(21) {
+ extends Message(ByNameParameterNotSupportedID) {
val kind = "Syntax"
val msg = "By-name parameter type not allowed here."
@@ -608,7 +617,7 @@ object messages {
}
case class WrongNumberOfTypeArgs(fntpe: Type, expectedArgs: List[TypeParamInfo], actual: List[untpd.Tree])(implicit ctx: Context)
- extends Message(22) {
+ extends Message(WrongNumberOfTypeArgsID) {
val kind = "Syntax"
private val expectedCount = expectedArgs.length
@@ -654,7 +663,7 @@ object messages {
}
case class IllegalVariableInPatternAlternative()(implicit ctx: Context)
- extends Message(23) {
+ extends Message(IllegalVariableInPatternAlternativeID) {
val kind = "Syntax"
val msg = "Variables are not allowed in alternative patterns"
val explanation = {
@@ -683,7 +692,7 @@ object messages {
}
case class TypeParamsTypeExpected(mods: untpd.Modifiers, identifier: TermName)(implicit ctx: Context)
- extends Message(24) {
+ extends Message(TypeParamsTypeExpectedID) {
val kind = "Syntax"
val msg = hl"""Expected ${"type"} keyword for type parameter $identifier"""
val explanation =
@@ -696,7 +705,7 @@ object messages {
}
case class IdentifierExpected(identifier: String)(implicit ctx: Context)
- extends Message(25) {
+ extends Message(IdentifierExpectedID) {
val kind = "Syntax"
val msg = "identifier expected"
val explanation = {
@@ -717,7 +726,7 @@ object messages {
}
case class AuxConstructorNeedsNonImplicitParameter()(implicit ctx:Context)
- extends Message(26) {
+ extends Message(AuxConstructorNeedsNonImplicitParameterID) {
val kind = "Syntax"
val msg = "auxiliary constructor needs non-implicit parameter list"
val explanation =
@@ -732,7 +741,8 @@ object messages {
|"""
}
- case class IncorrectRepeatedParameterSyntax()(implicit ctx: Context) extends Message(27) {
+ case class IncorrectRepeatedParameterSyntax()(implicit ctx: Context)
+ extends Message(IncorrectRepeatedParameterSyntaxID) {
val kind = "Syntax"
val msg = "'*' expected"
val explanation =
@@ -758,7 +768,8 @@ object messages {
|""".stripMargin
}
- case class IllegalLiteral()(implicit ctx: Context) extends Message(28) {
+ case class IllegalLiteral()(implicit ctx: Context)
+ extends Message(IllegalLiteralID) {
val kind = "Syntax"
val msg = "illegal literal"
val explanation =
@@ -773,7 +784,7 @@ object messages {
}
case class PatternMatchExhaustivity(uncovered: String)(implicit ctx: Context)
- extends Message(29) {
+ extends Message(PatternMatchExhaustivityID) {
val kind = "Pattern Match Exhaustivity"
val msg =
hl"""|match may not be exhaustive.
@@ -785,14 +796,14 @@ object messages {
}
case class MatchCaseUnreachable()(implicit ctx: Context)
- extends Message(30) {
+ extends Message(MatchCaseUnreachableID) {
val kind = s"""Match ${hl"case"} Unreachable"""
val msg = "unreachable code"
val explanation = ""
}
case class SeqWildcardPatternPos()(implicit ctx: Context)
- extends Message(31) {
+ extends Message(SeqWildcardPatternPosID) {
val kind = "Syntax"
val msg = "`_*' can be used only for last argument"
val explanation = {
@@ -815,7 +826,8 @@ object messages {
}
}
- case class IllegalStartOfSimplePattern()(implicit ctx: Context) extends Message(32) {
+ case class IllegalStartOfSimplePattern()(implicit ctx: Context)
+ extends Message(IllegalStartOfSimplePatternID) {
val kind = "Syntax"
val msg = "illegal start of simple pattern"
val explanation = {
@@ -895,13 +907,14 @@ object messages {
}
case class PkgDuplicateSymbol(existing: Symbol)(implicit ctx: Context)
- extends Message(33) {
+ extends Message(PkgDuplicateSymbolID) {
val kind = "Duplicate Symbol"
val msg = hl"trying to define package with same name as `$existing`"
val explanation = ""
}
- case class ExistentialTypesNoLongerSupported()(implicit ctx: Context) extends Message(34) {
+ case class ExistentialTypesNoLongerSupported()(implicit ctx: Context)
+ extends Message(ExistentialTypesNoLongerSupportedID) {
val kind = "Syntax"
val msg =
hl"""|Existential types are no longer supported -
@@ -923,7 +936,8 @@ object messages {
|"""
}
- case class UnboundWildcardType()(implicit ctx: Context) extends Message(35) {
+ case class UnboundWildcardType()(implicit ctx: Context)
+ extends Message(UnboundWildcardTypeID) {
val kind = "Syntax"
val msg = "Unbound wildcard type"
val explanation =
@@ -967,7 +981,7 @@ object messages {
|"""
}
- case class DanglingThisInPath()(implicit ctx: Context) extends Message(36) {
+ case class DanglingThisInPath()(implicit ctx: Context) extends Message(DanglingThisInPathID) {
val kind = "Syntax"
val msg = hl"""Expected an additional member selection after the keyword ${"this"}"""
@@ -1004,7 +1018,7 @@ object messages {
}
case class OverridesNothing(member: Symbol)(implicit ctx: Context)
- extends Message(37) {
+ extends Message(OverridesNothingID) {
val kind = "Reference"
val msg = hl"""${member} overrides nothing"""
@@ -1016,7 +1030,7 @@ object messages {
}
case class OverridesNothingButNameExists(member: Symbol, existing: List[Denotations.SingleDenotation])(implicit ctx: Context)
- extends Message(38) {
+ extends Message(OverridesNothingButNameExistsID) {
val kind = "Reference"
val msg = hl"""${member} has a different signature than the overridden declaration"""
@@ -1035,7 +1049,7 @@ object messages {
}
case class ForwardReferenceExtendsOverDefinition(value: Symbol, definition: Symbol)(implicit ctx: Context)
- extends Message(39) {
+ extends Message(ForwardReferenceExtendsOverDefinitionID) {
val kind = "Reference"
val msg = hl"`${definition.name}` is a forward reference extending over the definition of `${value.name}`"
@@ -1053,4 +1067,64 @@ object messages {
|""".stripMargin
}
+ case class ExpectedTokenButFound(expected: Token, found: Token, foundName: TermName)(implicit ctx: Context)
+ extends Message(ExpectedTokenButFoundID) {
+ val kind = "Syntax"
+
+ private val expectedText =
+ if (Tokens.isIdentifier(expected)) "an identifier"
+ else Tokens.showToken(expected)
+
+ private val foundText =
+ if (foundName != null) hl"`${foundName.show}`"
+ else Tokens.showToken(found)
+
+ val msg = hl"""${expectedText} expected, but ${foundText} found"""
+
+ private val ifKeyword =
+ if (Tokens.isIdentifier(expected) && Tokens.isKeyword(found))
+ s"""
+ |If you necessarily want to use $foundText as identifier, you may put it in backticks.""".stripMargin
+ else
+ ""
+
+ val explanation =
+ s"""|The text ${foundText} may not occur at that position, the compiler expected ${expectedText}.$ifKeyword
+ |""".stripMargin
+ }
+
+ case class MixedLeftAndRightAssociativeOps(op1: Name, op2: Name, op2LeftAssoc: Boolean)(implicit ctx: Context)
+ extends Message(MixedLeftAndRightAssociativeOpsID) {
+ val kind = "Syntax"
+ val op1Asso = if (op2LeftAssoc) "which is right-associative" else "which is left-associative"
+ val op2Asso = if (op2LeftAssoc) "which is left-associative" else "which is right-associative"
+ val msg = s"`${op1}` (${op1Asso}) and `${op2}` ($op2Asso) have same precedence and may not be mixed"
+ val explanation =
+ s"""|The operators ${op1} and ${op2} are used as infix operators in the same expression,
+ |but they bind to different sides:
+ |${op1} is applied to the operand to its ${if (op2LeftAssoc) "right" else "left"}
+ |${op2} is applied to the operand to its ${if (op2LeftAssoc) "left" else "right"}
+ |As both have the same precedence the compiler can't decide which to apply first.
+ |
+ |You may use parenthesis to make the application order explicit,
+ |or use method application syntax `operand1.${op1}(operand2)`.
+ |
+ |Operators ending in a colon `:` are right-associative. All other operators are left-associative.
+ |
+ |Infix operator precedence is determined by the operator's first character. Characters are listed
+ |below in increasing order of precedence, with characters on the same line having the same precedence.
+ | (all letters)
+ | |
+ | ^
+ | &
+ | = !
+ | < >
+ | :
+ | + -
+ | * / %
+ | (all other special characters)
+ |Operators starting with a letter have lowest precedence, followed by operators starting with `|`, etc.
+ |""".stripMargin
+ }
+
}