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.
>>> >>>
>>> >>>
>>> >
>>>
>>
>>

Reply via email to