# Type stability bug in compiler?

**URL:** <https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640>\
**Category:** General Usage\
**Tags:** question\
**Created:** [January 27, 2023, 3:17pm UTC](https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640 "2023-01-27T15:17:10Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)\
**Post date:** [January 27, 2023, 3:17pm UTC](https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640/1 "2023-01-27T15:17:10Z")

</div>

If I change a line of my code from

```julia
cost = typemax(Float64)

```

to

```julia
cost::Float64 = typemax(Float64)

```

then it becomes type stable (Any goes away).

How can it be? The rest of the code is somewhat complicated, and I’m not sure I can reproduce this problem in a simplified setting. It’s in a hot section of code, and I’ve spent hours tracking this down. I have no insight into what makes it type stable by putting the type annotation there.

---

<div class="post-metadata">

**Author:** ![skleinbo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skleinbo/32/36080_2.png) [@skleinbo](https://discourse.julialang.org/u/skleinbo)\
**Post date:** [January 27, 2023, 3:24pm UTC](https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640/2 "2023-01-27T15:24:52Z")

</div>

I’d wager there is at least one other assignment to `cost`, and that is type unstable. Probably inferred as `Union{Float64,...}`. The annotation gives the compiler permission to make it concrete.

Hard to diagnose without a MWE or the output of `@code_warntype`.

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [January 27, 2023, 3:25pm UTC](https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640/3 "2023-01-27T15:25:09Z")

</div>

Is it a global variable? The type assertion tells the compiler that the variable doesn’t change type throughout the evaluation. In general, the compiler can’t assume that about global variables.

---

<div class="post-metadata">

**Author:** ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)\
**Post date:** [January 27, 2023, 3:37pm UTC](https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640/4 "2023-01-27T15:37:29Z")

</div>

```julia
@code_warntype hybrid_ransac_fit(proposer, verifier)
MethodInstance for VisualGeometryToolkit.hybrid_ransac_fit(::Tuple{SamplePc7{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}, typeof(pc7_to_fund_mat)}, ::Tuple{CalcLosses{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}, MaskInliers})
  from hybrid_ransac_fit(proposers, verifiers; test_feasibility, solver_sampler, refine_model, polish_model) in VisualGeometryToolkit at /home/jbpritts/.julia/dev/VisualGeometryToolkit/src/estimators/ransac.jl:39
Arguments
  #self#::Core.Const(VisualGeometryToolkit.hybrid_ransac_fit)
  proposers::Tuple{SamplePc7{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}, typeof(pc7_to_fund_mat)}
  verifiers::Tuple{CalcLosses{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}, MaskInliers}
Locals
  #949::VisualGeometryToolkit.var"#949#954"
  #948::VisualGeometryToolkit.var"#948#953"
Body::Tuple{MMatrix{3, 3, Float64, 9}, BitVector, Any}
1 ─ (#948 = %new(VisualGeometryToolkit.:(var"#948#953")))
│ %2 = #948::Core.Const(VisualGeometryToolkit.var"#948#953"())
│ (#949 = %new(VisualGeometryToolkit.:(var"#949#954")))
│ %4 = #949::Core.Const(VisualGeometryToolkit.var"#949#954"())
│ %5 = VisualGeometryToolkit.:(var"#hybrid_ransac_fit#946")(%2, %4, VisualGeometryToolkit.nothing, VisualGeometryToolkit.nothing, #self#, proposers, verifiers)::Tuple{MMatrix{3, 3, Float64, 9}, BitVector, Any}
└── return %5

```

---

<div class="post-metadata">

**Author:** ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)\
**Post date:** [January 27, 2023, 3:40pm UTC](https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640/5 "2023-01-27T15:40:42Z")

</div>

There are no globals as far as I know. They are all defined withing the context of the function.

---

<div class="post-metadata">

**Author:** ![skleinbo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skleinbo/32/36080_2.png) [@skleinbo](https://discourse.julialang.org/u/skleinbo)\
**Post date:** [January 27, 2023, 3:42pm UTC](https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640/6 "2023-01-27T15:42:40Z")

</div>

Quote the code in triple backticks ``` please 🙂

---

<div class="post-metadata">

**Author:** ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)\
**Post date:** [January 27, 2023, 3:43pm UTC](https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640/7 "2023-01-27T15:43:37Z")

</div>

That Any goes away with a type annotation.

---

<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 27, 2023, 4:15pm UTC](https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640/8 "2023-01-27T16:15:26Z")

</div>

without MWE it’s impossible to help

---

<div class="post-metadata">

**Author:** ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)\
**Post date:** [January 27, 2023, 4:39pm UTC](https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640/9 "2023-01-27T16:39:04Z")

</div>

```julia
 @code_warntype ransac_fit_fund_mat(pc,1.0)
MethodInstance for VisualGeometryToolkit.ransac_fit_fund_mat(::StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}, ::Float64)
  from ransac_fit_fund_mat(pc, σ) in VisualGeometryToolkit at /home/jbpritts/.julia/dev/VisualGeometryToolkit/src/projective/fund_mat/ransac.jl:38
