Skip to content

Incorrect type information on hover with async/await #6013

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

Closed
DZakh opened this issue Jan 15, 2023 · 7 comments · Fixed by #6012
Closed

Incorrect type information on hover with async/await #6013

DZakh opened this issue Jan 15, 2023 · 7 comments · Fixed by #6012
Milestone

Comments

@DZakh
Copy link
Member

DZakh commented Jan 15, 2023

It happens when there's a compilation error inside of an async/await function. On hover, it shows a type of the async function instead of the hovered value. Works fine with normal functions in the same file.

image

@DZakh
Copy link
Member Author

DZakh commented Jan 15, 2023

The code:

module Promise = Js.Promise2
module Global = Js.Global

@module("uvu") external test: (string, unit => unit) => unit = "test"
@module("uvu") external asyncTest: (string, unit => promise<unit>) => unit = "test"
@module("uvu") @scope("test") external testRun: unit => unit = "run"
module Assert = {
  @module("uvu/assert") external is: ('a, 'a) => unit = "is"
}

asyncTest("[ReScript] redefine act.notify", async () => {
  Act.setNotify((. ()) => {
    Global.setTimeout(() => Act.notify(.), 0)
  })

  let a = Act.make(0)
  let callsRef = ref(0)
  let _ = a->Act.subscribe((. _) => callsRef.contents = callsRef.contents + 1)

  Assert.is(callsRef.contents, 1)

  a->Act.set(123)
  await Promise.resolve()
  Assert.is(callsRef.contents, 1)
  await Promise.make((~resolve, ~reject as _) => {
    Global.setTimeout(() => resolve(. ()), 0)->ignore
  })
  Assert.is(callsRef.contents, 2)
})

testRun()

@cristianoc
Copy link
Collaborator

I think the hover shows the type of what's "under the code" which has a type error: the enclosing function.
Not sure it has to do with async/await per se.
In general, when compilation fails, the compiler returns partial type information, of the parts it has typed (even partially).

@hellos3b
Copy link
Contributor

This happens to me too all the time, it makes debugging a little difficult because when there's any kind of error in an async function you can't inspect any other types in the call

promise-type

When working with records, this breaks intellisense/autocomplete which then makes it hard to fix. I typically find myself needing to flip through modules to find what a field was named

type output = {outDir: string}

let build = async () => {
  Promise.resolve({outDir: "dist"})
}

let serve = outDir => "localhost" ++ outDir

let devServer = async () => {
  let output = await build()
  serve(output.dir) // <-- "dir" instead of "outDir"
}
'a => promise<'a>
The record field dir can't be found.

If it's defined in another module or file, bring it into scope by:
- Prefixing it with said module name: TheModule.dir
- Or specifying its type: let theValue: TheModule.theType = {dir: VALUE}ReScript

@zth
Copy link
Collaborator

zth commented Feb 15, 2023

Something is indeed wrong. We'll be investigating this soon.

@cristianoc
Copy link
Collaborator

cristianoc commented Feb 15, 2023

Can you add a screenshot of the hover when there's the type error without async?

@hellos3b
Copy link
Contributor

Sure, here's the smallest reproducible example with and without async

x_int

x_promise

let test = async () => {
  let x = 0
  x + "y"
}

@cristianoc
Copy link
Collaborator

Take a look at this compiler PR which should fix that: #6012
Can be added to the 10.1 compiler version too, so it goes into bug fix release 10.1.3.

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 a pull request may close this issue.

4 participants