Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Constructor with partially specified type parameters fails to fallback to convert method #18203

Closed
jrevels opened this issue Aug 23, 2016 · 4 comments
Labels
types and dispatch Types, subtyping and method dispatch

Comments

@jrevels
Copy link
Member

jrevels commented Aug 23, 2016

This works:

julia> immutable Foo{X,Y}
           x::X
           y::Y
       end

julia> Base.convert{X,Y}(::Type{Foo{X}}, y::Y) = Foo{X,Y}(one(X), y)

julia> Foo{Int}(1.0)
Foo{Int64,Float64}(1,1.0)

So I would think this should work, but it doesn't:

julia> immutable Foo{X,Y}
          x::X
          y::Y
          z::Int
       end

julia> Base.convert{X,Y}(::Type{Foo{X}}, y::Y, z::Int) = Foo{X,Y}(one(X), y, z)

julia> Foo{Int}(1, 1)
ERROR: MethodError: no method matching Foo{Int64,Y}(::Int64, ::Int64)
Closest candidates are:
  Foo{Int64,Y}{T}(::Any) at sysimg.jl:53

If I define the constructor it's looking for rather than the convert method, it works:

julia> (::Type{Foo{X}}){X,Y}(y::Y, z::Int) = Foo{X,Y}(one(X), y, z)

julia> Foo{Int}(1, 1)
Foo{Int64,Int64}(1,1,1)

Note that I see similar behavior if I parameterize z's type instead of restricting it to Int.

I guess this is similar to #15120, but with multiple fields? Version info just in case:

julia> versioninfo()
Julia Version 0.5.0-rc2+1
Commit d259be5 (2016-08-18 20:15 UTC)
Platform Info:
  System: Darwin (x86_64-apple-darwin13.4.0)
  CPU: Intel(R) Core(TM) i5-4288U CPU @ 2.60GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.7.1 (ORCJIT, haswell)
@tkelman tkelman added the types and dispatch Types, subtyping and method dispatch label Aug 23, 2016
@tomaklutfu
Copy link
Contributor

For correctness, Base.convert{X,Y}(::Type{Foo{X}}, y::Y, z::Int) = Foo{X,Y}(one(x), y, z) or Base.convert{X,Y}(::Type{Foo{X}}, y::Y, z::Int) = Foo{X,Y}(one(X), y, z) ?

@jrevels
Copy link
Member Author

jrevels commented Aug 23, 2016

Sorry - the latter, I made a typo when copying the code over. Good catch, I've fixed it.

@mauro3
Copy link
Contributor

mauro3 commented Aug 25, 2016

Related: #17186

@yuyichao
Copy link
Contributor

I don't think this is supposed to work. We only define fallback to convert for single argument. In fact, I don't think you are supposed to define convert with more than two arguments, it won't be called anywhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
types and dispatch Types, subtyping and method dispatch
Projects
None yet
Development

No branches or pull requests

5 participants