elixir-lang / elixir

Elixir is a dynamic, functional language for building scalable and maintainable applications
https://elixir-lang.org/
Apache License 2.0
24.61k stars 3.38k forks source link

"No function clause matchin in `:elixir_utils.get_line/1`" since 1c19c60abbb8e45479c540024becb8a1104d09fd #13948

Closed NobbZ closed 1 month ago

NobbZ commented 1 month ago

Elixir and Erlang/OTP versions

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

Elixir 1.18.0-dev (compiled with Erlang/OTP 27)
bisection log ``` git bisect start # status: waiting for both good and bad commits # bad: [f2d8064121397d3d628defc762d966fbea71fc42] Do not halt streams twice in Stream.transform/5, closes #13944 git bisect bad f2d8064121397d3d628defc762d966fbea71fc42 # status: waiting for good commit(s), bad commit known # good: [809971a69065ce1c14c0a63f16caa4085163b0cb] Remove redundant warnings git bisect good 809971a69065ce1c14c0a63f16caa4085163b0cb # bad: [8c78a0ea9c846256d08190082814f55b5d5aa032] Mark defguard expansion outside of guards as generated git bisect bad 8c78a0ea9c846256d08190082814f55b5d5aa032 # good: [418ab7618aee7c41bd1b19eeddb7af7c25bb0aa7] Avoid warnings during parser_test.exs suite git bisect good 418ab7618aee7c41bd1b19eeddb7af7c25bb0aa7 # good: [f2565849b1e3f9df0ee388da94dd025058b43dee] Enable warnings_as_errors for Erlang only on latest git bisect good f2565849b1e3f9df0ee388da94dd025058b43dee # bad: [e6857d5af348a1a2bf6eab3831f01448691a1a99] Store record metadata in the documentation chunk (#13939) git bisect bad e6857d5af348a1a2bf6eab3831f01448691a1a99 # bad: [1c19c60abbb8e45479c540024becb8a1104d09fd] Add source and behaviour information to docs chunk metadata (#13914) git bisect bad 1c19c60abbb8e45479c540024becb8a1104d09fd # first bad commit: [1c19c60abbb8e45479c540024becb8a1104d09fd] Add source and behaviour information to docs chunk metadata (#13914) ```

Operating system

Linux

Current behavior

A handcrafted AST fails with the following unhelpful error.

A simple change made the compilation succeed.

== Compilation error in file lib/a_file.ex ==
** (FunctionClauseError) no function clause matching in :elixir_utils.get_line/1

    The following arguments were given to :elixir_utils.get_line/1:

        # 1
        nil

    (elixir 1.18.0-dev) elixir_utils.erl:169: :elixir_utils.get_line/1
    (stdlib 6.1.2) lists.erl:2146: :lists.foldl/3

The change making the build suceed is this:

diff --git a/a_file.ex b/a_file.ex
index c85f402af..9a54f575f 100644
--- a/a_file.ex
+++ b/a_file.ex
@@ -79,7 +79,7 @@ defmodule AFile do

     [
       quote bind_quoted: [a: a, c: c, t: t] do
-        @type unquote({t, nil, []}) ::
+        @type unquote({t, [], []}) ::
                 unquote(
                   c
                   |> Enum.map_join(" | ", &inspect/1)

I was unable to produce a similarily formed reproducer, so it is very likely that in the surrounding context more relevant things are happening.

Expected behavior

A nicer error or no error at all (the snippet worked with 1.16 and 1.17)

josevalim commented 1 month ago

The error is 100% correct in this case. unquote({t, nil, []}) is not a valid AST, it will fail in weird place for different reasons. And while we can improve the compiler to provide better reports, it is often not as trivial. :) I will try to improve it here.