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

dialyzer: add global variable binding (ERIERL-935) #7582

Closed

Conversation

kikofernandez
Copy link
Contributor

Make typed argument names and type variables global in their declaration.

Before this PR, the following example would make the linter to complain about singleton variable used:

-foo(X :: integer()) -> X.
foo(X) ->
    X.

So the linter would complain with the following message:

type variable 'X' is only used once (is unbound)

With this pull request, an argument name given to a type becomes bound globally and usable anywhere in the type specification.

@kikofernandez kikofernandez added team:VM Assigned to OTP team VM team:PS Assigned to OTP team PS bug Issue is reported as a bug types The issue is related to types labels Aug 23, 2023
@kikofernandez kikofernandez self-assigned this Aug 23, 2023
@kikofernandez kikofernandez changed the title dialyzer: add global variable binding dialyzer: add global variable binding (ERIERL-935) Aug 23, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Aug 23, 2023

CT Test Results

No tests were run for this PR. This is either because the build failed, or the PR is based on a branch without GH actions tests configured.

Results for commit d47e840

To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass.

See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally.

Artifacts

// Erlang/OTP Github Action Bot

@kikofernandez kikofernandez requested a review from bjorng August 23, 2023 11:03
@kikofernandez kikofernandez added the testing currently being tested, tag is used by OTP internal CI label Aug 23, 2023
@codeadict
Copy link
Contributor

codeadict commented Aug 28, 2023

This is really nice little quality of live improvement. It would be great to have a note on https://www.erlang.org/doc/reference_manual/typespec.html saying this is possible since OTP xx.

@kikofernandez kikofernandez force-pushed the kiko/dialyzer/erierl-935 branch from ada798a to 2c5f4ed Compare August 29, 2023 08:18
@kikofernandez kikofernandez force-pushed the kiko/dialyzer/erierl-935 branch 2 times, most recently from 46c9143 to 778fc0b Compare September 11, 2023 07:46
@kikofernandez
Copy link
Contributor Author

I have added some fixes so that (globally) bound type annotations cannot receive different types, which was something that we never took care of.

Example:

-spec id(X) -> X when
    X :: string(),
    X :: integer().   # notice that this was allowed

This PR throws a linter error if such declaration of duplicate names with different types appear.
That said, in cases where there are multiple type annotations with different types, the PR simply performs type equality of the types (such as nominal typing), and does not try to infer their structure (structural typing).

This means that the following is an error, even if their internal structure represent the same thing:

-spec id(X :: string()) -> X :: [char()].

The main reason for not detecting this type equivalence is that, if one really is going to duplicate the name, then it should be explicit that the types assigned to the same type annotation are identical.

@kikofernandez kikofernandez force-pushed the kiko/dialyzer/erierl-935 branch 3 times, most recently from 0890347 to af74d58 Compare September 11, 2023 09:37
@kikofernandez kikofernandez removed the testing currently being tested, tag is used by OTP internal CI label Sep 11, 2023
@kikofernandez kikofernandez force-pushed the kiko/dialyzer/erierl-935 branch from 9df2223 to 983c18b Compare September 13, 2023 10:27
@kikofernandez kikofernandez changed the base branch from maint to master September 13, 2023 10:27
@kikofernandez kikofernandez force-pushed the kiko/dialyzer/erierl-935 branch from 983c18b to 1718914 Compare September 13, 2023 12:46
Make typed argument names and type variables global in their
declaration. Before this PR, the following example would make the linter
to complain about singleton variable used:

```erlang
-foo(X :: integer()) -> X.
foo(X) ->
    X.
```

So the linter would complain with the following message:
```
type variable 'X' is only used once (is unbound)
```

With this pull request, an argument name given to a type becomes bound
globally and usable anywhere in the type specification.

bound type annotations cannot receive different types, which was
something that we never took care of.

Example:

```
-spec id(X) -> X when
    X :: string(),
    X :: integer().   # notice that this was allowed
```

This PR throws a linter error if such declaration of duplicate names
with different types appear. That said, in cases where there are
multiple type annotations with different types, the PR simply performs
type equality of the types (such as nominal typing), and does not try to
infer their structure (structural typing).

This means that the following is an error, even if their internal
structure represent the same thing:

```
-spec id(X :: string()) -> X :: [char()].
```

The main reason for not detecting  this type equivalence is that, if one
really is going  to duplicate the name, then it  should be explicit that
the types assigned to the same type annotation are identical.
@IngelaAndin IngelaAndin added the stalled waiting for input by the Erlang/OTP team label Sep 20, 2023
@kikofernandez kikofernandez linked an issue Sep 20, 2023 that may be closed by this pull request
@kikofernandez
Copy link
Contributor Author

We agreed that annotated variables can only be defined once. That is, the PR needs to be updated to reflect that the following is a linter error:

-spec id(X :: string()) -> X :: string().

Annotated variables can only be defined once.

with this commit, the linter rejects annotated variables that have the
same type:

```erlang
-spec id(X :: term()) -> X :: term().
```

the example above will be rejected.
@kikofernandez
Copy link
Contributor Author

Wrong naming scheme, superseeded by #7717

@IngelaAndin IngelaAndin removed the team:PS Assigned to OTP team PS label Dec 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue is reported as a bug stalled waiting for input by the Erlang/OTP team team:VM Assigned to OTP team VM types The issue is related to types
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants