https://github.com/JuliaLang/julia
Tip revision: 40059ec3fa2aedcfc93634658d3264f0e55470a3 authored by Jeff Bezanson on 28 June 2016, 19:44:22 UTC
specialize `cat` for the common case of cat'ing in one dimension
specialize `cat` for the common case of cat'ing in one dimension
Tip revision: 40059ec
inference.jl
# This file is a part of Julia. License is MIT: http://julialang.org/license
# tests for Core.Inference correctness and precision
# issue 9770
@noinline x9770() = false
function f9770(x)
return if x9770()
g9770(:a, :foo)
else
x
end
end
function g9770(x,y)
return if isa(y, Symbol)
f9770(x)
else
g9770(:a, :foo)
end
end
@test g9770(:a, "c") === :a
@test g9770(:b, :c) === :b
# issue #1628
type I1628{X}
x::X
end
let
# here the potential problem is that the run-time value of static
# parameter X in the I1628 constructor is (DataType,DataType),
# but type inference will track it more accurately as
# (Type{Integer}, Type{Int}).
f1628() = I1628((Integer,Int))
@test isa(f1628(), I1628{Tuple{DataType,DataType}})
end
let
fT{T}(x::T) = T
@test fT(Any) === DataType
@test fT(Int) === DataType
@test fT(Type{Any}) === DataType
@test fT(Type{Int}) === DataType
ff{T}(x::Type{T}) = T
@test ff(Type{Any}) === Type{Any}
@test ff(Type{Int}) === Type{Int}
@test ff(Any) === Any
@test ff(Int) === Int
end
# issue #3182
f3182{T}(::Type{T}) = 0
f3182(x) = 1
function g3182(t::DataType)
# tricky thing here is that DataType is a concrete type, and a
# subtype of Type, but we cannot infer the T in Type{T} just
# by knowing (at compile time) that the argument is a DataType.
# however the ::Type{T} method should still match at run time.
return f3182(t)
end
@test g3182(Complex) == 0
# issue #5906
abstract Outer5906{T}
immutable Inner5906{T}
a:: T
end
immutable Empty5906{T} <: Outer5906{T}
end
immutable Hanoi5906{T} <: Outer5906{T}
a::T
succ :: Outer5906{Inner5906{T}}
Hanoi5906(a) = new(a, Empty5906{Inner5906{T}}())
end
function f5906{T}(h::Hanoi5906{T})
if isa(h.succ, Empty5906) return end
f5906(h.succ)
end
# can cause infinite recursion in type inference via instantiation of
# the type of the `succ` field
@test f5906(Hanoi5906{Int}(1)) === nothing
# issue on the flight from DFW
# (type inference deducing Type{:x} rather than Symbol)
type FooBarDFW{s}; end
fooDFW(p::Type{FooBarDFW}) = string(p.parameters[1])
fooDFW(p) = string(p.parameters[1])
@test fooDFW(FooBarDFW{:x}) == "x" # not ":x"
# Type inference for tuple parameters
immutable fooTuple{s}; end
barTuple1() = fooTuple{(:y,)}()
barTuple2() = fooTuple{tuple(:y)}()
@test Base.return_types(barTuple1,Tuple{})[1] == Base.return_types(barTuple2,Tuple{})[1] == fooTuple{(:y,)}
# issue #12476
function f12476(a)
(k, v) = a
return v
end
@inferred f12476(1.0 => 1)
# issue #12551 (make sure these don't throw in inference)
Base.return_types(unsafe_load, (Ptr{nothing},))
Base.return_types(getindex, (Vector{nothing},))
# issue #12636
module MyColors
abstract Paint{T}
immutable RGB{T<:AbstractFloat} <: Paint{T}
r::T
g::T
b::T
end
myeltype{T}(::Type{Paint{T}}) = T
myeltype{P<:Paint}(::Type{P}) = myeltype(supertype(P))
myeltype(::Type{Any}) = Any
end
@test @inferred(MyColors.myeltype(MyColors.RGB{Float32})) == Float32
@test @inferred(MyColors.myeltype(MyColors.RGB)) == Any
# issue #12826
f12826{I<:Integer}(v::Vector{I}) = v[1]
@test Base.return_types(f12826,Tuple{Array{TypeVar(:I, Integer),1}})[1] == Integer
# non-terminating inference, issue #14009
# non-terminating codegen, issue #16201
type A14009{T}; end
A14009{T}(a::T) = A14009{T}()
f14009(a) = rand(Bool) ? f14009(A14009(a)) : a
code_typed(f14009, (Int,))
code_llvm(DevNull, f14009, (Int,))
type B14009{T}; end
g14009(a) = g14009(B14009{a})
code_typed(g14009, (Type{Int},))
code_llvm(DevNull, f14009, (Int,))
# issue #9232
arithtype9232{T<:Real}(::Type{T},::Type{T}) = arithtype9232(T)
result_type9232{T1<:Number,T2<:Number}(::Type{T1}, ::Type{T2}) = arithtype9232(T1, T2)
# this gave a "type too large", but not reliably
@test length(code_typed(result_type9232, Tuple{Type{TypeVar(:_, Union{Float32,Float64})}, Type{TypeVar(:T2, Number)}})) == 1
# issue #10878
function g10878(x; kw...); end
invoke_g10878() = invoke(g10878, Tuple{Any}, 1)
@code_typed invoke_g10878()
code_llvm(DevNull, invoke_g10878, ())
# issue #10930
@test isa(code_typed(promote,(Any,Any,Vararg{Any})), Array)
find_tvar10930{T<:Tuple}(sig::Type{T}) = 1
function find_tvar10930(arg)
if arg<:Tuple
find_tvar10930(arg[random_var_name])
end
return 1
end
@test find_tvar10930(Vararg{Int}) === 1
# issue #12474
@generated function f12474(::Any)
:(for i in 1
end)
end
let
ast12474 = code_typed(f12474, Tuple{Float64})
@test all(isleaftype, ast12474[1].slottypes)
end
# pr #15259
immutable A15259
x
y
end
# check that allocation was ellided
@eval f15259(x,y) = (a = $(Expr(:new, :A15259, :x, :y)); (a.x, a.y, getfield(a,1), getfield(a, 2)))
@test isempty(filter(x -> isa(x,Expr) && x.head === :(=) &&
isa(x.args[2], Expr) && x.args[2].head === :new,
code_typed(f15259, (Any,Int))[1].code))
@test f15259(1,2) == (1,2,1,2)
# check that error cases are still correct
@eval g15259(x,y) = (a = $(Expr(:new, :A15259, :x, :y)); a.z)
@test_throws ErrorException g15259(1,1)
@eval h15259(x,y) = (a = $(Expr(:new, :A15259, :x, :y)); getfield(a, 3))
@test_throws BoundsError h15259(1,1)
# issue #7810
type Foo7810{T<:AbstractVector}
v::T
end
bar7810() = [Foo7810([(a,b) for a in 1:2]) for b in 3:4]
@test Base.return_types(bar7810,Tuple{})[1] == Array{Foo7810{Array{Tuple{Int,Int},1}},1}
# issue #11366
f11366{T}(x::Type{Ref{T}}) = Ref{x}
@test !isleaftype(Base.return_types(f11366, (Any,))[1])
let f(T) = Type{T}
@test Base.return_types(f, Tuple{Type{Int}}) == [Type{Type{Int}}]
end
# issue #9222
function SimpleTest9222{T1<:Real}(pdedata, mu_actual::Vector{T1},
nu_actual::Vector{T1}, v0::Vector{T1}, epsilon::T1, beta::Vector{T1},
delta::T1, l::T1, R::T1, s0::T1, show_trace::Bool = true)
return 0.0
end
function SimpleTest9222{T1<:Real}(pdedata, mu_actual::Vector{T1},
nu_actual::Vector{T1}, v0::Vector{T1}, epsilon::T1, beta::Vector{T1},
delta::T1, l::T1, R::T1)
return SimpleTest9222(pdedata, mu_actual, nu_actual, v0, epsilon,
beta, delta, l, R, v0[1])
end
function foo9222()
v0 = rand(10)
mu_actual = rand(10)
nu_actual = rand(10)
SimpleTest9222(0.0, mu_actual, nu_actual, v0, 0.0, [1.0,1.0], 0.5, 5.0, 20.0)
end
@test 0.0 == foo9222()
# branching based on inferrable conditions
let f(x) = isa(x,Int) ? 1 : ""
@test Base.return_types(f, Tuple{Int}) == [Int]
end
let g() = Int <: Real ? 1 : ""
@test Base.return_types(g, Tuple{}) == [Int]
end
typealias NInt{N} Tuple{Vararg{Int, N}}
@test Base.eltype(NInt) === Int
fNInt(x::NInt) = (x...)
gNInt() = fNInt(x)
@test Base.return_types(gNInt, ()) == Any[NInt]