Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type Inference happens too soon (and incorrectly) #21792

Open
coreywoodfield opened this issue Oct 16, 2024 · 0 comments
Open

Type Inference happens too soon (and incorrectly) #21792

coreywoodfield opened this issue Oct 16, 2024 · 0 comments

Comments

@coreywoodfield
Copy link

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

@coreywoodfield coreywoodfield added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Oct 16, 2024
@dwijnand dwijnand added itype:enhancement area:infer and removed itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Oct 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants