The convert methods for Date.Period, Complex and Rational are inferred to give Any. The problem in Period is because of the use of the value method in line 4 of periods.jl. It extracts a field from an abstract type so even though all subtypes in base have the specified field and have it defined as Int64, the result is inferred to be Any. With three type asserts in the mentioned convert methods, the problem can be fixed, but I don't know if that is desirable.
I found one example where the inference fails for a concrete type, julia> @code_warntype convert(Float64, Complex{Real}(1,0)) Variables: #s59::Type{Float64} z::Complex{Real} Body: begin # complex.jl, line 18: unless (top(getfield))(z::Complex{Real},:im)::Real == 0::Any goto 0 return convert(T,(top(getfield))(z::Complex{Real},:re)::Real)::Any 0: return throw($(Expr(:new, :((top(getfield))(Core,:InexactError)::Type{InexactError})))) end::Any and a place where we might have another problem julia> convert(FloatingPoint, Rational{Integer}(1,1)) 1.0 julia> convert(Float64, Rational{Integer}(1,1)) ERROR: no promotion exists for Float64 and Integer in convert at no file Den mandag den 1. juni 2015 kl. 18.26.01 UTC-4 skrev Stefan Karpinski: > > Either that or there's some convert method that violates that expectation, > in which case inference would correctly decide that it can't predict the > result type. > > On Mon, Jun 1, 2015 at 6:05 PM, Yichao Yu <yyc...@gmail.com <javascript:>> > wrote: > >> On Mon, Jun 1, 2015 at 6:03 PM, Stefan Karpinski <ste...@karpinski.org >> <javascript:>> wrote: >> > Probably not necessary – that code already has more type annotations >> than it >> > needs. The compiler is usually quite good at figuring out types, in this >> > case the global sabotages it. >> >> And I guess typeinf gives up because of the number of methods out >> there (although seems that typeinf also fail on some of them though). >> >> ```julia >> julia> length(methods(convert, Tuple{Type{Float32}, Any})) >> 26 >> >> julia> length(methods(call, Tuple{Type{Float32}, Any})) >> 1 >> ``` >> >> > >> > On Mon, Jun 1, 2015 at 5:50 PM, Scott Jones <scott.pa...@gmail.com >> <javascript:>> >> > wrote: >> >> >> >> Does this mean that in all the code that I've written for UTF >> conversions, >> >> I should decorate the results of the convert with ::T to help the >> compiler's >> >> inference? >> >> >> >> On Monday, June 1, 2015 at 11:31:53 PM UTC+2, Stefan Karpinski wrote: >> >>> >> >>> There's nothing in the language that forces convert(T,x) to return >> >>> something of type T, so type inference has no idea what type b is. The >> >>> method that implements Float32(x) is this: >> >>> >> >>> call{T}(::Type{T}, arg) = convert(T, arg)::T >> >>> >> >>> >> >>> Note the type assertion – so type inference does know the type of the >> >>> result. Related: #1090. >> >>> >> >>> On Mon, Jun 1, 2015 at 5:06 PM, Arch Robison <arch.d....@gmail.com> >> >>> wrote: >> >>>> >> >>>> I was a bit surprised when I tried this example: >> >>>> function foo() >> >>>> global G >> >>>> #b = Float32(G) >> >>>> b = convert(Float32,G) >> >>>> b >> >>>> end >> >>>> >> >>>> G = 0.5 >> >>>> println(foo()) >> >>>> code_warntype(foo,()) >> >>>> and code_warntype deduced that the type of b is ANY instead of >> Float32. >> >>>> Is this a bug or a feature? If I use the constructor syntax instead >> (see >> >>>> comment in code), then the type of b is deduced as Float32. >> >>> >> >>> >> > >> > >