Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

type inference and tuples #10352

Closed
amartgon opened this issue Feb 27, 2015 · 4 comments
Closed

type inference and tuples #10352

amartgon opened this issue Feb 27, 2015 · 4 comments
Labels
types and dispatch Types, subtyping and method dispatch

Comments

@amartgon
Copy link

These two functions look equivalent, but type inference behaves differently with them. Apparently, it works well for f2 but not for f1. Can this be considered a bug? It is similar but not identical to #4846 (closed).

function f1(x::Float64, y::Int64, z::Int64)
    res::(Float64, (Int64, Int64)) = (x, (y, z))
    res
end

function f2(x::Float64, y::Int64, z::Int64)
    (x, (y, z))
end

println(@code_typed(f1(1.0, 2, 3)))
#prints:
#Any[:($(Expr(:lambda, Any[:x,:y,:z], Any[Any[:res],Any[Any[:x,Float64,0],Any[:y,Int64,0],Any[:z,Int64,0],Any[:res,Any,18]],Any[],Any[(Float64,(Int64,Int64)),((Int64,I\
nt64),),(Int64,Int64),(Float64,),Float64,(Int64,Int64),Float64,(Int64,Int64)]], :(begin  # /tmp/test.jl, line 5:
#        GenSym(6) = x::Float64
#        GenSym(7) = (top(tuple))(y::Int64,z::Int64)::(Int64,Int64)
#        GenSym(4) = GenSym(6)
#        GenSym(5) = GenSym(7)
#        GenSym(2) = GenSym(5)
#        res = (top(typeassert))(tuple(GenSym(4),tuple((top(tupleref))(GenSym(2),1)::Int64,(top(tupleref))(GenSym(2),2)::Int64)::(Int64,Int64))::(Float64,(Int64,Int64)\
),(top(tuple))(Float64,(Int64,Int64))::(Type{Float64},(Type{Int64},Type{Int64})))::ANY # line 6:
#        return res
#    end::ANY))))]

println(@code_typed(f2(1.0, 2, 3)))
# Prints:
#Any[:($(Expr(:lambda, Any[:x,:y,:z], Any[Any[],Any[Any[:x,Float64,0],Any[:y,Int64,0],Any[:z,Int64,0]],Any[],Any[]], :(begin  # /tmp/test.jl, line 10:
#        return (top(tuple))(x::Float64,(top(tuple))(y::Int64,z::Int64)::(Int64,Int64))::(Float64,(Int64,Int64))
#    end::(Float64,(Int64,Int64))))))]
@vtjnash
Copy link
Member

vtjnash commented Feb 28, 2015

the issue lies with the t_func definition for typeassert in inference not able to handle recursive type-tuples. of course, you could also just leave off the type-assert and then you wouldn't have any issues here :)

julia> Base.t_func[Base.typeassert][3](nothing, Any, (Type{Int}, (Type{Int},)))
Any

(tuple_to_Type in jltypes.c appears that it may have a similar issue)

@JeffBezanson
Copy link
Member

Hopefully will be fixed as part of #10380

@ihnorton ihnorton added the types and dispatch Types, subtyping and method dispatch label Mar 7, 2015
@yuyichao
Copy link
Contributor

yuyichao commented May 6, 2015

Should this be considered fixed? As shown below, the type inference infers the same types and they also generate identical llvm code.

julia> function f1(x::Float64, y::Int64, z::Int64)
       res::Tuple{Float64, Tuple{Int64, Int64}} = (x, (y, z))
       res
       end
f1 (generic function with 1 method)

julia> function f2(x::Float64, y::Int64, z::Int64)
       (x, (y, z))
       end
f2 (generic function with 1 method)

julia> @code_typed f1(1.0, 2, 3)
1-element Array{Any,1}:
 :($(Expr(:lambda, Any[:x,:y,:z], Any[Any[:res],Any[Any[:x,Float64,0],Any[:y,Int64,0],Any[:z,Int64,0],Any[:res,Tuple{Float64,Tuple{Int64,Int64}},18]],Any[],Any[Tuple{Float64,Tuple{Int64,Int64}},Tuple{Int64,Int64},Float64,Tuple{Int64,Int64}]], :(begin  # none, line 2:
        GenSym(2) = x::Float64
        GenSym(3) = (top(tuple))(y::Int64,z::Int64)::Tuple{Int64,Int64}
        GenSym(1) = GenSym(3)
        res = tuple(GenSym(2),tuple(getfield(GenSym(1),1)::Int64,(top(getfield))(GenSym(1),2)::Int64)::Tuple{Int64,Int64})::Tuple{Float64,Tuple{Int64,Int64}} # line 3:
        return res::Tuple{Float64,Tuple{Int64,Int64}}
    end::Tuple{Float64,Tuple{Int64,Int64}}))))

julia> @code_typed f2(1.0, 2, 3)
1-element Array{Any,1}:
 :($(Expr(:lambda, Any[:x,:y,:z], Any[Any[],Any[Any[:x,Float64,0],Any[:y,Int64,0],Any[:z,Int64,0]],Any[],Any[]], :(begin  # none, line 2:
        return (top(tuple))(x::Float64,(top(tuple))(y::Int64,z::Int64)::Tuple{Int64,Int64})::Tuple{Float64,Tuple{Int64,Int64}}
    end::Tuple{Float64,Tuple{Int64,Int64}}))))

julia> @code_llvm f1(1.0, 2, 3)

define { double, [2 x i64] } @julia_f1_44460(double, i64, i64) {                  
top:                                                                              
  %3 = insertvalue { double, [2 x i64] } undef, double %0, 0                      
  %4 = insertvalue [2 x i64] undef, i64 %1, 0                                     
  %5 = insertvalue [2 x i64] %4, i64 %2, 1                                        
  %6 = insertvalue { double, [2 x i64] } %3, [2 x i64] %5, 1                      
  ret { double, [2 x i64] } %6                                                    
}                                                                                 

julia> @code_llvm f2(1.0, 2, 3)

define { double, [2 x i64] } @julia_f2_44461(double, i64, i64) {                  
top:                                                                              
  %3 = insertvalue { double, [2 x i64] } undef, double %0, 0                      
  %4 = insertvalue [2 x i64] undef, i64 %1, 0                                     
  %5 = insertvalue [2 x i64] %4, i64 %2, 1                                        
  %6 = insertvalue { double, [2 x i64] } %3, [2 x i64] %5, 1                      
  ret { double, [2 x i64] } %6                                                    
}                                                                                 

@carnaval
Copy link
Contributor

carnaval commented May 6, 2015

@yuyichao thanks, it is indeed fixed by the tuple revamp.

@carnaval carnaval closed this as completed May 6, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

No branches or pull requests

6 participants