Skip to content

replacing a module leads to confusing errors #42109

@Volker-Weissmann

Description

@Volker-Weissmann

Let's say other.jl looks something like this

module dat
    export Visible, Invisible
    struct Visible
        a::Int
    end
    struct Invisible
        a::Int
    end
end
using .dat
const var = Visible(10)

And you accidentally include this file twice (directly or indirectly):

include("other.jl")
include("other.jl")
Visible(20)
Invisible(20)

Executing this will output

WARNING: replacing module dat.
WARNING: using dat.Visible in module Main conflicts with an existing identifier.
WARNING: both dat and dat export "Invisible"; uses of it in module Main must be qualified
ERROR: LoadError: UndefVarError: Invisible not defined
Stacktrace:
 [1] top-level scope
   @ main.jl:5
in expression starting at main.jl:5

If the line const var = Visible(10) is well hidden inside mountains of code, you can look at it for a loooong time without finding the bug. Other than const var = Visible(10) the types Visible and Invisible are defined in the same way at the same point, yet one is visible and the other one is not.

It is especially confusing because something like const var = Visible(10) does not affect the visibility of a type in most other languages.

I encountered this is a real world application and I only found it by

  1. deleting some code
  2. Check if the same error message still appears. If no, un-delete this code
  3. Repeat step 1 until you have 20 lines of code that reproduce the error message.

I don't know julia well enough to know how this can be made easier to debug. Hopefully you know.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions