Hey,

consider following two functions, to generate a generator:

```
function f(size; scaling=1.0)
if isnothing(scaling)
scaling = 1.0
end
return (sum(scaling .* Tuple(index)) for index in CartesianIndices(size))
end
function g(size; scaling=1.0)
return (sum(scaling .* Tuple(index)) for index in CartesianIndices(size))
end
```

The two functions, despite called with the same arguments, perform very differently because the type of `scaling`

is not inferred correctly in `f`

:

```
julia> @time collect(g((100, 100)));
0.000019 seconds (2 allocations: 78.203 KiB)
julia> @time collect(f((100, 100)));
0.003087 seconds (50.01 k allocations: 1.450 MiB)
```

The collect is needed because `f`

and `g`

return both generators.

From `@code_warntype`

we see can see the issue hat one returns generator where element type `Float64`

is returned:

```
julia> @code_warntype f((100, 100))
Variables
#self#::Core.Const(f)
size::Tuple{Int64, Int64}
Body::Base.Generator{CartesianIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}, var"#5#6"}
1 ─ %1 = Main.:(var"#f#4")(1.0, #self#, size)::Base.Generator{CartesianIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}, var"#5#6"}
└── return %1
julia> @code_warntype (g((100, 100)))
Variables
#self#::Core.Const(g)
size::Tuple{Int64, Int64}
Body::Base.Generator{CartesianIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}, var"#8#9"{Float64}}
1 ─ %1 = Main.:(var"#g#7")(1.0, #self#, size)::Core.PartialStruct(Base.Generator{CartesianIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}, var"#8#9"{Float64}}, Any[Core.Const(var"#8#9"{Float64}(1.0)), CartesianIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}])
└── return %1
```

I don’t really understand why it doesn’t infer the type correctly? Isn’t the generator generated after we checked that it isn’t nothing?

Even after enforcing the type, it fails:

```
julia> function f2(size; scaling::Float64=1.0)
if isnothing(scaling)
scaling = 1.0
end
return (sum(scaling .* Tuple(index)) for index in CartesianIndices(size))
end
f2 (generic function with 1 method)
julia> @time collect(f2((100, 100)));
0.013903 seconds (64.73 k allocations: 2.305 MiB, 81.88% compilation time)
julia> @time collect(f2((100, 100)));
0.003256 seconds (50.01 k allocations: 1.450 MiB)
julia> @code_warntype f2((100, 100))
Variables
#self#::Core.Const(f2)
size::Tuple{Int64, Int64}
Body::Base.Generator{CartesianIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}, var"#32#33"}
1 ─ %1 = Main.:(var"#f2#31")(1.0, #self#, size)::Base.Generator{CartesianIndices{2, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}, var"#32#33"}
└── return %1
```

I would very appreciate if somebody could explain that

Thanks a lot!

Felix