Skip to content

Module with "use Tesla" causes runtime error in Gradualizer #168

@japhib

Description

@japhib

The Tesla library is a common HTTP client for Elixir. Part of the setup for using Tesla involves declaring a module that looks like this:

defmodule MyHTTPClient do
  use Tesla
  # define middlewares & configs
end

The use Tesla line invokes a macro that generates a sizable amount of code for this module. When that code is typechecked via mix gradient, it results in a runtime error like the following:

Typechecking files...

** (FunctionClauseError) no function clause matching in :gradualizer_lib.pick_value/2

    The following arguments were given to :gradualizer_lib.pick_value/2:

        # 1
        {:type, 0, :any, []}

        # 2
        {:env, ... [edited for brevity]

    (gradualizer) use_tesla/deps/gradualizer/src/gradualizer_lib.erl:160: :gradualizer_lib.pick_value/2
    (gradualizer) use_tesla/deps/gradualizer/src/gradualizer_lib.erl:186: :gradualizer_lib."-pick_value/2-lc$^0/1-0-"/2
    (gradualizer) use_tesla/deps/gradualizer/src/gradualizer_lib.erl:186: :gradualizer_lib."-pick_value/2-lc$^0/1-0-"/2
    (gradualizer) use_tesla/deps/gradualizer/src/gradualizer_lib.erl:186: :gradualizer_lib.pick_value/2
    (gradualizer) use_tesla/deps/gradualizer/src/gradualizer_lib.erl:196: :gradualizer_lib."-pick_value/2-lc$^2/1-2-"/2
    (gradualizer) use_tesla/deps/gradualizer/src/gradualizer_lib.erl:197: :gradualizer_lib."-pick_value/2-lc$^2/1-2-"/2
    (gradualizer) use_tesla/deps/gradualizer/src/gradualizer_lib.erl:197: :gradualizer_lib.pick_value/2
    (gradualizer) use_tesla/deps/gradualizer/src/gradualizer_lib.erl:154: :gradualizer_lib."-pick_values/2-lc$^0/1-0-"/2

The same error occurs when doing mix gradient lib/use_tesla.ex, i.e. invoking only the single file rather than the entire Mix project.

I've attempted to reproduce the issue on pure Elixir code (i.e. not macros) using Gradient's decompilation facilities in Gradient.Debug, but so far no luck. This definitely seems like an issue in Gradualizer rather than Gradient, but I'm still working on reproducing it with pure Erlang code.

I've created a PR that adds this case to Gradient as a (failing) unit test: #167

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggradualizer-issueNeeds addressing in Gradualizer

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions