Skip to content

Autocomplete fails for struct-literal field inside a call nested as an array-literal element #1672

Description

@JxavierP

Summary:
OLS fails to infer the correct expected type for a struct literal's fields when that literal is an argument to a function call, and that call itself is an element of another array/composite literal (e.g. a []T{ f({...}) } shape). Instead of completing against the argument's actual parameter type, OLS falls back to suggesting field names from an unrelated/outer scope. This only affects editor completion — the code compiles and runs correctly with odin build/odin check.

Minimal Repro:

package main

Inner :: struct {
	top:   u16,
	color: [4]f32,
}

Config :: struct {
	borders: Inner,
}

make_thing :: proc(config: Config) -> int {
	return 0
}

main :: proc() {
	_ = []int{
		make_thing({borders = {}}), // <- cursor after "borders = ", trigger completion
		// Expected: completion offers Inner's fields (top, color)
		// Actual: completion offers unrelated/outer-scope suggestions
	}
}

Steps to reproduce:

  1. Open the file above (or an equivalent) in an editor with OLS attached.
  2. Place the cursor immediately after borders = inside the nested make_thing({...}) call.
  3. Trigger completion (Ctrl+Space).

Expected: Completion suggests Inner's fields (top,color).
Actual: Completion suggests incorrect/unrelated fields names, (actually grabs the intellisense that should be called if it would done on the outer scope) as if it lost track of the expected type at that position.

Additional Notes:

  • The same call written as a top-level, non-nested statement (make_thing({borders = {}}) outside any enclosing array/composite literal) completes correctly.
  • The issue reproduces regardless of whether the enclosing struct types are unions, plain structs, recursive, or reference external-package types — it appears specifically tied to the call being an element of a composite literal, not to any particular type shape.
  • Naming the inner literal explicitly (borders = Inner{...}) works around the issue, since it removes the need for inference.
  • Wrapping the nested call in an if-gated block (rather than a composite literal) also avoids the issue, since the block's scope ownership becomes grammatically unambiguous.

I'm building a gui framework with a declarative builder-style api and this issue breaks the expected dev experience of reliable field completions when nesting components.

Environment: ols version nightly-2026-09-06-8a347aa8, ols version nightly-2026-09-06-8a347aa8, vscode 1.131.0, OS - Linux

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions