Skip to content

Incorrect method order #7221

@david-moon

Description

@david-moon

In my ongoing, intermittent quest to understand Julia's precise definition of "most specific method", I found this anomaly in Julia 0.3 installed May 17:

ba = trues(3)
@which ba / ba
/(A::Union(AbstractArray{T,2},AbstractArray{T,1}),
  B::Union(AbstractArray{T,2},AbstractArray{T,1})) at linalg/generic.jl:225

It should be the method /(A::BitArray{N},B::BitArray{N}) at bitarray.jl:885, which is more specific according to jl_args_morespecific().

I don't know my way around the internals of Julia real well, but I think jl_method_list_insert() is putting the generic.jl:225 method at the wrong place because it is thought to be more specific than the method /{T<:Number}(x::T<:Number,y::T<:Number) at promotion.jl:191. But, obviously, those two methods have disjoint signatures. Julia's method dispatch mechanism fundamentally depends on the more specific relation being transitive, but it's only transitive if it's always false for disjoint signatures, I think.

Here's a simple test case which does not even depend on the loop at the end of jl_method_list_insert():

f{T<:Number}(::T) = 1
f(::BitArray) = 2
f(::AbstractVecOrMat) = 3
f(ba)  # returns 3, should be 2

But if I define the methods in a different order:

g(::BitArray) = 2
g(::AbstractVecOrMat) = 3
g{T<:Number}(::T) = 1
g(ba)  # returns 2 as expected

But surely in the absence of ambiguity warnings the result of method dispatch should not depend on the order of definition of methods. So there must be a bug somewhere.

Metadata

Metadata

Assignees

Labels

bugIndicates an unexpected problem or unintended behavior

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions