2

I am running Dialyzer with '-Woverspecs' and receive this warning:

room_channel.ex:143:
Type specification 'Elixir.Backend.RoomChannel':
testU(a) -> a when is_subtype(a,#{})
is a subtype of the success typing: 'Elixir.Backend.RoomChannel':testU(_) -> any()

with this code:

@spec testU( a ) :: a when a: %Backend.User{}
def testU(u) do
...

what I would love to do is nail down the function type with a guard so that the subtyping warning goes away and I have a precise definition of my function.

I see in the Erlang docs that -Woverspecs is not encouraged and suspect I am cutting against the grain, as the only solution I can think of is some complicated function guard...

Any ideas or pointers?

aronisstav
  • 7,755
  • 5
  • 23
  • 48
user3264325
  • 237
  • 1
  • 2
  • 9

1 Answers1

2

With -Woverspecs you get warnings when you have types that are more restrictive than what Dialyzer's own analysis can infer.

In your instance, it is probably the case that the testU function can also return a value when its argument is something different from a.

What you are probably looking for is -Wunderspecs, which produces warnings when your specification is more permissive than what Dialyzer can infer.

aronisstav
  • 7,755
  • 5
  • 23
  • 48
  • The purpose of the question is how to be more restrictive - whether it's possible or practical – user3264325 Apr 05 '16 at 16:15
  • That's what I'm saying. If you want to be warned when your specs are "loose", you should use Wunderspec – aronisstav Apr 05 '16 at 16:34
  • I want my specs to be restrictive though. For example, I can imagine a restrictive spec enforcing Ints on a function and then adding a guard which only allows Ints. But I cannot figure out how to add a guard for more complicated types – user3264325 Apr 06 '16 at 05:57
  • I.e. the Woverspec is OK by me - my aim is to get the function more restrictive. Somehow I think this isn't the intended use however, perhaps I need to readjust my expectations a little : ) – user3264325 Apr 06 '16 at 07:15
  • 1
    Dialyzer will always check/assume that calls to the function use the tightest type allowed by both the spec and its own analysis. I personally would avoid adding guards for the sake of precisely matching what your types are, unless the function is part of your "public" interface and you want to do all input sanity checking at the border. – aronisstav Apr 06 '16 at 08:21
  • I suppose the answer to the question would be how to write a guard specifically for such types as "%Backend.User{}" (if indeed possible) and then perhaps advising against this for most cases... – user3264325 Apr 06 '16 at 13:21