Arguments
  #self#::Core.Const(VisualGeometryToolkit.ransac_fit_fund_mat)
  pc::StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}
  σ@_3::Float64
Locals
  @_4::Int64
  #427::VisualGeometryToolkit.var"#427#428"
  cost::Any
  mask::BitVector
  model::Any
  verifiers::Tuple{NamedTuple{(:calc_loss, :mask_inliers), Tuple{CalcLosses{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}, MaskInliers}}}
  proposers::Tuple{NamedTuple{(:sample, :test_sample, :solve), Tuple{SamplePc7{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}, VisualGeometryToolkit.var"#427#428", typeof(pc7_to_fund_mat)}}}
  mask_inliers::MaskInliers
  calc_loss::CalcLosses{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}
  sample_pc7::SamplePc7{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}
  t::Float64
  σ@_15::Float64
Body::Tuple{Any, BitVector, Any}
1 ─ (σ@_15 = σ@_3)
│ %2 = Core.tuple(σ@_15, 0.0001)::Core.PartialStruct(Tuple{Float64, Float64}, Any[Float64, Core.Const(0.0001)])
│ (σ@_15 = VisualGeometryToolkit.maximum(%2))
│ %4 = Base.getproperty(pc, :first)::Vector{SVector{3, Float64}}
│ %5 = VisualGeometryToolkit.neltype(%4)::Core.Const(Float64)
│ %6 = VisualGeometryToolkit.one(%5)::Core.Const(1.0)
│ (t = VisualGeometryToolkit.cauchy_ρ(3.84, %6))
│ %8 = Core.apply_type(VisualGeometryToolkit.FmMinPtSample, VisualGeometryToolkit.Float64)::Core.Const(MVector{7, SVector{3, Float64}})
│ %9 = (%8)(VisualGeometryToolkit.undef)::MVector{7, SVector{3, Float64}}
│ %10 = Core.apply_type(VisualGeometryToolkit.FmMinPtSample, VisualGeometryToolkit.Float64)::Core.Const(MVector{7, SVector{3, Float64}})
│ %11 = (%10)(VisualGeometryToolkit.undef)::MVector{7, SVector{3, Float64}}
│ %12 = Core.apply_type(VisualGeometryToolkit.MVector, 7, VisualGeometryToolkit.UInt32)::Core.Const(MVector{7, UInt32})│ %13 = (%12)(VisualGeometryToolkit.undef)::MVector{7, UInt32}
│ (sample_pc7 = VisualGeometryToolkit.SamplePc7(pc, %9, %11, %13))
│ %15 = Core.apply_type(VisualGeometryToolkit.Vector, VisualGeometryToolkit.Float64)::Core.Const(Vector{Float64})
│ %16 = VisualGeometryToolkit.length(pc)::Int64
│ %17 = (%15)(VisualGeometryToolkit.undef, %16)::Vector{Float64}
│ (calc_loss = VisualGeometryToolkit.CalcLosses(pc, %17, σ@_15))
│ %19 = VisualGeometryToolkit.length(pc)::Int64
│ %20 = VisualGeometryToolkit.BitVector(VisualGeometryToolkit.undef, %19)::BitVector
│ (mask_inliers = VisualGeometryToolkit.MaskInliers(%20, t::Core.Const(2.756560961162584)))
│ %22 = (:sample, :test_sample, :solve)::Core.Const((:sample, :test_sample, :solve))
│ %23 = Core.apply_type(Core.NamedTuple, %22)::Core.Const(NamedTuple{(:sample, :test_sample, :solve)})
│ %24 = sample_pc7::SamplePc7{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}
│ (#427 = %new(VisualGeometryToolkit.:(var"#427#428")))
│ %26 = #427::Core.Const(VisualGeometryToolkit.var"#427#428"())
│ %27 = Core.tuple(%24, %26, VisualGeometryToolkit.pc7_to_fund_mat)::Tuple{SamplePc7{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}, VisualGeometryToolkit.var"#427#428", typeof(pc7_to_fund_mat)}
│ %28 = (%23)(%27)::NamedTuple{(:sample, :test_sample, :solve), Tuple{SamplePc7{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}, VisualGeometryToolkit.var"#427#428", typeof(pc7_to_fund_mat)}}
│ (proposers = Core.tuple(%28))
│ %30 = (:calc_loss, :mask_inliers)::Core.Const((:calc_loss, :mask_inliers))
│ %31 = Core.apply_type(Core.NamedTuple, %30)::Core.Const(NamedTuple{(:calc_loss, :mask_inliers)})
│ %32 = Core.tuple(calc_loss, mask_inliers::Core.PartialStruct(MaskInliers, Any[BitVector, Core.Const(2.756560961162584)]))::Core.PartialStruct(Tuple{CalcLosses{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}, MaskInliers}, Any[CalcLosses{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}, Core.PartialStruct(MaskInliers, Any[BitVector, Core.Const(2.756560961162584)])])
│ %33 = (%31)(%32)::Core.PartialStruct(NamedTuple{(:calc_loss, :mask_inliers), Tuple{CalcLosses{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}, MaskInliers}}, Any[CalcLosses{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}, Core.PartialStruct(MaskInliers, Any[BitVector, Core.Const(2.756560961162584)])])
│ (verifiers = Core.tuple(%33))
│ %35 = VisualGeometryToolkit.ransac_fit(proposers, verifiers::Core.PartialStruct(Tuple{NamedTuple{(:calc_loss, :mask_inliers), Tuple{CalcLosses{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}, MaskInliers}}}, Any[Core.PartialStruct(NamedTuple{(:calc_loss, :mask_inliers), Tuple{CalcLosses{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}, MaskInliers}}, Any[CalcLosses{StructArrays.StructVector{NamedTuple{(:first, :second), Tuple{SVector{3, Float64}, SVector{3, Float64}}}, NamedTuple{(:first, :second), Tuple{Vector{SVector{3, Float64}}, Vector{SVector{3, Float64}}}}, Int64}}, Core.PartialStruct(MaskInliers, Any[BitVector, Core.Const(2.756560961162584)])])]))::Tuple{Any, BitVector, Any}
│ %36 = Base.indexed_iterate(%35, 1)::Core.PartialStruct(Tuple{Any, Int64}, Any[Any, Core.Const(2)])
│ (model = Core.getfield(%36, 1))
│ (@_4 = Core.getfield(%36, 2))
│ %39 = Base.indexed_iterate(%35, 2, @_4::Core.Const(2))::Core.PartialStruct(Tuple{BitVector, Int64}, Any[BitVector, Core.Const(3)])
│ (mask = Core.getfield(%39, 1))
│ (@_4 = Core.getfield(%39, 2))
│ %42 = Base.indexed_iterate(%35, 3, @_4::Core.Const(3))::Core.PartialStruct(Tuple{Any, Int64}, Any[Any, Core.Const(4)])
│ (cost = Core.getfield(%42, 1))
│ %44 = Core.tuple(model, mask, cost)::Tuple{Any, BitVector, Any}
└── return %44

```

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [January 27, 2023, 4:47pm UTC](https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640/10 "2023-01-27T16:47:46Z")

</div>

A MWE means _other people_ have to be able to run the code example showing the issue. See [Please read: make it easier to help you](https://discourse.julialang.org/t/please-read-make-it-easier-to-help-you/14757) if you haven’t already.

---

<div class="post-metadata">

**Author:** ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)\
**Post date:** [January 27, 2023, 4:50pm UTC](https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640/11 "2023-01-27T16:50:20Z")

</div>

of course I would do this, if it were easy to reproduce.

---

<div class="post-metadata">

**Author:** ![ToucheSir](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/touchesir/32/14411_2.png) [@ToucheSir](https://discourse.julialang.org/u/ToucheSir)\
**Post date:** [January 27, 2023, 4:52pm UTC](https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640/12 "2023-01-27T16:52:46Z")

</div>

Is the behaviour non-deterministic, the code unpublishable or the example reliant on some non-public data? I can’t think of any other reasons for not being able to share something others can work with.

---

<div class="post-metadata">

**Author:** ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)\
**Post date:** [January 27, 2023, 5:00pm UTC](https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640/13 "2023-01-27T17:00:16Z")

</div>

It would take some time to tease out the dependencies, but I could do it. Regardless, I am putting functions in a tuple and passing it into another method so they can be called. Could this be the cause of the type instability? I see that there are FunctionWrappers.jl for something like this, but I don’t understand when it is needed.

```julia
    sample_pc7 = SamplePc7(pc,FmMinPtSample{Float64}(undef),FmMinPtSample{Float64}(undef),MVector{7,UInt32}(undef))
    calc_loss = CalcLosses(pc,Vector{Float64}(undef, length(pc)),σ)
    mask_inliers = MaskInliers(BitVector(undef, length(pc)),t)
    
    proposers = ((sample = sample_pc7, test_sample = (_)->true, solve = pc7_to_fund_mat),)
    verifiers = ((calc_loss = calc_loss, mask_inliers = mask_inliers),)

    model, mask, cost = ransac_fit(proposers, verifiers)

```

---

<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 27, 2023, 5:08pm UTC](https://discourse.julialang.org/t/type-stability-bug-in-compiler/93640/14 "2023-01-27T17:08:45Z")

</div>

> [@prittjam](#):
>
> functions in a tuple and passing it into another method so they can be called. Could this be the cause of the type instability?

yes, because by default functions argument are not specialized for!

[https://docs.julialang.org/en/v1/manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing](https://docs.julialang.org/en/v1/manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing)
