Skip to content

Mysterious inference failure that can be solved by redefining function #35537

@baggepinnen

Description

@baggepinnen

In a fresh julia session (v1.4.1), the following type inference test fails

x = [ones(3) for _ in 1:2]
s1(x) = x ./ sum(x)
testf(x) = s1.(x)
@inferred testf(x)

if

s1(x) = x ./ sum(x)
testf(x) = s1.(x)

are redefined, the test passes.
Output of REPL session below

               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.4.1 (2020-04-14)
 _/ |\__'_|_|_|\__'_|  |  
|__/                   |

julia> x = [ones(3) for _ in 1:2]

2-element Array{Array{Float64,1},1}:
 [1.0, 1.0, 1.0]
 [1.0, 1.0, 1.0]

julia> s1(x) = x ./ sum(x)
s1 (generic function with 1 method)

julia> testf(x) = s1.(x)
testf (generic function with 1 method)

julia> @inferred testf(x)
ERROR: return type Array{Array{Float64,1},1} does not match inferred return type Any
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] top-level scope at none:0

julia> s1(x) = x ./ sum(x)
s1 (generic function with 1 method)

julia> testf(x) = s1.(x)
testf (generic function with 1 method)

julia> @inferred testf(x)
2-element Array{Array{Float64,1},1}:
 [0.3333333333333333, 0.3333333333333333, 0.3333333333333333]
 [0.3333333333333333, 0.3333333333333333, 0.3333333333333333]

I think the problem lies in the broadcast machinery, if I replace

testf(x) = map(s1,x)

the problem goes away.
Cthulhu.jl points at Base.Broadcast.copy(%7::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Tuple{Base.OneTo{Int64}},typeof(s1),Tuple{Array{Array{Float64,1},1}}})::Any being the problem:

Body::Any
1 ─ %1 = Core.tuple(x)::Tuple{Array{Array{Float64,1},1}}
│   %2 = Base.arraysize(x, 1)::Int64
│   %3 = Base.slt_int(%2, 0)::Bool
│   %4 = Base.ifelse(%3, 0, %2)::Int64
│   %5 = %new(Base.OneTo{Int64}, %4)::Base.OneTo{Int64}
│   %6 = Core.tuple(%5)::Tuple{Base.OneTo{Int64}}
│   %7 = %new(Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Tuple{Base.OneTo{Int64}},typeof(s1),Tuple{Array{Array{Float64,1},1}}}, s1, %1, %6)::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Tuple{Base.OneTo{Int64}},typeof(s1),Tuple{Array{Array{Float64,1},1}}}
│   %8 = invoke Base.Broadcast.copy(%7::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Tuple{Base.OneTo{Int64}},typeof(s1),Tuple{Array{Array{Float64,1},1}}})::Any
└──      return %8

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions