Closed
Description
Compiler version
3.5.1
Minimized code
The following 2 examples demonstrating hypothetical syllogism are almost identical, but the second failed, because implicit def
is used instead of given
(example 1)
object AlmostNewStyle {
class A(val value: Int)
class B(val a: A)
class C(val b: B)
trait Conv[A, B] extends Conversion[A, B]
given ab: Conv[A, B] = { (a: A) => new B(a) }
given bc: Conv[B, C] = { (b: B) => new C(b) }
object ConvUtils {
given hypotheticalSyllogism[A, B, C](
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.given
def demo(): Unit = {
val a = new A(42)
val c: C = a
println(c.b.a.value) // Outputs: 42
}
}
(example 2)
object OldStyle {
class A(val value: Int)
class B(val a: A)
class C(val b: B)
trait Conv[A, B] extends Conversion[A, B]
given ab: Conv[A, B] = { (a: A) => new B(a) }
given bc: Conv[B, C] = { (b: B) => new C(b) }
object ConvUtils {
implicit def hypotheticalSyllogism[A, B, C](
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.given
def demo(): Unit = {
val a = new A(42)
val c: C = a
println(c.b.a.value) // Outputs: 42
}
}
Output
the error of example 2 is:
[Error] /home/peng/git/dottyspike/core/src/main/scala/com/tribbloids/spike/dotty/TransitiveConversion.scala:109:18: Found: (a : com.tribbloids.spike.dotty.TransitiveConversion.OldStyle.A)
Required: com.tribbloids.spike.dotty.TransitiveConversion.OldStyle.C
Note that implicit conversions cannot be applied because they are ambiguous;
both given instance ab in object OldStyle and given instance bc in object OldStyle match type com.tribbloids.spike.dotty.TransitiveConversion.OldStyle.Conv[A, B]
Explanation
===========
Tree: a
I tried to show that
(a : com.tribbloids.spike.dotty.TransitiveConversion.OldStyle.A)
conforms to
com.tribbloids.spike.dotty.TransitiveConversion.OldStyle.C
but none of the attempts shown below succeeded:
==> (a : com.tribbloids.spike.dotty.TransitiveConversion.OldStyle.A) <: com.tribbloids.spike.dotty.TransitiveConversion.OldStyle.C class dotty.tools.dotc.core.Types$CachedTermRef class dotty.tools.dotc.core.Types$CachedTypeRef
==> com.tribbloids.spike.dotty.TransitiveConversion.OldStyle.A <: com.tribbloids.spike.dotty.TransitiveConversion.OldStyle.C class dotty.tools.dotc.core.Types$CachedTypeRef class dotty.tools.dotc.core.Types$CachedTypeRef = false
Expectation
despite the deprecation warning of implicit
keyword, the 2 examples should use the same algorithm and behave identically