From 0396584f18bf6adb12d0bf5ecbe1b1f6901c32b9 Mon Sep 17 00:00:00 2001 From: Jan Chyb Date: Mon, 7 Apr 2025 15:41:52 +0200 Subject: [PATCH] Fail not inlined inline methods calls early All of them would be achieved with implicit resolution, during which the global state (ctx.base) would have stopInlining set to true, but the corresponding error might not have been shown as part of the implicit resolution - now we reset that value after failing the implicit, if it was not set before typing the implicit. --- .../dotty/tools/dotc/typer/Implicits.scala | 4 + tests/neg/i13044.check | 134 ++---------------- tests/neg/i13044.scala | 2 +- tests/neg/i22423.check | 24 ++++ tests/neg/i22423.scala | 35 +++++ 5 files changed, 72 insertions(+), 127 deletions(-) create mode 100644 tests/neg/i22423.check create mode 100644 tests/neg/i22423.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 25fed4e62de9..935930e1b8b3 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -1294,11 +1294,15 @@ trait Implicits: val history = ctx.searchHistory.nest(cand, pt) val typingCtx = searchContext().setNewTyperState().setFreshGADTBounds.setSearchHistory(history) + val alreadyStoppedInlining = ctx.base.stopInlining val result = typedImplicit(cand, pt, argument, span)(using typingCtx) result match case res: SearchSuccess => ctx.searchHistory.defineBynameImplicit(wideProto, res) case _ => + if !alreadyStoppedInlining && ctx.base.stopInlining then + // a call overflowed as part of the expansion when typing the implicit + ctx.base.stopInlining = false // Since the search failed, the local typerstate will be discarded // without being committed, but type variables local to that state // might still appear in an error message, so we run `gc()` here to diff --git a/tests/neg/i13044.check b/tests/neg/i13044.check index e504b14185da..71fef532ec43 100644 --- a/tests/neg/i13044.check +++ b/tests/neg/i13044.check @@ -1,63 +1,18 @@ --- Error: tests/neg/i13044.scala:61:40 --------------------------------------------------------------------------------- -61 | implicit def typeSchema: Schema[A] = Schema.gen // error // error +-- [E172] Type Error: tests/neg/i13044.scala:61:40 --------------------------------------------------------------------- +61 | implicit def typeSchema: Schema[A] = Schema.gen // error | ^^^^^^^^^^ - | given instance gen is declared as `inline`, but was not inlined + | No given instance of type Schema[B] was found. + | I found: | - | Try increasing `-Xmax-inlines` above 32 + | Schema.gen[B] + | + | But given instance gen in trait SchemaDerivation does not match type Schema[B]. |-------------------------------------------------------------------------------------------------------------------- |Inline stack trace |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:17 17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] - | ^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:17 -29 | lazy val fields = recurse[m.MirroredElemTypes] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:17 -33 | inline given gen[A]: Schema[A] = derived - | ^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:17 -17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] - | ^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:17 -29 | lazy val fields = recurse[m.MirroredElemTypes] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:17 -33 | inline given gen[A]: Schema[A] = derived - | ^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:17 -17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] - | ^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:17 -29 | lazy val fields = recurse[m.MirroredElemTypes] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:17 -33 | inline given gen[A]: Schema[A] = derived - | ^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:17 -17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] - | ^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:17 -29 | lazy val fields = recurse[m.MirroredElemTypes] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:17 -33 | inline given gen[A]: Schema[A] = derived - | ^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:17 -17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^ |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:17 18 | builder :: recurse[ts] @@ -71,76 +26,3 @@ 33 | inline given gen[A]: Schema[A] = derived | ^^^^^^^ -------------------------------------------------------------------------------------------------------------------- --- Error: tests/neg/i13044.scala:61:40 --------------------------------------------------------------------------------- -61 | implicit def typeSchema: Schema[A] = Schema.gen // error // error - | ^^^^^^^^^^ - | method recurse is declared as `inline`, but was not inlined - | - | Try increasing `-Xmax-inlines` above 32 - |-------------------------------------------------------------------------------------------------------------------- - |Inline stack trace - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -18 | builder :: recurse[ts] - | ^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -29 | lazy val fields = recurse[m.MirroredElemTypes] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -33 | inline given gen[A]: Schema[A] = derived - | ^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] - | ^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -29 | lazy val fields = recurse[m.MirroredElemTypes] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -33 | inline given gen[A]: Schema[A] = derived - | ^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] - | ^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -29 | lazy val fields = recurse[m.MirroredElemTypes] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -33 | inline given gen[A]: Schema[A] = derived - | ^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] - | ^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -29 | lazy val fields = recurse[m.MirroredElemTypes] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -33 | inline given gen[A]: Schema[A] = derived - | ^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -17 | val builder = summonInline[Schema[t]].asInstanceOf[Schema[Any]] - | ^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -18 | builder :: recurse[ts] - | ^^^^^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -29 | lazy val fields = recurse[m.MirroredElemTypes] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from i13044.scala:18 -33 | inline given gen[A]: Schema[A] = derived - | ^^^^^^^ - -------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg/i13044.scala b/tests/neg/i13044.scala index 2b00fc188f8c..2f9cae2f9039 100644 --- a/tests/neg/i13044.scala +++ b/tests/neg/i13044.scala @@ -58,5 +58,5 @@ case class B(c: C) case class A(a: A, b: B) object TestApp { - implicit def typeSchema: Schema[A] = Schema.gen // error // error + implicit def typeSchema: Schema[A] = Schema.gen // error } diff --git a/tests/neg/i22423.check b/tests/neg/i22423.check new file mode 100644 index 000000000000..ec189d99524a --- /dev/null +++ b/tests/neg/i22423.check @@ -0,0 +1,24 @@ +-- Error: tests/neg/i22423.scala:35:14 --------------------------------------------------------------------------------- +35 | exportReader[Settings] // error + | ^^^^^^^^^^^^^^^^^^^^^^ + | cannot reduce summonFrom with + | patterns : case given reader @ _:ConfigReader[List[String]] + |-------------------------------------------------------------------------------------------------------------------- + |Inline stack trace + |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + |This location contains code that was inlined from i22423.scala:12 +12 | summonFrom { case reader: ConfigReader[A] => reader } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + |This location contains code that was inlined from i22423.scala:12 +15 | summonConfigReader[List[String]] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + |This location contains code that was inlined from i22423.scala:12 + 8 | readCaseClass() + | ^^^^^^^^^^^^^^^ + |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + |This location contains code that was inlined from i22423.scala:12 +30 |inline given exportReader[A]: Exported[ConfigReader[A]] = Exported(HintsAwareConfigReaderDerivation.deriveReader[A]) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + -------------------------------------------------------------------------------------------------------------------- diff --git a/tests/neg/i22423.scala b/tests/neg/i22423.scala new file mode 100644 index 000000000000..4204f8f93216 --- /dev/null +++ b/tests/neg/i22423.scala @@ -0,0 +1,35 @@ +//> using options -Xmax-inlines:7 +import scala.deriving.Mirror +import scala.compiletime._ +import scala.compiletime.ops.int._ + +object HintsAwareConfigReaderDerivation { + inline def deriveReader[A]: ConfigReader[A] = + readCaseClass() + ??? + + private inline def summonConfigReader[A]: ConfigReader[A] = + summonFrom { case reader: ConfigReader[A] => reader } + + private inline def readCaseClass(): Unit = + summonConfigReader[List[String]] + val a1: Int = ??? + val a2: EmptyTuple = ??? + a1 *: a2 + ??? +} + +trait ConfigReader[A] +object ConfigReader { + implicit def traversableReader[A, F[A] <: TraversableOnce[A]](implicit configConvert: ConfigReader[A]): ConfigReader[F[A]] = ??? + implicit def exportedReader[A](implicit exported: Exported[ConfigReader[A]]): ConfigReader[A] = exported.instance + case class Exported[A](instance: A) +} + +import ConfigReader._ +inline given exportReader[A]: Exported[ConfigReader[A]] = Exported(HintsAwareConfigReaderDerivation.deriveReader[A]) + +case class Settings(rules: List[String]) + +val settings = + exportReader[Settings] // error