`on_mount` called from within `@before_compile` doesn't execute. Defect or on purpose?

Hey,

so I had this situation:

defmodule HelloWeb.Foo do
  use HelloWeb, :live_view
  use HelloWeb.Bar

  on_mount(__MODULE__)

  def on_mount(:default, _params, _session, socket) do
    dbg("on_mount Foo")
    {:cont, socket}
  end
end

defmodule HelloWeb.Bar do
  defmacro __using__(_) do
    quote do
      on_mount(HelloWeb.Bar)
    end
  end

  def on_mount(:default, _params, _session, socket) do
    dbg("on_mount Bar")
    {:cont, socket}
  end
end

Giving me the debug output:

[lib/hello_web/live/bar.ex:9: HelloWeb.Bar.on_mount/4]
"on_mount Bar" #=> "on_mount Bar"
[lib/hello_web/live/foo.ex:8: HelloWeb.Foo.on_mount/4]
"on_mount Foo" #=> "on_mount Foo"

But I would like the on_mount in Bar to be called last, so I modified it like this:

defmodule HelloWeb.Bar do
  defmacro __using__(_) do
    quote do
      @before_compile(HelloWeb.Bar)
    end
  end

  defmacro __before_compile__(_env) do
    quote do
      on_mount(HelloWeb.Bar)
    end
  end

  def on_mount(:default, _params, _session, socket) do
    dbg("on_mount Bar")
    {:cont, socket}
  end
end

With the debug output:

[(hello 0.1.0) lib/hello_web/live/foo.ex:8: HelloWeb.Foo.on_mount/4]
"on_mount Foo" #=> "on_mount Foo"

Raising my question:
Why is Bar.on_mount not called?

I’m aware that I could:

  1. switch places of use HelloWeb.Bar and on_mount(__MODULE__)
  2. call on_mount(HelloWeb.Bar) from Foo after on_mount(__MODULE__)
  3. use the mount callback in HelloWeb.Bar.__using__, which is called after all the on_mount calls.

All have there own drawbacks.