-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Misleading warning on ambiguous method definition #5384
Comments
Perhaps we should print type parameters as |
Couldn't they be renamed to be unique? Of course, it's a question of unique among what set of identifiers, with bad luck they can start to collide with argument and type names, and maybe more... |
They could, but that's such a pain. |
Aren't there cases where two types are the same, and shouldn't this be visible somehow? Calling them |
From a user's perspective I think that if the warning is going to suggest a solution it should suggest one that works i.e. one I can just copy and paste. I found it a bit confusing that the suggested code didn't have the template parameters defined. I think the perfect warning message would be:
but I the one I listed in my original post would be good enough. |
All of those type parameters are gratuitous. You could just do this: Warning: New definition
==(Any,Foo) at none:1
is ambiguous with:
==(Foo,Any) at none:1.
To fix, define
==(Foo,Foo)
before the new definition. The real problem is how type vars are printed in this context (and in others, since there's no input syntax for them). |
IMO the most confusing case is: julia> f{T}(::Array{T}, ::Array{T}) = 1
f (generic function with 1 method)
julia> f{T}(::Array{T}, ::Array) = 1
f (generic function with 2 methods)
julia> methods(f)
# 2 methods for generic function "f":
f{T}(::Array{T,N},::Array{T,N}) at none:1
f{T}(::Array{T,N},::Array{T,N}) at none:1 |
I did try
The only thing that worked was: |
If so, it's a bug. |
OK, should I raise another issue for that too? |
No, we can leave it all here for now. Unless I'm being really dumb, this does appear to be a problem: julia> immutable Foo{T} end
julia> =={S,T}(lhs::Foo{S},rhs::Foo{T}) = lhs===rhs
== (generic function with 47 methods)
julia> =={S}(lhs::Foo{S},rhs::Any) = false
== (generic function with 48 methods)
julia> =={T}(lhs::Any,rhs::Foo{T}) = false
== (generic function with 49 methods) julia> immutable Foo{T} end
julia> ==(lhs::Foo,rhs::Foo) = lhs===rhs
== (generic function with 47 methods)
julia> =={S}(lhs::Foo{S},rhs::Any) = false
== (generic function with 48 methods)
julia> =={T}(lhs::Any,rhs::Foo{T}) = false
Warning: New definition
==(Any,Foo{T}) at none:1
is ambiguous with:
==(Foo{S},Any) at none:1.
To fix, define
==(Foo{S},Foo{T})
before the new definition.
== (generic function with 49 methods) |
Come to think about it, I if we don't want to give the typevars unique names, it would still be a huge improvement if the error message in the original post had type parameters on the function name as well,
then you would see that there is something fishy with the last one. |
It wouldn't be too bad --- you can create an environment mapping the parameters of the second signature to new names (as necessary), and then call |
@StefanKarpinski I think this is because matching a type parameter is better than not matching a type parameter, so
Is this frowned upon in some way? julia> immutable Foo{T} end
julia> ==(lhs::Foo{TypeVar(:T)},rhs::Foo{TypeVar(:T)}) = lhs===rhs
== (generic function with 47 methods)
julia> =={T}(lhs::Foo{T},rhs::Any) = false
== (generic function with 48 methods)
julia> =={T}(lhs::Any,rhs::Foo{T}) = false
== (generic function with 49 methods) I find you can do some fun things with it: typealias Index Union(AbstractVector{TypeVar(:I,Integer)}, Integer)
isindex(i::Index) = true
isindex(otherwise) = false
julia> isindex(1)
true
julia> isindex([1,2])
true
julia> isindex([1,2.0])
false (generalization of |
I'm not sure if it's related, but I get the following warning (0.5.0-dev, 0.4): julia> foo(A::AbstractVecOrMat, B::Tridiagonal) = println("tridiagonal")
foo (generic function with 1 method)
julia> foo(A::AbstractVector, B::AbstractMatrix) = println("abstract matrix")
WARNING: New definition
foo(AbstractArray{T<:Any, 1}, AbstractArray{T<:Any, 2}) at none:1
is ambiguous with:
foo(Union{AbstractArray{T<:Any, 1}, AbstractArray{T<:Any, 2}}, Base.LinAlg.Tridiagonal) at none:1.
To fix, define
foo(AbstractArray{T<:Any, 1}, Base.LinAlg.Tridiagonal)
before the new definition.
foo (generic function with 2 methods) The warning can be avoided by inserting the following between the two lines: foo(A::AbstractVector, B::Tridiagonal) = println("tridiagonal vector") Or the first line can be split into separate definitions for |
Close now that no more warnings are printed? |
If I do this:
I get this warning
even though I have already defined
==(Foo{T},Foo{T})
.After a trying lots of alternatives it would seem that the solution is to do:
So I think that the warning is misleading and should be changed to:
The text was updated successfully, but these errors were encountered: