You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hello 👋🏼 This could be ElixirLS or dialyzer related. Any help is appreciated. 🙂
Environment
Elixir & Erlang versions (elixir --version):
Project: 1.12.3 (compiled with Erlang/OTP 24)
ElixirLS compiled with Elixir 1.12.3 and erlang 24
Elixir Language Server version: v0.9.0
Operating system: macOS 12.4
Editor or IDE name (e.g. Emacs/VSCode): VSCode
Editor Plugin/LSP Client name and version: ElixirLS for VSCode, v0.9.0 (with custom compiled ElixirLS)
Current behavior
Dialyzer occasionally ignores changes to a struct type %__MODULE__{...} when dialyzing other modules. For example, if I add a new field to struct type %A{}, and then access that field in another module B, dialyzer warns that the new field "cannot exist in a map of type...".
ElixirLS logs when saving the new field to struct %A{}
MIX_ENV: test
MIX_TARGET: host
Compiling 39 files (.ex)
[Info - 10:29:59 AM] Compile took 3196 milliseconds
[Info - 10:29:59 AM] [ElixirLS WorkspaceSymbols] Updating index...
MIX_ENV: test
MIX_TARGET: host
[Info - 10:30:00 AM] Compile took 895 milliseconds
[Info - 10:30:00 AM] [ElixirLS Dialyzer] Checking for stale beam files
[Info - 10:30:00 AM] [ElixirLS WorkspaceSymbols] 5 modules need reindexing
[Info - 10:30:00 AM] [ElixirLS WorkspaceSymbols] 0 callbacks added to index
[Info - 10:30:00 AM] [ElixirLS WorkspaceSymbols] 5 modules added to index
[Info - 10:30:00 AM] [ElixirLS WorkspaceSymbols] 6 types added to index
[Info - 10:30:00 AM] [ElixirLS WorkspaceSymbols] 91 functions added to index
[Info - 10:30:00 AM] [ElixirLS Dialyzer] Found 72 changed files in 248 milliseconds
[Info - 10:30:01 AM] [ElixirLS Dialyzer] Analyzing 21 modules: [...unrelated modules omitted..., B, A]
[Info - 10:30:02 AM] [ElixirLS Dialyzer] Analysis finished in 1439 milliseconds
[Info - 10:30:02 AM] Dialyzer analysis is up to date
[Info - 10:30:03 AM] [ElixirLS Dialyzer] Writing manifest...
[Info - 10:30:04 AM] [ElixirLS Dialyzer] Done writing manifest in 2058 milliseconds.
ElixirLS logs when saving module B, which accesses the new field of type %A{}
MIX_ENV: test
MIX_TARGET: host
Compiling 38 files (.ex)
[Info - 10:30:19 AM] Compile took 3210 milliseconds
[Info - 10:30:19 AM] [ElixirLS Dialyzer] Checking for stale beam files
[Info - 10:30:19 AM] [ElixirLS WorkspaceSymbols] Updating index...
[Info - 10:30:20 AM] [ElixirLS WorkspaceSymbols] 1 modules need reindexing
[Info - 10:30:20 AM] [ElixirLS WorkspaceSymbols] 0 callbacks added to index
[Info - 10:30:20 AM] [ElixirLS WorkspaceSymbols] 0 types added to index
[Info - 10:30:20 AM] [ElixirLS WorkspaceSymbols] 1 modules added to index
[Info - 10:30:20 AM] [ElixirLS WorkspaceSymbols] 57 functions added to index
[Info - 10:30:20 AM] [ElixirLS Dialyzer] Found 41 changed files in 345 milliseconds
[Info - 10:30:20 AM] [ElixirLS Dialyzer] Analyzing 20 modules: [...unrelated modules omitted..., B]
[Info - 10:30:21 AM] [ElixirLS Dialyzer] Analysis finished in 1461 milliseconds
[Info - 10:30:22 AM] Dialyzer analysis is up to date
[Info - 10:30:23 AM] [ElixirLS Dialyzer] Writing manifest...
[Info - 10:30:24 AM] [ElixirLS Dialyzer] Done writing manifest in 1986 milliseconds.
Dialyzer warning
A key of type
'test' cannot exist in a map of type
#{'__meta__' := _,
'__struct__' := 'A',
...all fields except "test"...
}
(No seemingly relevant console messages in the VSCode devtools. Only the usual "starting client" message.)
Heavily abbreviated LSP trace when saving module A
[Trace - 10:43:00 AM] Received notification 'textDocument/publishDiagnostics'.
...for every file in the project that currently has a dialyzer warning, including module B...
[Info - 10:43:01 AM] [ElixirLS Dialyzer] Checking for stale beam files
[Trace - 10:43:01 AM] Received notification 'textDocument/publishDiagnostics'.
...for every file in the project that currently has a dialyzer warning, including module B...
[Trace - 10:43:02 AM] Received notification 'textDocument/publishDiagnostics'.
...for every file in the project that currently has a dialyzer warning, including module B...
...
[Info - 10:43:03 AM] Dialyzer analysis is up to date
[Info - 10:43:04 AM] [ElixirLS Dialyzer] Writing manifest...
[Info - 10:43:05 AM] [ElixirLS Dialyzer] Done writing manifest in 1961 milliseconds.
Heavily abbreviated LSP trace when saving module B
[Trace - 10:59:57 AM] Received notification 'textDocument/publishDiagnostics'.
...for every file in the project that currently has a dialyzer warning, including module B...
Note: no new warning, yet.
[Info - 10:59:58 AM] [ElixirLS Dialyzer] Found 41 changed files in 366 milliseconds
...
[Info - 11:00:00 AM] [ElixirLS Dialyzer] Analysis finished in 1470 milliseconds
[Trace - 11:00:00 AM] Received notification 'textDocument/publishDiagnostics'.
...for every file in the project that currently has a dialyzer warning, including module B...
Note: includes new warning.
[Info - 11:00:00 AM] Dialyzer analysis is up to date
[Info - 11:00:01 AM] [ElixirLS Dialyzer] Writing manifest...
[Info - 11:00:02 AM] [ElixirLS Dialyzer] Done writing manifest in 2093 milliseconds.
Steps to reproduce:
Anecdotally, I only encounter this issue in larger projects, at least the size of a Phoenix app with a few schemas (which unfortunately I cannot make public).
Create a module A with use Ecto.Schema and some number of fields defined.
Create a module B with a function that references %A{}, perhaps pattern matching a value.
Allow dialyzer to write out a manifest.
In A add a new field to the schema.
In B, attempt to use the new field, e.g. %A{a | new_field: "value"}
Observe dialyzer warning for the usage of the new field.
Other Notes
I usually have a canonical type t :: %__MODULE__{} defined when this occurs.
Manually deleting the BEAM file for module A in .elixir_ls/build and .elixir_ls/dialyzer_tmp, and then reloading the window, does nothing. The BEAM file is not regenerated until another change is made to A.
Deleting .elixir_ls and reloading, as you might imagine, fixes the issue.
I've experienced this issue over a wide range of Elixir/OTP versions (both the versions running the project, and the versions used to compile ElixirLS).
Expected behavior
Dialyzer should recognize the change to type %A{}.
The text was updated successfully, but these errors were encountered:
This issue will be resolved on OTP 26+ in the upcoming 0.21 release. This release switches dialyzer backend to builtin OTP incremental mode. Incremental dialyzer mode is much better at tracking dependencies. I tested it and the scenario no longer results in persisting warnings. Unfortunately it is much slower
Hello 👋🏼 This could be ElixirLS or dialyzer related. Any help is appreciated. 🙂
Environment
1.12.3
(compiled with Erlang/OTP 24)ElixirLS compiled with Elixir 1.12.3 and erlang 24
v0.9.0
Current behavior
Dialyzer occasionally ignores changes to a struct type
%__MODULE__{...}
when dialyzing other modules. For example, if I add a new field to struct type%A{}
, and then access that field in another moduleB
, dialyzer warns that the new field "cannot exist in a map of type...".ElixirLS logs when saving the new field to struct
%A{}
ElixirLS logs when saving module
B
, which accesses the new field of type%A{}
Dialyzer warning
(No seemingly relevant console messages in the VSCode devtools. Only the usual "starting client" message.)
Heavily abbreviated LSP trace when saving module
A
Heavily abbreviated LSP trace when saving module
B
Steps to reproduce:
Anecdotally, I only encounter this issue in larger projects, at least the size of a Phoenix app with a few schemas (which unfortunately I cannot make public).
A
withuse Ecto.Schema
and some number of fields defined.B
with a function that references%A{}
, perhaps pattern matching a value.A
add a new field to the schema.B
, attempt to use the new field, e.g.%A{a | new_field: "value"}
Other Notes
t :: %__MODULE__{}
defined when this occurs.A
in.elixir_ls/build
and.elixir_ls/dialyzer_tmp
, and then reloading the window, does nothing. The BEAM file is not regenerated until another change is made toA
..elixir_ls
and reloading, as you might imagine, fixes the issue.Expected behavior
Dialyzer should recognize the change to type
%A{}
.The text was updated successfully, but these errors were encountered: