aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-10-19 22:13:10 +0200
committerGitHub <noreply@github.com>2016-10-19 22:13:10 +0200
commit0d1721c8aebaf6877e9d1ea3d65d40446a869170 (patch)
tree5cfe422a253af0b2f5d79838f90b490fcee29f46 /src
parentb648d1d9d41b33212192fa94ce5ece56af7c47ea (diff)
parent2a310ac672e79c0a561e80c33f4616a43d7bd5d9 (diff)
downloaddotty-0d1721c8aebaf6877e9d1ea3d65d40446a869170.tar.gz
dotty-0d1721c8aebaf6877e9d1ea3d65d40446a869170.tar.bz2
dotty-0d1721c8aebaf6877e9d1ea3d65d40446a869170.zip
Merge pull request #1611 from ShaneDelmore/1589_Missing_error_messages
Improved error messages in Desugar.scala
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala8
-rw-r--r--src/dotty/tools/dotc/reporting/diagnostic/messages.scala84
2 files changed, 87 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index af34164dc..8b8e0b318 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -433,11 +433,11 @@ object desugar {
if (!mods.is(Implicit))
Nil
else if (ctx.owner is Package) {
- ctx.error("implicit classes may not be toplevel", cdef.pos)
+ ctx.error(TopLevelImplicitClass(cdef), cdef.pos)
Nil
}
else if (isCaseClass) {
- ctx.error("implicit classes may not be case classes", cdef.pos)
+ ctx.error(ImplicitCaseClass(cdef), cdef.pos)
Nil
}
else
@@ -497,7 +497,7 @@ object desugar {
.withPos(mdef.pos)
val ValDef(selfName, selfTpt, _) = tmpl.self
val selfMods = tmpl.self.mods
- if (!selfTpt.isEmpty) ctx.error("object definition may not have a self type", tmpl.self.pos)
+ if (!selfTpt.isEmpty) ctx.error(ObjectMayNotHaveSelfType(mdef), tmpl.self.pos)
val clsSelf = ValDef(selfName, SingletonTypeTree(Ident(name)), tmpl.self.rhs)
.withMods(selfMods)
.withPos(tmpl.self.pos orElse tmpl.pos.startPos)
@@ -931,7 +931,7 @@ object desugar {
val arity = ts.length
def tupleTypeRef = defn.TupleType(arity)
if (arity > Definitions.MaxTupleArity) {
- ctx.error(s"tuple too long (max allowed: ${Definitions.MaxTupleArity})", tree.pos)
+ ctx.error(TupleTooLong(ts), tree.pos)
unitLiteral
} else if (arity == 1) ts.head
else if (ctx.mode is Mode.Type) AppliedTypeTree(ref(tupleTypeRef), ts)
diff --git a/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
index 9a02e0b04..633501295 100644
--- a/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
+++ b/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -5,11 +5,12 @@ package diagnostic
import dotc.core._
import Contexts.Context, Decorators._, Symbols._, Names._, Types._
+import ast.untpd.{Modifiers, ModuleDef}
import util.{SourceFile, NoSource}
import util.{SourcePosition, NoSourcePosition}
import config.Settings.Setting
import interfaces.Diagnostic.{ERROR, WARNING, INFO}
-import printing.SyntaxHighlighting._
+import printing.Highlighting._
import printing.Formatting
object messages {
@@ -318,4 +319,85 @@ object messages {
|$code2
|""".stripMargin
}
+
+ def implicitClassRestrictionsText(implicit ctx: Context) =
+ hl"""${NoColor("For a full list of restrictions on implicit classes visit")}
+ | ${Blue("http://docs.scala-lang.org/overviews/core/implicit-classes.html")}""".stripMargin
+
+ case class TopLevelImplicitClass(cdef: untpd.TypeDef)(implicit ctx: Context)
+ extends Message(10) {
+ val kind = "Syntax"
+
+ val msg = hl"""|An ${"implicit class"} may not be top-level"""
+
+ val explanation = {
+ val TypeDef(name, impl @ Template(constr0, parents, self, _)) = cdef
+ val exampleArgs = constr0.vparamss(0).map(_.withMods(Modifiers()).show).mkString(", ")
+ def defHasBody[T] = impl.body.exists(!_.isEmpty)
+ val exampleBody = if (defHasBody) "{\n ...\n }" else ""
+ hl"""|There may not be any method, member or object in scope with the same name as the
+ |implicit class and a case class automatically gets a companion object with the same name
+ |created by the compiler which would cause a naming conflict if it were allowed.
+ |
+ |""".stripMargin + implicitClassRestrictionsText + hl"""|
+ |
+ |To resolve the conflict declare ${cdef.name} inside of an ${"object"} then import the class
+ |from the object at the use site if needed, for example:
+ |
+ |object Implicits {
+ | implicit class ${cdef.name}($exampleArgs)$exampleBody
+ |}
+ |
+ |// At the use site:
+ |import Implicits.${cdef.name}""".stripMargin
+ }
+ }
+
+ case class ImplicitCaseClass(cdef: untpd.TypeDef)(implicit ctx: Context)
+ extends Message(11) {
+ val kind = "Syntax"
+
+ val msg = hl"""|A ${"case class"} may not be defined as ${"implicit"}"""
+
+ val explanation =
+ hl"""|implicit classes may not be case classes. Instead use a plain class:
+ | example: implicit class ${cdef.name}...
+ |
+ |""".stripMargin + implicitClassRestrictionsText
+ }
+
+ case class ObjectMayNotHaveSelfType(mdef: untpd.ModuleDef)(implicit ctx: Context)
+ extends Message(12) {
+ val kind = "Syntax"
+
+ val msg = hl"""|${"objects"} must not have a ${"self type"}"""
+
+ val explanation = {
+ val ModuleDef(name, tmpl) = mdef
+ val ValDef(_, selfTpt, _) = tmpl.self
+ hl"""|objects must not have a ${"self type"}:
+ |
+ |Consider these alternative solutions:
+ | - Create a trait or a class instead of an object
+ | - Let the object extend a trait containing the self type:
+ | example: object $name extends ${selfTpt.show}""".stripMargin
+ }
+ }
+
+ case class TupleTooLong(ts: List[untpd.Tree])(implicit ctx: Context)
+ extends Message(13) {
+ import Definitions.MaxTupleArity
+ val kind = "Syntax"
+
+ val msg = hl"""|A ${"tuple"} cannot have more than ${MaxTupleArity} members"""
+
+ val explanation = {
+ val members = ts.map(_.showSummary).grouped(MaxTupleArity)
+ val nestedRepresentation = members.map(_.mkString(", ")).mkString(")(")
+ hl"""|This restriction will be removed in the future.
+ |Currently it is possible to use nested tuples when more than ${MaxTupleArity} are needed, for example:
+ |
+ | ((${nestedRepresentation}))""".stripMargin
+ }
+ }
}