]> Nishi Git Mirror - gwion.git/commitdiff
:art: More on generic specialization
authorJérémie Astor <fennecdjay@gmail.com>
Sun, 30 May 2021 13:06:44 +0000 (15:06 +0200)
committerJérémie Astor <fennecdjay@gmail.com>
Sun, 30 May 2021 13:06:44 +0000 (15:06 +0200)
ast
include/env/type.h
src/parse/check_traits.c
src/parse/func_resolve_tmpl.c
src/parse/template.c

diff --git a/ast b/ast
index f0007dceb4ce87d3c1882fa385be805fa1c21b62..1233e819aee03cc1239f0461cfe6a2bc02b78edb 160000 (submodule)
--- a/ast
+++ b/ast
@@ -1 +1 @@
-Subproject commit f0007dceb4ce87d3c1882fa385be805fa1c21b62
+Subproject commit 1233e819aee03cc1239f0461cfe6a2bc02b78edb
index 0b021da4cbf2f16e102879cde7c0523f864d617c..615632345cdd495131954df698120753358e9105 100644 (file)
@@ -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,
index b830a97041938c3e3f5810364e5376ecd9d367ad..079260cdd912259212fdcf4096253e0de57c3883 100644 (file)
@@ -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) {
index 12c1b3e4796213ef2d98cb5a9df96ea96bbb2005..5ad14d16a53d9da6eee013081d651c79c5087ee1 100644 (file)
@@ -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;
   }
index af92ddeee696436dd9a8fa195496eb824ff8b047..1805a942d67ca242a258a924e184da37a06c823b 100644 (file)
@@ -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)