Skip to content

Commit

Permalink
args_morespecific for TypeVars: don't fail due to invariance (fixes J…
Browse files Browse the repository at this point in the history
…uliaLang#8652)

In jl_args_morespecific(a,b), one of the important tests is to call
type_match_(b,a), essentially reasoning that if b <: a then a cannot
be more specific than b. The problem is that this test can fail for
an independent reason, like invariance. This takes the drastic step
of keeping invariance=false for the type_match_ check in
jl_args_morespecific. Surprisingly, this doesn't appear to break anything.
  • Loading branch information
timholy authored and mbauman committed Jun 5, 2015
1 parent 0d62888 commit 4238c02
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 3 deletions.
8 changes: 5 additions & 3 deletions src/gf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1126,10 +1126,12 @@ DLLEXPORT int jl_args_morespecific(jl_value_t *a, jl_value_t *b)
return msp;
}
if (jl_has_typevars(a)) {
//if (jl_type_match_morespecific(b,a) == (jl_value_t*)jl_false)
// return 1;
type_match_invariance_mask = 0;
//int result = jl_type_match_morespecific(b,a) == (jl_value_t*)jl_false);
// this rule seems to work better:
if (jl_type_match(b,a) == (jl_value_t*)jl_false)
int result = jl_type_match(b,a) == (jl_value_t*)jl_false;
type_match_invariance_mask = 1;
if (result)
return 1;
}
int nmsp = jl_type_morespecific(b,a);
Expand Down
4 changes: 4 additions & 0 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2718,6 +2718,8 @@ int jl_type_morespecific(jl_value_t *a, jl_value_t *b)

// ----------------------------------------------------------------------------

int type_match_invariance_mask = 1;

static jl_value_t *type_match_(jl_value_t *child, jl_value_t *parent,
cenv_t *env, int morespecific, int invariant);

Expand All @@ -2728,6 +2730,7 @@ static jl_value_t *tuple_match(jl_datatype_t *child, jl_datatype_t *parent,
size_t cl = jl_nparams(child);
size_t pl = jl_nparams(parent);
int mode = 0;
invariant = invariant & type_match_invariance_mask;
while(1) {
int cseq = (ci<cl) && jl_is_vararg_type(jl_tparam(child,ci));
int pseq = (pi<pl) && jl_is_vararg_type(jl_tparam(parent,pi));
Expand Down Expand Up @@ -2778,6 +2781,7 @@ static jl_value_t *type_match_(jl_value_t *child, jl_value_t *parent,
cenv_t *env, int morespecific, int invariant)
{
jl_value_t *tmp, *tmp2;
invariant = invariant & type_match_invariance_mask;
if (jl_is_typector(child))
child = (jl_value_t*)((jl_typector_t*)child)->body;
if (jl_is_typector(parent))
Expand Down
1 change: 1 addition & 0 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ int jl_tuple_subtype(jl_value_t **child, size_t cl, jl_datatype_t *pdt, int ta);

int jl_subtype_invariant(jl_value_t *a, jl_value_t *b, int ta);
jl_value_t *jl_type_match(jl_value_t *a, jl_value_t *b);
extern int type_match_invariance_mask;
jl_value_t *jl_type_match_morespecific(jl_value_t *a, jl_value_t *b);
int jl_types_equal_generic(jl_value_t *a, jl_value_t *b, int useenv);
jl_datatype_t *jl_inst_concrete_tupletype_v(jl_value_t **p, size_t np);
Expand Down
18 changes: 18 additions & 0 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,19 @@ let T = TypeVar(:T,Union(Float64,Array{Float64,1}),true)
testintersect(T,Real,Float64)
end

# issue #8652
args_morespecific(a, b) = ccall(:jl_args_morespecific, Cint, (Any,Any), a, b) != 0
let T1 = TypeVar(:T, Integer, true), T2 = TypeVar(:T, Integer, true)
a = Tuple{Type{T1}, T1}
b2 = Tuple{Type{T2}, Integer}
@test args_morespecific(a, b2)
@test !args_morespecific(b2, a)
a = Tuple{Type{T1}, Ptr{T1}}
b2 = Tuple{Type{T2}, Ptr{Integer}}
@test args_morespecific(a, b2)
@test !args_morespecific(b2, a)
end

# join
@test typejoin(Int8,Int16) === Signed
@test typejoin(Int,AbstractString) === Any
Expand Down Expand Up @@ -317,6 +330,11 @@ let m = sptest3(:a)
@test is(m(0),Symbol)
end

sptest4{T}(x::T, y::T) = 42
sptest4{T}(x::T, y) = 44
@test sptest4(1,2) == 42
@test sptest4(1, "cat") == 44

# closures
function clotest()
c = 0
Expand Down

0 comments on commit 4238c02

Please sign in to comment.