This open statement shadows the label

Hello,

I often see this warning in my code:

I don’t quite get why this is problematic and how to avoid this warning.
I think it is pretty common for types to use the same field name.
What am I missing here?

If you want to give the latest open higher priority, you can add ! to it.

open! Blah

But this is a last resort, it is better to do the following:

Write the module name in front of the first field of a record to explicitly tell the type system from which module it is imported.

let x = { Meh.data: 7 }
let y = { Blah.data: 9 }

And it is necessary because you may indeed ending up misguiding the type system.

Generally, I’d use open very sparingly. If you have a module with a very long name that you use quite often you can also alias it:

module MyAlias = MyVeryVeryLongModuleName

Thanks, but I still don’t quite grasp what the problem space is that two modules expose the same record field? data could not be misused, because I would need a type annotation anyway. And I would assume data on itself cannot be used anywhere else but inside the context of creating a new record instance.

If this were two let bindings with the same name, from different modules, I could understand the compiler warning. But I can’t grasp where the shadowing is happening here.

I have another one of these I don’t get:

module DOMAPI = {
  type timeoutId
}

module Global = {
  open DOMAPI

  external setTimeout: (~handler: unit => unit, ~timeout: int=?) => timeoutId =
    "setTimeout"
}
[W] Line 6, column 2:
this open statement shadows the type identifier timeoutId (which is later used)

What is wrong here? How is anything shadowed?

this comes from the fact you’re shadowing Stdlib.timeoutId that is globally available.

1 Like