Skip to content

Difficult to rationalize cyclic dependency checks. #14535

Closed
@ityonemo

Description

@ityonemo

Elixir and Erlang/OTP versions

Erlang/OTP 27 [erts-15.2.7] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [jit:ns]

Elixir 1.18.3 (compiled with Erlang/OTP 27)

Operating system

linux (but this is a compiler issue)

Current behavior

a.ex:

defmodule A do
  defmacro __using__(_), do: :ok

  def fun(%B{}), do: :ok
end

b.ex:

defmodule B do
  use A
  defstruct []
end

Causes a cylic dependency error. Error message:

== Compilation error in file lib/b.ex ==
** (CompileError) deadlocked waiting on module A
    (elixir 1.18.3) src/elixir_dispatch.erl:261: :elixir_dispatch.expand_quoted/7

== Compilation error in file lib/a.ex ==
** (CompileError) deadlocked waiting on struct B


Compilation failed because of a deadlock between files.
The following files depended on the following modules:

  lib/b.ex => A
  lib/a.ex => B

Ensure there are no compile-time dependencies between those files and that the modules they reference exist and are correctly named

if the matching is done inside of the function body, this can be used as an escape hatch to avoid struct field type checking:

defmacrop struct_of(module, fields \\ []) do
  fields = [__struct__: module | fields]
  quote do
    %{unquote_splicing(fields)}
  end
end

but this does not work for function header matching, of course it could be in a separate module and with a require statement it works.

Expected behavior

suggested improvements:

option 1: Add "avoids type checking macro" to the kernel.

option 2: memoize all struct patterns across compiled files and defer struct field checking till a later stage in the compiler pipeline.

option 3: improve the error message to declare the nature of the cyclic dependency and provide suggestions to fix

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions