Skip to content

Recursive types cause endless loop #40

@turion

Description

@turion

Discovered by @evnu.

defmodule IWantToSeeTheWorldBurn do
  @type a :: a
  @spec foo(a) :: a()
  def foo(a) do
    a
  end

  @type forest :: [tree]
  @type tree :: {integer, forest}
  @spec flatten(forest) :: [integer]
  def flatten(forest) do
    Enum.map(forest, fn {int, subforest} -> [int | flatten(subforest)] end)
    |> Enum.concat()
  end
end

The first example is a minimal example that should type check, but hangs. The second one is an actually useful thing people might do in practice.

Like in #39 , the problem is in the treatment of local types. They are evaluated directly, causing an endless loop of variable lookup. Maybe it's possible to stop this by making references to local types lazy. Instead of evaluating them, insert a closure, and only compute it when you need to compare the type spec to something else.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions