Closed
Description
In v1.10.0-beta2 I get
julia> f(v, x) = (1 .- (v ./ x) .^ 2)
f (generic function with 1 method)
julia> code_warntype(f, Tuple{Vector{Float64}, Float64})
MethodInstance for f(::Vector{Float64}, ::Float64)
from f(v, x) @ Main REPL[1]:1
Arguments
#self#::Core.Const(f)
v::Vector{Float64}
x::Float64
Body::Union{Vector, BitVector}
1 ─ %1 = Main.:-::Core.Const(-)
│ %2 = Main.:^::Core.Const(^)
│ %3 = Base.broadcasted(Main.:/, v, x)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}
│ %4 = Core.apply_type(Base.Val, 2)::Core.Const(Val{2})
│ %5 = (%4)()::Core.Const(Val{2}())
│ %6 = Base.broadcasted(Base.literal_pow, %2, %3, %5)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(^)}, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}, Base.RefValue{Val{2}}}}
│ %7 = Base.broadcasted(%1, 1, %6)::Core.PartialStruct(Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(-), Tuple{Int64, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(^)}, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}, Base.RefValue{Val{2}}}}}}, Any[Core.Const(Base.Broadcast.DefaultArrayStyle{1}()), Core.Const(-), Core.PartialStruct(Tuple{Int64, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(^)}, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}, Base.RefValue{Val{2}}}}}, Any[Core.Const(1), Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(^)}, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}, Base.RefValue{Val{2}}}}]), Nothing])
│ %8 = Base.materialize(%7)::Union{Vector, BitVector}
└── return %8
Return type of f
is inferred as Union{Vector, BitVector}
, but I'm missing how this can be a BitVector
at all.
Interestingly, if I change the definition of f
to f(v, x) = ((v ./ x) .^ 2)
and then change back to f(v, x) = (1 .- (v ./ x) .^ 2)
then this is inferred correctly as Vector{Float64}
:
julia> f(v, x) = ((v ./ x) .^ 2)
f (generic function with 1 method)
julia> code_warntype(f, Tuple{Vector{Float64}, Float64})
MethodInstance for f(::Vector{Float64}, ::Float64)
from f(v, x) @ Main REPL[5]:1
Arguments
#self#::Core.Const(f)
v::Vector{Float64}
x::Float64
Body::Vector{Float64}
1 ─ %1 = Main.:^::Core.Const(^)
│ %2 = Base.broadcasted(Main.:/, v, x)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}
│ %3 = Core.apply_type(Base.Val, 2)::Core.Const(Val{2})
│ %4 = (%3)()::Core.Const(Val{2}())
│ %5 = Base.broadcasted(Base.literal_pow, %1, %2, %4)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(^)}, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}, Base.RefValue{Val{2}}}}
│ %6 = Base.materialize(%5)::Vector{Float64}
└── return %6
julia> f(v, x) = (1 .- (v ./ x) .^ 2)
f (generic function with 1 method)
julia> code_warntype(f, Tuple{Vector{Float64}, Float64})
MethodInstance for f(::Vector{Float64}, ::Float64)
from f(v, x) @ Main REPL[7]:1
Arguments
#self#::Core.Const(f)
v::Vector{Float64}
x::Float64
Body::Vector{Float64}
1 ─ %1 = Main.:-::Core.Const(-)
│ %2 = Main.:^::Core.Const(^)
│ %3 = Base.broadcasted(Main.:/, v, x)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}
│ %4 = Core.apply_type(Base.Val, 2)::Core.Const(Val{2})
│ %5 = (%4)()::Core.Const(Val{2}())
│ %6 = Base.broadcasted(Base.literal_pow, %2, %3, %5)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(^)}, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}, Base.RefValue{Val{2}}}}
│ %7 = Base.broadcasted(%1, 1, %6)::Core.PartialStruct(Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(-), Tuple{Int64, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(^)}, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}, Base.RefValue{Val{2}}}}}}, Any[Core.Const(Base.Broadcast.DefaultArrayStyle{1}()), Core.Const(-), Core.PartialStruct(Tuple{Int64, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(^)}, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}, Base.RefValue{Val{2}}}}}, Any[Core.Const(1), Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(^)}, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}, Base.RefValue{Val{2}}}}]), Nothing])
│ %8 = Base.materialize(%7)::Vector{Float64}
└── return %8
The fact that this depends on previous definitions of the function is quite surprising.
In 1.9.3 I get out-of-the-box the return type Vector{Float64}
julia> code_warntype(f, Tuple{Vector{Float64}, Float64})
MethodInstance for f(::Vector{Float64}, ::Float64)
from f(v, x) @ Main REPL[1]:1
Arguments
#self#::Core.Const(f)
v::Vector{Float64}
x::Float64
Body::Vector{Float64}
1 ─ %1 = Main.:-::Core.Const(-)
│ %2 = Main.:^::Core.Const(^)
│ %3 = Base.broadcasted(Main.:/, v, x)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}
│ %4 = Core.apply_type(Base.Val, 2)::Core.Const(Val{2})
│ %5 = (%4)()::Core.Const(Val{2}())
│ %6 = Base.broadcasted(Base.literal_pow, %2, %3, %5)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(^)}, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}, Base.RefValue{Val{2}}}}
│ %7 = Base.broadcasted(%1, 1, %6)::Core.PartialStruct(Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(-), Tuple{Int64, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(^)}, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}, Base.RefValue{Val{2}}}}}}, Any[Core.Const(-), Core.PartialStruct(Tuple{Int64, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(^)}, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}, Base.RefValue{Val{2}}}}}, Any[Core.Const(1), Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(Base.literal_pow), Tuple{Base.RefValue{typeof(^)}, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Vector{Float64}, Float64}}, Base.RefValue{Val{2}}}}]), Core.Const(nothing)])
│ %8 = Base.materialize(%7)::Vector{Float64}
└── return %8
as expected.