Skip to content

Commit 15c4964

Browse files
committed
Disallow case classes defined in inline methods
1 parent cc8ffb1 commit 15c4964

File tree

8 files changed

+34
-7
lines changed

8 files changed

+34
-7
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,8 @@ enum ErrorMessageID extends java.lang.Enum[ErrorMessageID] {
169169
InvalidReferenceInImplicitNotFoundAnnotationID,
170170
TraitMayNotDefineNativeMethodID,
171171
JavaEnumParentArgsID,
172-
AlreadyDefinedID
172+
AlreadyDefinedID,
173+
CaseClassInInlinedCodeID
173174

174175
def errorNumber = ordinal - 2
175176
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2500,3 +2500,14 @@ import transform.SymUtils._
25002500
|""".stripMargin
25012501
def explain = ""
25022502
}
2503+
2504+
class CaseClassInInlinedCode(tree: tpd.Tree)(using Context)
2505+
extends SyntaxMsg(CaseClassInInlinedCodeID) {
2506+
2507+
def defKind = if tree.symbol.is(Module) then "object" else "class"
2508+
def msg = s"Case $defKind definitions are not allowed in inline methods or quoted code. Use a normal $defKind instead."
2509+
def explain =
2510+
em"""Case class/object definitions generate a considerable fooprint in code size.
2511+
|Inlining such definition would multiply this footprint for each call site.
2512+
|""".stripMargin
2513+
}

compiler/src/dotty/tools/dotc/transform/PCPCheckAndHeal.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
9393
checkAnnotations(tree)
9494
healInfo(tree, tree.srcPos)
9595
super.transform(tree)
96-
96+
case tree: TypeDef if tree.symbol.is(Case) && level > 0 =>
97+
report.error(reporting.CaseClassInInlinedCode(tree), tree)
98+
super.transform(tree)
9799
case _ =>
98100
super.transform(tree)
99101
}

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,11 @@ object PrepareInlineable {
177177
// myAccessors += TypeDef(accessor).withPos(tree.pos.focus)
178178
// ref(accessor).withSpan(tree.span)
179179
//
180-
case _ => tree
180+
case _: TypeDef if tree.symbol.is(Case) =>
181+
report.error(reporting.CaseClassInInlinedCode(tree), tree)
182+
tree
183+
case _ =>
184+
tree
181185
}
182186
}
183187

@@ -251,7 +255,7 @@ object PrepareInlineable {
251255
}
252256
}
253257

254-
def checkInlineMethod(inlined: Symbol, body: Tree)(using Context): body.type = {
258+
private def checkInlineMethod(inlined: Symbol, body: Tree)(using Context): body.type = {
255259
if (inlined.owner.isClass && inlined.owner.seesOpaques)
256260
report.error(em"Implementation restriction: No inline methods allowed where opaque type aliases are in scope", inlined.srcPos)
257261
if Inliner.inInlineMethod(using ctx.outer) then
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import scala.quoted._
22
def test(using Quotes) = {
3-
'{ case class Foo() }
3+
'{ case class Foo() } // error
44
}

tests/neg-macros/i7068-c.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
def species(using quoted.Quotes) = '{
2+
case object Bar // error
3+
case class FooT() // error
4+
${
5+
case object Baz // ok
6+
???
7+
}
8+
FooT()
9+
}

tests/pos/i7068-a.scala renamed to tests/neg/i7068-a.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ sealed trait Foo[T] {
33
}
44

55
inline def species[T](t: T) = {
6-
case class FooT(x: T) extends Foo[T] {
6+
case class FooT(x: T) extends Foo[T] { // error
77
def foo(s: Foo[T]) = s match {
88
case FooT(x) => ???
99
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
inline def species() = {
2-
case class FooT()
2+
case class FooT() // error
33
FooT()
44
}
55
val foo = species()

0 commit comments

Comments
 (0)