# Why are ref's in structs type unstable?

**URL:** <https://discourse.julialang.org/t/why-are-refs-in-structs-type-unstable/80041>\
**Category:** Performance\
**Tags:** type-stability\
**Created:** [April 26, 2022, 10:31am UTC](https://discourse.julialang.org/t/why-are-refs-in-structs-type-unstable/80041 "2022-04-26T10:31:42Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![tr00](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tr00/32/35710_2.png) [@tr00](https://discourse.julialang.org/u/tr00)\
**Post date:** [April 26, 2022, 10:31am UTC](https://discourse.julialang.org/t/why-are-refs-in-structs-type-unstable/80041/1 "2022-04-26T10:31:42Z")

</div>

Hello Julia Community,

I’ve just came across a small code example which isn’t type stable according to `@code_warntype` but clearly should be, at least according to my understanding of refs.

Here is the example:

```julia
julia> struct Foo
           bar :: Ref{Int}
       end

julia> increment(foo) = foo.bar[] += 1
increment (generic function with 1 method)

julia> @code_warntype increment(Foo(Ref(0)))
Variables
  #self#::Core.Const(increment)
  foo::Foo

Body::Any
1 ─ %1 = Base.getproperty(foo, :bar)::Ref{Int64}
│ %2 = Base.getindex(%1)::Any
│ %3 = (%2 + 1)::Any
│ %4 = Base.getproperty(foo, :bar)::Ref{Int64}
│ Base.setindex!(%4, %3)
└── return %3

```

Is this intended and a misunderstanding on my side or this an unintended bug?

Using `@edit getindex(Ref(0))` shows that the definition of getindex doesnt specialize on the eltype.  
So I could just roll my own Ref implementation, but is this really intended? Was this a decision to reduce compilation times?

(I was using 1.6.0 but it still seems to be there in 1.7.2)

---

<div class="post-metadata">

**Author:** ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)\
**Post date:** [April 26, 2022, 10:45am UTC](https://discourse.julialang.org/t/why-are-refs-in-structs-type-unstable/80041/2 "2022-04-26T10:45:16Z")

</div>

`Ref{Int}` is an abstract type. `Ref(0)` creates a `Base.RefValue{Int}`, which is a concrete subtype of `Base.Ref{Int}`:

```julia
julia> isconcretetype(Ref{Int})
false

julia> Ref{Int}(5)
Base.RefValue{Int64}(5)

julia> isconcretetype(Base.RefValue{Int64})
true

```

Therefore, the struct field should have the type `Base.RefValue{Int}` instead of `Ref{Int}` if you want type stability.

---

<div class="post-metadata">

**Author:** ![pablosanjose](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pablosanjose/32/7006_2.png) [@pablosanjose](https://discourse.julialang.org/u/pablosanjose)\
**Post date:** [April 26, 2022, 12:56pm UTC](https://discourse.julialang.org/t/why-are-refs-in-structs-type-unstable/80041/3 "2022-04-26T12:56:46Z")

</div>

Oh, TIL!

The next question of course is: why do we have a `Ref{T}` and a `RefValue{T}`? Why not just `RefValue{T}`?

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [April 26, 2022, 1:30pm UTC](https://discourse.julialang.org/t/why-are-refs-in-structs-type-unstable/80041/4 "2022-04-26T13:30:52Z")

</div>

Because there are more kinds of `Ref`s beside `RefValue`s:

```julia
julia> subtypes(Ref)
6-element Vector{Any}:
 Base.CFunction
 Base.RefArray
 Base.RefValue
 Core.Compiler.RefValue
 Core.LLVMPtr
 Ptr

```

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [April 26, 2022, 2:39pm UTC](https://discourse.julialang.org/t/why-are-refs-in-structs-type-unstable/80041/5 "2022-04-26T14:39:15Z")

</div>

`RefArray` in particular is an underrated gem!
