From a4387dbc8383f76a7be66b03c4598fcc16741727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pa=C5=82ka?= Date: Wed, 16 Oct 2024 15:55:59 +0200 Subject: [PATCH] Apply implicit conversion from derived Conversion instance defined as implicit rather than given --- .../dotty/tools/dotc/typer/Implicits.scala | 2 +- tests/pos/i21757.scala | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 tests/pos/i21757.scala diff --git a/compiler/src/dotty/tools/dotc/typer/Implicits.scala b/compiler/src/dotty/tools/dotc/typer/Implicits.scala index 3c2f025dc095..c42b196b8dfb 100644 --- a/compiler/src/dotty/tools/dotc/typer/Implicits.scala +++ b/compiler/src/dotty/tools/dotc/typer/Implicits.scala @@ -1176,7 +1176,7 @@ trait Implicits: case _ => info.derivesFrom(defn.ConversionClass) def tryConversion(using Context) = { val untpdConv = - if ref.symbol.is(Given) && producesConversion(ref.symbol.info) then + if ref.symbol.isOneOf(GivenOrImplicit) && producesConversion(ref.symbol.info) then untpd.Select( untpd.TypedSplice( adapt(generated, diff --git a/tests/pos/i21757.scala b/tests/pos/i21757.scala new file mode 100644 index 000000000000..7595540c4b58 --- /dev/null +++ b/tests/pos/i21757.scala @@ -0,0 +1,33 @@ +object ConversionChain { + + class X(val value: Int) + + class Y(val x: X) + + class Z(val y: Y) + + trait Conv[A, B] extends Conversion[A, B] + + given xy: Conv[X, Y] = { (x: X) => new Y(x) } + + given yz: Conv[Y, Z] = { (y: Y) => new Z(y) } + + object ConvUtils { + implicit def hypotheticalSyllogism[A, B, C]( // implicit def instead of given + using + ab: Conv[A, B], + bc: Conv[B, C] + ): Conv[A, C] = { + + new Conv[A, C] { + def apply(a: A): C = bc(ab(a)) + } + } + } + import ConvUtils.hypotheticalSyllogism + + def test(): Unit = { + val x = new X(42) + val z: Z = x + } +}