-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Still can't find implicit of refined type when path-dependent type is used #8882
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Here's a workaround without an extra type parameter in
This looks like some limitation of |
Still reproducible in 3.3.0-RC3 https://scastie.scala-lang.org/DmytroMitin/3vDND7fzTnuU77hj9yhTfA/1 |
Currently I don't really have time to actively work on fixing that but did some further investigations about the potential cause of the problem.
import scala.compiletime.ops.int.+
trait Length[T <: Tuple]:
type Out <: Int
object Length:
given lengthEmpty: Length[EmptyTuple] with
override type Out = 0
given lengthCons(using length: Length[EmptyTuple] { type Out = 0 }): Length[Int *: EmptyTuple] with
override type Out = length.Out + 1
val a = summon[Length[Int *: EmptyTuple]]
val b = summon[a.Out =:= 1]
val c = summon[Length[Int *: EmptyTuple] {type Out = 1}]
import scala.compiletime.ops.int.+
trait Length[T <: Tuple]:
type Out <: Int
object Length:
given lengthEmpty: Length[EmptyTuple] with
override type Out = 0
given lengthCons(using length: Length[EmptyTuple]): Length[Int *: EmptyTuple] with
override type Out = length.Out + 1
val a = summon[Length[Int *: EmptyTuple]]
val b = summon[a.Out =:= 1]
val c = summon[Length[Int *: EmptyTuple] {type Out = 1}] raising errors: [error] Length.scala:15:28
[error] Cannot prove that a.Out =:= (1 : Int).
[error] val b = summon[a.Out =:= 1]
[error] ^
[error] Length.scala:16:57
[error] No given instance of type Length[Int *: EmptyTuple]{type Out = (1 : Int)} was found for parameter x of method summon in object Predef
[error] val c = summon[Length[Int *: EmptyTuple] {type Out = 1}]
[error] The difference in the snippets is in (using length: Length[EmptyTuple] { type Out = 0 }) vs (using length: Length[EmptyTuple]) After removing the invocations of package <empty> {
import scala.compiletime.ops.int.+
trait Length[T >: Nothing <: Tuple]() extends Object {
T <: Tuple
type Out >: Nothing <: Int
}
final lazy module val Length: Length = new Length()
final module class Length() extends Object() { this: Length.type =>
final lazy module given val lengthEmpty: Length.lengthEmpty =
new Length.lengthEmpty()
final module class lengthEmpty() extends Object(), Length[EmptyTuple] {
this: Length.lengthEmpty.type =>
override type Out = 0.type
}
given class lengthCons(using length: Length[EmptyTuple] { type Out = 0.type }) extends
Object(), Length[*:[Int, EmptyTuple]] {
protected given val length: Length[EmptyTuple] { type Out = (0 : Int) }
override type Out =
compiletime.ops.int.+[lengthCons.this.length.Out, 1.type]
}
final given def lengthCons(using length: Length[EmptyTuple] { type Out = 0.type }):
Length.lengthCons = new Length.lengthCons(using length)()
}
} and package <empty> {
import scala.compiletime.ops.int.+
trait Length[T >: Nothing <: Tuple]() extends Object {
T <: Tuple
type Out >: Nothing <: Int
}
final lazy module val Length: Length = new Length()
final module class Length() extends Object() { this: Length.type =>
final lazy module given val lengthEmpty: Length.lengthEmpty =
new Length.lengthEmpty()
final module class lengthEmpty() extends Object(), Length[EmptyTuple] {
this: Length.lengthEmpty.type =>
override type Out = 0.type
}
given class lengthCons(using length: Length[EmptyTuple]) extends
Object(), Length[*:[Int, EmptyTuple]] {
protected given val length: Length[EmptyTuple]
override type Out =
compiletime.ops.int.+[lengthCons.this.length.Out, 1.type]
}
final given def lengthCons(using length: Length[EmptyTuple]):
Length.lengthCons = new Length.lengthCons(using length)()
}
} respectively. Here we can see that the As I mentioned in my previous comment the problem seems to be related to how |
Uh oh!
There was an error while loading. Please reload this page.
#8825 is resolved but if we rewrite code slightly the problem remains.
Minimized code
In Dotty 0.25.0-bin-20200504-11760ea-NIGHTLY with
Output
summon[Length[HCons[Int, HNil]] { type Out = One}]
doesn't compileExpectation
summon[Length[HCons[Int, HNil]] { type Out = One}]
should compile.If we replace line (*) with (**) then
summon[Length[HCons[Int, HNil]] { type Out = One}]
compiles.If we resolve implicits manually,
summon[Length[HCons[Int, HNil]] { type Out = One}](using Length.hconsLength[Int, HNil](using Length.hnilLength))
doesn't compile with (*) eitherThe text was updated successfully, but these errors were encountered: