# Surprising type widening when constructing Tuple{...}

**URL:** <https://discourse.julialang.org/t/surprising-type-widening-when-constructing-tuple/92840>\
**Category:** Performance\
**Tags:** question\
**Created:** [January 12, 2023, 2:36am UTC](https://discourse.julialang.org/t/surprising-type-widening-when-constructing-tuple/92840 "2023-01-12T02:36:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [January 12, 2023, 2:36am UTC](https://discourse.julialang.org/t/surprising-type-widening-when-constructing-tuple/92840/1 "2023-01-12T02:36:43Z")

</div>

Dear Julia type inference masters,

I am facing some inference/performance problems which look like they could be circumvented, but I don’t know enough about what is going on here.

```julia
struct ValType{T, V} end
ValTypeof(v::T) where T = ValType{T, v}

surprising_type_widening(i) = Tuple{Int, ValTypeof(i)}
@code_warntype surprising_type_widening(3)

```

outputs

```julia
MethodInstance for surprising_type_widening(::Int64)
  from surprising_type_widening(i) in Main at REPL[6]:1
Arguments
  #self#::Core.Const(surprising_type_widening)
  i::Int64
Body::Type{<:Tuple{Int64, Any}}
1 ─ %1 = Main.ValTypeof(i)::Type{ValType{Int64, _A}} where _A
│ %2 = Core.apply_type(Main.Tuple, Main.Int, %1)::Type{<:Tuple{Int64, Any}}
└── return %2

```

where you can see that despite it could have inferred `Type{<:Tuple{Int64, ValType{Int64}}}`, it widens to `Type{<:Tuple{Int64, Any}}`

any help about why this happens and how to circumvent it is highly appreciated  
(tested on julia version 1.8.1 and nightly 1.10.0-DEV.350)

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [January 12, 2023, 3:13am UTC](https://discourse.julialang.org/t/surprising-type-widening-when-constructing-tuple/92840/3 "2023-01-12T03:13:44Z")

</div>

> [@schlichtanders](#):
>
> `ValTypeof(v::T) where T = ValType{T, v}`

I mean this is the classical type instability right? your output type depends on value of `v`, not type of `v`

you can workaround this by using `Val()`

```julia
julia> ValTypeof(::Val{v}) where v = ValType{typeof(v), v}
ValTypeof (generic function with 2 methods)

julia> ValTypeof(Val(3))
ValType{Int64, 3}

julia> @code_warntype ValTypeof(Val(3))
MethodInstance for ValTypeof(::Val{3})
  from ValTypeof(::Val{v}) where v @ Main REPL[15]:1
Static Parameters
  v = 3
Arguments
  #self#::Core.Const(ValTypeof)
  _::Core.Const(Val{3}())
Body::Type{ValType{Int64, 3}}
1 ─ %1 = Main.ValType::Core.Const(ValType)
│ %2 = Main.typeof($(Expr(:static_parameter, 1)))::Core.Const(Int64)
│ %3 = Core.apply_type(%1, %2, $(Expr(:static_parameter, 1)))::Core.Const(ValType{Int64, 3})
└── return %3

```

---

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [January 12, 2023, 3:18am UTC](https://discourse.julialang.org/t/surprising-type-widening-when-constructing-tuple/92840/4 "2023-01-12T03:18:58Z")

</div>

yes, I agree this is a type instability. Such instabilities occur in my code.

What I would like to improve is the widening strategy. Currently my instable ValTypes are widened to `Any`, while I would like them to be widened to `ValType{Int}`, which at least seems intuitively possible.
