-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
/
inference.jl
366 lines (300 loc) · 9.05 KB
/
inference.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# This file is a part of Julia. License is MIT: http:https://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 isleaftype(ast12474[1][2])
@test all(isleaftype, ast12474[1][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][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]
# issue #17572
function f17572{A}(::Type{Val{A}})
return Tuple{Int}(Tuple{A}((1,)))
end
# test that inference doesn't error
@test isa(code_typed(f17572, (Type{Val{0}},)), Array)
# === with singleton constants
let f(x) = (x===nothing) ? 1 : 1.0
@test Base.return_types(f, (Void,)) == Any[Int]
end
# issue #16530
type Foo16530a{dim}
c::Vector{NTuple{dim, Float64}}
d::Vector
end
type Foo16530b{dim}
c::Vector{NTuple{dim, Float64}}
end
f16530a() = fieldtype(Foo16530a, :c)
f16530a(c) = fieldtype(Foo16530a, c)
f16530b() = fieldtype(Foo16530b, :c)
f16530b(c) = fieldtype(Foo16530b, c)
let T = Array{Tuple{Vararg{Float64,TypeVar(:dim)}},1},
TTlim = Type{TypeVar(:_,Array{TypeVar(:_,Tuple),1})}
@test f16530a() == T
@test f16530a(:c) == T
@test Base.return_types(f16530a, ()) == Any[TTlim]
@test Base.return_types(f16530b, ()) == Any[TTlim]
@test Base.return_types(f16530b, (Symbol,)) == Any[TTlim]
end
@test f16530a(:d) == Vector
let T1 = Tuple{Int, Float64},
T2 = Tuple{Int, Float32},
T = Tuple{T1, T2}
global f18037
f18037() = fieldtype(T, 1)
f18037(i) = fieldtype(T, i)
@test f18037() === T1
@test f18037(1) === T1
@test f18037(2) === T2
@test Base.return_types(f18037, ()) == Any[Type{T1}]
@test Base.return_types(f18037, (Int,)) == Any[Type{TypeVar(:T, Tuple{Int, AbstractFloat})}]
end
# issue #18015
type Triple18015
a::Int
b::Int
c::Int
end
a18015(tri) = tri.a
b18015(tri) = tri.b
c18015(tri) = tri.c
setabc18015!(tri, a, b, c) = (tri.a = a; tri.b = b; tri.c = c)
let tri = Triple18015(1, 2, 3)
setabc18015!(tri, b18015(tri), c18015(tri), a18015(tri))
@test tri.a === 2 && tri.b === 3 && tri.c === 1
end
# issue #18222
f18222{T<:AbstractFloat}(::Union{T, Int}) = false
f18222(x) = true
g18222(x) = f18222(x)
@test f18222(1) == g18222(1) == true
@test f18222(1.0) == g18222(1.0) == false
# issue #18399
# TODO: this test is rather brittle
type TSlow18399{T}
x::T
end
function hvcat18399(as)
cb = ri->as[ri]
g = Base.Generator(cb, 1)
return g.f(1)
end
function cat_t18399(X...)
for i = 2:1
X[i]
d->i
end
end
C18399 = TSlow18399{Int}(1)
GB18399 = TSlow18399{Int}(1)
function test18399(C)
B = GB18399::Union{TSlow18399{Int},TSlow18399{Any}}
cat_t18399()
cat_t18399(B, B, B)
hvcat18399((C,))
return hvcat18399(((2, 3),))
end
@test test18399(C18399) == (2, 3)