Oh, good stuff, Andreas – how'd you go about looking for this? Can you open an issue about this? We should really make sure that all convert methods are well-behaved.
On Tue, Jun 2, 2015 at 11:25 AM, Andreas Noack <andreasnoackjen...@gmail.com > wrote: > 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> wrote: >> >>> On Mon, Jun 1, 2015 at 6:03 PM, Stefan Karpinski <ste...@karpinski.org> >>> 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> >>> >>> > 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. >>> >>> >>> >>> >>> > >>> >> >>