Inlay hints: variable types + parameter names (TypeHints facade)#1266
Draft
lukaszsamson wants to merge 27 commits into
Draft
Inlay hints: variable types + parameter names (TypeHints facade)#1266lukaszsamson wants to merge 27 commits into
lukaszsamson wants to merge 27 commits into
Conversation
Recovers the experimental LSP textDocument/inlayHint provider that renders inferred variable types inline (InlayHintKind.type) on binding occurrences (LHS of a match). Reconstructed from the 2025-10-02 design/implementation session after the original branch was lost. - New ElixirLS.LanguageServer.Providers.InlayHints (phase 1: variable type hints, with range/variable/label/depth budgets and elixirLS.inlayHints.variableTypes.enabled) - Wire textDocument/inlayHint handler and advertise inlay_hint_provider capability - Tests for variable hints, settings toggle, binding-vs-read positions - Point :elixir_sense at the elixir-types type engine (local path dep) in all 3 apps - INLINE_HINTS.md design doc + INLAY_HINTS_RECOVERY.md status notes Known incomplete: variable-hint extraction returns empty against the current elixir_sense branch (needs debugging); call parameter-name hints designed but not yet implemented. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adapts the provider to the new type-engine API instead of rendering shapes
locally.
- Delete the local render_shape/2; render via TypePresentation.render_hint/2,
which resolves VarInfo.type through Binding (descriptor fallback), stays
thunk-free, and skips uninformative term()/none()/unknown types.
- Binding occurrence = head of VarInfo.positions; reads (tail) are not
annotated. Each destructured var is its own VarInfo, so every bound name is
covered. showOnlyBindings=false opts into annotating reads.
- Labels carry the leading colon (": integer()"); provider keeps only the
max-length truncation.
- Settings: inlayHints.variableTypes.{enabled, showOnlyBindings, maxLength}.
- Tests assert real engine output (integer/binary/tuple/map/list literals,
%URI{} struct, fn arrow), plus suppression, binding-vs-read, settings,
truncation. 14 tests, all passing against the elixir-types engine.
Richer precision (branch-narrowing, map/union, precise struct field types)
remains gated on the type engine and is intentionally not addressed here.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implements the second inlay-hint case from the design: parameter names rendered before each argument of a function call (e.g. `Map.put(map: m, key: :k, value: v)`), kind `parameter`. - Collect calls from the parsed AST (Parser.Context.ast), excluding def-heads and special forms/operators. - Resolve MFA via Introspection.actual_mod_fun/6; parameter names from Metadata.get_function_signatures/3 (local) or Introspection.get_signatures/2 (remote/stdlib), selecting the arity-matching signature (defaults handled). - Compute per-argument columns from the Elixir tokenizer by matching the call's (…) and splitting top-level commas — robust against commas inside strings/sigils and fn/do blocks. - Pipes shift the parameter window by one (piped value is implicit). - Suppress an argument hint when its source text already equals the param name. - Setting inlayHints.parameterNames.enabled (default true). 21 tests, all passing against the elixir-types engine. Richer type precision (narrowing/union/struct-field types) remains engine-gated and untouched here. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ordering Addresses review findings: - P1: dynamic remote-call receivers (`mod.put(...)`, `factory().call(...)`) no longer crash the request. `module_of/1` returns `:error` for non-atom/alias receivers and the call is skipped; per-call resolution is also wrapped so one bad call can't fail the whole request. - P2: filter calls to the requested line range *before* resolution/introspection /tokenizing, so viewport requests in large files don't process every call. - P2: the server `textDocument/inlayHint` handler now skips non-Elixir files (.ex/.exs or language_id == "elixir"), mirroring sibling providers. - P3: merge type + parameter hints and sort by position before the cap, so neither category starves the other and output is in document order. Tests: dynamic-receiver no-crash, range filtering, document-order (24 total, all passing). Updated the recovery doc (stale "designed only"/engine-gated claims removed; guardrails and counts corrected). List rendering now reflects the upgraded engine (`[1 | 2 | 3]`). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mirrors the elixir-types changes elixir_sense made in its own providers, on the elixir-ls forks: - Hover: ElixirLS.LanguageServer.Providers.Hover.Docs now renders a variable's inferred type via TypePresentation.render_hint/2; hover.ex shows it as a "### Type" section. - Completion: ElixirLS.Utils.CompletionEngine.match_map_fields/5 falls back to the inferred field type (TypePresentation.render/1) for map/struct fields without a declared @type, so field completions surface e.g. %{asdf: term()} or %MyStruct{}. Bare term()/none() are suppressed to avoid noise (a small, deliberate divergence from elixir_sense). Tests: new hover "variable with inferred type"; updated completion_engine field-completion expectations to the now-richer type_spec values. All affected suites green (hover, completion provider, completion_engine, inlay). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Turn on the native Module.Types backend (use_elixir_types) in config/config.exs
so inlay hints, hover, and completion use set-theoretic type inference. On by
default; ELIXIR_LS_TYPE_INFERENCE=false disables it for A/B testing. Falls back
to the custom engine automatically when Module.Types is unavailable (< 1.19).
Update inlay-hint test expectations to native-mode rendering:
- tuple {:ok, 1} -> {:ok, integer()}
- list [1, 2, 3] -> [integer()]
- fn arg/return types inferred (float() | integer()); assert the stable prefix
since the full arrow can exceed maxLength.
All affected suites green with native mode on (hover, completion provider,
completion_engine, inlay).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`x = 1`, `s = "foo"`, `t = {:ok, 1}`, `m = %{…}`, `l = […]`, `%S{…}` render a
type that merely restates the source — pure noise. Suppress the variable type
hint when the match RHS is a literal value or literal data constructor
(number/string/atom/charlist/tuple/list/map/struct/bitstring); chained matches
(`a = b = 1`) propagate the inner RHS. Hints are kept for calls, operators,
`fn`, vars, and control-flow (`total = a + b` → `: integer()`).
The obvious-binding positions are collected from the AST (LHS pattern var
positions of literal-RHS matches) and filtered out before rendering. Hover is
unchanged (hovering is explicit, so showing a literal's type there is fine).
Tests reworked: literal-binding cases became suppression cases; kept-case and
binding/read/settings tests use non-literal RHS. inlay/hover/completion green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`=` is a match, so the type-evident value can be the RHS (`x = 1`,
`t = {:ok, 1}`) or the LHS (`%User{} = user`, common in function heads). Make
the obvious-value check symmetric: in `left = right`, if either side is a
literal/struct/map/list/tuple/bitstring, suppress the variables on the opposite
side. Collecting vars from the value side is harmless — those occurrences are
reads whose binding positions live elsewhere.
Adds a test for `def run(%URI{} = uri)` producing no hint for uri.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Inlay hints provider:
- Correct param-name labels with non-trailing defaults: defaulted params are
dropped right-to-left for the called arity (verified: f(a, b \\ 1, c) called
/2 binds {a, c})
- Clamp >1000-line ranges to the budget instead of returning zero hints
(whole-document clients on large files)
- Codepoint (not grapheme) arithmetic for hint positions
- Labels/tooltips via TypePresentation.render_hint/3 max_length: — elided
label, full type in the tooltip; provider-side byte/grapheme truncate removed
- @call_blocklist applies to local calls only; __MODULE__-prefixed receivers
resolve from env instead of raising
- obvious_value? requires all-literal leaves ({:ok, compute()} keeps its hint)
- Single tokenize per request with tuple index and one-pass delimiter
matching (was O(n^2) per call)
Server/config:
- ELIXIR_LS_TYPE_INFERENCE applied at runtime in language_server startup
(config.exs alone is baked into releases)
Tests: 12 new inlay-hint tests; stale ported expectations updated for the
type-integration output (hover variable docs type field, completion field
type_spec rendering). Pre-existing locator/markdown failures documented in
ELIXIR_LS_TYPES_FABLE.md (status + deferred items, incl. the path-dep
repointing required before merge).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- New elixirLS.inlayHints.variableTypes.minimumTrust setting
("native" | "bestEffort", default "bestEffort"): "native" drops variable
hints whose TypePresentation source is :shape (structural engine), keeping
only compiler-descriptor-backed types; parameter-name hints unaffected
- One-time backend-status Logger.info on the first inlay-hint request:
compiler-native / structural-disabled / structural-unavailable, derived
from ElixirTypes.enabled?/available?
- Consumes render_hint/3 source field and literal widening from elixir_sense
(hint labels show integer()/binary() instead of literal values)
- 11 new tests: literal-widening leakage guard, remote-call and destructuring
hints, minimumTrust gating, param-hint independence with inference disabled,
failure-mode robustness (nonexistent module)
51 inlay-hint tests passing; hover/docs/completion provider suites green
(345); format gate clean. Status tracked in ELIXIR_LS_TYPES_GPT.md /
ELIXIR_LS_TYPES_FABLE.md. The corresponding minimumTrust schema lives in
vscode-elixir-ls package.json (separate repo).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ts backlog ELIXIR_LS_TYPES_FABLE.md is now the single prioritized backlog, merging the GPT and Gemini second-round reviews with verification verdicts: per-hint Binding.from_env confirmed (no batching); read-occurrence binding-type reuse reframed as semantically correct + off by default; tooltip bloat bounded (conditional + 1000-grapheme cap, lazy resolve premature); param parsing improved but still string-based (pattern defaults silently drop hints); clamp_range off-by-one (>= needed); server-level and ExCk e2e coverage confirmed absent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tests
Layering: the provider no longer references ElixirSense.Core.Binding or
TypePresentation. One TypeHints.request_context per request (request-scoped
caches shared across all hints — kills the verified per-hint env/binding/
local-sigs rebuild); variable hints via type_hint_for_var/4; parameter names
via effective_params/4 (parse_param string-splitting deleted; pattern-match
defaults like `%{} = opts \\ %{}` now label `opts:` instead of dropping).
clamp_range: inclusive at-most-1000-lines window (off-by-one fixed,
boundary-tested).
New coverage:
- server_inlay_hints_test.exs (real Server GenServer): capability
advertisement, full textDocument/inlayHint round-trip, sub-range scoping,
exact UTF-16 positions for non-ASCII identifiers, cancellation robustness
- inlay_hints_integration_test.exs: compiled fixture beam on a tmp code path,
remote-call binding hint, degradation without the fixture, minimumTrust
interplay
362 tests green across inlay unit + integration + server e2e + hover/docs/
completion; format gate clean. Backlog status updated in
ELIXIR_LS_TYPES_FABLE.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- minimumTrust now supports compiler | native | bestEffort, filtered through
TypeHints.trust_rank/1 over the refined sources (:native_exck >
:native_inferred > :spec > :shape); unrecognized future source atoms fail
safe to weakest (shown only under bestEffort)
- 23 new tests: overloaded ExCk fixture returns selected by argument type,
struct-returning fixture, ExCk version-mismatch degradation (foreign checker
tag), missing-chunk module, destructuring suppression policy locked in
(%Struct{} = call() hints; {:ok, value} = call() hints value), minimumTrust
matrix against observed source attribution (Enum.map binding classifies
:native_exck in practice)
378 tests green across inlay unit + integration + server e2e + hover/docs/
completion; format gate clean. Status updated in ELIXIR_LS_TYPES_GPT.md.
The minimumTrust "compiler" schema value and README settings docs live in the
vscode-elixir-ls repo (uncommitted there).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Unrecognized minimumTrust setting values (e.g. "strict") log a one-time warning per value listing the valid options, instead of silently behaving as the most permissive level; behavior still fails open to bestEffort - minimum_rank computed once in config/1 with a rescue fallback (was per-hint and asymmetric with the source-side rescue) Round-4 independent review otherwise verified the provider sound (context scoping, piped-param math, range filtering, padding/kind spec compliance) and closed the benchmark backlog item with data: native typing is 2.4x faster on the hint path (802ms vs 1912ms full-document on a 1795-line module; 140ms vs 317ms for a 100-line viewport). Status in ELIXIR_LS_TYPES_FABLE.md. 380 provider tests green; format gate clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Read occurrences (showOnlyBindings: false) route through the new
TypeHints.type_hint_at/4 and show the type narrowed AT the read position
(cond/guard narrowing verified: x inside is_integer(x) branch hints
integer()); binding occurrences keep the binding-site path; minimumTrust
applies to both; default users (bindings-only) see zero change
- occurrences/2 emits tagged {:binding, var} | {:read, name} tuples; obvious-
value suppression remains binding-only by construction
- release-gate CI job rejects absolute local path deps in mix.exs/mix.lock
(continue-on-error on this branch — the local elixir_sense worktree dep is
intentional during development; flip to hard-fail at release)
385 tests green across inlay unit + integration + server e2e + hover/docs/
completion; format clean. Status in ELIXIR_LS_TYPES_FABLE.md.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Integration coverage: dependency-chain fixtures (buffer -> A -> B with real ExCk chunks; fixture compilation needed debug_info enabled and on-disk beam re-load for ExCk path lookups — mechanism documented in the test), optional- key map returns, struct returns, stdlib overloads (Enum.at/2 vs /3, Keyword.get) - Release smoke scaffold (:release_smoke tag, excluded by default): the no-absolute-path-deps assertion that documents the release blocker, an always-running companion asserting the local path dep IS currently present (flips loudly when the state changes), and the documented manual packaged-dependency check 397 provider tests green (2 smoke exclusions by design); format clean. Status in ELIXIR_LS_TYPES_FABLE.md. The read-occurrence README docs live in the vscode-elixir-ls repo (uncommitted there). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace the development-time local worktree path dependency with the git pin: elixir-lsp/elixir_sense @ eeb32891 (claude/trusting-wu-d1f603 — the full types integration: TypeHints facade, trust levels, three-marker map tails, improper lists, ModuleResolver, apply parity). dep_versions.exs and mix.lock updated. This resolves the P0 path-dep release blocker for CI purposes: the release-gate job and the release-smoke companion test will now observe the git dep. CI can exercise the full Elixir version matrix against the published dep to validate progressive enhancement on < 1.20. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n 1.16-1.20) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts: # dep_versions.exs # mix.lock
…ood guard
Real fixes:
- Parameter-name inlay hints were silently ABSENT on Elixir 1.16:
:elixir_tokenizer.tokenize returns tokens in forward order on 1.16
(5-tuple) but reverse order on 1.17+ (6-tuple); the unconditional reverse
scrambled the delimiter stack so argument spans never resolved. Replaced
with position-based ordering, version-independent
- markdown_utils: the :..// atom renders unquoted on the 1.20 formatter but
quoted on 1.16 — no literal form passes --check-formatted on both;
replaced with String.to_atom("..//")
- complete_test: charlists normalized to ~c sigils + line-break stability
(1.16 and 1.20 formatters now both accept the file)
- Test isolation: ExCk fixture compiles crashed when a prior test left the
LSP Tracer registered as a compiler tracer after its GenServer died —
fixtures now compile with tracers stripped
1.18/1.19 runner kills root-caused as a LOG FLOOD (not a hang): the dep's
native typing logged ~178 multi-KB crash traces per run on unexpanded
Record/defguard/struct patterns (718 KB -> 33 KB after fix). Mitigated with
per-module Logger suppression in test_helper (a global :error floor broke 22
tests asserting window/logMessage flow); the dep-side root fix (of_head
non-pattern filtering) ships in the elixir_sense pin bumped here
(b65c4e4a, PR elixir-lsp/elixir_sense#334 — 18/18 green incl. all versions).
Version-gated test expectations: capability tiers are NOT uniform 1.18+ —
available?() (1.18+) for spec unions/provenance, available?(:expr) (1.19+)
for literal widening/fn returns, available?(:previous) (1.20) for
default-nil widening and fn argument inference; assertions gated per tier
without weakening 1.20.
Release smoke: the companion test flipped to assert the NEW state (git pin,
no absolute path dep) per its design.
Local matrix (apps/language_server): 1.16 and 1.17 green (full suite);
1.18/1.19 green except the 3 known pre-existing locator hangs; 1.20
unchanged; umbrella format green on 1.16 and 1.20.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…x — unblocks the locator hangs) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- elixir_range: drop dead || 1 fallbacks (lsp_position_to_elixir columns are always pos_integer per success typing — guard_fail) - .dialyzer_ignore: the 1.16 tokenizer 5-tuple (and older 4-tuple) clauses in tokenize/1 are required at runtime on old Elixirs but appear dead against the 1.20 PLT (same class as the existing OTP-26 markdown_utils entry) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tting - module_of/2 hand-concatenated __aliases__ without consulting env.aliases, so aliased remote calls (alias Foo.Bar; Bar.fun(x)) resolved to the wrong module and parameter-name hints silently dropped — now delegates to ElixirSense.Core.ModuleResolver.resolve/2 (regression test added) - split_arguments accumulates by prepend+reverse instead of O(K^2) appends - documented that clean_identifier? rejecting leading underscores is deliberate display suppression (differs from the facade-side predicate on purpose) 103 inlay tests green; format gate clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds first-class LSP inlay hints support (variable type hints + parameter name hints) backed by the ElixirSense TypeHints facade, and wires it through the language server with extensive end-to-end and integration tests. It also introduces runtime/config toggles for ElixirSense native typing, and expands hover/completion to surface inferred types.
Changes:
- Implement
textDocument/inlayHinthandling in the server and a newProviders.InlayHintsimplementation (variable type hints + parameter-name hints, range clamping, settings support). - Add broad automated coverage: server e2e tests, provider unit tests, compiled-fixture integration tests, and release-gate smoke tests.
- Extend hover and completion output to include rendered inferred types (via
TypePresentation) and adjust CI/release guardrails.
Reviewed changes
Copilot reviewed 20 out of 21 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| mix.lock | Updates the pinned elixir_sense git ref. |
| dep_versions.exs | Updates the tracked elixir_sense ref used by umbrella apps. |
| config/config.exs | Adds config-time toggle for ElixirSense native typing via ELIXIR_LS_TYPE_INFERENCE. |
| apps/language_server/test/test_helper.exs | Silences noisy ElixirSense degradation logs in tests; excludes :release_smoke by default. |
| apps/language_server/test/server_inlay_hints_test.exs | New server-level e2e tests for textDocument/inlayHint (capability, range, unicode, cancellation). |
| apps/language_server/test/release_smoke_test.exs | New release-gate smoke tests (absolute-path dep checks + placeholder release steps). |
| apps/language_server/test/providers/inlay_hints_test.exs | New unit tests for variable-type and parameter-name hint behavior, settings, and robustness. |
| apps/language_server/test/providers/inlay_hints_integration_test.exs | New integration tests compiling fixtures and validating degradation-safe behavior (incl. ExCk scenarios). |
| apps/language_server/test/providers/hover/docs_test.exs | Updates variable hover docs expectations to include type. |
| apps/language_server/test/providers/hover_test.exs | Adds hover test asserting inferred variable type is rendered. |
| apps/language_server/test/providers/completion/suggestions_test.exs | Updates completion expectations for rendered type_spec, with version-gated widening behavior. |
| apps/language_server/lib/language_server/server.ex | Registers InlayHints provider and adds request handler + capability advertisement. |
| apps/language_server/lib/language_server/providers/inlay_hints.ex | New inlay-hints provider implementation (variable types + parameter names, settings, tokenization, range clamping). |
| apps/language_server/lib/language_server/providers/hover/docs.ex | Adds type to variable docs using TypePresentation.render_hint/2. |
| apps/language_server/lib/language_server/providers/hover.ex | Renders a “Type” section in variable hover markdown when available. |
| apps/language_server/lib/language_server/markdown_utils.ex | Adjusts special-case parsing for ..///3 to be formatter-stable across Elixir versions. |
| apps/language_server/lib/language_server.ex | Applies ELIXIR_LS_TYPE_INFERENCE at runtime (release-safe) by setting :elixir_sense, :use_elixir_types. |
| apps/elixir_ls_utils/test/complete_test.exs | Updates completion-engine tests for new type_spec values; normalizes some charlist literals. |
| apps/elixir_ls_utils/lib/completion_engine.ex | Uses TypePresentation to render inferred field types when no declared typespec exists. |
| .github/workflows/ci.yml | Adds a “release gate” job checking for absolute path: "/..." deps (currently continue-on-error). |
| .dialyzer_ignore.exs | Adds ignore for inlay hints tokenizer pattern matching across Elixir versions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+32
to
+35
| config :elixir_sense, | ||
| use_elixir_types: | ||
| System.get_env("ELIXIR_LS_TYPE_INFERENCE", "true") |> String.downcase() != "false" | ||
|
|
Comment on lines
+9
to
+13
| They are intended to run against a CLEAN checkout with production deps (no | ||
| `path:` overrides) before cutting a release. Today most of them are excluded | ||
| because the workspace intentionally uses a local `path:` dep for | ||
| `elixir_sense` during development. | ||
|
|
Comment on lines
+12
to
+16
| # Release gate: absolute local path dependencies must never ship. This is | ||
| # EXPECTED to flag on the inlay-hints development branch (elixir_sense is a | ||
| # local worktree path dep during development) — continue-on-error keeps the | ||
| # branch green while documenting the blocker. Flip continue-on-error to | ||
| # false before release. |
Comment on lines
+231
to
+245
| type_section = | ||
| case Map.get(info, :type) do | ||
| type when is_binary(type) and type != "" -> | ||
| """ | ||
|
|
||
| ### Type | ||
|
|
||
| ```elixir | ||
| #{type} | ||
| ``` | ||
| """ | ||
|
|
||
| _ -> | ||
| "" | ||
| end |
Comment on lines
+20
to
+26
| 1. `no_absolute_path_deps` — asserts that no `mix.exs` file in the umbrella | ||
| tree contains `path: "/"` (an absolute-path dep). Today this test | ||
| DOCUMENTS A KNOWN RELEASE BLOCKER: the `elixir_sense` dep in | ||
| `apps/language_server/mix.exs` uses an absolute `path:` pointing to a | ||
| local worktree. The always-running companion test | ||
| (`path_dep_is_still_present`) asserts that the path dep IS present so the | ||
| suite notices when it is removed. |
Comment on lines
+431
to
+436
| # NOTE: `String.to_atom("..//")` rather than the literal `:..//` atom because | ||
| # the two supported formatters disagree on how to render that atom — Elixir | ||
| # 1.20 emits it unquoted (`:..//`) while 1.16 quotes it (`:"..//"`), so no | ||
| # single literal form is `mix format --check-formatted`-clean on both. The | ||
| # string form is left untouched by every formatter and yields the same atom. | ||
| defp get_module_fun_arity("..///3"), do: {Kernel, String.to_atom("..//"), 3} |
…p elixir_sense pin
- module_of/2 passed the %State.Env{} struct to ModuleResolver.resolve/2,
whose env type is an anonymous %{optional(:module), optional(:aliases)} map;
a struct is not a subtype, so dialyzer flagged the call as never-succeeding
(no_return). Pass %{module: env.module, aliases: env.aliases} — same fix as
the elixir_sense-side ModuleResolver callers.
- Bump elixir_sense pin b3ad3c30 -> 53f8879d (review fixes incl. domain-key
field_get crash fix, combinator/cache cleanups, test consolidation/trim).
Inlay suites 103 passed; format clean; dialyzer clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft PR to run the CI matrix against the inlay-hints branch with the published elixir_sense pin (elixir-lsp/elixir_sense@c9f34e24 — its own matrix is green on 1.16–1.20, validating progressive enhancement).
Contents: textDocument/inlayHint provider (variable type hints incl. flow-sensitive read hints, parameter-name hints), consuming the ElixirSense.Core.TypeHints facade exclusively; minimumTrust setting over compiler/native/bestEffort trust ranks; runtime ELIXIR_LS_TYPE_INFERENCE kill switch; server e2e + compiled-ExCk-fixture + release-smoke test suites. Tracked in ELIXIR_LS_TYPES_FABLE.md.
Remaining release mechanics before un-drafting: flip the release-gate CI job to hard-fail, freeze defaults, land the VS Code extension schema/docs.
🤖 Generated with Claude Code