Skip to content

Commit ffaab87

Browse files
Backport "Add warning for anonymous inline classes (#16723)" to LTS (#21110)
Backports #20291 to the LTS branch. PR submitted by the release tooling.
2 parents 0d787e2 + 7a6b83b commit ffaab87

File tree

19 files changed

+119
-47
lines changed

19 files changed

+119
-47
lines changed

community-build/src/scala/dotty/communitybuild/projects.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,10 @@ object projects:
368368

369369
lazy val shapeless3 = SbtCommunityProject(
370370
project = "shapeless-3",
371-
sbtTestCommand = "testJVM; testJS",
371+
sbtTestCommand = List(
372+
"""set derivingJVM/scalacOptions += "-Wconf:msg=New anonymous class definition will be duplicated at each inline site:s" """,
373+
"""set derivingJS/scalacOptions += "-Wconf:msg=New anonymous class definition will be duplicated at each inline site:s" """,
374+
"testJVM", "testJS").mkString("; "),
372375
sbtDocCommand = forceDoc("typeable", "deriving"),
373376
scalacOptions = SbtCommunityProject.scalacOptions.filter(_ != "-Ysafe-init"), // due to -Xfatal-warnings
374377
)

compiler/src/dotty/tools/dotc/printing/Formatting.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ object Formatting {
4242
trait CtxShow:
4343
def run(using Context): Shown
4444

45-
private inline def CtxShow(inline x: Context ?=> Shown) = new CtxShow { def run(using Context) = x(using ctx) }
45+
private inline def CtxShow(inline x: Context ?=> Shown) =
46+
class InlinedCtxShow extends CtxShow { def run(using Context) = x(using ctx) }
47+
new InlinedCtxShow
4648
private def toStr[A: Show](x: A)(using Context): String = Shown.toStr(toShown(x))
4749
private def toShown[A: Show](x: A)(using Context): Shown = Show[A].show(x).runCtxShow
4850

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe
208208
case UnstableInlineAccessorID // errorNumber: 192 - unused in LTS
209209
case VolatileOnValID // errorNumber: 193
210210
case ExtensionNullifiedByMemberID // errorNumber: 194
211+
case InlinedAnonClassWarningID // errorNumber: 195
211212

212213
def errorNumber = ordinal - 1
213214

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3073,6 +3073,15 @@ extends SyntaxMsg(InlineGivenShouldNotBeFunctionID):
30733073
| inline def apply(x: A) = x.toB
30743074
"""
30753075

3076+
class InlinedAnonClassWarning()(using Context)
3077+
extends Message(InlinedAnonClassWarningID):
3078+
def kind = MessageKind.PotentialIssue
3079+
def msg(using Context) = "New anonymous class definition will be duplicated at each inline site"
3080+
def explain(using Context) =
3081+
i"""Anonymous class will be defined at each use site, which may lead to a larger number of classfiles.
3082+
|
3083+
|To inline class definitions, you may provide an explicit class name to avoid this warning."""
3084+
30763085
class ValueDiscarding(tp: Type)(using Context)
30773086
extends Message(ValueDiscardingID):
30783087
def kind = MessageKind.PotentialIssue

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Symbols.*
1010
import typer.RefChecks
1111
import MegaPhase.MiniPhase
1212
import ast.tpd
13+
import reporting.InlinedAnonClassWarning
1314

1415
import config.Feature
1516
import Decorators.*
@@ -51,6 +52,17 @@ class PruneErasedDefs extends MiniPhase with SymTransformer { thisTransform =>
5152
else cpy.ValDef(tree)(rhs = trivialErasedTree(tree.rhs))
5253

5354
override def transformDefDef(tree: DefDef)(using Context): Tree =
55+
def checkNoInlineAnnoClasses(tree: DefDef)(using Context): Unit =
56+
if tree.symbol.is(Inline) then
57+
new TreeTraverser {
58+
def traverse(tree: Tree)(using Context): Unit =
59+
tree match
60+
case tree: TypeDef if tree.symbol.isAnonymousClass =>
61+
report.warning(new InlinedAnonClassWarning(), tree.symbol.sourcePos)
62+
case _ => traverseChildren(tree)
63+
}.traverse(tree)
64+
65+
checkNoInlineAnnoClasses(tree)
5466
checkErasedInExperimental(tree.symbol)
5567
if !tree.symbol.isEffectivelyErased || tree.rhs.isEmpty then tree
5668
else cpy.DefDef(tree)(rhs = trivialErasedTree(tree.rhs))

tests/neg/i13044.check

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
-- Error: tests/neg/i13044.scala:50:40 ---------------------------------------------------------------------------------
2-
50 | implicit def typeSchema: Schema[A] = Schema.gen // error // error
1+
-- Error: tests/neg/i13044.scala:46:40 ---------------------------------------------------------------------------------
2+
46 | implicit def typeSchema: Schema[A] = Schema.gen // error // error
33
| ^^^^^^^^^^
44
| given instance gen is declared as `inline`, but was not inlined
55
|
@@ -12,47 +12,47 @@
1212
| ^
1313
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1414
|This location contains code that was inlined from i13044.scala:17
15-
31 | lazy val fields = recurse[m.MirroredElemTypes]
15+
29 | lazy val fields = recurse[m.MirroredElemTypes]
1616
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1717
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1818
|This location contains code that was inlined from i13044.scala:17
19-
37 | inline given gen[A]: Schema[A] = derived
19+
33 | inline given gen[A]: Schema[A] = derived
2020
| ^^^^^^^
2121
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2222
|This location contains code that was inlined from i13044.scala:17
2323
17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]]
2424
| ^
2525
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
2626
|This location contains code that was inlined from i13044.scala:17
27-
31 | lazy val fields = recurse[m.MirroredElemTypes]
27+
29 | lazy val fields = recurse[m.MirroredElemTypes]
2828
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2929
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3030
|This location contains code that was inlined from i13044.scala:17
31-
37 | inline given gen[A]: Schema[A] = derived
31+
33 | inline given gen[A]: Schema[A] = derived
3232
| ^^^^^^^
3333
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3434
|This location contains code that was inlined from i13044.scala:17
3535
17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]]
3636
| ^
3737
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3838
|This location contains code that was inlined from i13044.scala:17
39-
31 | lazy val fields = recurse[m.MirroredElemTypes]
39+
29 | lazy val fields = recurse[m.MirroredElemTypes]
4040
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4141
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4242
|This location contains code that was inlined from i13044.scala:17
43-
37 | inline given gen[A]: Schema[A] = derived
43+
33 | inline given gen[A]: Schema[A] = derived
4444
| ^^^^^^^
4545
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
4646
|This location contains code that was inlined from i13044.scala:17
4747
17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]]
4848
| ^
4949
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5050
|This location contains code that was inlined from i13044.scala:17
51-
31 | lazy val fields = recurse[m.MirroredElemTypes]
51+
29 | lazy val fields = recurse[m.MirroredElemTypes]
5252
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5353
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5454
|This location contains code that was inlined from i13044.scala:17
55-
37 | inline given gen[A]: Schema[A] = derived
55+
33 | inline given gen[A]: Schema[A] = derived
5656
| ^^^^^^^
5757
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5858
|This location contains code that was inlined from i13044.scala:17
@@ -64,15 +64,15 @@
6464
| ^^^^^^^^^^^
6565
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6666
|This location contains code that was inlined from i13044.scala:17
67-
31 | lazy val fields = recurse[m.MirroredElemTypes]
67+
29 | lazy val fields = recurse[m.MirroredElemTypes]
6868
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6969
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7070
|This location contains code that was inlined from i13044.scala:17
71-
37 | inline given gen[A]: Schema[A] = derived
71+
33 | inline given gen[A]: Schema[A] = derived
7272
| ^^^^^^^
7373
--------------------------------------------------------------------------------------------------------------------
74-
-- Error: tests/neg/i13044.scala:50:40 ---------------------------------------------------------------------------------
75-
50 | implicit def typeSchema: Schema[A] = Schema.gen // error // error
74+
-- Error: tests/neg/i13044.scala:46:40 ---------------------------------------------------------------------------------
75+
46 | implicit def typeSchema: Schema[A] = Schema.gen // error // error
7676
| ^^^^^^^^^^
7777
| method recurse is declared as `inline`, but was not inlined
7878
|
@@ -85,47 +85,47 @@
8585
| ^^^^^^^
8686
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8787
|This location contains code that was inlined from i13044.scala:18
88-
31 | lazy val fields = recurse[m.MirroredElemTypes]
88+
29 | lazy val fields = recurse[m.MirroredElemTypes]
8989
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9090
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9191
|This location contains code that was inlined from i13044.scala:18
92-
37 | inline given gen[A]: Schema[A] = derived
92+
33 | inline given gen[A]: Schema[A] = derived
9393
| ^^^^^^^
9494
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9595
|This location contains code that was inlined from i13044.scala:18
9696
17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]]
9797
| ^
9898
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9999
|This location contains code that was inlined from i13044.scala:18
100-
31 | lazy val fields = recurse[m.MirroredElemTypes]
100+
29 | lazy val fields = recurse[m.MirroredElemTypes]
101101
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
102102
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
103103
|This location contains code that was inlined from i13044.scala:18
104-
37 | inline given gen[A]: Schema[A] = derived
104+
33 | inline given gen[A]: Schema[A] = derived
105105
| ^^^^^^^
106106
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
107107
|This location contains code that was inlined from i13044.scala:18
108108
17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]]
109109
| ^
110110
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
111111
|This location contains code that was inlined from i13044.scala:18
112-
31 | lazy val fields = recurse[m.MirroredElemTypes]
112+
29 | lazy val fields = recurse[m.MirroredElemTypes]
113113
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
114114
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
115115
|This location contains code that was inlined from i13044.scala:18
116-
37 | inline given gen[A]: Schema[A] = derived
116+
33 | inline given gen[A]: Schema[A] = derived
117117
| ^^^^^^^
118118
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
119119
|This location contains code that was inlined from i13044.scala:18
120120
17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]]
121121
| ^
122122
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
123123
|This location contains code that was inlined from i13044.scala:18
124-
31 | lazy val fields = recurse[m.MirroredElemTypes]
124+
29 | lazy val fields = recurse[m.MirroredElemTypes]
125125
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
126126
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
127127
|This location contains code that was inlined from i13044.scala:18
128-
37 | inline given gen[A]: Schema[A] = derived
128+
33 | inline given gen[A]: Schema[A] = derived
129129
| ^^^^^^^
130130
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
131131
|This location contains code that was inlined from i13044.scala:18
@@ -137,10 +137,10 @@
137137
| ^^^^^^^^^^^
138138
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
139139
|This location contains code that was inlined from i13044.scala:18
140-
31 | lazy val fields = recurse[m.MirroredElemTypes]
140+
29 | lazy val fields = recurse[m.MirroredElemTypes]
141141
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
142142
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
143143
|This location contains code that was inlined from i13044.scala:18
144-
37 | inline given gen[A]: Schema[A] = derived
144+
33 | inline given gen[A]: Schema[A] = derived
145145
| ^^^^^^^
146146
--------------------------------------------------------------------------------------------------------------------

tests/neg/i13044.scala

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,11 @@ trait SchemaDerivation {
2323
inline summonInline[Mirror.Of[A]] match {
2424
case m: Mirror.SumOf[A] =>
2525
lazy val subTypes = recurse[m.MirroredElemTypes]
26-
new Schema[A] {
27-
def build: A = ???
28-
}
26+
???
2927

3028
case m: Mirror.ProductOf[A] =>
3129
lazy val fields = recurse[m.MirroredElemTypes]
32-
new Schema[A] {
33-
def build: A = ???
34-
}
30+
???
3531
}
3632

3733
inline given gen[A]: Schema[A] = derived

tests/pos/i17314.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ object circelike {
1313
inline final def derived[A](using conf: Configuration)(using
1414
inline mirror: Mirror.Of[A]
1515
): ConfiguredCodec[A] =
16-
new ConfiguredCodec[A]:
16+
class InlinedConfiguredCodec extends ConfiguredCodec[A]:
1717
val codec = summonInline[Codec[URI]] // simplification
18+
new InlinedConfiguredCodec
1819
}
1920

2021
object foo {

0 commit comments

Comments
 (0)