@@ -34,14 +34,23 @@ trait Deriving { this: Typer =>
34
34
/** the children of `cls` ordered by textual occurrence */
35
35
lazy val children = cls.children
36
36
37
+ private def shapeError (explanation : => String ): Unit =
38
+ ctx.error(i " cannot take shape of $cls\n $explanation" , codePos)
39
+
37
40
/** The shape (of type Shape.Case) of a case given by `sym`. `sym` is either `cls`
38
41
* itself, or a subclass of `cls`, or an instance of `cls`.
39
42
*/
40
43
private def caseShape (sym : Symbol ): Type = {
41
44
val (constr, elems) =
42
45
sym match {
43
46
case caseClass : ClassSymbol =>
44
- if (caseClass.is(Module ))
47
+ if (! caseClass.is(Case )) {
48
+ shapeError(
49
+ if (caseClass == cls) " it has anonymous or inaccessible subclasses"
50
+ else i " its subclass $caseClass is not a case class " )
51
+ return NoType
52
+ }
53
+ else if (caseClass.is(Module ))
45
54
(caseClass.sourceModule.termRef, Nil )
46
55
else caseClass.primaryConstructor.info match {
47
56
case info : PolyType =>
@@ -72,7 +81,7 @@ trait Deriving { this: Typer =>
72
81
73
82
/** The shape of `cls` if `cls` is sealed */
74
83
private def sealedShape : Type = {
75
- val cases = children.map(caseShape)
84
+ val cases = children.map(caseShape).filter(_.exists)
76
85
val casesShape = (cases :\ (defn.UnitType : Type ))(defn.PairType .appliedTo(_, _))
77
86
defn.ShapeCasesType .appliedTo(casesShape)
78
87
}
@@ -84,7 +93,10 @@ trait Deriving { this: Typer =>
84
93
lazy val shapeWithClassParams : Type = {
85
94
if (cls.is(Case )) caseShape(cls)
86
95
else if (cls.is(Sealed )) sealedShape
87
- else NoType
96
+ else {
97
+ shapeError(i " it is neither sealed nor a case class " )
98
+ defn.ShapeCasesType .appliedTo(defn.UnitType )
99
+ }
88
100
}.reporting(res => i " shape of $cls = $res" , derive)
89
101
90
102
private def shapeOfType (tp : Type ) = {
@@ -410,13 +422,11 @@ trait Deriving { this: Typer =>
410
422
def syntheticDefs : List [Tree ] = synthetics.map(syntheticDef).toList
411
423
}
412
424
413
- def finalize (stat : tpd.TypeDef ): tpd.Tree =
414
- if (ctx.reporter.hasErrors) stat
415
- else {
416
- val templ @ Template (_, _, _, _) = stat.rhs
417
- tpd.cpy.TypeDef (stat)(
418
- rhs = tpd.cpy.Template (templ)(body = templ.body ++ new Finalizer ().syntheticDefs))
419
- }
425
+ def finalize (stat : tpd.TypeDef ): tpd.Tree = {
426
+ val templ @ Template (_, _, _, _) = stat.rhs
427
+ tpd.cpy.TypeDef (stat)(
428
+ rhs = tpd.cpy.Template (templ)(body = templ.body ++ new Finalizer ().syntheticDefs))
429
+ }
420
430
421
431
/** Synthesized instance for `Generic[<clsType>]` */
422
432
def genericInstance (clsType : Type ): tpd.Tree = {
0 commit comments