Maybe this is known but I hit this on the latest master.
julia> abstract type A{N, S <: NTuple{N}, T} end
julia> A{2, Tuple{2,2}}
crashes julia with
julia: /home/kc/juliamaster/src/subtype.c:1986: jl_types_equal: Assertion `subtype_ab == 3 || subtype_ab == subtype || jl_has_free_typevars(a) || jl_has_free_typevars(b)' failed.
signal (6): Aborted
in expression starting at REPL[4]:1
gsignal at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
abort at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
unknown function (ip: 0x7fd11a26a728)
__assert_fail at /lib/x86_64-linux-gnu/libc.so.6 (unknown line)
jl_types_equal at /home/kc/juliamaster/src/subtype.c:1986
inst_datatype_inner at /home/kc/juliamaster/src/jltypes.c:1270
inst_type_w_ at /home/kc/juliamaster/src/jltypes.c:1707
jl_instantiate_unionall at /home/kc/juliamaster/src/jltypes.c:1019
jl_wrap_Type at /home/kc/juliamaster/src/jltypes.c:1751 [inlined]
jl_inst_arg_tuple_type at /home/kc/juliamaster/src/jltypes.c:1537
arg_type_tuple at /home/kc/juliamaster/src/gf.c:1791 [inlined]
jl_lookup_generic_ at /home/kc/juliamaster/src/gf.c:2318 [inlined]
jl_apply_generic at /home/kc/juliamaster/src/gf.c:2370
jl_apply at /home/kc/juliamaster/src/julia.h:1687 [inlined]
do_call at /home/kc/juliamaster/src/interpreter.c:115
eval_value at /home/kc/juliamaster/src/interpreter.c:204
eval_stmt_value at /home/kc/juliamaster/src/interpreter.c:155 [inlined]
eval_body at /home/kc/juliamaster/src/interpreter.c:575
jl_interpret_toplevel_thunk at /home/kc/juliamaster/src/interpreter.c:669
jl_toplevel_eval_flex at /home/kc/juliamaster/src/toplevel.c:837
jl_toplevel_eval_flex at /home/kc/juliamaster/src/toplevel.c:785
jl_obvious_subtype needs to be more defensive here, it seems:
julia> abstract type Foo{A,B,C} end
julia> subtype_ab = Ref(true)
Base.RefValue{Bool}(true)
julia> ccall(:jl_obvious_subtype, Bool, (Any,Any,Ptr{Bool}), Foo{2, Tuple{2,2}}, Foo{N,S,T} where {N, S<:NTuple{N}, T}, subtype_ab)
true
julia> subtype_ab[]
false
The return value true signifies that jl_obvious_subtype reached a conclusion, namely that Foo{2, Tuple{2,2}} is not a subtype of Foo{N,S,T} where {N, S<:NTuple{N}, T} (as reported by subtype_ab). Alas, it is. And in a debug build this is verified by forall_exists_subtype and the inconsistency triggers the assertion.
Not specifically "more defensive", but doing "specified correctly" would be helpful 馃槣:
diff --git a/src/subtype.c b/src/subtype.c
index 34590492c1..f5beb922d8 100644
--- a/src/subtype.c
+++ b/src/subtype.c
@@ -1518,7 +1518,8 @@ static int concrete_min(jl_value_t *t)
return count;
return count + concrete_min(((jl_uniontype_t*)t)->b);
}
- return 2; // up to infinite
+ assert(!jl_is_kind(t));
+ return 1; // a non-Type is also considered concrete
}
static jl_value_t *find_var_body(jl_value_t *t, jl_tvar_t *v)
Most helpful comment
Not specifically "more defensive", but doing "specified correctly" would be helpful 馃槣: