Interesting. I can reproduce.

Also worth pointing out that just like changing `foo`

to treat `B`

and `C`

the same causes type stability, replacing the `c`

in the function call with `b`

is also type stable with the original foo.

```
julia> @code_warntype foo(A{Float64,0}, b, c, b, b)
Variables:
t<optimized out>
ts::Tuple{C{Float64,2},B{Float64,2},B{Float64,2}}
Body:
begin
(Core.getfield)(ts::Tuple{C{Float64,2},B{Float64,2},B{Float64,2}}, 1)::C{Float64,2}
Core.SSAValue(4) = (Core.getfield)(ts::Tuple{C{Float64,2},B{Float64,2},B{Float64,2}}, 2)::B{Float64,2}
Core.SSAValue(5) = (Core.getfield)(ts::Tuple{C{Float64,2},B{Float64,2},B{Float64,2}}, 3)::B{Float64,2}
# meta: location REPL[4] foo 1
Core.SSAValue(9) = $(Expr(:invoke, MethodInstance for foo(::Type{A{Float64,2}}, ::B{Float64,2}, ::B{Float64,2}, ::Vararg{B{Float64,2},N} where N), :(Main.foo), A{Float64,2}, Core.SSAValue(4), Core.SSAValue(5)))::Type{A{Float64,_1}} where _1
# meta: pop location
return Core.SSAValue(9)
end::Type{A{Float64,_1}} where _1
julia> @code_warntype foo(A{Float64,0}, b, b, b, b)
Variables:
t<optimized out>
ts::Tuple{B{Float64,2},B{Float64,2},B{Float64,2}}
Body:
begin
(Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},B{Float64,2}}, 1)::B{Float64,2}
Core.SSAValue(4) = (Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},B{Float64,2}}, 2)::B{Float64,2}
(Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},B{Float64,2}}, 3)::B{Float64,2}
return A{Float64,0}
end::Type{A{Float64,0}}
```

Curiously, switching the position of c to anywhere but 2nd was type stable:

```
julia> @code_warntype foo(A{Float64,0}, c, b, b, b)
Variables:
t<optimized out>
ts::Tuple{B{Float64,2},B{Float64,2},B{Float64,2}}
Body:
begin
(Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},B{Float64,2}}, 1)::B{Float64,2}
Core.SSAValue(4) = (Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},B{Float64,2}}, 2)::B{Float64,2}
(Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},B{Float64,2}}, 3)::B{Float64,2}
return A{Float64,2}
end::Type{A{Float64,2}}
julia> @code_warntype foo(A{Float64,0}, b, c, b, b)
Variables:
t<optimized out>
ts::Tuple{C{Float64,2},B{Float64,2},B{Float64,2}}
Body:
begin
(Core.getfield)(ts::Tuple{C{Float64,2},B{Float64,2},B{Float64,2}}, 1)::C{Float64,2}
Core.SSAValue(4) = (Core.getfield)(ts::Tuple{C{Float64,2},B{Float64,2},B{Float64,2}}, 2)::B{Float64,2}
Core.SSAValue(5) = (Core.getfield)(ts::Tuple{C{Float64,2},B{Float64,2},B{Float64,2}}, 3)::B{Float64,2}
# meta: location REPL[4] foo 1
Core.SSAValue(9) = $(Expr(:invoke, MethodInstance for foo(::Type{A{Float64,2}}, ::B{Float64,2}, ::B{Float64,2}, ::Vararg{B{Float64,2},N} where N), :(Main.foo), A{Float64,2}, Core.SSAValue(4), Core.SSAValue(5)))::Type{A{Float64,_1}} where _1
# meta: pop location
return Core.SSAValue(9)
end::Type{A{Float64,_1}} where _1
julia> @code_warntype foo(A{Float64,0}, b, b, c, b)
Variables:
t<optimized out>
ts::Tuple{B{Float64,2},C{Float64,2},B{Float64,2}}
Body:
begin
(Core.getfield)(ts::Tuple{B{Float64,2},C{Float64,2},B{Float64,2}}, 1)::B{Float64,2}
Core.SSAValue(4) = (Core.getfield)(ts::Tuple{B{Float64,2},C{Float64,2},B{Float64,2}}, 2)::C{Float64,2}
(Core.getfield)(ts::Tuple{B{Float64,2},C{Float64,2},B{Float64,2}}, 3)::B{Float64,2}
return A{Float64,2}
end::Type{A{Float64,2}}
julia> @code_warntype foo(A{Float64,0}, b, b, b, c)
Variables:
t<optimized out>
ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2}}
Body:
begin
(Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2}}, 1)::B{Float64,2}
Core.SSAValue(4) = (Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2}}, 2)::B{Float64,2}
(Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2}}, 3)::C{Float64,2}
return A{Float64,2}
end::Type{A{Float64,2}}
```

I’ve encountered a problem before where incrementally calling parametric functions made them all type stable, but when jumping ahead they are not. However, I started over in a new session and called them in a different order, and that doesn’t seem to be going on here.

I once again got that specifically the order `b, c, b, b`

is not inferable, but `c`

in the other three locations is.

Throwing extra `b`

s on the end makes it switch back and fourth:

```
julia> @code_warntype foo(A{Float64,0}, b, b, b, c, b)
Variables:
t<optimized out>
ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2}}
Body:
begin
(Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2}}, 1)::B{Float64,2}
Core.SSAValue(4) = (Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2}}, 2)::B{Float64,2}
(Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2}}, 3)::C{Float64,2}
Core.SSAValue(6) = (Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2}}, 4)::B{Float64,2}
return A{Float64,2}
end::Type{A{Float64,2}}
julia> @code_warntype foo(A{Float64,0}, b, b, b, c, b, b)
Variables:
t<optimized out>
ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2},B{Float64,2}}
Body:
begin
(Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2},B{Float64,2}}, 1)::B{Float64,2}
Core.SSAValue(4) = (Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2},B{Float64,2}}, 2)::B{Float64,2}
(Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2},B{Float64,2}}, 3)::C{Float64,2}
Core.SSAValue(6) = (Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2},B{Float64,2}}, 4)::B{Float64,2}
Core.SSAValue(7) = (Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2},B{Float64,2}}, 5)::B{Float64,2}
return A{Float64,2}
end::Type{A{Float64,_1}} where _1
julia> @code_warntype foo(A{Float64,0}, b, b, b, c, b, b, b)
Variables:
t<optimized out>
ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2},B{Float64,2},B{Float64,2}}
Body:
begin
(Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2},B{Float64,2},B{Float64,2}}, 1)::B{Float64,2}
Core.SSAValue(4) = (Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2},B{Float64,2},B{Float64,2}}, 2)::B{Float64,2}
Core.SSAValue(5) = (Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2},B{Float64,2},B{Float64,2}}, 3)::C{Float64,2}
Core.SSAValue(6) = (Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2},B{Float64,2},B{Float64,2}}, 4)::B{Float64,2}
(Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2},B{Float64,2},B{Float64,2}}, 5)::B{Float64,2}
(Core.getfield)(ts::Tuple{B{Float64,2},B{Float64,2},C{Float64,2},B{Float64,2},B{Float64,2},B{Float64,2}}, 6)::B{Float64,2}
return A{Float64,2}
end::Type{A{Float64,2}}
```

I have no idea what is going on.