Skip to content

IEx crash on missing struct #12113

@starkeepers

Description

@starkeepers

Elixir and Erlang/OTP versions

Elixir 1.13.4 (compiled with Erlang/OTP 25)

Operating system

Ubuntu 20.04.3

Current behavior

An accidental edit led to IEx telling me to Please report this bug, so I'm adding it here although it is a bizarre edge case.

Load the following trivial module into IEx:

defmodule D1 do
  defstruct [:title]
  def d(), do: %D1{}
end

Now (accidentally) remove the defstruct1 line:

defmodule D1 do
  def d(), do: %D1{}
end

and r D1 in IEx. The outcome:

** (EXIT from #PID<0.1123.0>) shell process exited with reason: an exception was raised:
    ** (Module.Types.Error) found error while checking types for D1.d/0

def d() do
  %D1{title: nil}
end

Please report this bug: https://github.com/elixir-lang/elixir/issues

** (UndefinedFunctionError) function D1.__struct__/0 is undefined or private
        D1.__struct__()
        (elixir 1.13.4) lib/module/types/of.ex:131: Module.Types.Of.struct/3
        (elixir 1.13.4) lib/module/types/expr.ex:193: Module.Types.Expr.of_expr/4
        (elixir 1.13.4) lib/module/types.ex:63: Module.Types.warnings_from_clause/6
        (elixir 1.13.4) lib/module/types.ex:22: anonymous fn/8 in Module.Types.warnings/5
        (elixir 1.13.4) lib/enum.ex:4086: Enum.flat_map_list/2
        (elixir 1.13.4) lib/module/parallel_checker.ex:201: Module.ParallelChecker.check_module/3
        (elixir 1.13.4) lib/module/parallel_checker.ex:68: anonymous fn/5 in Module.ParallelChecker.spawn/3
[error] Process #PID<0.1146.0> raised an exception

Expected behavior

Compiling the defective a second time with r D1 leads to the expected behavior, a compilation error but no crash:

== Compilation error in file lib/d1.ex ==
** (CompileError) lib/d1.ex:9: D1.__struct__/1 is undefined, cannot expand struct D1. Make sure the struct name is correct. If the struct name exists and is correct but it still cannot be found, you likely have cyclic module usage in your code
    lib/d1.ex:9: (module)
    (stdlib 4.0.1) lists.erl:1355: :lists.foldl_1/3
    (elixir 1.13.4) lib/kernel/parallel_compiler.ex:347: anonymous fn/5 in Kernel.ParallelCompiler.spawn_workers/7
** (MatchError) no match of right hand side value: {:error, [{"/tmp/d/lib/d1.ex", 9, "** (CompileError) lib/d1.ex:9: D1.__struct__/1 is undefined, cannot expand struct D1. Make sure the struct name is correct. If the struct name exists and is correct but it still cannot be found, you likely have cyclic module usage in your code\n    lib/d1.ex:9: (module)\n    (stdlib 4.0.1) lists.erl:1355: :lists.foldl_1/3\n    (elixir 1.13.4) lib/kernel/parallel_compiler.ex:347: anonymous fn/5 in Kernel.ParallelCompiler.spawn_workers/7\n"}], [{"/tmp/d/lib/d1.ex", 7, "redefining module D1 (current version defined in memory)"}]}
    (iex 1.13.4) lib/iex/helpers.ex:453: IEx.Helpers.r/1

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