aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--tests/neg/applydynamic_sip.scala6
-rw-r--r--tests/neg/assignments.scala2
-rw-r--r--tests/neg/dynamicApplyDynamicTest3.scala2
-rw-r--r--tests/neg/i1424.scala2
-rw-r--r--tests/neg/tailcall/t6574.scala2
-rw-r--r--tests/repl/errmsgs.check16
-rw-r--r--tests/repl/imports.check2
16 files changed, 82 insertions, 46 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))
diff --git a/tests/neg/applydynamic_sip.scala b/tests/neg/applydynamic_sip.scala
index 7b131e7ff..86cff5fc4 100644
--- a/tests/neg/applydynamic_sip.scala
+++ b/tests/neg/applydynamic_sip.scala
@@ -18,9 +18,9 @@ object Test extends App {
}
val bad1 = new Bad1
bad1.sel // error
- bad1.sel(1) // error // error
- bad1.sel(a = 1) // error // error
- bad1.sel = 1 // error // error
+ bad1.sel(1) // error
+ bad1.sel(a = 1) // error
+ bad1.sel = 1 // error
class Bad2 extends Dynamic {
def selectDynamic = 1
diff --git a/tests/neg/assignments.scala b/tests/neg/assignments.scala
index 5be107717..273419cb5 100644
--- a/tests/neg/assignments.scala
+++ b/tests/neg/assignments.scala
@@ -13,7 +13,7 @@ object assignments {
x = x + 1
x *= 2
- x_= = 2 // error should give missing arguments + // error reassignment to val
+ x_= = 2 // error should give missing arguments
}
var c = new C
diff --git a/tests/neg/dynamicApplyDynamicTest3.scala b/tests/neg/dynamicApplyDynamicTest3.scala
index 61d3c9677..d68132b02 100644
--- a/tests/neg/dynamicApplyDynamicTest3.scala
+++ b/tests/neg/dynamicApplyDynamicTest3.scala
@@ -3,5 +3,5 @@ import scala.language.dynamics
class Foo extends scala.Dynamic
object DynamicTest {
- new Foo().bazApply _ // error // error
+ new Foo().bazApply _ // error
}
diff --git a/tests/neg/i1424.scala b/tests/neg/i1424.scala
index 3586260c1..8eba32842 100644
--- a/tests/neg/i1424.scala
+++ b/tests/neg/i1424.scala
@@ -1,3 +1,3 @@
class Test {
- (x: Int) => x // error: not a legal self type clause // error: package x is not a value // error: package x is not a value
+ (x: Int) => x // error: not a legal self type clause // error: not found x
}
diff --git a/tests/neg/tailcall/t6574.scala b/tests/neg/tailcall/t6574.scala
index d9ba2882d..462ef800f 100644
--- a/tests/neg/tailcall/t6574.scala
+++ b/tests/neg/tailcall/t6574.scala
@@ -4,7 +4,7 @@ class Bad[X, Y](val v: Int) extends AnyVal {
println("tail")
}
- @annotation.tailrec final def differentTypeArgs : Unit = { // error
+ @annotation.tailrec final def differentTypeArgs: Unit = { // error
{(); new Bad[String, Unit](0)}.differentTypeArgs // error
}
}
diff --git a/tests/repl/errmsgs.check b/tests/repl/errmsgs.check
index 2a65fd949..066d98d0f 100644
--- a/tests/repl/errmsgs.check
+++ b/tests/repl/errmsgs.check
@@ -1,34 +1,34 @@
scala> class Inv[T](x: T)
defined class Inv
scala> val x: List[String] = List(1)
--- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
+-- [E007] Type Mismatch Error: <console> -------------------------------------------------------------------------------
4 |val x: List[String] = List(1)
| ^
| found: Int(1)
| required: String
|
scala> val y: List[List[String]] = List(List(1))
--- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
+-- [E007] Type Mismatch Error: <console> -------------------------------------------------------------------------------
4 |val y: List[List[String]] = List(List(1))
| ^
| found: Int(1)
| required: String
|
scala> val z: (List[String], List[Int]) = (List(1), List("a"))
--- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
+-- [E007] Type Mismatch Error: <console> -------------------------------------------------------------------------------
4 |val z: (List[String], List[Int]) = (List(1), List("a"))
| ^
| found: Int(1)
| required: String
|
--- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
+-- [E007] Type Mismatch Error: <console> -------------------------------------------------------------------------------
4 |val z: (List[String], List[Int]) = (List(1), List("a"))
| ^^^
| found: String("a")
| required: Int
|
scala> val a: Inv[String] = new Inv(new Inv(1))
--- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
+-- [E007] Type Mismatch Error: <console> -------------------------------------------------------------------------------
5 |val a: Inv[String] = new Inv(new Inv(1))
| ^^^^^
| found: Inv[T]
@@ -36,7 +36,7 @@ scala> val a: Inv[String] = new Inv(new Inv(1))
|
| where: T is a type variable with constraint >: Int(1)
scala> val b: Inv[String] = new Inv(1)
--- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
+-- [E007] Type Mismatch Error: <console> -------------------------------------------------------------------------------
5 |val b: Inv[String] = new Inv(1)
| ^
| found: Int(1)
@@ -57,7 +57,7 @@ scala> abstract class C {
}
}
}
--- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
+-- [E007] Type Mismatch Error: <console> -------------------------------------------------------------------------------
9 | var y: T = x
| ^
| found: C.this.T(C.this.x)
@@ -65,7 +65,7 @@ scala> abstract class C {
|
| where: T is a type in class C
| T' is a type in the initalizer of value s which is an alias of String
--- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
+-- [E007] Type Mismatch Error: <console> -------------------------------------------------------------------------------
13 | val z: T = y
| ^
| found: T(y)
diff --git a/tests/repl/imports.check b/tests/repl/imports.check
index 9743d2b94..26b725637 100644
--- a/tests/repl/imports.check
+++ b/tests/repl/imports.check
@@ -7,7 +7,7 @@ defined module o
scala> import o._
import o._
scala> buf += xs
--- [E006] Type Mismatch Error: <console> -------------------------------------------------------------------------------
+-- [E007] Type Mismatch Error: <console> -------------------------------------------------------------------------------
11 |buf += xs
| ^^
| found: scala.collection.immutable.List[Int](o.xs)