Skip to content

Propagate expected dict value type into dict literal typing#8359

Open
zth wants to merge 2 commits intomasterfrom
improve-dict-type-propagation
Open

Propagate expected dict value type into dict literal typing#8359
zth wants to merge 2 commits intomasterfrom
improve-dict-type-propagation

Conversation

@zth
Copy link
Copy Markdown
Member

@zth zth commented Apr 18, 2026

Currently, this fails:

module Hidden = {
  type routeHandlerObject = {get: int}
}

let dictValueInference: Dict.t<Hidden.routeHandlerObject> = dict{
  "health": {get: 200},
}

let primitiveMakeValueInference: Dict.t<Hidden.routeHandlerObject> = dict{"health": {get: 200}}

It fails because dict{} expression is emitted as Primitive_dict.make(["health", {get: 200}]), and that makes it loose type info. This PR propagates the expected dict type info further, which means the above code will work.

As a nice side effect, this PR also improves type error messages for dict. This:

let x: dict<JSON.t> = dict{"1": 1.}

Will currently fail on the whole dict{} (although it's just 1. that's wrong). After this fix it'll fail on 1. instead (Expected JSON.t, got float).

@cristianoc can you think of a better cleaner way to do this?

Also, Codex is saying these cases are also broken and could be fixed the same way:

  1. async
  2. spread arrays/lists
  3. tagged templates

These fail today:

module M = { type t = {get: int} }

// Fails
let f: unit => promise<M.t> = async () => {get: 1}
// Works (no async)
let f: unit => M.t = () => {get: 1}

// Fails
let xs: array<M.t> = [...[], {get: 1}]
let xs: list<M.t> = list{...list{}, {get: 1}}

// Fails
let tag = (_strings, values) => values[0]->Option.getOrThrow
let x: M.t = tag`a${{get: 1}}`

@zth zth requested a review from cristianoc April 18, 2026 15:01
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 18, 2026

Open in StackBlitz

rescript

npm i https://pkg.pr.new/rescript@8359

@rescript/darwin-arm64

npm i https://pkg.pr.new/@rescript/darwin-arm64@8359

@rescript/darwin-x64

npm i https://pkg.pr.new/@rescript/darwin-x64@8359

@rescript/linux-arm64

npm i https://pkg.pr.new/@rescript/linux-arm64@8359

@rescript/linux-x64

npm i https://pkg.pr.new/@rescript/linux-x64@8359

@rescript/runtime

npm i https://pkg.pr.new/@rescript/runtime@8359

@rescript/win32-x64

npm i https://pkg.pr.new/@rescript/win32-x64@8359

commit: 19b5ddd

Copy link
Copy Markdown
Collaborator

@cristianoc cristianoc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Legit.
I guess a first class support for dict would avoid the issue, but might be more invasive.
(And async etc).

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants