From e3667c4ab225670876df698367686628061ed11d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 2 Jan 2021 18:13:21 +0100 Subject: [PATCH] Better specification of references in error messages Previously we sometimes printed `` for a reference with a missing symbol. Fixes #9436 --- compiler/src/dotty/tools/dotc/reporting/messages.scala | 2 +- compiler/src/dotty/tools/dotc/typer/Applications.scala | 2 +- .../src/dotty/tools/dotc/typer/ErrorReporting.scala | 8 +++++++- compiler/src/dotty/tools/dotc/typer/Typer.scala | 4 ++-- tests/neg/i2033.check | 2 +- tests/neg/i9436.check | 10 ++++++++++ tests/neg/i9436.scala | 9 +++++++++ 7 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 tests/neg/i9436.check create mode 100644 tests/neg/i9436.scala diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index eca28faaacc8..93a90548a5ef 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -1778,7 +1778,7 @@ import transform.SymUtils._ |To convert to a function value, you need to explicitly write ${hl("() => x")}""" } - class MissingEmptyArgumentList(method: Symbol)(using Context) + class MissingEmptyArgumentList(method: String)(using Context) extends SyntaxMsg(MissingEmptyArgumentListID) { def msg = em"$method must be called with ${hl("()")} argument" def explain = { diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala index 85a3be7b6fdd..58d81b2d4d6b 100644 --- a/compiler/src/dotty/tools/dotc/typer/Applications.scala +++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala @@ -373,7 +373,7 @@ trait Applications extends Compatibility { def success: Boolean = ok protected def methodType: MethodType = methType.asInstanceOf[MethodType] - private def methString: String = i"${methRef.symbol}: ${methType.show}" + private def methString: String = i"${err.refStr(methRef)}: ${methType.show}" /** Re-order arguments to correctly align named arguments */ def reorder[T >: Untyped](args: List[Trees.Tree[T]]): List[Trees.Tree[T]] = { diff --git a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala index 50aa24ff045c..3d50e4b3e519 100644 --- a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala +++ b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala @@ -84,7 +84,13 @@ object ErrorReporting { else anonymousTypeMemberStr(denot.info) def refStr(tp: Type): String = tp match { - case tp: NamedType => denotStr(tp.denot) + case tp: NamedType => + if tp.denot.symbol.exists then tp.denot.symbol.showLocated + else + val kind = tp.info match + case _: MethodOrPoly | _: ExprType => "method" + case _ => if tp.isType then "type" else "value" + s"$kind ${tp.name}" case _ => anonymousTypeMemberStr(tp) } diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala index ad4eb742fd47..31937ca404f1 100644 --- a/compiler/src/dotty/tools/dotc/typer/Typer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala @@ -2951,7 +2951,7 @@ class Typer extends Namer def readaptSimplified(tree: Tree)(using Context) = readapt(simplify(tree, pt, locked)) def missingArgs(mt: MethodType) = { - val meth = methPart(tree).symbol + val meth = err.exprStr(methPart(tree)) if (mt.paramNames.length == 0) report.error(MissingEmptyArgumentList(meth), tree.srcPos) else report.error(em"missing arguments for $meth", tree.srcPos) tree.withType(mt.resultType) @@ -3221,7 +3221,7 @@ class Typer extends Namer def isAutoApplied(sym: Symbol): Boolean = sym.isConstructor || sym.matchNullaryLoosely - || warnOnMigration(MissingEmptyArgumentList(sym), tree.srcPos) + || warnOnMigration(MissingEmptyArgumentList(sym.show), tree.srcPos) && { patch(tree.span.endPos, "()"); true } // Reasons NOT to eta expand: diff --git a/tests/neg/i2033.check b/tests/neg/i2033.check index 91ee4434c937..5727dbd0c49e 100644 --- a/tests/neg/i2033.check +++ b/tests/neg/i2033.check @@ -1,7 +1,7 @@ -- Error: tests/neg/i2033.scala:7:30 ----------------------------------------------------------------------------------- 7 | val arr = bos toByteArray () // error | ^^ - |can't supply unit value with infix notation because nullary method toByteArray: (): Array[Byte] takes no arguments; use dotted invocation instead: (...).toByteArray() + |can't supply unit value with infix notation because nullary method toByteArray in class ByteArrayOutputStream: (): Array[Byte] takes no arguments; use dotted invocation instead: (...).toByteArray() -- [E007] Type Mismatch Error: tests/neg/i2033.scala:20:35 ------------------------------------------------------------- 20 | val out = new ObjectOutputStream(println) // error | ^^^^^^^ diff --git a/tests/neg/i9436.check b/tests/neg/i9436.check new file mode 100644 index 000000000000..8938dbacb6cb --- /dev/null +++ b/tests/neg/i9436.check @@ -0,0 +1,10 @@ +-- [E100] Syntax Error: tests/neg/i9436.scala:8:12 --------------------------------------------------------------------- +8 | println(x.f1) // error + | ^^^^ + | method f1 must be called with () argument + +longer explanation available when compiling with `-explain` +-- Error: tests/neg/i9436.scala:9:14 ----------------------------------------------------------------------------------- +9 | println(x.f2(1)) // error + | ^^^^^^^ + | missing argument for parameter y of method f2: (x: Int, y: Int): Int diff --git a/tests/neg/i9436.scala b/tests/neg/i9436.scala new file mode 100644 index 000000000000..5cae13928a9b --- /dev/null +++ b/tests/neg/i9436.scala @@ -0,0 +1,9 @@ +class Bag extends reflect.Selectable + +@main def Test = + val x = new Bag: + def f1() = 23 + def f2(x: Int, y: Int) = x + y + + println(x.f1) // error + println(x.f2(1)) // error