-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Description
"Redefining" a struct with the identical definition does nothing and is legal:
julia> struct NoRec end;
julia> struct NoRec end;
However, this fails when the struct references itself in its supertype:
julia> struct Rec <: AbstractVector{Rec} end;
julia> struct Rec <: AbstractVector{Rec} end;
ERROR: invalid redefinition of constant Main.Rec
Stacktrace:
[1] top-level scope
@ REPL[2]:1
In practice, this creates problems with Revise: in any file that contains such a type, any modification unrelated to the type triggers this "ERROR: invalid redefinition of constant" and blocks Revise, with no way of unblocking it: see timholy/Revise.jl#813
I believe the cause of this error comes from Core._equiv_typedef
, which behaves differently on NoRec
and Rec
. For two instances of NoRec
, we have
julia> var"#1001#NoRec" = Core._structtype(Main, :NoRec, Core.svec(), Core.svec(), Core.svec(), false, 1); Core._setsuper!(var"#1001#NoRec", Any)
julia> var"#1000#NoRec" = Core._structtype(Main, :NoRec, Core.svec(), Core.svec(), Core.svec(), false, 1); Core._setsuper!(var"#1000#NoRec", Any)
julia> Core._equiv_typedef(var"#1000#NoRec", var"#1001#NoRec")
true
but for two instances of Rec
it becomes:
julia> var"#1000#Rec" = Core._structtype(Main, :Rec, Core.svec(), Core.svec(), Core.svec(), false, 1); Core._setsuper!(var"#1000#Rec", Core.apply_type(AbstractVector, var"#1000#Rec"))
julia> var"#1001#Rec" = Core._structtype(Main, :Rec, Core.svec(), Core.svec(), Core.svec(), false, 1); Core._setsuper!(var"#1001#Rec", Core.apply_type(AbstractVector, var"#1001#Rec"))
julia> Core._equiv_typedef(var"#1000#Rec", var"#1001#Rec")
false
So a fix could consist in teaching equiv_type
to handle this kind of self-reference, i.e. to fix the following approach:
Lines 2222 to 2225 in 7197c9e
a = jl_rewrap_unionall((jl_value_t*)dta->super, dta->name->wrapper); | |
b = jl_rewrap_unionall((jl_value_t*)dtb->super, dtb->name->wrapper); | |
if (!jl_types_equal(a, b)) | |
goto no; |