I want a macro that detects (and makes the function fail or warns me) if some variable is not inferred correctly, if the variable’s type is inferred, then it should do nothing.
E.g. something like this:
j = 3
function f(x)
for i in 1:100
@warn_any j
x += j
end
return x
end
can you use @inferred to do what you want? That is,
using Base.Test
function bad(x)
innerbad(x) = if rand() < 0.5 x else true end
@inferred innerbad(x)
end
julia> bad(4)
ERROR: return type Int64 does not match inferred return type Union{Bool, Int64}
Thanks for the tip with @inferred, your code still does the checking at runtime and not compiletime. There is no easy way to give just a warning, but this one quite close to what I want:
macro typestable(x)
Base.Test.@inferred eval(:(()->$x))()
return :()
end
const k = 3
l = 3
function f1(x)
@typestable(k)
for i in 1:10
x += k - 1
end
return x
end
function f2(x)
@typestable(l)
for i in 1:10
x = x + l
end
return x
end
Throws an error when sourcing f2 and gives very nice LLVM assembly for f1:
julia> function f2(x)
+ @typestable(l)
+ for i in 1:10
+ x = x + l
+ end
+ return x
end
ERROR: return type Int64 does not match inferred return type Any
julia> @code_llvm f1(19)
define i64 @julia_f1_71937(i64) #0 {
top:
%1 = add i64 %0, 20
ret i64 %1
}