aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala7
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala20
-rw-r--r--src/dotty/tools/dotc/printing/Formatting.scala10
-rw-r--r--src/dotty/tools/dotc/reporting/ConsoleReporter.scala1
-rw-r--r--src/dotty/tools/dotc/reporting/UniqueMessagePositions.scala16
-rw-r--r--src/dotty/tools/dotc/reporting/diagnostic/messages.scala19
-rw-r--r--src/dotty/tools/dotc/transform/TailRec.scala13
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala8
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala2
9 files changed, 66 insertions, 30 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index ecb6a3212..af34164dc 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -9,6 +9,7 @@ import Decorators._
import language.higherKinds
import collection.mutable.ListBuffer
import util.Property
+import reporting.diagnostic.messages._
object desugar {
import untpd._
@@ -71,7 +72,9 @@ object desugar {
val defctx = ctx.outersIterator.dropWhile(_.scope eq ctx.scope).next
var local = defctx.denotNamed(tp.name).suchThat(_ is ParamOrAccessor).symbol
if (local.exists) (defctx.owner.thisType select local).dealias
- else throw new Error(s"no matching symbol for ${tp.symbol.showLocated} in ${defctx.owner} / ${defctx.effectiveScope}")
+ else throw new java.lang.Error(
+ s"no matching symbol for ${tp.symbol.showLocated} in ${defctx.owner} / ${defctx.effectiveScope}"
+ )
case _ =>
mapOver(tp)
}
@@ -281,7 +284,7 @@ object desugar {
val constrVparamss =
if (constr1.vparamss.isEmpty) { // ensure parameter list is non-empty
if (isCaseClass)
- ctx.error("case class needs to have at least one parameter list", cdef.pos)
+ ctx.error(CaseClassMissingParamList(cdef), cdef.namePos)
ListOfNil
}
else constr1.vparamss.nestedMap(toDefParam)
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala
index 620cc1273..6d40107a8 100644
--- a/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -215,6 +215,9 @@ object Parsers {
}
}
+ def warning(msg: Message, sourcePos: SourcePosition) =
+ ctx.warning(msg, sourcePos)
+
def warning(msg: Message, offset: Int = in.offset) =
ctx.warning(msg, source atPos Position(offset))
@@ -1006,6 +1009,7 @@ object Parsers {
DoWhile(body, cond)
}
case TRY =>
+ val tryOffset = in.offset
atPos(in.skipToken()) {
val body = expr()
val handler =
@@ -1014,16 +1018,26 @@ object Parsers {
expr()
} else EmptyTree
+ // A block ends before RBRACE, if next token is RBRACE, simply add 1
+ def realEnd(pos: Position) =
+ if (in.token == RBRACE) pos.end + 1
+ else pos.end
+
handler match {
- case Block(Nil, EmptyTree) =>
- syntaxError(new EmptyCatchBlock(body), handler.pos)
+ case Block(Nil, EmptyTree) => syntaxError(
+ new EmptyCatchBlock(body),
+ Position(tryOffset, realEnd(handler.pos))
+ )
case _ =>
}
val finalizer =
if (in.token == FINALLY) { accept(FINALLY); expr() }
else {
- if (handler.isEmpty) warning(EmptyCatchAndFinallyBlock(body))
+ if (handler.isEmpty) warning(
+ EmptyCatchAndFinallyBlock(body),
+ source atPos Position(tryOffset, realEnd(body.pos))
+ )
EmptyTree
}
ParsedTry(body, handler, finalizer)
diff --git a/src/dotty/tools/dotc/printing/Formatting.scala b/src/dotty/tools/dotc/printing/Formatting.scala
index 95ac03647..9cbf07914 100644
--- a/src/dotty/tools/dotc/printing/Formatting.scala
+++ b/src/dotty/tools/dotc/printing/Formatting.scala
@@ -74,9 +74,9 @@ object Formatting {
}
class SyntaxFormatter(sc: StringContext) extends StringFormatter(sc) {
- override protected def showArg(arg: Any)(implicit ctx: Context): String = {
- if (ctx.settings.color.value != "never") arg match {
- case arg: Showable =>
+ override protected def showArg(arg: Any)(implicit ctx: Context): String =
+ arg match {
+ case arg: Showable if ctx.settings.color.value != "never" =>
val highlighted =
SyntaxHighlighting(wrapNonSensical(arg, super.showArg(arg)))
new String(highlighted.toArray)
@@ -84,12 +84,10 @@ object Formatting {
hl.show
case hb: HighlightBuffer =>
hb.toString
- case str: String =>
+ case str: String if ctx.settings.color.value != "never" =>
new String(SyntaxHighlighting(str).toArray)
case _ => super.showArg(arg)
}
- else super.showArg(arg)
- }
}
private def wrapNonSensical(arg: Any, str: String)(implicit ctx: Context): String = {
diff --git a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
index d96ff48a4..6ebd53bea 100644
--- a/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
+++ b/src/dotty/tools/dotc/reporting/ConsoleReporter.scala
@@ -108,6 +108,7 @@ class ConsoleReporter(
|${Blue("Explanation")}
|${Blue("===========")}""".stripMargin)
printMessage(m.explanation)
+ if (m.explanation.lastOption != Some('\n')) printMessage("")
}
override def doReport(m: MessageContainer)(implicit ctx: Context): Unit = {
diff --git a/src/dotty/tools/dotc/reporting/UniqueMessagePositions.scala b/src/dotty/tools/dotc/reporting/UniqueMessagePositions.scala
index c5ff8cb6b..6fd971c2a 100644
--- a/src/dotty/tools/dotc/reporting/UniqueMessagePositions.scala
+++ b/src/dotty/tools/dotc/reporting/UniqueMessagePositions.scala
@@ -7,10 +7,8 @@ import util.{SourcePosition, SourceFile}
import core.Contexts.Context
import diagnostic.MessageContainer
-/**
- * This trait implements `isHidden` so that multiple messages per position
- * are suppressed, unless they are of increasing severity.
- */
+/** This trait implements `isHidden` so that multiple messages per position
+ * are suppressed, unless they are of increasing severity. */
trait UniqueMessagePositions extends Reporter {
private val positions = new mutable.HashMap[(SourceFile, Int), Int]
@@ -21,10 +19,14 @@ trait UniqueMessagePositions extends Reporter {
override def isHidden(m: MessageContainer)(implicit ctx: Context): Boolean =
super.isHidden(m) || {
m.pos.exists && {
- positions get (ctx.source, m.pos.point) match {
- case Some(level) if level >= m.level => true
- case _ => positions((ctx.source, m.pos.point)) = m.level; false
+ var shouldHide = false
+ for (pos <- m.pos.start to m.pos.end) {
+ positions get (ctx.source, pos) match {
+ case Some(level) if level >= m.level => shouldHide = true
+ case _ => positions((ctx.source, pos)) = m.level
+ }
}
+ shouldHide
}
}
}
diff --git a/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
index 4553a2d22..14978449a 100644
--- a/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
+++ b/src/dotty/tools/dotc/reporting/diagnostic/messages.scala
@@ -166,9 +166,22 @@ object messages {
}
}
+ case class CaseClassMissingParamList(cdef: untpd.TypeDef)(implicit ctx: Context)
+ extends Message(4) {
+ val kind = "Syntax"
+ val msg =
+ hl"""|A ${"case class"} must have at least one parameter list"""
+
+ val explanation =
+ hl"""|${cdef.name} must have at least one parameter list, if you would rather
+ |have a singleton representation of ${cdef.name}, use a "${"case object"}".
+ |Or, add an explicit `()' as a parameter list to ${cdef.name}.""".stripMargin
+ }
+
+
// Type Errors ------------------------------------------------------------ //
case class DuplicateBind(bind: untpd.Bind, tree: untpd.CaseDef)(implicit ctx: Context)
- extends Message(4) {
+ extends Message(5) {
val kind = "Naming"
val msg = em"duplicate pattern variable: `${bind.name}`"
@@ -195,7 +208,7 @@ object messages {
}
case class MissingIdent(tree: untpd.Ident, treeKind: String, name: String)(implicit ctx: Context)
- extends Message(5) {
+ extends Message(6) {
val kind = "Missing Identifier"
val msg = em"not found: $treeKind$name"
@@ -206,7 +219,7 @@ object messages {
}
case class TypeMismatch(found: Type, expected: Type, whyNoMatch: String = "", implicitFailure: String = "")(implicit ctx: Context)
- extends Message(6) {
+ extends Message(7) {
val kind = "Type Mismatch"
private val (where, printCtx) = Formatting.disambiguateTypes(found, expected)
private val (fnd, exp) = Formatting.typeDiff(found, expected)(printCtx)
diff --git a/src/dotty/tools/dotc/transform/TailRec.scala b/src/dotty/tools/dotc/transform/TailRec.scala
index b345dda61..065bcb397 100644
--- a/src/dotty/tools/dotc/transform/TailRec.scala
+++ b/src/dotty/tools/dotc/transform/TailRec.scala
@@ -145,17 +145,22 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
})
Block(List(labelDef), ref(label).appliedToArgss(vparamss0.map(_.map(x=> ref(x.symbol)))))
}} else {
- if (mandatory)
- ctx.error("TailRec optimisation not applicable, method not tail recursive", dd.pos)
+ if (mandatory) ctx.error(
+ "TailRec optimisation not applicable, method not tail recursive",
+ // FIXME: want to report this error on `dd.namePos`, but
+ // because of extension method getting a weird pos, it is
+ // better to report on symbol so there's no overlap
+ sym.pos
+ )
dd.rhs
}
})
}
case d: DefDef if d.symbol.hasAnnotation(defn.TailrecAnnot) || methodsWithInnerAnnots.contains(d.symbol) =>
- ctx.error("TailRec optimisation not applicable, method is neither private nor final so can be overridden", d.pos)
+ ctx.error("TailRec optimisation not applicable, method is neither private nor final so can be overridden", sym.pos)
d
case d if d.symbol.hasAnnotation(defn.TailrecAnnot) || methodsWithInnerAnnots.contains(d.symbol) =>
- ctx.error("TailRec optimisation not applicable, not a method", d.pos)
+ ctx.error("TailRec optimisation not applicable, not a method", sym.pos)
d
case _ => tree
}
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index b02b0ad21..7ba66e3d8 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -45,7 +45,7 @@ object Checking {
for ((arg, which, bound) <- ctx.boundsViolations(args, boundss, instantiate))
ctx.error(
ex"Type argument ${arg.tpe} does not conform to $which bound $bound ${err.whyNoMatchStr(arg.tpe, bound)}",
- arg.pos)
+ arg.pos.focus)
}
/** Check that type arguments `args` conform to corresponding bounds in `poly`
@@ -98,9 +98,9 @@ object Checking {
checkWildcardHKApply(tycon.tpe.appliedTo(args.map(_.tpe)), tree.pos)
checkValidIfHKApply(ctx.addMode(Mode.AllowLambdaWildcardApply))
case Select(qual, name) if name.isTypeName =>
- checkRealizable(qual.tpe, qual.pos)
+ checkRealizable(qual.tpe, qual.pos.focus)
case SingletonTypeTree(ref) =>
- checkRealizable(ref.tpe, ref.pos)
+ checkRealizable(ref.tpe, ref.pos.focus)
case _ =>
}
traverseChildren(tree)
@@ -378,7 +378,7 @@ object Checking {
if (tp.symbol.is(Private) &&
!accessBoundary(sym).isContainedIn(tp.symbol.owner)) {
errors = (em"non-private $sym refers to private ${tp.symbol}\n in its type signature ${sym.info}",
- pos) :: errors
+ sym.pos) :: errors
tp
}
else mapOver(tp)
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index a4dc2f871..bbb20bcf5 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -1259,7 +1259,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val impl1 = cpy.Template(impl)(constr1, parents1, self1, body1)
.withType(dummy.nonMemberTermRef)
checkVariance(impl1)
- if (!cls.is(AbstractOrTrait) && !ctx.isAfterTyper) checkRealizableBounds(cls.typeRef, cdef.pos)
+ if (!cls.is(AbstractOrTrait) && !ctx.isAfterTyper) checkRealizableBounds(cls.typeRef, cdef.namePos)
val cdef1 = assignType(cpy.TypeDef(cdef)(name, impl1, Nil), cls)
if (ctx.phase.isTyper && cdef1.tpe.derivesFrom(defn.DynamicClass) && !ctx.dynamicsEnabled) {
val isRequired = parents1.exists(_.tpe.isRef(defn.DynamicClass))