Skip to content

Recursive match type fails after 3rd call when using explicit type #16596

Closed
@hmf

Description

@hmf

Compiler version

Versions 3.2.0, 3.2.1-RC2 and 3.2.1

Minimized code

Code below can be found in scastie

import scala.compiletime.ops.int

type Count0[N,T] <: Tuple = (N,T) match
  case (0,_)      => EmptyTuple
  case (N,String)      => String *: Count0[int.-[N, 1], String]
  case (N,Int)         => Int *: Count0[int.-[N, 1], Int]
  case (N,Float)       => Float *: Count0[int.-[N, 1], Float]  
  case (N,Double)      => Double *: Count0[int.-[N, 1], Double]  


type Count1[N,T] <: Tuple = (N,T) match
  case (0,T)      => EmptyTuple
  case (N,String)      => String *: Count1[int.-[N, 1], String]
  case (N,Int)         => Int *: Count1[int.-[N, 1], Int]
  case (N,Float)       => Float *: Count1[int.-[N, 1], Float]  
  case (N,Double)      => Double *: Count1[int.-[N, 1], Double]  

summon[Count0[1, Int] =:= Int *: EmptyTuple ]
summon[Count0[2, Int] =:= Int *: Int *: EmptyTuple] 
summon[Count0[3, Int] =:= Int *: Int *: Int *: EmptyTuple] 
summon[Count0[4, Int] =:= Int *: Int *: Int *: Int *: EmptyTuple] 
summon[Count0[5, Int] =:= Int *: Int *: Int *: Int *: Int *: EmptyTuple] 

summon[Count1[1, Int] =:= Int *: EmptyTuple ]
summon[Count1[2, Int] =:= Int *: Int *: EmptyTuple] 
// Fail from here
summon[Count1[3, Int] =:= Int *: Int *: Int *: EmptyTuple] 
summon[Count1[4, Int] =:= Int *: Int *: Int *: Int *: EmptyTuple] 
summon[Count1[5, Int] =:= Int *: Int *: Int *: Int *: Int *: EmptyTuple] 

Output

[error] -- Error: /home/hmf/VSCodeProjects/sploty/meta/src/data/Data8.scala:380:62 -----
[error] 380 |    summon[Count1[3, Int] =:= Int *: Int *: Int *: EmptyTuple] 
[error]     |                                                              ^
[error]     |Cannot prove that Int *: Int *: data.Macros5.Count1[(2 : Int) - (1 : Int), Int] =:= (Int, Int, Int).
[error] -- Error: /home/hmf/VSCodeProjects/sploty/meta/src/data/Data8.scala:381:69 -----
[error] 381 |    summon[Count1[4, Int] =:= Int *: Int *: Int *: Int *: EmptyTuple] 
[error]     |                                                                     ^
[error]     |Cannot prove that Int *: Int *: data.Macros5.Count1[(3 : Int) - (1 : Int), Int] =:= (Int, Int, Int, Int).
[error] -- Error: /home/hmf/VSCodeProjects/sploty/meta/src/data/Data8.scala:382:76 -----
[error] 382 |    summon[Count1[5, Int] =:= Int *: Int *: Int *: Int *: Int *: EmptyTuple] 
[error]     |                                                                            ^
[error]     |Cannot prove that Int *: Int *: data.Macros5.Count1[(4 : Int) - (1 : Int), Int] =:= (Int, Int, Int, Int, Int).

Expectation

I expects both Count0 and Count1 to compile successfully. Removing the type T from Count0, to get Count1, seems to allow compilation to succeed, but I don't think it should change anything. Also, compilation only fails for 3 or or more recursive calls, which seems suspect.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions