gradient icon indicating copy to clipboard operation
gradient copied to clipboard

Unclear cyclic dependency warning

Open eksperimental opened this issue 3 years ago • 4 comments

Running Gradient in this project. https://github.com/eksperimental/beam_meta/tree/1de809c6266d9ee877354f8c2b6dd32adc7d4bf9

lib/beam_meta/compatibility/otp_elixir.ex: The pattern %{version: elixir_version, version_requirement: elixir_requirement, otp_versions: otp_versions} on line 138 doesn't have the type any()

lib/beam_meta/compatibility/otp_elixir.ex: The type spec bounded_fun((deep_list -> list()), [{:type, 0, :constraint, [{:atom, 0, :is_subtype}, [{:var, 0, :deep_list}, {:type, 0, :list, [{:type, 0, :union, [{:type, 0, :any, []}, {:var, 0, :deep_list}]}]}]]}]) has a cyclic dependency in variable deep_list

I assume these two are unrelated. If they are, the second warning gives no clue where this happens.

eksperimental avatar Feb 09 '22 04:02 eksperimental

Thanks for the report, @eksperimental :+1: Both of these need some research on our side.

erszcz avatar Feb 09 '22 09:02 erszcz

I also have many reports like:

The pattern %{context: %{current_user: current_user}} on line 57 doesn't have the type any()

It seems that when we use pattern matching on a function without a @spec (like every private functions), the default any() raises an error for our "typed" map in the pattern.

I thought that the pattern match would "define" a typing like in TypeScript:

image

simonprev avatar Feb 17 '22 20:02 simonprev

@simonprev Indeed, your diagnosis is correct. Thanks for looking into it :+1:

I thought that the pattern match would "define" a typing like in TypeScript.

I think that's a reasonable path forward - we're just not there yet :)

We've run into this problem in another issue, let me quote my comment also here:

lib/project/auth.ex: The pattern %Project.Accounts.User{role: "admin"} on line 23 doesn't have the type any()

These stem from functions with no specs using pattern matching in their heads. In other words, Gradient assumes argument type any() if there's no spec. The function matches on %User{role: "admin"} as one of the params - this obviously isn't of type any(). Therefore, we get the above warning. This is a common pattern both in Erlang and Elixir, so I imagine inference of such more specific specs would be handy, but currently the only way to get rid of them is to add specs to such functions.

erszcz avatar Feb 18 '22 09:02 erszcz

I have investigated it and tracked down what is causing this, it is reported in #129.

eksperimental avatar Sep 21 '22 15:09 eksperimental