From: Jérémie Astor Date: Sun, 30 May 2021 13:06:44 +0000 (+0200) Subject: :art: More on generic specialization X-Git-Tag: nightly~615 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=378a9b894b92a132772c637aeae83aededd73d3f;p=gwion.git :art: More on generic specialization --- diff --git a/ast b/ast index f0007dce..1233e819 160000 --- a/ast +++ b/ast @@ -1 +1 @@ -Subproject commit f0007dceb4ce87d3c1882fa385be805fa1c21b62 +Subproject commit 1233e819aee03cc1239f0461cfe6a2bc02b78edb diff --git a/include/env/type.h b/include/env/type.h index 0b021da4..61563234 100644 --- a/include/env/type.h +++ b/include/env/type.h @@ -83,6 +83,26 @@ ANN static inline Type get_gack(Type t) { return t; // unreachable } +// trait helpers +ANN static inline bool has_trait(const Type t, const Symbol trait) { + ID_List list = t->info->traits; + while(list) { + if(list->xid == trait) + return true; + list = list->next; + } + return false; +} + +ANN static inline ID_List miss_traits(const Type t, const Specialized_List sl) { + ID_List traits = sl->traits; + while(traits) { + if(!has_trait(t, traits->xid)) + return traits; + traits = traits->next; + } + return NULL; +} typedef enum { et_void, et_int, et_bool, et_char, et_float, et_error, et_compound, et_object, et_shred, et_fork, et_event, et_ugen, et_string, et_ptr, et_array, et_gack, diff --git a/src/parse/check_traits.c b/src/parse/check_traits.c index b830a970..079260cd 100644 --- a/src/parse/check_traits.c +++ b/src/parse/check_traits.c @@ -98,7 +98,7 @@ ANN static bool check_trait_functions(const Env env, const Type t, const Trait t return error; } -ANN2(1,2,3) static inline bool trait_nodup(Type t, const Symbol trait, ID_List list) { +ANN2(1,2) static inline bool trait_nodup(Type t, const Symbol trait, ID_List list) { bool nodup = true; do { while(list) { diff --git a/src/parse/func_resolve_tmpl.c b/src/parse/func_resolve_tmpl.c index 12c1b3e4..5ad14d16 100644 --- a/src/parse/func_resolve_tmpl.c +++ b/src/parse/func_resolve_tmpl.c @@ -147,33 +147,13 @@ ANN static Func __find_template_match(const Env env, const Value v, Exp_Call *co return f; } -ANN static inline bool has_trait(const Type t, const Symbol trait) { - ID_List list = t->info->traits; - while(list) { - if(list->xid == trait) - return true; - list = list->next; - } - return false; -} - -ANN static inline bool has_traits(const Type t, const Specialized_List sl) { - ID_List traits = sl->traits; - while(traits) { - if(!has_trait(t, traits->xid)) - return false; - traits = traits->next; - } - return true; -} - ANN static Func _find_template_match(const Env env, const Value v, Exp_Call *const exp) { DECL_OO(const Func, f, = __find_template_match(env, v, exp)); Type_List tl = exp->tmpl->call; Specialized_List sl = f->def->base->tmpl->list; while(tl) { DECL_OO(const Type, t, = known_type(env, tl->td)); - if(!has_traits(t, sl)) + if(miss_traits(t, sl)) return NULL; tl = tl->next; } diff --git a/src/parse/template.c b/src/parse/template.c index af92ddee..1805a942 100644 --- a/src/parse/template.c +++ b/src/parse/template.c @@ -101,6 +101,18 @@ ANN Type _scan_type(const Env env, const Type t, Type_Decl* td) { if(tflag(t, tflag_ntmpl) && !td->types) return t; struct TemplateScan ts = { .t=t, .td=td }; +Type_List tl = td->types; +Specialized_List sl = t->info->cdef->base.tmpl->list; + +while(tl && sl) { + DECL_OO(const Type, t, = known_type(env, tl->td)); + ID_List missing = miss_traits(t, sl); + if(missing) { + ERR_O(tl->td->pos, "does not implement requested trait '{/}%s{0}'", s_name(missing->xid)); + } + tl = tl->next; + sl = sl->next; +} struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=t, .data=(uintptr_t)&ts, .pos=td->pos }; return op_check(env, &opi); } else if(td->types)