Skip to content

Commit

Permalink
allow nested combinations of (named)tuples, symbols, and bits as type…
Browse files Browse the repository at this point in the history
… parameters
  • Loading branch information
JeffBezanson committed Aug 10, 2022
1 parent 686afd3 commit 48443e5
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 10 deletions.
22 changes: 15 additions & 7 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -1258,20 +1258,28 @@ JL_CALLABLE(jl_f_set_binding_type)

// apply_type -----------------------------------------------------------------

int jl_valid_type_param(jl_value_t *v)
static int is_nestable_type_param(jl_value_t *t)
{
if (jl_is_tuple(v)) {
if (jl_is_namedtuple_type(t))
t = jl_tparam1(t);
if (jl_is_tuple_type(t)) {
// NOTE: tuples of symbols are not currently bits types, but have been
// allowed as type parameters. this is a bit ugly.
jl_value_t *tt = jl_typeof(v);
size_t i, l = jl_nparams(tt);
for(i=0; i < l; i++) {
jl_value_t *pi = jl_tparam(tt,i);
if (!(pi == (jl_value_t*)jl_symbol_type || jl_isbits(pi)))
size_t i, l = jl_nparams(t);
for (i = 0; i < l; i++) {
jl_value_t *pi = jl_tparam(t, i);
if (!(pi == (jl_value_t*)jl_symbol_type || jl_isbits(pi) || is_nestable_type_param(pi)))
return 0;
}
return 1;
}
return 0;
}

int jl_valid_type_param(jl_value_t *v)
{
if (jl_is_tuple(v) || jl_is_namedtuple(v))
return is_nestable_type_param(jl_typeof(v));
if (jl_is_vararg(v))
return 0;
// TODO: maybe more things
Expand Down
9 changes: 6 additions & 3 deletions test/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1987,9 +1987,8 @@ mutable struct TupleParam{P}
x::Bool
end

function tupledispatch(a::TupleParam{(1,:a)})
a.x
end
tupledispatch(a::TupleParam{(1,:a)}) = a.x
tupledispatch(a::TupleParam{(1,(:a,))}) = 42

# tuples can be used as type params
let t1 = TupleParam{(1,:a)}(true),
Expand All @@ -2001,6 +2000,10 @@ let t1 = TupleParam{(1,:a)}(true),
# dispatch works properly
@test tupledispatch(t1) == true
@test_throws MethodError tupledispatch(t2)

@test tupledispatch(TupleParam{(1,(:a,))}(true)) === 42
@test_throws TypeError TupleParam{NamedTuple{(:a,), Tuple{Any}}((1,))}
@test_throws TypeError Val{NamedTuple{(:a,), Tuple{NamedTuple{<:Any,Tuple{Int}}}}(((x=2,),))}
end

# issue #5254
Expand Down

0 comments on commit 48443e5

Please sign in to comment.