Skip to content

Type Inference happens too soon (and incorrectly) #21792

Open
@coreywoodfield

Description

@coreywoodfield

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions