enso
enso copied to clipboard
Imported name shadowed by local type not reported
Within a project with 2 files:
Mod.enso
type A
Ctor1
make_a = A.Ctor1
and Main.enso
from Standard.Base import all
import project.Mod.A
from project.Mod import make_a
type A
Ctor2
foo (a : A) -> A = a
main =
IO.println (foo (A.Ctor2))
IO.println (foo make_a)
running Main.enso
will result in:
Ctor2
Execution finished with an error: Type error: expected `a` to be A, but got A.
at <enso> Main.foo(src\Main.enso:9:1-20)
at <enso> Main.main<arg-1>(src\Main.enso:13:17-26)
at <enso> Main.main(src\Main.enso:13:5-27)
There's 2 issues here:
- The imported name
A
is shadowed by the type definitiontype A
but this is not reported. If not error, at least a warning should be reported to the user about the shadowing. - The
Type_Error
message is confusing: expected A but got A - ???. The problem is that the qualified name of the types differs. We should record the qualified name of each type and if the short-names are equal, we should display the qualified names to allow the user to disambiguate types with same short names.
### Tasks
- [ ] Shadowing should display warning
- [ ] Improve type error message
Moreover, adding make_a = A.Ctor2
to Main.enso
makes the program run:
Ctor2
Ctor2
because it also shadows the imported make_a
.
This shadowing also does not issue any error nor warning.
I think shadowed symbols (methods and types) should result in a warning.
According to @4e6 and @JaroslavTulach, type shadowing is perfectly fine. Imagine you would like to define your Boolean
type. In that case, you would not be able to import all symbols from Standard.Base
. Nevertheless, it should at least report a warning, as shadowing might not always be the desired behavior.
The type error message is indeed confusing. I will try to improve it.
Pavel Marek reports a new STANDUP for today (2024-05-03):
Progress: - Writing tests and test utilities to create a whole temporary project structure. It should be finished by 2024-05-07.
According to @4e6 and @JaroslavTulach, type shadowing is perfectly fine. Imagine you would like to define your
Boolean
type. In that case, you would not be able to import all symbols fromStandard.Base
.
That's exactly the rationale behind the hiding
construct.
If you want to define your own Boolean
- that's perfectly fine, you need to use:
from Standard.Base import all hiding Boolean
Marking this issue as x-on-hold
, as it would be very useful to have more specific information in BindingsMap.resolvedImports
. For example, for these two modules:
local.Proj.Mod:
type T
local.Proj.Main:
from local.Proj.Mod import T
if we look into the bindings map of local.Proj.Main
, there is a ResolvedImport with the target of ResolvedModule("local.Proj.Mod")
, but it should rather be ResolvedType("local.Proj.Mod.T")
.
Adding this kind of information to the BindingsMap is tracked in https://github.com/enso-org/enso/issues/6729
Without this additional information, implementing a static linting compiler pass to detect shadowing of imported symbols is not worth the effort at the moment.
Closing the associated PR #9863 with tests and a skeleton of the linting pass. Let's re-open it once we have a better BindingMap.