Ecto: Ecto.Schema and typespec issues in Elixir 1.10

Created on 22 Feb 2020  路  1Comment  路  Source: elixir-ecto/ecto

Environment

  • Elixir version (elixir -v): 1.10.1
  • Database and version (PostgreSQL 9.4, MongoDB 3.2, etc.): N/A, but Postgres 12.2
  • Ecto version (mix deps): 3.3.3
  • Database adapter and version (mix deps): N/A, but ecto_sql, 3.3.4
  • Operating system: Mac OS Mojave

Current behavior

I think this is an Ecto issue with the newest minor version of Elixir, but in Elixir 1.10.1, I can't use the schema types in my typespecs. This is not an issue on previous versions of Elixir.

Using this code (note the spec on what would be line 12):

defmodule MyApp.User do
  use Ecto.Schema
  import Ecto.Changeset
  alias __MODULE__

  schema "users" do
    field :email, :string
    field :password, :string
    timestamps()
  end

  @spec changeset(User.t(), map()) :: Ecto.Changeset.t()
  def changeset(%User{} = user \\ %User{}, attrs) do
    user
    |> cast(attrs, [:email, :password])
  end
end

Paste in an iex session with Elixir 1.10.1 (erlang 22.2.6, Ecto 3.3.3), and you'll get this error:

** (CompileError) iex:12: type t/0 undefined (no such type in MyApp.User)
    (elixir 1.10.1) lib/kernel/typespec.ex:898: Kernel.Typespec.compile_error/2
    (stdlib 3.11.2) lists.erl:1354: :lists.mapfoldl/3
    (elixir 1.10.1) lib/kernel/typespec.ex:950: Kernel.Typespec.fn_args/5
    (elixir 1.10.1) lib/kernel/typespec.ex:936: Kernel.Typespec.fn_args/6
    (elixir 1.10.1) lib/kernel/typespec.ex:377: Kernel.Typespec.translate_spec/8
    (stdlib 3.11.2) lists.erl:1354: :lists.mapfoldl/3
    (elixir 1.10.1) lib/kernel/typespec.ex:229: Kernel.Typespec.translate_typespecs_for_module/2
    (elixir 1.10.1) src/elixir_erl_compiler.erl:12: anonymous fn/3 in :elixir_erl_compiler.spawn/2

Paste that same code in an iex session with Elixir 1.9.1 (erlang 22.1.3, Ecto 3.1.7), and it compiles:

{:module, MyApp.User,
 <<70, 79, 82, 49, 0, 0, 15, 84, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 1, 248,
   0, 0, 0, 51, 17, 69, 108, 105, 120, 105, 114, 46, 77, 121, 65, 112, 112, 46,
   85, 115, 101, 114, 8, 95, 95, 105, 110, ...>>, {:changeset, 2}}

Expected behavior

I expect to be able to use schemas in Elixir 1.10 like I used them in 1.9. Again, this may be an issue with how Elixir changes something in Kernel, but since I do define types in the schema definition, I do not expect to have to define them again (i.e. @type t :: %__MODULE__{...).

Most helpful comment

Hi @davelively14!

Ecto does not define typespecs for you (and it never has). So the code above did not ever work, it is just that Elixir v1.10 started to error if you point to a typespec in the same module that does not exist. You have to define @type t :: %User{} yourself, preferably with proper typespecs inside. :)

>All comments

Hi @davelively14!

Ecto does not define typespecs for you (and it never has). So the code above did not ever work, it is just that Elixir v1.10 started to error if you point to a typespec in the same module that does not exist. You have to define @type t :: %User{} yourself, preferably with proper typespecs inside. :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

a12e picture a12e  路  4Comments

atsheehan picture atsheehan  路  4Comments

fuelen picture fuelen  路  3Comments

sntran picture sntran  路  4Comments

ericmj picture ericmj  路  3Comments