From 403262c46b8067569228b32108ea68294c5741be Mon Sep 17 00:00:00 2001 From: aherlihy Date: Tue, 6 Feb 2024 18:14:23 +0100 Subject: [PATCH] Add explanation for NotClassType error message Fixes #14175 [Cherry-picked 00b6fb43bcec049f1ad89a3a8c22b9bf88c3858b] --- .../dotty/tools/dotc/reporting/messages.scala | 6 +++++- .../jsconstructorof-error-in-prepjsinterop.check | 16 ++++++++++++++++ ...jsconstructortag-error-in-prepjsinterop.check | 16 ++++++++++++++++ tests/neg/classOf.check | 6 ++++++ tests/neg/i13808.check | 4 ++++ 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index c435ee0d7f5c..bd5efcd8ff1b 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -2749,7 +2749,11 @@ extends SyntaxMsg(TargetNameOnTopLevelClassID): class NotClassType(tp: Type)(using Context) extends TypeMsg(NotClassTypeID), ShowMatchTrace(tp): def msg(using Context) = i"$tp is not a class type" - def explain(using Context) = "" + def explain(using Context) = + i"""A class type includes classes and traits in a specific order. Defining a class, even an anonymous class, + |requires specifying a linearization order for the traits it extends. For example, `A & B` is not a class type + |because it doesn't specify which trait takes precedence, A or B. For more information about class types, please see the Scala Language Specification. + |Class types also can't have refinements.""" class NotConstant(suffix: String, tp: Type)(using Context) extends TypeMsg(NotConstantID), ShowMatchTrace(tp): diff --git a/tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.check b/tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.check index 7687543ea75f..54d3d8f6c556 100644 --- a/tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.check +++ b/tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.check @@ -6,14 +6,20 @@ 14 | val b = js.constructorOf[NativeJSObject.type] // error | ^^^^^^^^^^^^^^^^^^^ | NativeJSObject.type is not a class type + | + | longer explanation available when compiling with `-explain` -- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:16:27 ----------------------------- 16 | val c = js.constructorOf[NativeJSClass with NativeJSTrait] // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | NativeJSClass & NativeJSTrait is not a class type + | + | longer explanation available when compiling with `-explain` -- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:17:27 ----------------------------- 17 | val d = js.constructorOf[NativeJSClass { def bar: Int }] // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | NativeJSClass{def bar: Int} is not a class type + | + | longer explanation available when compiling with `-explain` -- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:19:27 ----------------------------------------- 19 | val e = js.constructorOf[JSTrait] // error | ^^^^^^^ @@ -22,19 +28,29 @@ 20 | val f = js.constructorOf[JSObject.type] // error | ^^^^^^^^^^^^^ | JSObject.type is not a class type + | + | longer explanation available when compiling with `-explain` -- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:22:27 ----------------------------- 22 | val g = js.constructorOf[JSClass with JSTrait] // error | ^^^^^^^^^^^^^^^^^^^^ | JSClass & JSTrait is not a class type + | + | longer explanation available when compiling with `-explain` -- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:23:27 ----------------------------- 23 | val h = js.constructorOf[JSClass { def bar: Int }] // error | ^^^^^^^^^^^^^^^^^^^^^^^^ | JSClass{def bar: Int} is not a class type + | + | longer explanation available when compiling with `-explain` -- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:25:42 ----------------------------- 25 | def foo[A <: js.Any] = js.constructorOf[A] // error | ^ | A is not a class type + | + | longer explanation available when compiling with `-explain` -- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:26:66 ----------------------------- 26 | def bar[A <: js.Any: scala.reflect.ClassTag] = js.constructorOf[A] // error | ^ | A is not a class type + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.check b/tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.check index 142de318efd3..879a566d9fea 100644 --- a/tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.check +++ b/tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.check @@ -6,14 +6,20 @@ 14 | val b = js.constructorTag[NativeJSObject.type] // error | ^ | NativeJSObject.type is not a class type + | + | longer explanation available when compiling with `-explain` -- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:16:61 ---------------------------- 16 | val c = js.constructorTag[NativeJSClass with NativeJSTrait] // error | ^ | NativeJSClass & NativeJSTrait is not a class type + | + | longer explanation available when compiling with `-explain` -- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:17:59 ---------------------------- 17 | val d = js.constructorTag[NativeJSClass { def bar: Int }] // error | ^ | NativeJSClass{def bar: Int} is not a class type + | + | longer explanation available when compiling with `-explain` -- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:19:36 ---------------------------------------- 19 | val e = js.constructorTag[JSTrait] // error | ^ @@ -22,19 +28,29 @@ 20 | val f = js.constructorTag[JSObject.type] // error | ^ | JSObject.type is not a class type + | + | longer explanation available when compiling with `-explain` -- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:22:49 ---------------------------- 22 | val g = js.constructorTag[JSClass with JSTrait] // error | ^ | JSClass & JSTrait is not a class type + | + | longer explanation available when compiling with `-explain` -- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:23:53 ---------------------------- 23 | val h = js.constructorTag[JSClass { def bar: Int }] // error | ^ | JSClass{def bar: Int} is not a class type + | + | longer explanation available when compiling with `-explain` -- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:25:45 ---------------------------- 25 | def foo[A <: js.Any] = js.constructorTag[A] // error | ^ | A is not a class type + | + | longer explanation available when compiling with `-explain` -- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:26:69 ---------------------------- 26 | def bar[A <: js.Any: scala.reflect.ClassTag] = js.constructorTag[A] // error | ^ | A is not a class type + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/classOf.check b/tests/neg/classOf.check index e3be3ca17026..e6576a60bbff 100644 --- a/tests/neg/classOf.check +++ b/tests/neg/classOf.check @@ -2,13 +2,19 @@ 6 | def f1[T] = classOf[T] // error | ^ | T is not a class type + | + | longer explanation available when compiling with `-explain` -- [E170] Type Error: tests/neg/classOf.scala:7:32 --------------------------------------------------------------------- 7 | def f2[T <: String] = classOf[T] // error | ^ | T is not a class type | | where: T is a type in method f2 with bounds <: String + | + | longer explanation available when compiling with `-explain` -- [E170] Type Error: tests/neg/classOf.scala:9:18 --------------------------------------------------------------------- 9 | val y = classOf[C { type I = String }] // error | ^^^^^^^^^^^^^^^^^^^^^ | Test.C{type I = String} is not a class type + | + | longer explanation available when compiling with `-explain` diff --git a/tests/neg/i13808.check b/tests/neg/i13808.check index f3e0ebac7141..e0f6d01c09db 100644 --- a/tests/neg/i13808.check +++ b/tests/neg/i13808.check @@ -2,7 +2,11 @@ 13 |case class Boom[A](value: A) derives OpaqueType, Foo // error // error | ^^^^^^^^^^ | OpaqueTypes.OpaqueType is not a class type + | + | longer explanation available when compiling with `-explain` -- [E170] Type Error: tests/neg/i13808.scala:13:49 --------------------------------------------------------------------- 13 |case class Boom[A](value: A) derives OpaqueType, Foo // error // error | ^^^ | FooModule.Foo is not a class type + | + | longer explanation available when compiling with `-explain`