Closed
Description
Minimized code
enum Bool {
case True
case False
}
import Bool._
enum SBool[B <: Bool] {
case STrue extends SBool[True.type]
case SFalse extends SBool[False.type]
}
import SBool._
type Not[B <: Bool] = B match {
case True.type => False.type
case False.type => True.type
}
def not[B <: Bool](b: SBool[B]): SBool[Not[B]] = b match {
case STrue => SFalse
case SFalse => STrue
}
Output
Found: (SBool.STrue : SBool[(Bool.True : Bool)])
Required: SBool[Not[B]]
where: B is a type in method not which is an alias of (Bool.False : Bool)
Expectation
I would expect the not
function to pass typechecking, but it doesn't. Interestingly if I add a implicitly[Not[B] =:= False.type]
in the first branch of not
it will not complain, so it does know that B
is actually True.type
in that branch and it will reduce Not
correctly if I ask for it.
It looks like the types are not reduced enough when checking the type of the branches against the return type of the function (not
).