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

Type of nested map creation expression is not inferred correctly #378

Closed
erszcz opened this issue Feb 7, 2022 · 1 comment · Fixed by #457
Closed

Type of nested map creation expression is not inferred correctly #378

erszcz opened this issue Feb 7, 2022 · 1 comment · Fixed by #457
Labels

Comments

@erszcz
Copy link
Collaborator

erszcz commented Feb 7, 2022

@eksperimental in esl/gradient#30 reports an interesting bug, which I minimised to the following Elixir example:

iex(3)> Gradient.type_check_file("_build/dev/lib/beam_langs_meta_data/ebin/Elixir.Test.beam")
lib/test.ex: The map on line 10 is expected to have type %{required(:inner) => %{required(:a) => 5}} but it has type %{required(:inner) => %{optional(:a) => 5}}
8   @spec g :: %{inner: %{a: 5}}
9   def g do
10     %{inner: %{a: 5}}
11  end

iex(1)> Gradient.Debug.print_erlang(Test)
-module('Elixir.Test').

-spec g() -> #{inner := #{a := 5}}.
g() -> #{inner => #{a => 5}}.

It seems that nested map creation expressions don't get their type inferred properly, i.e. the associations are inferred as optional, whereas after map creation we know they must be present in the resulting map, therefore they should be inferred as required. One idea is that we might need some recursion in update_map_type, but this has to be confirmed.

@erszcz erszcz added the bug label Feb 7, 2022
@zuiderkwast
Copy link
Collaborator

I didn't think there would be any inference happening here, but now I see that there's actually some inference happening.

In to_type_check_expr_in we have a type ResTy (the map type from the spec) and an expression which is checked against this type.

The problem with inferring the type of the map expression and then checking if it's a subtype of the expected type is that the map expression can contain any kind of expression below it. It'd be better if we can call type_check_expr_in recursively on the map keys and values against their corresponding key and value types.

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

Successfully merging a pull request may close this issue.

2 participants