Right, and this is why I think Jose is arguing that this is a job for Dialyzer. The only way to know that two specs are duplicate is if they are logically duplicate. Elixir does not know about the logic of specs today, that's dialyzer's job. eg:
@type one :: 1
@spec foo(1) :: "one"
@spec foo(one) :: "one"
This is logically duplicate, but not AST level duplicate. You could special case things I suppose at the Elixir level and only care about AST level duplicates but this leaves out a lot of cases people probably care about:
@spec age(user :: %User{}) :: integer
@spec age(current_user :: %User{}) :: integer
Here we have specs that are basically duplicates, but there is a difference in the argument name.