Skip to content

Commit 3c1328d

Browse files
committed
Show a match type trace for "not a class type" errors
Closes #15155
1 parent b61036b commit 3c1328d

File tree

7 files changed

+35
-7
lines changed

7 files changed

+35
-7
lines changed

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

+2-1
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

+5
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

+1-1
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/classOf.check

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
-- Error: tests/neg/classOf.scala:6:22 ---------------------------------------------------------------------------------
1+
-- [E079] 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+
-- [E079] 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+
-- [E079] 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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
-- Error: tests/neg/i13808.scala:13:37 ---------------------------------------------------------------------------------
1+
-- [E079] 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+
-- [E079] 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

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
-- [E079] 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

+11
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)