Skip to content

Commit bfcdef8

Browse files
smarterWojciechMazur
authored andcommitted
Restore pre-3.3.2 behavior of inline implicit def
`inline implicit def` is not really a supported feature since it combines Scala 3's `inline` with Scala 2's `implicit` where the latter should eventually be deprecated. This however didn't prevent at least one project from using this combination in a way that was broken by #18249, see #19862 for the details. The issue is that when definining: implicit def foo(x: A): B = ... Then `foo` is a valid implicit search candidate when looking up an implicit `Function1[A, B]`. However, before #18249 if instead we wrote: inline implicit def foo(x: A): B = ... Then `foo` would be considered as an implicit search candidate but discarded because eta-expansion was disabled. There is no particular reason for `inline implicit def` to behave differently from `implicit def` here, but since `implicit def` is a legacy feature and since Scala 3.3 is an LTS release, we choose to restore the pre-#18249 behavior for compatibility reasons. Fixes #19862. [Cherry-picked af69895]
1 parent 38ab06f commit bfcdef8

File tree

3 files changed

+11
-0
lines changed

3 files changed

+11
-0
lines changed

compiler/src/dotty/tools/dotc/core/Flags.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,7 @@ object Flags {
581581
val LazyGiven: FlagSet = Given | Lazy
582582
val InlineOrProxy: FlagSet = Inline | InlineProxy // An inline method or inline argument proxy */
583583
val InlineMethod: FlagSet = Inline | Method
584+
val InlineImplicitMethod: FlagSet = Implicit | InlineMethod
584585
val InlineParam: FlagSet = Inline | Param
585586
val InlineByNameProxy: FlagSet = InlineProxy | Method
586587
val JavaEnumTrait: FlagSet = JavaDefined | Enum // A Java enum trait

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3939,10 +3939,12 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
39393939

39403940
// Reasons NOT to eta expand:
39413941
// - we reference a constructor
3942+
// - we reference an inline implicit def (see #19862)
39423943
// - we are in a pattern
39433944
// - the current tree is a synthetic apply which is not expandable (eta-expasion would simply undo that)
39443945
if arity >= 0
39453946
&& !tree.symbol.isConstructor
3947+
&& !tree.symbol.isAllOf(InlineImplicitMethod)
39463948
&& !ctx.mode.is(Mode.Pattern)
39473949
&& !(isSyntheticApply(tree) && !functionExpected)
39483950
then

tests/pos/i19862.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import scala.language.implicitConversions
2+
3+
object Test:
4+
implicit inline def uhOh[A](value: A): A =
5+
compiletime.error("Should not have been called")
6+
def test =
7+
// Compiles because `uhOh` fails to eta-expand and we fallback to `Predef.$conforms[A, A]`
8+
summon[Function1[Int, Int]]

0 commit comments

Comments
 (0)