Description
This snippet of Elixir:
String.slice(str, 0, -1)
Started with slice/2 form of this call, but swapped to slice/3 to confirm the error wasn't being generated by the Elixir range.
Raises the following exception
** (EXIT from #PID<0.95.0>) an exception was raised:
** (FunctionClauseError) no function clause matching in ElixirScript.Translate.Form.compile/2
lib/elixir_script/passes/translate/form.ex:28: ElixirScript.Translate.Form.compile(&Inspect.inspect/2, %{anonymous_fn: false, function: {:struct, nil}, in_guard: false, module: Inspect.Opts, pid: #PID<0.200.0>, vars: %{}})
lib/elixir_script/passes/translate/form.ex:16: ElixirScript.Translate.Form.compile!/2
lib/elixir_script/passes/translate/forms/map.ex:37: anonymous fn/2 in ElixirScript.Translate.Forms.Map.compile/2
(elixir 1.10.4) lib/enum.ex:1396: Enum."-map/2-lists^map/1-0-"/2
(elixir 1.10.4) lib/enum.ex:1396: Enum."-map/2-lists^map/1-0-"/2
lib/elixir_script/passes/translate/forms/map.ex:32: ElixirScript.Translate.Forms.Map.compile/2
lib/elixir_script/passes/translate/form.ex:16: ElixirScript.Translate.Form.compile!/2
lib/elixir_script/passes/translate/function.ex:170: ElixirScript.Translate.Function.compile_block/2
Modified Transcript.Form.compile! as follows:
@spec compile!(any, map) :: ESTree.Node.t()
def compile!(ast, state) do
{js_ast, _} = compile(ast, state)
js_ast
rescue
e -> Logger.debug inspect({:compile!, ast, state})
raise RuntimeError, message: inspect({"compile!/2", e})
end
Which revealed the following debugging info:
03:45:21.580 [debug] {:compile!, &Inspect.inspect/2, %{anonymous_fn: false, function: {:struct, nil}, in_guard: false, module: Inspect.Opts, pid: #PID<0.200.0>, vars: %{}}}
03:45:21.696 [debug] {:compile!, {:%{}, [line: 74], [struct: Inspect.Opts, base: :decimal, binaries: :infer, char_lists: :infer, charlists: :infer, custom_options: [], inspect_fun: &Inspect.inspect/2, limit: 50, pretty: false, printable_limit: 4096, safe: true, structs: true, syntax_colors: [], width: 80]}, %{anonymous_fn: false, function: {:struct, nil}, in_guard: false, module: Inspect.Opts, pid: #PID<0.200.0>, vars: %{}}}
Thoughts
Not too familiar with this codebase, but I'm working from the premise that inspect_fun: &Inspect.inspect/2
might be malformed, for it to be promoted into the ast
parameter of compile!
.