Skip to content

Commit 56ca1ba

Browse files
authored
Merge pull request #15218 from dotty-staging/fix-15155
Show a match type trace for "not a class type" errors
2 parents 7e9b07b + bdcbff9 commit 56ca1ba

9 files changed

+51
-23
lines changed

compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,8 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe
183183
case LossyWideningConstantConversionID // errorNumber: 167
184184
case ImplicitSearchTooLargeID // errorNumber: 168
185185
case TargetNameOnTopLevelClassID // errorNumber: 169
186-
186+
case NotClassTypeID // errorNumber 170
187+
187188
def errorNumber = ordinal - 1
188189

189190
object ErrorMessageID:

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2521,3 +2521,8 @@ import transform.SymUtils._
25212521
| $annot $symbol { ... }
25222522
|
25232523
|${hl("export")} Wrapper.${symbol.name} ${hl("// optional")}"""
2524+
2525+
class NotClassType(tp: Type)(using Context)
2526+
extends TypeMsg(NotClassTypeID), ShowMatchTrace(tp):
2527+
def msg = ex"$tp is not a class type"
2528+
def explain = ""

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@ trait Checking {
937937
if (stablePrefixReq && ctx.phase <= refchecksPhase) checkStable(tref.prefix, pos, "class prefix")
938938
tp
939939
case _ =>
940-
report.error(ex"$tp is not a class type", pos)
940+
report.error(NotClassType(tp), pos)
941941
defn.ObjectType
942942
}
943943

tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.check

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,39 @@
22
13 | val a = js.constructorOf[NativeJSTrait] // error
33
| ^^^^^^^^^^^^^
44
| non-trait class type required but NativeJSTrait found
5-
-- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:14:27 -----------------------------------------
5+
-- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:14:27 -----------------------------
66
14 | val b = js.constructorOf[NativeJSObject.type] // error
77
| ^^^^^^^^^^^^^^^^^^^
88
| NativeJSObject.type is not a class type
9-
-- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:16:27 -----------------------------------------
9+
-- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:16:27 -----------------------------
1010
16 | val c = js.constructorOf[NativeJSClass with NativeJSTrait] // error
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212
| NativeJSClass & NativeJSTrait is not a class type
13-
-- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:17:27 -----------------------------------------
13+
-- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:17:27 -----------------------------
1414
17 | val d = js.constructorOf[NativeJSClass { def bar: Int }] // error
1515
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1616
| NativeJSClass{bar: Int} is not a class type
1717
-- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:19:27 -----------------------------------------
1818
19 | val e = js.constructorOf[JSTrait] // error
1919
| ^^^^^^^
2020
| non-trait class type required but JSTrait found
21-
-- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:20:27 -----------------------------------------
21+
-- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:20:27 -----------------------------
2222
20 | val f = js.constructorOf[JSObject.type] // error
2323
| ^^^^^^^^^^^^^
2424
| JSObject.type is not a class type
25-
-- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:22:27 -----------------------------------------
25+
-- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:22:27 -----------------------------
2626
22 | val g = js.constructorOf[JSClass with JSTrait] // error
2727
| ^^^^^^^^^^^^^^^^^^^^
2828
| JSClass & JSTrait is not a class type
29-
-- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:23:27 -----------------------------------------
29+
-- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:23:27 -----------------------------
3030
23 | val h = js.constructorOf[JSClass { def bar: Int }] // error
3131
| ^^^^^^^^^^^^^^^^^^^^^^^^
3232
| JSClass{bar: Int} is not a class type
33-
-- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:25:42 -----------------------------------------
33+
-- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:25:42 -----------------------------
3434
25 | def foo[A <: js.Any] = js.constructorOf[A] // error
3535
| ^
3636
| A is not a class type
37-
-- Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:26:66 -----------------------------------------
37+
-- [E170] Type Error: tests/neg-scalajs/jsconstructorof-error-in-prepjsinterop.scala:26:66 -----------------------------
3838
26 | def bar[A <: js.Any: scala.reflect.ClassTag] = js.constructorOf[A] // error
3939
| ^
4040
| A is not a class type

tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.check

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,39 @@
22
13 | val a = js.constructorTag[NativeJSTrait] // error
33
| ^
44
| non-trait class type required but NativeJSTrait found
5-
-- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:14:48 ----------------------------------------
5+
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:14:48 ----------------------------
66
14 | val b = js.constructorTag[NativeJSObject.type] // error
77
| ^
88
| NativeJSObject.type is not a class type
9-
-- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:16:61 ----------------------------------------
9+
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:16:61 ----------------------------
1010
16 | val c = js.constructorTag[NativeJSClass with NativeJSTrait] // error
1111
| ^
1212
| (NativeJSClass & NativeJSTrait) is not a class type
13-
-- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:17:59 ----------------------------------------
13+
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:17:59 ----------------------------
1414
17 | val d = js.constructorTag[NativeJSClass { def bar: Int }] // error
1515
| ^
1616
| NativeJSClass{bar: Int} is not a class type
1717
-- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:19:36 ----------------------------------------
1818
19 | val e = js.constructorTag[JSTrait] // error
1919
| ^
2020
| non-trait class type required but JSTrait found
21-
-- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:20:42 ----------------------------------------
21+
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:20:42 ----------------------------
2222
20 | val f = js.constructorTag[JSObject.type] // error
2323
| ^
2424
| JSObject.type is not a class type
25-
-- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:22:49 ----------------------------------------
25+
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:22:49 ----------------------------
2626
22 | val g = js.constructorTag[JSClass with JSTrait] // error
2727
| ^
2828
| (JSClass & JSTrait) is not a class type
29-
-- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:23:53 ----------------------------------------
29+
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:23:53 ----------------------------
3030
23 | val h = js.constructorTag[JSClass { def bar: Int }] // error
3131
| ^
3232
| JSClass{bar: Int} is not a class type
33-
-- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:25:45 ----------------------------------------
33+
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:25:45 ----------------------------
3434
25 | def foo[A <: js.Any] = js.constructorTag[A] // error
3535
| ^
3636
| A is not a class type
37-
-- Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:26:69 ----------------------------------------
37+
-- [E170] Type Error: tests/neg-scalajs/jsconstructortag-error-in-prepjsinterop.scala:26:69 ----------------------------
3838
26 | def bar[A <: js.Any: scala.reflect.ClassTag] = js.constructorTag[A] // error
3939
| ^
4040
| A is not a class type

tests/neg/classOf.check

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
-- Error: tests/neg/classOf.scala:6:22 ---------------------------------------------------------------------------------
1+
-- [E170] Type Error: tests/neg/classOf.scala:6:22 ---------------------------------------------------------------------
22
6 | def f1[T] = classOf[T] // error
33
| ^
44
| T is not a class type
5-
-- Error: tests/neg/classOf.scala:7:32 ---------------------------------------------------------------------------------
5+
-- [E170] Type Error: tests/neg/classOf.scala:7:32 ---------------------------------------------------------------------
66
7 | def f2[T <: String] = classOf[T] // error
77
| ^
88
| T is not a class type
99
|
1010
| where: T is a type in method f2 with bounds <: String
11-
-- Error: tests/neg/classOf.scala:9:18 ---------------------------------------------------------------------------------
11+
-- [E170] Type Error: tests/neg/classOf.scala:9:18 ---------------------------------------------------------------------
1212
9 | val y = classOf[C { type I = String }] // error
1313
| ^^^^^^^^^^^^^^^^^^^^^
1414
| Test.C{I = String} is not a class type

tests/neg/i13808.check

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
-- Error: tests/neg/i13808.scala:13:37 ---------------------------------------------------------------------------------
1+
-- [E170] Type Error: tests/neg/i13808.scala:13:37 ---------------------------------------------------------------------
22
13 |case class Boom[A](value: A) derives OpaqueType, Foo // error // error
33
| ^^^^^^^^^^
44
| OpaqueTypes.OpaqueType is not a class type
5-
-- Error: tests/neg/i13808.scala:13:49 ---------------------------------------------------------------------------------
5+
-- [E170] Type Error: tests/neg/i13808.scala:13:49 ---------------------------------------------------------------------
66
13 |case class Boom[A](value: A) derives OpaqueType, Foo // error // error
77
| ^^^
88
| FooModule.Foo is not a class type

tests/neg/i15155.check

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
-- [E170] Type Error: tests/neg/i15155.scala:10:33 ---------------------------------------------------------------------
2+
10 | val EnumerationClass = classOf[EnumValue[E]] // error
3+
| ^^^^^^^^^^^^
4+
| EnumValue[E] is not a class type
5+
|
6+
| Note: a match type could not be fully reduced:
7+
|
8+
| trying to reduce EnumValue[E]
9+
| failed since selector E
10+
| does not match case Aux[a] => a
11+
| and cannot be shown to be disjoint from it either.

tests/neg/i15155.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import scala.reflect.ClassTag
2+
// https://github.com/json4s/json4s/blob/355d8751391773e0d79d04402a4f9fb7bfc684ec/ext/src/main/scala-3/org/json4s/ext/package.scala#L4-L8
3+
type Aux[A] = { type Value = A }
4+
type EnumValue[A <: Enumeration] = A match {
5+
case Aux[a] => a
6+
}
7+
8+
// https://github.com/json4s/json4s/blob/355d8751391773e0d79d04402a4f9fb7bfc684ec/ext/src/main/scala/org/json4s/ext/EnumSerializer.scala#L25-L26
9+
class EnumSerializer[E <: Enumeration: ClassTag](enumeration: E) {
10+
val EnumerationClass = classOf[EnumValue[E]] // error
11+
}

0 commit comments

Comments
 (0)