diff --git a/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala b/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala index 530e5f6d3f2d..7b22eb77e90e 100644 --- a/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala +++ b/compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala @@ -183,7 +183,8 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe case LossyWideningConstantConversionID // errorNumber: 167 case ImplicitSearchTooLargeID // errorNumber: 168 case TargetNameOnTopLevelClassID // errorNumber: 169 - + case NotClassTypeID // errorNumber 170 + def errorNumber = ordinal - 1 object ErrorMessageID: diff --git a/compiler/src/dotty/tools/dotc/reporting/messages.scala b/compiler/src/dotty/tools/dotc/reporting/messages.scala index f2b14ee315df..aa233b62c784 100644 --- a/compiler/src/dotty/tools/dotc/reporting/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/messages.scala @@ -2521,3 +2521,8 @@ import transform.SymUtils._ | $annot $symbol { ... } | |${hl("export")} Wrapper.${symbol.name} ${hl("// optional")}""" + + class NotClassType(tp: Type)(using Context) + extends TypeMsg(NotClassTypeID), ShowMatchTrace(tp): + def msg = ex"$tp is not a class type" + def explain = "" diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala index acbd4f65acc7..313d238181e1 100644 --- a/compiler/src/dotty/tools/dotc/typer/Checking.scala +++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala @@ -937,7 +937,7 @@ trait Checking { if (stablePrefixReq && ctx.phase <= refchecksPhase) checkStable(tref.prefix, pos, "class prefix") tp case _ => - report.error(ex"$tp is not a class type", pos) + report.error(NotClassType(tp), pos) defn.ObjectType } diff --git a/tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.check b/tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.check index 57be080100e9..301111860aa7 100644 --- a/tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.check +++ b/tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.check @@ -2,15 +2,15 @@ 13 | val a = js.constructorOf[NativeJSTrait] // error | ^^^^^^^^^^^^^ | non-trait class type required but NativeJSTrait found --- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:14:27 ----------------------------------------- +-- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:14:27 ----------------------------- 14 | val b = js.constructorOf[NativeJSObject.type] // error | ^^^^^^^^^^^^^^^^^^^ | NativeJSObject.type is not a class type --- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:16:27 ----------------------------------------- +-- [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 --- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:17:27 ----------------------------------------- +-- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:17:27 ----------------------------- 17 | val d = js.constructorOf[NativeJSClass { def bar: Int }] // error | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | NativeJSClass{bar: Int} is not a class type @@ -18,23 +18,23 @@ 19 | val e = js.constructorOf[JSTrait] // error | ^^^^^^^ | non-trait class type required but JSTrait found --- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:20:27 ----------------------------------------- +-- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:20:27 ----------------------------- 20 | val f = js.constructorOf[JSObject.type] // error | ^^^^^^^^^^^^^ | JSObject.type is not a class type --- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:22:27 ----------------------------------------- +-- [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 --- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:23:27 ----------------------------------------- +-- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:23:27 ----------------------------- 23 | val h = js.constructorOf[JSClass { def bar: Int }] // error | ^^^^^^^^^^^^^^^^^^^^^^^^ | JSClass{bar: Int} is not a class type --- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:25:42 ----------------------------------------- +-- [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 --- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:26:66 ----------------------------------------- +-- [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 diff --git a/tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.check b/tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.check index 7b4c98a95008..c4ce18b2e57c 100644 --- a/tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.check +++ b/tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.check @@ -2,15 +2,15 @@ 13 | val a = js.constructorTag[NativeJSTrait] // error | ^ | non-trait class type required but NativeJSTrait found --- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:14:48 ---------------------------------------- +-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:14:48 ---------------------------- 14 | val b = js.constructorTag[NativeJSObject.type] // error | ^ | NativeJSObject.type is not a class type --- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:16:61 ---------------------------------------- +-- [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 --- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:17:59 ---------------------------------------- +-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:17:59 ---------------------------- 17 | val d = js.constructorTag[NativeJSClass { def bar: Int }] // error | ^ | NativeJSClass{bar: Int} is not a class type @@ -18,23 +18,23 @@ 19 | val e = js.constructorTag[JSTrait] // error | ^ | non-trait class type required but JSTrait found --- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:20:42 ---------------------------------------- +-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:20:42 ---------------------------- 20 | val f = js.constructorTag[JSObject.type] // error | ^ | JSObject.type is not a class type --- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:22:49 ---------------------------------------- +-- [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 --- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:23:53 ---------------------------------------- +-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:23:53 ---------------------------- 23 | val h = js.constructorTag[JSClass { def bar: Int }] // error | ^ | JSClass{bar: Int} is not a class type --- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:25:45 ---------------------------------------- +-- [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 --- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:26:69 ---------------------------------------- +-- [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 diff --git a/tests/neg/classOf.check b/tests/neg/classOf.check index 45ae749a0940..c3873aff7391 100644 --- a/tests/neg/classOf.check +++ b/tests/neg/classOf.check @@ -1,14 +1,14 @@ --- Error: tests/neg/classOf.scala:6:22 --------------------------------------------------------------------------------- +-- [E170] Type Error: tests/neg/classOf.scala:6:22 --------------------------------------------------------------------- 6 | def f1[T] = classOf[T] // error | ^ | T is not a class type --- Error: tests/neg/classOf.scala:7:32 --------------------------------------------------------------------------------- +-- [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 --- Error: tests/neg/classOf.scala:9:18 --------------------------------------------------------------------------------- +-- [E170] Type Error: tests/neg/classOf.scala:9:18 --------------------------------------------------------------------- 9 | val y = classOf[C { type I = String }] // error | ^^^^^^^^^^^^^^^^^^^^^ | Test.C{I = String} is not a class type diff --git a/tests/neg/i13808.check b/tests/neg/i13808.check index e9b55a5ddec2..f3e0ebac7141 100644 --- a/tests/neg/i13808.check +++ b/tests/neg/i13808.check @@ -1,8 +1,8 @@ --- Error: tests/neg/i13808.scala:13:37 --------------------------------------------------------------------------------- +-- [E170] Type Error: tests/neg/i13808.scala:13:37 --------------------------------------------------------------------- 13 |case class Boom[A](value: A) derives OpaqueType, Foo // error // error | ^^^^^^^^^^ | OpaqueTypes.OpaqueType is not a class type --- Error: tests/neg/i13808.scala:13:49 --------------------------------------------------------------------------------- +-- [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 diff --git a/tests/neg/i15155.check b/tests/neg/i15155.check new file mode 100644 index 000000000000..5f24a6dc48a1 --- /dev/null +++ b/tests/neg/i15155.check @@ -0,0 +1,11 @@ +-- [E170] Type Error: tests/neg/i15155.scala:10:33 --------------------------------------------------------------------- +10 | val EnumerationClass = classOf[EnumValue[E]] // error + | ^^^^^^^^^^^^ + | EnumValue[E] is not a class type + | + | Note: a match type could not be fully reduced: + | + | trying to reduce EnumValue[E] + | failed since selector E + | does not match case Aux[a] => a + | and cannot be shown to be disjoint from it either. diff --git a/tests/neg/i15155.scala b/tests/neg/i15155.scala new file mode 100644 index 000000000000..083f199823fb --- /dev/null +++ b/tests/neg/i15155.scala @@ -0,0 +1,11 @@ +import scala.reflect.ClassTag +// https://github.com/json4s/json4s/blob/355d8751391773e0d79d04402a4f9fb7bfc684ec/ext/src/main/scala-3/org/json4s/ext/package.scala#L4-L8 +type Aux[A] = { type Value = A } +type EnumValue[A <: Enumeration] = A match { + case Aux[a] => a +} + +// https://github.com/json4s/json4s/blob/355d8751391773e0d79d04402a4f9fb7bfc684ec/ext/src/main/scala/org/json4s/ext/EnumSerializer.scala#L25-L26 +class EnumSerializer[E <: Enumeration: ClassTag](enumeration: E) { + val EnumerationClass = classOf[EnumValue[E]] // error +} \ No newline at end of file