# Strange @code\_warntype

**URL:** https://discourse.julialang.org/t/strange-code-warntype/14002
**Category:** New to Julia
**Created:** [August 24, 2018, 3:24pm UTC](https://discourse.julialang.org/t/strange-code-warntype/14002 "2018-08-24T15:24:52Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)
#### Post date: [August 24, 2018, 3:24pm UTC](https://discourse.julialang.org/t/strange-code-warntype/14002/1 "2018-08-24T15:24:52Z")

</div>

hello, I’ve tried to ensure type stability by using `@code_warntype`. However, something very strange happened: In the following, `closureB()` only differs from `closureA()` with a leading ` if-end` block, which is irrelevant actually. But, a lot of types in `gg()` becomes **`ANY`** , is it a bug??? I’m using JuliaPro-0.6.3.1.

```julia
function closureA(x::Int64)::Function
    oneto3 = Base.OneTo(3)

    function f()
        for i in oneto3
            println(i)
        end
    end

    return f
end

function closureB(x::Int64)::Function
    ### the only difference with closureA()
    if x < 0
        error("abc")
    end
    ### the only difference with closureB()

    oneto3 = Base.OneTo(3)

    function f()
        for i in oneto3
            println(i)
        end
    end

    return f
end

ff = closureA(1)
gg = closureB(1)

julia> @code_warntype ff()
Variables:
  #self#::#f#5{Base.OneTo{Int64}}
  i::Int64
  #temp#::Int64

Body:
  begin
      SSAValue(0) = (Core.getfield)(#self#::#f#5{Base.OneTo{Int64}}, :oneto3)::Base.OneTo{Int64}
      #temp#::Int64 = 1
      3:
      unless (Base.not_int)((#temp#::Int64 === (Base.add_int)((Core.getfield)(SSAValue(0), :stop)::Int64, 1)::Int64)::Bool)::Bool goto 18
      SSAValue(3) = #temp#::Int64
      SSAValue(4) = (Base.add_int)(#temp#::Int64, 1)::Int64
      i::Int64 = SSAValue(3)
      #temp#::Int64 = SSAValue(4) # line 6:
      $(Expr(:inbounds, false))
      # meta: location coreio.jl println 5
      SSAValue(2) = (Core.typeassert)(Base.STDOUT, Base.IO)::IO
      # meta: pop location
      $(Expr(:inbounds, :pop))
      (Base.print)(SSAValue(2), i::Int64, $(QuoteNode('\n')))::Void
      16:
      goto 3
      18:
      return
  end::Void

julia> @code_warntype gg()
Variables:
  #self#::#f#8
  i::Any
  #temp#::Any

Body:
  begin
      SSAValue(0) = (Core.getfield)((Core.getfield)(#self#::#f#8, :oneto3)::Any, :contents)::Any
      #temp#::Any = (Base.start)(SSAValue(0))::Any
      3:
      unless !((Base.done)(SSAValue(0), #temp#::Any)::Any)::Any goto 12
      SSAValue(1) = (Base.next)(SSAValue(0), #temp#::Any)::Any
      i::Any = (Core.getfield)(SSAValue(1), 1)::Any
      #temp#::Any = (Core.getfield)(SSAValue(1), 2)::Any # line 12:
      (Main.println)(i::Any)::Void
      10:
      goto 3
      12:
      return
  end::Void

```

---

<div class="post-metadata">

### Author: ![Wenjie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wenjie/32/10123_2.png) [@Wenjie](https://discourse.julialang.org/u/Wenjie)
#### Post date: [August 24, 2018, 3:34pm UTC](https://discourse.julialang.org/t/strange-code-warntype/14002/2 "2018-08-24T15:34:23Z")

</div>

Tried your code on v1.0. It works fine:

```julia
julia> @code_warntype gg()
Body::Nothing
11 1 ── %1 = (Core.getfield)(#self#, :oneto3)::Base.OneTo{Int64}   
   │ %2 = (Base.getfield)(%1, :stop)::Int64 │╻╷╷ iterate
   │ %3 = (Base.slt_int)(%2, 1)::Bool ││╻ isempty
   └─── goto #3 if not %3 ││  
   2 ── goto #4 ││  
   3 ── goto #4 ││  
   4 ┄─ %7 = φ (#2 => true, #3 => false)::Bool │   
   │ %8 = φ (#3 => 1)::Int64 │   
   │ %9 = φ (#3 => 1)::Int64 │   
   │ %10 = (Base.not_int)(%7)::Bool │   
   └─── goto #10 if not %10 │   
   5 ┄─ %12 = φ (#4 => %8, #9 => %21)::Int64 │   
   │ %13 = φ (#4 => %9, #9 => %22)::Int64 │   
12 │ invoke Main.println(%12::Int64) │   
   │ %15 = (Base.getfield)(%1, :stop)::Int64 ││╻╷ last
   │ %16 = (%13 === %15)::Bool ││╻ ==
   └─── goto #7 if not %16 ││  
   6 ── goto #8 ││  
   7 ── %19 = (Base.add_int)(%13, 1)::Int64 ││╻ +
   └─── goto #8 │╻ iterate
   8 ┄─ %21 = φ (#7 => %19)::Int64 │   
   │ %22 = φ (#7 => %19)::Int64 │   
   │ %23 = φ (#6 => true, #7 => false)::Bool │   
   │ %24 = (Base.not_int)(%23)::Bool │   
   └─── goto #10 if not %24 │   
   9 ── goto #5 │   
   10 ─ return │   

```

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 24, 2018, 3:36pm UTC](https://discourse.julialang.org/t/strange-code-warntype/14002/3 "2018-08-24T15:36:32Z")

</div>

The issue to track for this is [performance of captured variables in closures · Issue #15276 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/15276).

---

<div class="post-metadata">

### Author: ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)
#### Post date: [August 24, 2018, 3:40pm UTC](https://discourse.julialang.org/t/strange-code-warntype/14002/4 "2018-08-24T15:40:40Z")

</div>

thanks.

just a silly question: could I have more than one version of Julia installed? (wanna know before crashing everything)

---

<div class="post-metadata">

### Author: ![Wenjie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wenjie/32/10123_2.png) [@Wenjie](https://discourse.julialang.org/u/Wenjie)
#### Post date: [August 24, 2018, 3:49pm UTC](https://discourse.julialang.org/t/strange-code-warntype/14002/5 "2018-08-24T15:49:56Z")

</div>

> could I have more than one version of Julia installed? (wanna know before crashing everything)

I am not the perfect person to answer this question. I only know, in Linux, you can download the binaries for various versions, but I’m not sure whether the packages of various versions are by default installed at the same place (hopefully not).

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 24, 2018, 3:52pm UTC](https://discourse.julialang.org/t/strange-code-warntype/14002/6 "2018-08-24T15:52:34Z")

</div>

Yes, there is no problem with multiple installations.

---

<div class="post-metadata">

### Author: ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)
#### Post date: [August 24, 2018, 3:55pm UTC](https://discourse.julialang.org/t/strange-code-warntype/14002/7 "2018-08-24T15:55:00Z")

</div>

performance-wise, should I treat those “captured variables in closure” like global variables and declare them with `const` ? for example:

```julia

function closure(x::Int64)
    const y = fill(x, 3) # "const" needed here for performance ???

    function f(z::Int64)
        y .+= z
        println(y)
    end

    return f
end

```

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 24, 2018, 3:57pm UTC](https://discourse.julialang.org/t/strange-code-warntype/14002/8 "2018-08-24T15:57:27Z")

</div>

`const` doesn’t do anything in local scope. There are some workaround in that issue including using `let` blocks and type annotations.

---

<div class="post-metadata">

### Author: ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)
#### Post date: [August 24, 2018, 4:03pm UTC](https://discourse.julialang.org/t/strange-code-warntype/14002/9 "2018-08-24T16:03:53Z")

</div>

> [@kristoffer.carlsson](#):
>
> There are some workaround in that issue including using `let` blocks and type annotations.

could you kindly give an example (when u’re free) ?

I just don’t know how to let the compiler knows the type of those “captured variables in closure” when the function is “generated”.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 24, 2018, 4:11pm UTC](https://discourse.julialang.org/t/strange-code-warntype/14002/10 "2018-08-24T16:11:36Z")

</div>

```julia
julia> function closureB(x::Int64)::Function
           ### the only difference with closureA()
           if x < 0
               error("abc")
           end
           ### the only difference with closureB()

           oneto3 = Base.OneTo(3)
           local f
           let oneto3 = oneto3
           function f()
               for i in oneto3
                   println(i)
               end
           end
           end

           return f
       end

closureB (generic function with 1 method)

julia> gg = closureB(1)
(::f) (generic function with 1 method)

julia> @code_warntype gg()
Variables:
  #self#::#f#6{Base.OneTo{Int64}}
  i::Int64
  #temp#::Int64

Body:
  begin
      SSAValue(0) = (Core.getfield)(#self#::#f#6{Base.OneTo{Int64}}, Symbol("#4#oneto3"))::Base.OneTo{Int64}
      #temp#::Int64 = 1
      3:
      unless (Base.not_int)((#temp#::Int64 === (Base.add_int)((Core.getfield)(SSAValue(0), :stop)::Int64, 1)::Int64)::Bool)::Bool goto 18
      SSAValue(3) = #temp#::Int64
      SSAValue(4) = (Base.add_int)(#temp#::Int64, 1)::Int64
      i::Int64 = SSAValue(3)
      #temp#::Int64 = SSAValue(4) # line 13:
      $(Expr(:inbounds, false))
      # meta: location coreio.jl println 5
      SSAValue(2) = (Core.typeassert)(Base.STDOUT, Base.IO)::IO
      # meta: pop location
      $(Expr(:inbounds, :pop))
      (Base.print)(SSAValue(2), i::Int64, $(QuoteNode('\n')))::Void
      16:
      goto 3
      18:
      return
  end::Void

```
