about summary refs log tree commit diff
path: root/src/rt/rust_shape.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/rt/rust_shape.h')
-rw-r--r--src/rt/rust_shape.h33
1 files changed, 25 insertions, 8 deletions
diff --git a/src/rt/rust_shape.h b/src/rt/rust_shape.h
index 64859dbfa35..e71c5c8188f 100644
--- a/src/rt/rust_shape.h
+++ b/src/rt/rust_shape.h
@@ -310,27 +310,44 @@ public:
     }
 
     // Creates type parameters from a type descriptor.
-    static inline type_param *from_tydesc(const type_desc **tydesc,
+    static inline type_param *from_tydesc(const type_desc *tydesc,
                                           arena &arena) {
-        if ((*tydesc)->n_obj_params) {
-            uintptr_t n_obj_params = (*tydesc)->n_obj_params;
+        // In order to find the type parameters of objects and functions, we
+        // have to actually have the data pointer, since we don't statically
+        // know from the type of an object or function which type parameters
+        // it closes over.
+        assert(!tydesc->n_obj_params && "Type-parametric objects and "
+               "functions must go through from_tydesc_and_data() instead!");
+
+        return make(tydesc->first_param, tydesc->n_params, arena);
+    }
+
+    static type_param *from_tydesc_and_data(const type_desc *tydesc,
+                                            uint8_t *dp, arena &arena) {
+        if (tydesc->n_obj_params) {
+            uintptr_t n_obj_params = tydesc->n_obj_params;
             const type_desc **first_param;
             if (n_obj_params & 0x80000000) {
                 // Function closure.
                 DPRINT("n_obj_params FN %lu, tydesc %p, starting at %p\n",
-                       (unsigned long)n_obj_params, tydesc, tydesc + 4);
+                       (unsigned long)n_obj_params, tydesc,
+                       dp + sizeof(uintptr_t) + tydesc->size);
                 n_obj_params &= 0x7fffffff;
+                // FIXME: Is this right?
                 first_param = (const type_desc **)
-                    ((uint8_t *)(tydesc + 4) + (*tydesc)->size);
+                    (dp + sizeof(uintptr_t) + tydesc->size);
             } else {
                 // Object closure.
                 DPRINT("n_obj_params OBJ %lu, tydesc %p, starting at %p\n",
-                       (unsigned long)n_obj_params, tydesc, tydesc + 4);
-                first_param = tydesc + 4;
+                       (unsigned long)n_obj_params, tydesc,
+                       dp + sizeof(uintptr_t) * 2);
+                first_param = (const type_desc **)
+                    (dp + sizeof(uintptr_t) * 2);
             }
+            return make(first_param, n_obj_params, arena);
         }
 
-        return make((*tydesc)->first_param, (*tydesc)->n_params, arena);
+        return make(tydesc->first_param, tydesc->n_params, arena);
     }
 };