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

Handling aliases correctly #32

Closed
TheGeorge opened this issue Sep 24, 2018 · 4 comments
Closed

Handling aliases correctly #32

TheGeorge opened this issue Sep 24, 2018 · 4 comments

Comments

@TheGeorge
Copy link

Currently the following code

-spec test() -> {atom1, atom2} | atom3.
test() ->
    case f() of
        {atom1, _} = X -> X;
        _ -> atom3
    end.

-spec f() -> {atom1, atom2} | atom4.
f() ->
    {atom1, atom2}.

gives me the error

The variable 'X' on line 7 has type {atom1, atom2} | atom4 but is expected to have type {atom1, atom2} | atom3
@josefs
Copy link
Owner

josefs commented Sep 25, 2018

Gradualizer currently doesn't do type refinement based on patterns. So even though X is bound to a pattern which can only have the type {atom1, atom2}, Gradualizer doesn't detect this. X is given the type of the whole pattern.

I'd like Gradualizer to do more type refinement in the future, but I'm afraid it's not at the top of my todo list. If you disagree and think that this is a superimportant feature, please let me know. I might be persuaded to bump it up the list.

@zuiderkwast
Copy link
Collaborator

Shouldn't solving the constraints be enough in this case? It's not implemented, but from the pattern {atom1, _} = X, there should be a constraint X :: {atom1, _} which can be used to eliminate atom4.

@josefs
Copy link
Owner

josefs commented Sep 26, 2018

@zuiderkwast, your suggestion implies that we can infer the type of the pattern. I suppose we could attempt to do that, but it's not something we currently do.

@josefs
Copy link
Owner

josefs commented Oct 3, 2018

I just want to mention that I've come across this problem myself now. I didn't write the code but I've type checked a few modules which use this idiom.

zuiderkwast added a commit that referenced this issue Dec 11, 2018
Recursively handled in tuples. Only when there are no guards.
Annotated types are also handled.

Also limit upper bounds on varibles bound in patterns on the form
`Pattern1 = Pattern2` by infering types from patterns.

Fixes #91
Fixes #32
zuiderkwast added a commit that referenced this issue Dec 11, 2018
Singleton integers, atoms and nil are used for type refinement. Recursively
type refinement in tuples. Only when there are no guards. Annotated types
are also handled.

Also limit upper bounds on "aliases" i.e. variables bound in 'match' patterns
on the form `Pattern1 = Pattern2` by inferring types from the patterns.

Two extra types are returned by add_type_pat/4.

Fixes #91
Fixes #32
zuiderkwast added a commit that referenced this issue Dec 18, 2018
Singleton integers, atoms and nil are used for type refinement. Recursively
type refinement in tuples. Only when there are no guards. Annotated types
are also handled.

Also limit upper bounds on "aliases" i.e. variables bound in 'match' patterns
on the form `Pattern1 = Pattern2` by inferring types from the patterns.

Two extra types are returned by add_type_pat/4.

Fixes #91
Fixes #32
berbiche pushed a commit to berbiche/Gradualizer that referenced this issue Feb 9, 2021
Singleton integers, atoms and nil are used for type refinement. Recursively
type refinement in tuples. Only when there are no guards. Annotated types
are also handled.

Also limit upper bounds on "aliases" i.e. variables bound in 'match' patterns
on the form `Pattern1 = Pattern2` by inferring types from the patterns.

Two extra types are returned by add_type_pat/4.

Fixes josefs#91
Fixes josefs#32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants