Skip to content

Incorrect Typespec Generation for Fields with Custom or Parameterized Ecto Types in Strukt #20

Open
@fishtreesugar

Description

@fishtreesugar

Problem Description:

When defining a field with a custom Ecto type or a parameterized type in Strukt, the generated typespec for the field defaults to any() instead of the expected specific type (e.g., Ecto.UUID.t()). This issue may lead to less precise type checks and unexpected behaviors in development environments that rely on typespecs for static analysis or documentation purposes.

Example Code:

defmodule Foo do
  use Strukt
  
  defstruct do
    field :bar, Ecto.UUID
  end
end

Expected: The typespec for :bar should be Ecto.UUID.t().
Actual: The typespec for :bar is any().

Identified Issues:

Incorrect Handling of value_type:

The value_type in the typespec.ex function is not being correctly passed as a quoted expression. This results in the type not matching the expected case for processing.

Relevant code:

type_name = type_to_type_name(meta.value_type)

defp type_to_type_name({:__aliases__, _, parts} = ast) do

Failure in defines_type? Check:

The defines_type? function check always fails. This function, intended to verify if the current module defines a given type, is not feasible in current Elixir compiler. The docs of defines_type? say

Checks if the current module defines the given type (private, opaque or not).
This function is only available for modules being compiled.

Discussion related to this issue can be found here: Getting the @type module attribute
Relevant code:

if Kernel.Typespec.defines_type?(mod, {:t, 0}) do

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions