shithub: mc

Download patch

ref: 5c7910da4770a4495e90eb5c243993ec778d4e68
parent: c8c4b88ecadf05438561c05f97500e35843218c4
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Sep 28 20:19:22 EDT 2015

Complain about missing trait impls.

    Because exploding with an abort is confusing for the user.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -2348,6 +2348,24 @@
     popstab();
 }
 
+void verify(Inferstate *st, Node *f)
+{
+    Node *n;
+    size_t i;
+
+    pushstab(f->file.globls);
+    /* for now, traits can only be declared globally */
+    for (i = 0; i < f->file.nstmts; i++) {
+        if (f->file.stmts[i]->type == Nimpl) {
+            n = f->file.stmts[i];
+            /* we merge, so we need to get it back again when error checking */
+            if (n->impl.isproto)
+                fatal(n, "missing implementation for prototype '%s %s'",
+                    namestr(n->impl.traitname), tystr(n->impl.type));
+        }
+    }
+}
+
 void infer(Node *file)
 {
     Inferstate st = {0,};
@@ -2366,5 +2384,6 @@
     /* and replace type vars with actual types */
     typesub(&st, file, 0);
     specialize(&st, file);
+    verify(&st, file);
 }
 
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -373,6 +373,9 @@
 
 static int mergetrait(Trait *old, Trait *new)
 {
+    Vis vis;
+
+    vis = max(old->vis, new->vis);
     if (old->isproto && !new->isproto)
         *old = *new;
     else if (new->isproto && !old->isproto)
@@ -379,6 +382,8 @@
         *new = *old;
     else
         return 0;
+    old->vis = vis;
+    new->vis = vis;
     return 1;
 }
 
@@ -403,6 +408,9 @@
 
 static int mergeimpl(Node *old, Node *new)
 {
+    Vis vis;
+
+    vis = max(old->impl.vis, new->impl.vis);
     if (old->impl.isproto && !new->impl.isproto)
         *old = *new;
     else if (new->impl.isproto && !old->impl.isproto)
@@ -409,6 +417,8 @@
         *new = *old;
     else
         return 0;
+    old->impl.vis = vis;
+    new->impl.vis = vis;
     return 1;
 }