Skip to content

Commit 7dd54f0

Browse files
committed
Improve message when -Xmax-inlines limit reached
Fixes #13044
1 parent afaac17 commit 7dd54f0

File tree

5 files changed

+153
-2
lines changed

5 files changed

+153
-2
lines changed

Diff for: compiler/src/dotty/tools/dotc/transform/Erasure.scala

+6-2
Original file line numberDiff line numberDiff line change
@@ -593,8 +593,12 @@ object Erasure {
593593
*/
594594
private def checkNotErased(tree: Tree)(using Context): tree.type = {
595595
if (!ctx.mode.is(Mode.Type)) {
596-
if (isErased(tree))
597-
report.error(em"${tree.symbol} is declared as erased, but is in fact used", tree.srcPos)
596+
if isErased(tree) then
597+
val msg =
598+
if tree.symbol.is(Flags.Inline) then
599+
em"${tree.symbol} is declared as `inline`, but was not inlined\n\nTry increasing `-Xmax-inlines` above ${ctx.settings.XmaxInlines.value}"
600+
else em"${tree.symbol} is declared as `erased`, but is in fact used"
601+
report.error(msg, tree.srcPos)
598602
tree.symbol.getAnnotation(defn.CompileTimeOnlyAnnot) match {
599603
case Some(annot) =>
600604
def defaultMsg =

Diff for: compiler/test/dotty/tools/dotc/CompilationTests.scala

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class CompilationTests {
6363
compileFile("tests/pos-special/extend-java-enum.scala", defaultOptions.and("-source", "3.0-migration")),
6464
compileFile("tests/pos-custom-args/help.scala", defaultOptions.and("-help", "-V", "-W", "-X", "-Y")),
6565
compileFile("tests/pos-custom-args/i10383.scala", defaultOptions.and("-source", "future", "-deprecation", "-Xfatal-warnings")),
66+
compileFile("tests/pos-custom-args/i13044.scala", defaultOptions.and("-Xmax-inlines:33")),
6667
).checkCompile()
6768
}
6869

Diff for: tests/neg/i13044.check

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
-- Error: tests/neg/i13044.scala:50:40 ---------------------------------------------------------------------------------
2+
50 | implicit def typeSchema: Schema[A] = Schema.gen // error // error
3+
| ^^^^^^^^^^
4+
| given instance gen is declared as `inline`, but was not inlined
5+
|
6+
| Try increasing `-Xmax-inlines` above 32
7+
| This location contains code that was inlined from i13044.scala:17
8+
| This location contains code that was inlined from i13044.scala:31
9+
| This location contains code that was inlined from i13044.scala:37
10+
| This location contains code that was inlined from i13044.scala:17
11+
| This location contains code that was inlined from i13044.scala:31
12+
| This location contains code that was inlined from i13044.scala:37
13+
| This location contains code that was inlined from i13044.scala:17
14+
| This location contains code that was inlined from i13044.scala:31
15+
| This location contains code that was inlined from i13044.scala:37
16+
| This location contains code that was inlined from i13044.scala:17
17+
| This location contains code that was inlined from i13044.scala:31
18+
| This location contains code that was inlined from i13044.scala:37
19+
| This location contains code that was inlined from i13044.scala:17
20+
| This location contains code that was inlined from i13044.scala:18
21+
| This location contains code that was inlined from i13044.scala:31
22+
| This location contains code that was inlined from i13044.scala:37
23+
-- Error: tests/neg/i13044.scala:50:40 ---------------------------------------------------------------------------------
24+
50 | implicit def typeSchema: Schema[A] = Schema.gen // error // error
25+
| ^^^^^^^^^^
26+
| method recurse is declared as `inline`, but was not inlined
27+
|
28+
| Try increasing `-Xmax-inlines` above 32
29+
| This location contains code that was inlined from i13044.scala:18
30+
| This location contains code that was inlined from i13044.scala:31
31+
| This location contains code that was inlined from i13044.scala:37
32+
| This location contains code that was inlined from i13044.scala:17
33+
| This location contains code that was inlined from i13044.scala:31
34+
| This location contains code that was inlined from i13044.scala:37
35+
| This location contains code that was inlined from i13044.scala:17
36+
| This location contains code that was inlined from i13044.scala:31
37+
| This location contains code that was inlined from i13044.scala:37
38+
| This location contains code that was inlined from i13044.scala:17
39+
| This location contains code that was inlined from i13044.scala:31
40+
| This location contains code that was inlined from i13044.scala:37
41+
| This location contains code that was inlined from i13044.scala:17
42+
| This location contains code that was inlined from i13044.scala:18
43+
| This location contains code that was inlined from i13044.scala:31
44+
| This location contains code that was inlined from i13044.scala:37

Diff for: tests/neg/i13044.scala

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import scala.deriving.Mirror
2+
import scala.compiletime._
3+
4+
trait Schema[T] {
5+
def build: T
6+
}
7+
8+
object Schema extends SchemaDerivation {
9+
implicit lazy val int: Schema[Int] = ???
10+
implicit def option[A](implicit ev: Schema[A]): Schema[Option[A]] = ???
11+
}
12+
13+
trait SchemaDerivation {
14+
inline def recurse[A <: Tuple]: List[Schema[Any]] =
15+
inline erasedValue[A] match {
16+
case _: (t *: ts) =>
17+
val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]]
18+
builder :: recurse[ts]
19+
case _: EmptyTuple => Nil
20+
}
21+
22+
inline def derived[A]: Schema[A] =
23+
inline summonInline[Mirror.Of[A]] match {
24+
case m: Mirror.SumOf[A] =>
25+
lazy val subTypes = recurse[m.MirroredElemTypes]
26+
new Schema[A] {
27+
def build: A = ???
28+
}
29+
30+
case m: Mirror.ProductOf[A] =>
31+
lazy val fields = recurse[m.MirroredElemTypes]
32+
new Schema[A] {
33+
def build: A = ???
34+
}
35+
}
36+
37+
inline given gen[A]: Schema[A] = derived
38+
}
39+
40+
case class H(i: Int)
41+
case class G(h: H)
42+
case class F(g: G)
43+
case class E(f: Option[F])
44+
case class D(e: E)
45+
case class C(d: D)
46+
case class B(c: C)
47+
case class A(a: A, b: B)
48+
49+
object TestApp {
50+
implicit def typeSchema: Schema[A] = Schema.gen // error // error
51+
}

Diff for: tests/pos-custom-args/i13044.scala

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import scala.deriving.Mirror
2+
import scala.compiletime._
3+
4+
trait Schema[T] {
5+
def build: T
6+
}
7+
8+
object Schema extends SchemaDerivation {
9+
implicit lazy val int: Schema[Int] = ???
10+
implicit def option[A](implicit ev: Schema[A]): Schema[Option[A]] = ???
11+
}
12+
13+
trait SchemaDerivation {
14+
inline def recurse[A <: Tuple]: List[Schema[Any]] =
15+
inline erasedValue[A] match {
16+
case _: (t *: ts) =>
17+
val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]]
18+
builder :: recurse[ts]
19+
case _: EmptyTuple => Nil
20+
}
21+
22+
inline def derived[A]: Schema[A] =
23+
inline summonInline[Mirror.Of[A]] match {
24+
case m: Mirror.SumOf[A] =>
25+
lazy val subTypes = recurse[m.MirroredElemTypes]
26+
new Schema[A] {
27+
def build: A = ???
28+
}
29+
30+
case m: Mirror.ProductOf[A] =>
31+
lazy val fields = recurse[m.MirroredElemTypes]
32+
new Schema[A] {
33+
def build: A = ???
34+
}
35+
}
36+
37+
inline given gen[A]: Schema[A] = derived
38+
}
39+
40+
case class H(i: Int)
41+
case class G(h: H)
42+
case class F(g: G)
43+
case class E(f: Option[F])
44+
case class D(e: E)
45+
case class C(d: D)
46+
case class B(c: C)
47+
case class A(a: A, b: B)
48+
49+
object TestApp {
50+
implicit def typeSchema: Schema[A] = Schema.gen
51+
}

0 commit comments

Comments
 (0)