From eafa761e45bda0912065ff1245322a2ba16e953f Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Thu, 10 Oct 2024 19:41:58 +0200 Subject: [PATCH] Fix `isInlineable` check to work during overloading resolution Overloading may create temporary symbols via `Applications#resolveMapped`, these symbols do not carry the annotations from the original symbols which means the `isInlineable` would always return false for them. This matters because during the course of overloading resolution we might call `ProtoTypes.Compatibility#constrainResult` which special-cases transparent inline methods. Fixes a regression in Monocle introduced in the previous commit. --- compiler/src/dotty/tools/dotc/inlines/Inlines.scala | 8 +++++++- tests/pos/i21410c.scala | 11 +++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i21410c.scala diff --git a/compiler/src/dotty/tools/dotc/inlines/Inlines.scala b/compiler/src/dotty/tools/dotc/inlines/Inlines.scala index aeecd9c376e3..7cb87f70803a 100644 --- a/compiler/src/dotty/tools/dotc/inlines/Inlines.scala +++ b/compiler/src/dotty/tools/dotc/inlines/Inlines.scala @@ -49,7 +49,13 @@ object Inlines: /** Can a call to method `meth` be inlined? */ def isInlineable(meth: Symbol)(using Context): Boolean = - meth.is(Inline) && meth.hasAnnotation(defn.BodyAnnot) && !inInlineMethod + meth.is(Inline) + && (meth.hasAnnotation(defn.BodyAnnot) + // Ensure `isInlineable` works with temporary symbols created during + // overloading resolution by `Applications#resolveMapped`. + // Testcase: tests/pos/i21410c.scala + || meth.hasAnnotation(defn.MappedAlternativeAnnot)) + && !inInlineMethod /** Should call be inlined in this context? */ def needsInlining(tree: Tree)(using Context): Boolean = tree match { diff --git a/tests/pos/i21410c.scala b/tests/pos/i21410c.scala new file mode 100644 index 000000000000..21f69fec20fa --- /dev/null +++ b/tests/pos/i21410c.scala @@ -0,0 +1,11 @@ +class AppliedPIso[A, B]() +case class User(age: Int) + +object Test: + extension [From, To](from: From) + def focus(): AppliedPIso[From, From] = ??? + transparent inline def focus(inline lambda: (From => To)): Any = ??? + + + val u = User(1) + val ap: AppliedPIso[User, User] = u.focus(_.age) // error