Open
Description
Compiler version
3.5.1
Minimized code
trait Trait {
type T <: Tuple
val t: T
def foo[A](f: Tuple.Fold[T, A, Function1]): A = {
def inner[TI <: Tuple](t: TI, fOrA: Tuple.Fold[TI, A, Function1]): A = {
type Head = Tuple.Head[TI]
type Tail = Tuple.Tail[TI]
type F = Head => Tuple.Fold[Tail, A, Function1]
(t, fOrA) match {
case (EmptyTuple, a: A @unchecked) => a
case ((head: Head @unchecked) *: (tail: Tail @unchecked), f: F @unchecked) => inner(tail, f(head))
case _ => throw new MatchError("It should be impossible to get here")
}
}
inner(t, f)
}
}
object Object extends Trait {
type T = (Int, String)
val t = (1, "foo")
// doesn't compile: infers A to be Nothing
val listNoType = foo { i => s => List.fill(i)(s) }
// compiles
val typedList: List[String] = foo { i => s => List.fill(i)(s) }
// compiles
val typedCall = foo[List[String]] { i => s => List.fill(i)(s) }
}
Output
-- [E007] Type Mismatch Error: .../Test.scala:26:47
26 | val listNoType = foo { i => s => List.fill(i)(s) }
| ^^^^^^^^^^^^^^^
| Found: List[String]
| Required: Nothing
|----------------------------------------------------------------------------
| Explanation (enabled by `-explain`)
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
| Tree: List.fill[String](i)(s)
| I tried to show that
| List[String]
| conforms to
| Nothing
| but none of the attempts shown below succeeded:
|
| ==> List[String] <: Nothing = false
|
| The tests were made under a constraint with:
| uninstantiated variables: A
| constrained types: [A](f: Tuple.Fold[Object.T, A, [T1, R] =>> T1 => R]): A
| bounds:
| A
| ordering:
| co-deps:
| contra-deps:
----------------------------------------------------------------------------
one error found
Expectation
I would expect the type of A
to be inferred as List[String]
without explicit type annotations, as that is what the function returns. Instead, the compiler infers A
as Nothing
and then expects the function to return Nothing