I’m working on function that either shows full types or not based on some variable.
I encountered weird bug I can’t figure out because the function is not behaving the same when running it and when debugging it.
The function is here: https://github.com/racinmat/Mill.jl/blob/master/src/Mill.jl#L74
When I run it, it crashes with
ERROR: type DataType has no field var
Stacktrace:
[1] getproperty at .\Base.jl:28 [inlined]
[2] show(::IOContext{Base.GenericIOBuffer{Array{UInt8,1}}}, ::Type{ERROR: type DataType has no field var
but when I use Debugger and debug it line per line, Julia executes the code succesfully, it does not crash, it returns correctly.
During debugging, x isa DataType
is true, but when running it outside of debug, it’s false.
I restarted Julia multiple times to make sure it’s not some old version of code in the REPL.
The function itself is here:
function Base.show(io::IO, x::Type{T}) where {T<:Union{AbstractNode,AbstractMillModel}}
if _terseprint[]
if hasproperty(x, :body) && !hasproperty(x.body, :name) && hasproperty(x.body, :body)
print(io, "$(x.body.body.name){…}")
return
elseif hasproperty(x, :body) && !hasproperty(x, :name)
print(io, "$(x.body.name){…}")
return
else
print(io, "$(x.name){…}")
return
end
else
# specifically function show(io::IO, @nospecialize(x::Type))
if x isa DataType
Base.show_datatype(io, x)
return
elseif x isa Union
if x.a isa DataType && Core.Compiler.typename(x.a) === Core.Compiler.typename(DenseArray)
T2, N = x.a.parameters
if x == StridedArray{T2,N}
print(io, "StridedArray")
Base.show_delim_array(io, (T2,N), '{', ',', '}', false)
return
elseif x == StridedVecOrMat{T2}
print(io, "StridedVecOrMat")
Base.show_delim_array(io, (T2,), '{', ',', '}', false)
return
elseif StridedArray{T2,N} <: x
print(io, "Union")
Base.show_delim_array(io, vcat(StridedArray{T2,N}, Base.uniontypes(Core.Compiler.typesubtract(x, StridedArray{T2,N}))), '{', ',', '}', false)
return
end
end
print(io, "Union")
Base.show_delim_array(io, Base.uniontypes(x), '{', ',', '}', false)
return
end
if Base.print_without_params(x)
return show(io, Base.unwrap_unionall(x).name)
end
if x.var.name === :_ || Base.io_has_tvar_name(io, x.var.name, x)
counter = 1
while true
newname = Symbol(x.var.name, counter)
if !Base.io_has_tvar_name(io, newname, x)
newtv = TypeVar(newname, x.var.lb, x.var.ub)
x = UnionAll(newtv, x{newtv})
break
end
counter += 1
end
end
show(IOContext(io, :unionall_env => x.var), x.body)
print(io, " where ")
show(io, x.var)
end
end
I’m desperate, I can’t figure out how to make it work and make it consistent.
I know one should generally not overload Base.show
, but we have good usecase for this.
The error can be seen here: Travis CI - Test and Deploy with Confidence