# These stack traces are out of control

**URL:** https://discourse.julialang.org/t/these-stack-traces-are-out-of-control/47162
**Category:** General Usage
**Created:** [September 23, 2020, 11:23pm UTC](https://discourse.julialang.org/t/these-stack-traces-are-out-of-control/47162 "2020-09-23T23:23:06Z")
**Posts on this page:** 1
**Showing post:** 6

<div class="post-metadata">

### Author: ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)
#### Post date: [September 27, 2020, 6:54pm UTC](https://discourse.julialang.org/t/these-stack-traces-are-out-of-control/47162/6 "2020-09-27T18:54:56Z")

</div>

As per my edit, the solution is to check a flag in the relevant show method. A lot of digging later (and also my first time using Debugger.jl, which was _awesome_, by the way), I found out this can be done by modifying [this line in Base](https://github.com/JuliaLang/julia/blob/697e782ab86bfcdd7fd15550241fe162c51d9f98/base/show.jl#L1788).

It’s quite a long function so I’m hiding it, but the diff between this and Base is 3 lines (and could technically be just one).

> **Summary**
>
> ```julia
> @eval Base function show_tuple_as_call(io::IO, name::Symbol, sig::Type, demangle=false, kwargs=nothing)
> # print a method signature tuple for a lambda definition
> in_backtrace = get(io, :backtrace, false)
> color = get(io, :color, false) && in_backtrace ? stackframe_function_color() : :nothing
> if sig === Tuple
> printstyled(io, demangle ? demangle_function_name(name) : name, "(...)", color=color)
> return
> end
> tv = Any[]
> env_io = io
> while isa(sig, UnionAll)
> push!(tv, sig.var)
> env_io = IOContext(env_io, :unionall_env => sig.var)
> sig = sig.body
> end
> sig = sig.parameters
> with_output_color(color, env_io) do io
> ft = sig[1]
> uw = unwrap_unionall(ft)
> if ft <: Function && isa(uw, DataType) && isempty(uw.parameters) &&
> isdefined(uw.name.module, uw.name.mt.name) &&
> ft == typeof(getfield(uw.name.module, uw.name.mt.name))
> print(io, (demangle ? demangle_function_name : identity)(uw.name.mt.name))
> elseif isa(ft, DataType) && ft.name === Type.body.name && !Core.Compiler.has_free_typevars(ft)
> f = ft.parameters[1]
> print(io, f)
> else
> print(io, "(::", ft, ")")
> end
> end
> first = true
>     
> print_style = get(io, :color, false) && in_backtrace ? :bold : :nothing
> printstyled(io, "(", color=print_style)
> for i = 2:length(sig) # fixme (iter): `eachindex` with offset?
> first || print(io, ", ")
> first = false
> print(env_io, "::", in_backtrace ? typename(sig[i]) : sig[i])
> end
> if kwargs !== nothing
> print(io, "; ")
> first = true
> for (k, t) in kwargs
> first || print(io, ", ")
> first = false
> print(io, k, "::")
> show(io, t)
> end
> end
> printstyled(io, ")", color=print_style)
> show_method_params(io, tv)
> nothing
> end
> 
> ```

For the effect, see:

```julia
## Create a contrived stacktrace to see the effect
## and a similar method for h so we get "Closest candidates"
julia> begin 
           f(x) = g(x, x, x)
           g(x, y, z) = h(x, y, z)
           h(x::Complicated{Float64}, y::Complicated{Float64}) = "anything"
       end

julia> struct Complicated{a,b,c,d} end

julia> C = Complicated{ntuple(i->Float64, 4)...}()
Complicated{Float64,Float64,Float64,Float64}()

julia> f(C)
ERROR: MethodError: no method matching h(::Complicated{Float64,Float64,Float64,Float64}, ::Complicated{Float64,Float64,Float64,Float64}, ::Complicated{Float64,Float64,Float64,Float64})
Closest candidates are:
  h(::Complicated{Float64,b,c,d} where d where c where b, ::Complicated{Float64,b,c,d} where d where c where b) at REPL[16]:1
Stacktrace:
 [1] g(::Complicated, ::Complicated, ::Complicated) at ./REPL[16]:1
 [2] f(::Complicated) at ./REPL[16]:1
 [3] top-level scope at REPL[19]:1

```

We get the full method signature in the method error itself and in the closest candidates (which we may need to know to disambiguate the error), but the type name in the stacktrace is always shortened. It’s still worth considering I think whether this is behavior that should be enabled by default, or whether only certain “complicated” types should feature this, i.e. if this is opt-in by the struct creator.

---

_[View the full topic](https://discourse.julialang.org/t/these-stack-traces-are-out-of-control/47162)._
