Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a type hint system #10303

Merged
merged 6 commits into from
Sep 6, 2020
Merged

Introduce a type hint system #10303

merged 6 commits into from
Sep 6, 2020

Conversation

josevalim
Copy link
Member

Instead of trying to assuming that a certain usage of a type is the correct one, we keep the unification message agnostic and add hints to the message.

Each message may have multiple hints, as they are computed alongside the trace. The traces are also reversed in order to keep the order they are added.

Here is how the new warning for dot access look like:

warning: incompatible types:

    map() !~ atom()

in expression:

    # a.ex:4
    module.__struct__

where "module" was given the type map() (due to calling var.field) in:

    # a.ex:4
    module.__struct__

where "module" was given the type atom() in:

    # a.ex:3
    %module{}

HINT: "var.field" (without parentheses) implies "var" is a map() while
"var.fun()" (with parentheses) implies "var" is an atom()

Conflict found at
  a.ex:4: A.a/1

And here is the hint for binaries:

warning: incompatible types:

    binary() !~ integer()

in expression:

    # a.ex:2
    <<foo>>

where "foo" was given the type binary() in:

    # a.ex:2
    is_binary(foo)

where "foo" was given the type integer() in:

    # a.ex:2
    <<foo>>

HINT: all expressions given to binaries are assumed to be of type
integer unless said otherwise. For example, <<expr>> assumes "expr" 
is an integer. Pass a modifier, such as <<expr::float>> or <<expr::binary>>, 
to change the default behaviour.

Conflict found at
  a.ex:2: A.a/1

Instead of trying to assuming that a certain usage of
a type is the correct one, we keep the unification message
agnostic and add hints to the message.

Each message may have multiple hints, as they are computed
alongside the trace.

Here is how the new warning for dot access look like:

    warning: incompatible types:

        map() !~ atom()

    in expression:

        # a.ex:4
        module.__struct__

    where "module" was given the type map() (due to calling var.field) in:

        # a.ex:4
        module.__struct__

    where "module" was given the type atom() in:

        # a.ex:3
        %module{}

    HINT: "var.field" (without parentheses) implies "var" is a map() while
    "var.fun()" (with parentheses) implies "var" is an atom()

    Conflict found at
      a.ex:4: A.a/1
@@ -782,17 +782,17 @@ defmodule Module.CheckerTest do
in expression:

# a.ex:2
<<var::integer(), var::binary()>>
<<..., var::binary()>>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the removal of the uninteresting parts 👍

@josevalim josevalim merged commit 8f95fda into master Sep 6, 2020
@josevalim josevalim deleted the jv-type-hints branch September 6, 2020 14:58
ma2gedev added a commit to ma2gedev/power_assert_ex that referenced this pull request Dec 20, 2020
```
HINT: "var.field" (without parentheses) implies "var" is a map() while "var.fun()" (with parentheses) implies "var" is an atom()
```

related pull request: elixir-lang/elixir#10303
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants