MOD015: Imported name collides with a module-level definition
Code: MOD015
Category: Module system
Since: the release after v0.51.1 (#1467)
What this error means
A module imports a name explicitly and defines a module-level binding with the same
name. The import can be a selective import (import M (tick)), an aliased symbol
(import M (f as tick)), or the selective list of a module alias (import M as L (tick)).
The module-level binding can be a func, a let/letrec, or an ADT constructor (an
imported constructor colliding with one of the module's own constructors).
A bare tick in that module could mean either binding, so it is rejected — the same rule
as Haskell's and Elm's "ambiguous occurrence" and Rust's E0255. Up to v0.51.1 this
compiled and the import silently won: the module's own definition was ignored at
every bare use, so a program could run the wrong function with no diagnostic.
Example
module rx/p/q
import rx/p/a (tick) -- binding 1: the import
pure func tick(n: int) -> int = n + 100 -- binding 2: same name
export func main() -> () ! {IO} = println(show(tick(1)))
Error MOD015: 'tick' is both imported (import rx/p/a (tick) at q.ail:2:1) and defined in this
module as a func (at q.ail:4:6) — an imported name and a module-level definition may not share a name.
Fix: rename the local definition, or alias the import: import rx/p/a (tick as aTick)
How to fix
- Alias the import so the two bindings have different names:
import rx/p/a (tick as aTick)— thentickis yours andaTickis the import. - Rename the local definition.
- With a module alias (
import rx/p/a as A (tick)), droptickfrom the list and writeA.tick— a module alias already gives qualified access to every export.
What is not an error
- Lexical binders — a parameter,
let, or match binder named like an import shadows it inside its own scope. - A module alias alone —
import M as Lbinds no bare names, so a localticknext to it is fine. AILANG has no wildcard (import M) import. - Types — a local
type Twins over an imported typeT; importing typeTnext to a local constructorTis not a collision either (types and constructors are separate namespaces). - The same export imported twice from the same module.