Type class fails for range in scala 3 but works in scala 2

I’m creating this issue here for discussion. The origin in a discussion in discord.

I have a piece of code which works in scala 2 and fails when I try to convert the project to scala 3. The original code is something I don’t really understand in the first place; several experts helped me develop the code.

The very high level issue is that I have some code which allows my to use the syntax obj.treeMapReduce(…)(…) and in scala 2 I can use a range in place of the object. (1 to 100).treeMapReduce(…)(…) but in scala 3 this fails to compile.

I’ve created a scastie showing my code.

In the meantime, Aly, aly.fish from discord minimised the test case to the following. Scastie - An interactive playground for Scala.

Here is the code for the minimised test case.

class Foo[C[_]] {}
object Foo {
  def apply[C[_], A](ca: C[A])(using fooC: Foo[C]): Foo[C] = fooC
  given iterableOnceFoo[C[x] <: IterableOnce[x]]: Foo[C] with {}
}

val v2: Range = 1 to 10
Foo.apply(v2)
No given instance of type worksheet.Foo[
  [C] =>> scala.collection.immutable.StrictOptimizedSeqOps[Int, IndexedSeq, C]] was found for parameter fooC of method apply in object Foo.
I found:

    worksheet.Foo.iterableOnceFoo[C]

But given instance iterableOnceFoo in object Foo does not match type worksheet.Foo[
  [C] =>> scala.collection.immutable.StrictOptimizedSeqOps[Int, IndexedSeq, C]].

Defininig it as either works

  given iterableOnceFoo[C[x] <: IterableOnce[?]]: Foo[C] with {}
  given iterableOnceFoo[C[_] <: IterableOnce[?]]: Foo[C] with {}

similary to defining

val v2: Seq[Int] = 1 to 10

My guess is for the case of Range Scala does not infer C as [X] =>> Range. It infers a type constructor of the form: [C] =>> StrictOptimizedSeqOps[Int, IndexedSeq, C]

For the inferred constructor, that becomes something like: StrictOptimizedSeqOps[Int, IndexedSeq, x] <: IterableOnce[x]

Here the last parameter of StrictOptimizedSeqOps is not “element type” in general; in this hierarchy it is tied to the collection self-type (the C in SeqOps[A, CC, C]). IterableOnce’s type parameter, on the other hand, is the element type.

I’d recommend opening an issue on Issues · scala/scala3 · GitHub which would be best place to discuss with the compiler team, is given somebody assigned and that also is would not be lost

I’ve created an issue: unexpected compiler behavior of Range · Issue #25730 · scala/scala3 · GitHub
The bug reporting interface is too frightening for me. I don’t know what information to provide, so I only created an issue. Hopefully someone in the compiler team can yell at me and provide the information I need to file the bug report properly.