Skip to content

warning: module attribute @my_value was set but never used when used in a specific way in a macro #10579

@dylan-chong

Description

@dylan-chong

Precheck

done

Environment

  • Elixir & Erlang/OTP versions (elixir --version):
Erlang/OTP 22 [erts-10.7.2.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]

Elixir 1.11.0-rc.0 (8e9ece0) (compiled with Erlang/OTP 21)
  • Operating system: mac os 10.14.6

Current behaviour

The following code produces a warning: module attribute @my_value was set but never used warning

defmodule Macros do
  defmacro save_this_somewhere(value) do
    Module.put_attribute(__CALLER__.module, :storage, value)
    loaded_value = Module.get_attribute(__CALLER__.module, :storage)
    loaded_value |> IO.inspect(label: "loaded_value")
    nil
  end
end

defmodule Test do
  import Macros

  @my_value 1
  save_this_somewhere(@my_value)
end

Expected behaviour

No warning


More complex version, but original version of the bug report

Not too important to look this section now that i think about it but it's a simplified architecture of my app, which triggered the warning. Just ignore this really

Current behavior

When we:

  • use a module attribute in a macro
  • save the value dynamically using Module.put_attribute
  • load the value dynamically using Module.get_attribute
  • but don't actually output any code into the compiled module that uses the module attribute
  • we get an warning: module attribute @my_value was set but never used warning.
defmodule Scratch do
  def expand_ast(ast, env) do
    Macro.prewalk(ast, fn
      {_, _, _} = node ->
        Macro.expand(node, env)

      node ->
        node
    end)
  end

  defmacro save_this_somewhere(value) do
    expanded_value = expand_ast(value, __CALLER__) # Seemingly we need this for some reason
    Module.put_attribute(__CALLER__.module, :storage, {:unquote, [], [expanded_value]})
  end

  def __after_compile__(env, _) do
    value = Module.get_attribute(env.module, :storage)

    Module.create(
      Scratch.Storage,
      quote do
        def get_stored_value() do
          unquote(Macro.escape(value, unquote: true))
        end
      end,
      __ENV__
    )

    Scratch.Storage.get_stored_value
    |> IO.inspect(label: "Stored value is")
  end
end

defmodule Test do
  import Scratch

  @my_value 1
  save_this_somewhere(@my_value)  # WE ARE TOTALLY USING @my_value

  @after_compile Scratch
end

Expected behavior

We should not get a warning. We definitely used @my_value


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions