From 53ec6c3f9b495dd930cd061784251534bef58d74 Mon Sep 17 00:00:00 2001
From: Brian Anderson <banderson@mozilla.com>
Date: Mon, 5 Nov 2012 13:43:32 -0800
Subject: [PATCH] rt: Remove shape code

---
 mk/rt.mk               |    1 -
 src/rt/rust_shape.cpp  |  542 -----------------
 src/rt/rust_shape.h    | 1314 ----------------------------------------
 src/rt/rust_type.h     |    9 +-
 src/rt/rust_upcall.cpp |   54 +-
 src/rt/rust_util.cpp   |   14 +-
 src/rt/rustrt.def.in   |    2 -
 7 files changed, 8 insertions(+), 1928 deletions(-)
 delete mode 100644 src/rt/rust_shape.cpp
 delete mode 100644 src/rt/rust_shape.h

diff --git a/mk/rt.mk b/mk/rt.mk
index fd948fbc53a..efabfc39749 100644
--- a/mk/rt.mk
+++ b/mk/rt.mk
@@ -69,7 +69,6 @@ RUNTIME_CXXS_$(1) := \
               rt/isaac/randport.cpp \
               rt/miniz.cpp \
               rt/rust_kernel.cpp \
-              rt/rust_shape.cpp \
               rt/rust_abi.cpp \
               rt/rust_debug.cpp \
               rt/memory_region.cpp \
diff --git a/src/rt/rust_shape.cpp b/src/rt/rust_shape.cpp
deleted file mode 100644
index 8ad36af4ed2..00000000000
--- a/src/rt/rust_shape.cpp
+++ /dev/null
@@ -1,542 +0,0 @@
-// Functions that interpret the shape of a type to perform various low-level
-// actions, such as copying, freeing, comparing, and so on.
-
-
-#include <algorithm>
-#include <iomanip>
-#include <iostream>
-#include <sstream>
-#include <utility>
-
-#include "rust_task.h"
-#include "rust_shape.h"
-
-namespace shape {
-
-using namespace shape;
-
-// Constants
-
-const uint8_t CMP_EQ = 0u;
-const uint8_t CMP_LT = 1u;
-const uint8_t CMP_LE = 2u;
-
-// A shape printer, useful for debugging
-
-void
-print::walk_tag1(tag_info &tinfo) {
-    DPRINT("tag%u", tinfo.tag_id);
-}
-
-void
-print::walk_struct1(const uint8_t *end_sp) {
-    DPRINT("(");
-
-    bool first = true;
-    while (sp != end_sp) {
-        if (!first)
-            DPRINT(",");
-        first = false;
-
-        walk();
-    }
-
-    DPRINT(")");
-}
-
-void
-print::walk_res1(const rust_fn *dtor, const uint8_t *end_sp) {
-    DPRINT("res@%p", dtor);
-
-    // Print arguments.
-
-    if (sp == end_sp)
-        return;
-
-    DPRINT("(");
-
-    bool first = true;
-    while (sp != end_sp) {
-        if (!first)
-            DPRINT(",");
-        first = false;
-
-        walk();
-    }
-
-    DPRINT(")");
-}
-
-template<>
-void print::walk_number1<uint8_t>()      { DPRINT("u8"); }
-template<>
-void print::walk_number1<uint16_t>()     { DPRINT("u16"); }
-template<>
-void print::walk_number1<uint32_t>()     { DPRINT("u32"); }
-template<>
-void print::walk_number1<uint64_t>()     { DPRINT("u64"); }
-template<>
-void print::walk_number1<int8_t>()       { DPRINT("i8"); }
-template<>
-void print::walk_number1<int16_t>()      { DPRINT("i16"); }
-template<>
-void print::walk_number1<int32_t>()      { DPRINT("i32"); }
-template<>
-void print::walk_number1<int64_t>()      { DPRINT("i64"); }
-template<>
-void print::walk_number1<float>()        { DPRINT("f32"); }
-template<>
-void print::walk_number1<double>()       { DPRINT("f64"); }
-
-
-void
-size_of::compute_tag_size(tag_info &tinfo) {
-    // If the precalculated size and alignment are good, use them.
-    if (tinfo.tag_sa.is_set())
-        return;
-
-    uint16_t n_largest_variants = get_u16_bump(tinfo.largest_variants_ptr);
-    tinfo.tag_sa.set(0, 0);
-    for (uint16_t i = 0; i < n_largest_variants; i++) {
-        uint16_t variant_id = get_u16_bump(tinfo.largest_variants_ptr);
-        std::pair<const uint8_t *,const uint8_t *> variant_ptr_and_end =
-            get_variant_sp(tinfo, variant_id);
-        const uint8_t *variant_ptr = variant_ptr_and_end.first;
-        const uint8_t *variant_end = variant_ptr_and_end.second;
-
-        size_of sub(*this, variant_ptr, NULL);
-        sub.align = false;
-
-        // Compute the size of this variant.
-        size_align variant_sa;
-        bool first = true;
-        while (sub.sp != variant_end) {
-            if (!first)
-                variant_sa.size = align_to(variant_sa.size, sub.sa.alignment);
-            sub.walk();
-            sub.align = true, first = false;
-
-            variant_sa.add(sub.sa.size, sub.sa.alignment);
-        }
-
-        if (tinfo.tag_sa.size < variant_sa.size)
-            tinfo.tag_sa = variant_sa;
-    }
-
-    if (tinfo.variant_count == 1) {
-        if (!tinfo.tag_sa.size)
-            tinfo.tag_sa.set(1, 1);
-    } else {
-        // Add in space for the tag.
-        tinfo.tag_sa.add(sizeof(tag_variant_t), rust_alignof<tag_align_t>());
-    }
-}
-
-void
-size_of::walk_tag1(tag_info &tinfo) {
-    compute_tag_size(*this, tinfo);
-    sa = tinfo.tag_sa;
-}
-
-void
-size_of::walk_struct1(const uint8_t *end_sp) {
-    size_align struct_sa(0, 1);
-
-    bool first = true;
-    while (sp != end_sp) {
-        if (!first)
-            struct_sa.size = align_to(struct_sa.size, sa.alignment);
-        walk();
-        align = true, first = false;
-
-        struct_sa.add(sa);
-    }
-
-    sa = struct_sa;
-}
-
-// Copy constructors
-
-#if 0
-
-class copy : public data<copy,uint8_t *> {
-    // FIXME #2892
-};
-
-#endif
-
-
-// Structural comparison glue.
-
-class cmp : public data<cmp,ptr_pair> {
-    friend class data<cmp,ptr_pair>;
-
-private:
-    void walk_slice2(bool is_pod,
-                     const std::pair<ptr_pair,ptr_pair> &data_range);
-
-    void walk_vec2(bool is_pod,
-                   const std::pair<ptr_pair,ptr_pair> &data_range);
-
-    inline void walk_subcontext2(cmp &sub) {
-        sub.walk();
-        result = sub.result;
-    }
-
-    inline void walk_box_contents2(cmp &sub) {
-        sub.align = true;
-        sub.walk();
-        result = sub.result;
-    }
-
-    inline void walk_uniq_contents2(cmp &sub) {
-        sub.align = true;
-        sub.walk();
-        result = sub.result;
-    }
-
-    inline void walk_rptr_contents2(cmp &sub) {
-        sub.align = true;
-        sub.walk();
-        result = sub.result;
-    }
-
-    inline void cmp_two_pointers() {
-        ALIGN_TO(rust_alignof<void *>());
-        data_pair<uint8_t *> fst = bump_dp<uint8_t *>(dp);
-        data_pair<uint8_t *> snd = bump_dp<uint8_t *>(dp);
-        cmp_number(fst);
-        if (!result)
-            cmp_number(snd);
-    }
-
-    inline void cmp_pointer() {
-        ALIGN_TO(rust_alignof<void *>());
-        cmp_number(bump_dp<uint8_t *>(dp));
-    }
-
-    template<typename T>
-    void cmp_number(const data_pair<T> &nums) {
-        result = (nums.fst < nums.snd) ? -1 : (nums.fst == nums.snd) ? 0 : 1;
-    }
-
-public:
-    int result;
-
-    cmp(rust_task *in_task,
-        bool in_align,
-        const uint8_t *in_sp,
-        const rust_shape_tables *in_tables,
-        uint8_t *in_data_0,
-        uint8_t *in_data_1)
-    : data<cmp,ptr_pair>(in_task, in_align, in_sp, in_tables,
-                         ptr_pair::make(in_data_0, in_data_1)),
-      result(0) {}
-
-    cmp(const cmp &other,
-        const uint8_t *in_sp,
-        const rust_shape_tables *in_tables,
-        ptr_pair &in_dp)
-    : data<cmp,ptr_pair>(other.task, other.align, in_sp, in_tables,
-                         in_dp),
-      result(0) {}
-
-    cmp(const cmp &other,
-        const uint8_t *in_sp = NULL,
-        const rust_shape_tables *in_tables = NULL)
-    : data<cmp,ptr_pair>(other.task,
-                         other.align,
-                         in_sp ? in_sp : other.sp,
-                         in_tables ? in_tables : other.tables,
-                         other.dp),
-      result(0) {}
-
-    cmp(const cmp &other, const ptr_pair &in_dp)
-    : data<cmp,ptr_pair>(other.task,
-                         other.align,
-                         other.sp,
-                         other.tables,
-                         in_dp),
-      result(0) {}
-
-    void walk_vec2(bool is_pod) {
-        walk_vec2(is_pod, get_vec_data_range(dp));
-    }
-
-    void walk_unboxed_vec2(bool is_pod) {
-        walk_vec2(is_pod, get_unboxed_vec_data_range(dp));
-    }
-
-
-    void walk_slice2(bool is_pod, bool is_str) {
-        // Slices compare just like vecs.
-        walk_vec2(is_pod, get_slice_data_range(is_str, dp));
-    }
-
-    void walk_fixedvec2(uint16_t n_elts, size_t elt_sz, bool is_pod) {
-        // Fixedvecs compare just like vecs.
-        walk_vec2(is_pod, get_fixedvec_data_range(n_elts, elt_sz, dp));
-    }
-
-    void walk_box2() {
-        data<cmp,ptr_pair>::walk_box_contents1();
-    }
-
-    void walk_uniq2() {
-        data<cmp,ptr_pair>::walk_uniq_contents1();
-    }
-
-    void walk_rptr2() {
-        data<cmp,ptr_pair>::walk_rptr_contents1();
-    }
-
-    void walk_trait2() {
-        data<cmp,ptr_pair>::walk_box_contents1();
-    }
-
-    void walk_tydesc2(char) {
-        cmp_pointer();
-    }
-
-    void walk_fn2(char) { return cmp_two_pointers(); }
-    void walk_obj2()    { return cmp_two_pointers(); }
-
-    void walk_tag2(tag_info &tinfo,
-                   const data_pair<tag_variant_t> &tag_variants);
-    void walk_struct2(const uint8_t *end_sp);
-    void walk_res2(const rust_fn *dtor, const uint8_t *end_sp);
-    void walk_variant2(tag_info &tinfo,
-                       tag_variant_t variant_id,
-                       const std::pair<const uint8_t *,const uint8_t *>
-                       variant_ptr_and_end);
-
-    template<typename T>
-    void walk_number2() { cmp_number(get_dp<T>(dp)); }
-};
-
-template<>
-void cmp::cmp_number<int32_t>(const data_pair<int32_t> &nums) {
-    result = (nums.fst < nums.snd) ? -1 : (nums.fst == nums.snd) ? 0 : 1;
-}
-
-void
-cmp::walk_vec2(bool is_pod, const std::pair<ptr_pair,ptr_pair> &data_range) {
-    cmp sub(*this, data_range.first);
-    ptr_pair data_end = sub.end_dp = data_range.second;
-    while (!result && sub.dp < data_end) {
-        sub.walk_reset();
-        result = sub.result;
-        sub.align = true;
-    }
-
-    if (!result) {
-        // If we hit the end, the result comes down to length comparison.
-        int len_fst = data_range.second.fst - data_range.first.fst;
-        int len_snd = data_range.second.snd - data_range.first.snd;
-        cmp_number(data_pair<int>::make(len_fst, len_snd));
-    }
-}
-
-void
-cmp::walk_tag2(tag_info &tinfo,
-               const data_pair<tag_variant_t> &tag_variants) {
-    cmp_number(tag_variants);
-    if (result != 0)
-        return;
-    data<cmp,ptr_pair>::walk_variant1(tinfo, tag_variants.fst);
-}
-
-void
-cmp::walk_struct2(const uint8_t *end_sp) {
-    while (!result && this->sp != end_sp) {
-        this->walk();
-        align = true;
-    }
-}
-
-void
-cmp::walk_res2(const rust_fn *dtor, const uint8_t *end_sp) {
-    this->cmp_two_pointers();
-}
-
-void
-cmp::walk_variant2(tag_info &tinfo,
-                   tag_variant_t variant_id,
-                   const std::pair<const uint8_t *,const uint8_t *>
-                   variant_ptr_and_end) {
-    cmp sub(*this, variant_ptr_and_end.first);
-
-    const uint8_t *variant_end = variant_ptr_and_end.second;
-    while (!result && sub.sp < variant_end) {
-        sub.walk();
-        result = sub.result;
-        sub.align = true;
-    }
-}
-
-
-// Polymorphic logging, for convenience
-
-void
-log::walk_string2(const std::pair<ptr,ptr> &data) {
-    out << prefix << "\"" << std::hex;
-
-    ptr subdp = data.first;
-    while (subdp < data.second) {
-        char ch = *subdp;
-        switch(ch) {
-        case '\n': out << "\\n"; break;
-        case '\r': out << "\\r"; break;
-        case '\t': out << "\\t"; break;
-        case '\\': out << "\\\\"; break;
-        case '"': out << "\\\""; break;
-        default:
-            if (isprint(ch)) {
-                out << ch;
-            } else if (ch) {
-                out << "\\x" << std::setw(2) << std::setfill('0')
-                    << (unsigned int)(unsigned char)ch;
-            }
-        }
-        ++subdp;
-    }
-
-    out << "\"" << std::dec;
-}
-
-void
-log::walk_struct2(const uint8_t *end_sp) {
-    out << prefix << "(";
-    prefix = "";
-
-    bool first = true;
-    while (sp != end_sp) {
-        if (!first)
-            out << ", ";
-        walk();
-        align = true, first = false;
-    }
-
-    out << ")";
-}
-
-void
-log::walk_vec2(bool is_pod, const std::pair<ptr,ptr> &data) {
-    if (peek() == SHAPE_U8) {
-        sp++;   // It's a string. We handle this ourselves.
-        walk_string2(data);
-        return;
-    }
-
-    out << prefix << "[";
-
-    log sub(*this, data.first);
-    sub.end_dp = data.second;
-
-    while (sub.dp < data.second) {
-        sub.walk_reset();
-        sub.align = true;
-        sub.prefix = ", ";
-    }
-
-    out << "]";
-}
-
-void
-log::walk_variant2(tag_info &tinfo,
-                   tag_variant_t variant_id,
-                   const std::pair<const uint8_t *,const uint8_t *>
-                   variant_ptr_and_end) {
-    log sub(*this, variant_ptr_and_end.first);
-    const uint8_t *variant_end = variant_ptr_and_end.second;
-
-    bool first = true;
-    while (sub.sp < variant_end) {
-        out << (first ? "(" : ", ");
-        sub.walk();
-        sub.align = true, first = false;
-    }
-
-    if (!first)
-        out << ")";
-}
-
-void
-log::walk_res2(const rust_fn *dtor, const uint8_t *end_sp) {
-    out << prefix << "res";
-
-    if (this->sp == end_sp)
-        return;
-
-    out << "(";
-
-    bool first = true;
-    while (sp != end_sp) {
-        if (!first)
-            out << ", ";
-        walk();
-        align = true, first = false;
-    }
-
-    out << ")";
-}
-
-} // end namespace shape
-
-extern "C" void
-shape_cmp_type(int8_t *result, const type_desc *tydesc,
-               uint8_t *data_0, uint8_t *data_1, uint8_t cmp_type) {
-    rust_task *task = rust_get_current_task();
-    shape::arena arena;
-
-    shape::cmp cmp(task, true, tydesc->shape, tydesc->shape_tables,
-                   data_0, data_1);
-    cmp.walk();
-
-    switch (cmp_type) {
-    case shape::CMP_EQ: *result = cmp.result == 0;  break;
-    case shape::CMP_LT: *result = cmp.result < 0;   break;
-    case shape::CMP_LE: *result = cmp.result <= 0;  break;
-    }
-}
-
-extern "C" rust_str *
-shape_log_str(const type_desc *tydesc, uint8_t *data) {
-    rust_task *task = rust_get_current_task();
-
-    shape::arena arena;
-
-    std::stringstream ss;
-    shape::log log(task, true, tydesc->shape, tydesc->shape_tables,
-                   data, ss);
-
-    log.walk();
-
-    int len = ss.str().length();
-    return make_str(task->kernel, ss.str().c_str(), len, "log_str");
-}
-
-extern "C" void
-shape_log_type(const type_desc *tydesc, uint8_t *data, uint32_t level) {
-    rust_task *task = rust_get_current_task();
-
-    shape::arena arena;
-
-    std::stringstream ss;
-    shape::log log(task, true, tydesc->shape, tydesc->shape_tables,
-                   data, ss);
-
-    log.walk();
-
-    task->sched_loop->get_log().log(task, level, "%s", ss.str().c_str());
-}
-
-//
-// Local Variables:
-// mode: C++
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
-//
diff --git a/src/rt/rust_shape.h b/src/rt/rust_shape.h
deleted file mode 100644
index fffbfad1d81..00000000000
--- a/src/rt/rust_shape.h
+++ /dev/null
@@ -1,1314 +0,0 @@
-// Functions that interpret the shape of a type to perform various low-level
-// actions, such as copying, freeing, comparing, and so on.
-
-#ifndef RUST_SHAPE_H
-#define RUST_SHAPE_H
-
-// Tell ISAAC to let go of max() and min() defines.
-#undef max
-#undef min
-
-#include <iostream>
-
-#include "rust_globals.h"
-#include "rust_util.h"
-
-// ISAAC pollutes our namespace.
-#undef align
-
-#define ARENA_SIZE          256
-
-//#define DPRINT(fmt,...)     fprintf(stderr, fmt, ##__VA_ARGS__)
-//#define DPRINTCX(cx)        shape::print::print_cx(cx)
-
-#define DPRINT(fmt,...)
-#define DPRINTCX(cx)
-
-
-namespace shape {
-
-typedef unsigned long tag_variant_t;
-typedef unsigned long tag_align_t;
-
-// Constants
-
-const uint8_t SHAPE_U8 = 0u;
-const uint8_t SHAPE_U16 = 1u;
-const uint8_t SHAPE_U32 = 2u;
-const uint8_t SHAPE_U64 = 3u;
-const uint8_t SHAPE_I8 = 4u;
-const uint8_t SHAPE_I16 = 5u;
-const uint8_t SHAPE_I32 = 6u;
-const uint8_t SHAPE_I64 = 7u;
-const uint8_t SHAPE_F32 = 8u;
-const uint8_t SHAPE_F64 = 9u;
-const uint8_t SHAPE_BOX = 10u;
-const uint8_t SHAPE_TAG = 12u;
-const uint8_t SHAPE_STRUCT = 17u;
-const uint8_t SHAPE_BOX_FN = 18u;
-const uint8_t SHAPE_RES = 20u;
-const uint8_t SHAPE_UNIQ = 22u;
-const uint8_t SHAPE_UNIQ_FN = 25u;
-const uint8_t SHAPE_STACK_FN = 26u;
-const uint8_t SHAPE_BARE_FN = 27u;
-const uint8_t SHAPE_TYDESC = 28u;
-const uint8_t SHAPE_SEND_TYDESC = 29u;
-const uint8_t SHAPE_RPTR = 31u;
-const uint8_t SHAPE_FIXEDVEC = 32u;
-const uint8_t SHAPE_SLICE = 33u;
-const uint8_t SHAPE_UNBOXED_VEC = 34u;
-
-#ifdef _LP64
-const uint8_t SHAPE_PTR = SHAPE_U64;
-#else
-const uint8_t SHAPE_PTR = SHAPE_U32;
-#endif
-
-
-// Forward declarations
-
-struct rust_obj;
-struct size_align;
-class ptr;
-
-
-// Arenas; these functions must execute very quickly, so we use an arena
-// instead of malloc or new.
-
-class arena {
-    uint8_t *ptr;
-    uint8_t data[ARENA_SIZE];
-
-public:
-    arena() : ptr(data) {}
-
-    template<typename T>
-    inline T *alloc(size_t count = 1) {
-        // FIXME: align (probably won't fix before #1498)
-        size_t sz = count * sizeof(T);
-        T *rv = (T *)ptr;
-        ptr += sz;
-        if (ptr > &data[ARENA_SIZE]) {
-            fprintf(stderr, "Arena space exhausted, sorry\n");
-            abort();
-        }
-        return rv;
-    }
-};
-
-
-// Alignment inquiries
-//
-// We can't directly use __alignof__ everywhere because that returns the
-// preferred alignment of the type, which is different from the ABI-mandated
-// alignment of the type in some cases (e.g. doubles on x86). The latter is
-// what actually gets used for struct elements.
-
-template<typename T>
-inline size_t
-rust_alignof() {
-#ifdef _MSC_VER
-    return __alignof(T);
-#else
-    return __alignof__(T);
-#endif
-}
-
-template<>
-inline size_t
-rust_alignof<double>() {
-    return 4;
-}
-
-// Issue #2303
-// On 32-bit x86 the alignment of 64-bit ints in structures is 4 bytes
-// Which is different from the preferred 8-byte alignment reported
-// by __alignof__ (at least on gcc).
-#ifndef __WIN32__
-#ifdef __i386__
-template<>
-inline size_t
-rust_alignof<uint64_t>() {
-    return 4;
-}
-#endif
-#endif
-
-
-// Utility classes
-
-struct size_align {
-    size_t size;
-    size_t alignment;
-
-    size_align(size_t in_size = 0, size_t in_align = 1) :
-        size(in_size), alignment(in_align) {}
-
-    bool is_set() const { return alignment != 0; }
-
-    inline void set(size_t in_size, size_t in_align) {
-        size = in_size;
-        alignment = in_align;
-    }
-
-    inline void add(const size_align &other) {
-        add(other.size, other.alignment);
-    }
-
-    inline void add(size_t extra_size, size_t extra_align) {
-        size += extra_size;
-        alignment = std::max(alignment, extra_align);
-    }
-
-    static inline size_align make(size_t in_size) {
-        size_align sa;
-        sa.size = sa.alignment = in_size;
-        return sa;
-    }
-
-    static inline size_align make(size_t in_size, size_t in_align) {
-        size_align sa;
-        sa.size = in_size;
-        sa.alignment = in_align;
-        return sa;
-    }
-};
-
-struct tag_info {
-    uint16_t tag_id;                        // The tag ID.
-    const uint8_t *info_ptr;                // Pointer to the info table.
-    uint16_t variant_count;                 // Number of variants in the tag.
-    const uint8_t *largest_variants_ptr;    // Ptr to largest variants table.
-    size_align tag_sa;                      // Size and align of this tag.
-};
-
-
-// Utility functions
-
-inline uint16_t
-get_u16(const uint8_t *addr) {
-    return *reinterpret_cast<const uint16_t *>(addr);
-}
-
-inline uint16_t
-get_u16_bump(const uint8_t *&addr) {
-    uint16_t result = get_u16(addr);
-    addr += sizeof(uint16_t);
-    return result;
-}
-
-template<typename T>
-inline void
-fmt_number(std::ostream &out, T n) {
-    out << n;
-}
-
-// Override the character interpretation for these two.
-template<>
-inline void
-fmt_number<uint8_t>(std::ostream &out, uint8_t n) {
-    out << (int)n;
-}
-template<>
-inline void
-fmt_number<int8_t>(std::ostream &out, int8_t n) {
-    out << (int)n;
-}
-
-
-// Contexts
-
-// The base context, an abstract class. We use the curiously recurring
-// template pattern here to avoid virtual dispatch.
-template<typename T>
-class ctxt {
-public:
-    const uint8_t *sp;                  // shape pointer
-    const rust_shape_tables *tables;
-    rust_task *task;
-    bool align;
-
-    ctxt(rust_task *in_task,
-         bool in_align,
-         const uint8_t *in_sp,
-         const rust_shape_tables *in_tables)
-    : sp(in_sp),
-      tables(in_tables),
-      task(in_task),
-      align(in_align) {}
-
-    template<typename U>
-    ctxt(const ctxt<U> &other,
-         const uint8_t *in_sp = NULL,
-         const rust_shape_tables *in_tables = NULL)
-    : sp(in_sp ? in_sp : other.sp),
-      tables(in_tables ? in_tables : other.tables),
-      task(other.task),
-      align(other.align) {}
-
-    void walk();
-    void walk_reset();
-
-    std::pair<const uint8_t *,const uint8_t *>
-    get_variant_sp(tag_info &info, tag_variant_t variant_id);
-
-    const char *
-    get_variant_name(tag_info &info, tag_variant_t variant_id);
-
-protected:
-    inline uint8_t peek() { return *sp; }
-
-    inline size_align get_size_align(const uint8_t *&addr);
-
-private:
-    void walk_vec0();
-    void walk_unboxed_vec0();
-    void walk_tag0();
-    void walk_box0();
-    void walk_uniq0();
-    void walk_struct0();
-    void walk_res0();
-    void walk_rptr0();
-    void walk_fixedvec0();
-    void walk_slice0();
-};
-
-
-// Core Rust types
-
-struct rust_fn {
-    void (*code)(uint8_t *rv, rust_task *task, void *env, ...);
-    void *env;
-};
-
-// Traversals
-
-#define WALK_NUMBER(c_type) \
-    static_cast<T *>(this)->template walk_number1<c_type>()
-#define WALK_SIMPLE(method) static_cast<T *>(this)->method()
-
-template<typename T>
-void
-ctxt<T>::walk() {
-  char s = *sp++;
-  switch (s) {
-    case SHAPE_U8:       WALK_NUMBER(uint8_t);       break;
-    case SHAPE_U16:      WALK_NUMBER(uint16_t);      break;
-    case SHAPE_U32:      WALK_NUMBER(uint32_t);      break;
-    case SHAPE_U64:      WALK_NUMBER(uint64_t);      break;
-    case SHAPE_I8:       WALK_NUMBER(int8_t);        break;
-    case SHAPE_I16:      WALK_NUMBER(int16_t);       break;
-    case SHAPE_I32:      WALK_NUMBER(int32_t);       break;
-    case SHAPE_I64:      WALK_NUMBER(int64_t);       break;
-    case SHAPE_F32:      WALK_NUMBER(float);         break;
-    case SHAPE_F64:      WALK_NUMBER(double);        break;
-    case SHAPE_TAG:      walk_tag0();             break;
-    case SHAPE_BOX:      walk_box0();             break;
-    case SHAPE_STRUCT:   walk_struct0();          break;
-    case SHAPE_RES:      walk_res0();             break;
-    case SHAPE_UNIQ:     walk_uniq0();            break;
-    case SHAPE_BOX_FN:
-    case SHAPE_UNIQ_FN:
-    case SHAPE_STACK_FN:
-    case SHAPE_BARE_FN:  static_cast<T*>(this)->walk_fn1(s); break;
-    case SHAPE_TYDESC:
-    case SHAPE_SEND_TYDESC: static_cast<T*>(this)->walk_tydesc1(s); break;
-    case SHAPE_RPTR:     walk_rptr0();            break;
-    case SHAPE_FIXEDVEC: walk_fixedvec0();        break;
-    case SHAPE_SLICE:    walk_slice0();           break;
-    case SHAPE_UNBOXED_VEC: walk_unboxed_vec0();  break;
-    default:             abort();
-    }
-}
-
-template<typename T>
-void
-ctxt<T>::walk_reset() {
-    const uint8_t *old_sp = sp;
-    walk();
-    sp = old_sp;
-}
-
-template<typename T>
-size_align
-ctxt<T>::get_size_align(const uint8_t *&addr) {
-    size_align result;
-    result.size = get_u16_bump(addr);
-    result.alignment = *addr++;
-    return result;
-}
-
-// Returns a pointer to the beginning and a pointer to the end of the shape of
-// the tag variant with the given ID.
-template<typename T>
-std::pair<const uint8_t *,const uint8_t *>
-ctxt<T>::get_variant_sp(tag_info &tinfo, tag_variant_t variant_id) {
-    uint16_t variant_offset = get_u16(tinfo.info_ptr +
-                                      variant_id * sizeof(uint16_t));
-    const uint8_t *variant_ptr = tables->tags + variant_offset;
-    uint16_t variant_len = get_u16_bump(variant_ptr);
-    const uint8_t *variant_end = variant_ptr + variant_len;
-
-    return std::make_pair(variant_ptr, variant_end);
-}
-
-template<typename T>
-const char *
-ctxt<T>::get_variant_name(tag_info &tinfo, tag_variant_t variant_id) {
-    std::pair<const uint8_t *,const uint8_t *> variant_ptr_and_end =
-      this->get_variant_sp(tinfo, variant_id);
-    // skip over the length to get the null-terminated string:
-    return (const char*)(variant_ptr_and_end.second + 2);
-}
-
-template<typename T>
-void
-ctxt<T>::walk_vec0() {
-    bool is_pod = *sp++;
-
-    uint16_t sp_size = get_u16_bump(sp);
-    const uint8_t *end_sp = sp + sp_size;
-
-    static_cast<T *>(this)->walk_vec1(is_pod);
-
-    sp = end_sp;
-}
-
-template<typename T>
-void
-ctxt<T>::walk_unboxed_vec0() {
-    bool is_pod = *sp++;
-
-    uint16_t sp_size = get_u16_bump(sp);
-    const uint8_t *end_sp = sp + sp_size;
-
-    static_cast<T *>(this)->walk_unboxed_vec1(is_pod);
-
-    sp = end_sp;
-}
-
-template<typename T>
-void
-ctxt<T>::walk_tag0() {
-    tag_info tinfo;
-    tinfo.tag_id = get_u16_bump(sp);
-
-    // Determine the info pointer.
-    uint16_t info_offset = get_u16(tables->tags +
-                                   tinfo.tag_id * sizeof(uint16_t));
-    tinfo.info_ptr = tables->tags + info_offset;
-
-    tinfo.variant_count = get_u16_bump(tinfo.info_ptr);
-
-    // Determine the largest-variants pointer.
-    uint16_t largest_variants_offset = get_u16_bump(tinfo.info_ptr);
-    tinfo.largest_variants_ptr = tables->tags + largest_variants_offset;
-
-    // Determine the size and alignment.
-    tinfo.tag_sa = get_size_align(tinfo.info_ptr);
-
-    // Call to the implementation.
-    static_cast<T *>(this)->walk_tag1(tinfo);
-}
-
-template<typename T>
-void
-ctxt<T>::walk_box0() {
-    static_cast<T *>(this)->walk_box1();
-}
-
-template<typename T>
-void
-ctxt<T>::walk_uniq0() {
-    uint16_t sp_size = get_u16_bump(sp);
-    const uint8_t *end_sp = sp + sp_size;
-
-    static_cast<T *>(this)->walk_uniq1();
-
-    sp = end_sp;
-}
-
-template<typename T>
-void
-ctxt<T>::walk_rptr0() {
-    uint16_t sp_size = get_u16_bump(sp);
-    const uint8_t *end_sp = sp + sp_size;
-
-    static_cast<T *>(this)->walk_rptr1();
-
-    sp = end_sp;
-}
-
-template<typename T>
-void
-ctxt<T>::walk_fixedvec0() {
-    uint16_t n_elts = get_u16_bump(sp);
-    bool is_pod = *sp++;
-    uint16_t sp_size = get_u16_bump(sp);
-    const uint8_t *end_sp = sp + sp_size;
-
-    static_cast<T *>(this)->walk_fixedvec1(n_elts, is_pod);
-
-    sp = end_sp;
-}
-
-template<typename T>
-void
-ctxt<T>::walk_slice0() {
-    bool is_pod = *sp++;
-    bool is_str = *sp++;
-    uint16_t sp_size = get_u16_bump(sp);
-    const uint8_t *end_sp = sp + sp_size;
-
-    static_cast<T *>(this)->walk_slice1(is_pod, is_str);
-
-    sp = end_sp;
-}
-
-
-template<typename T>
-void
-ctxt<T>::walk_struct0() {
-    uint16_t sp_size = get_u16_bump(sp);
-    const uint8_t *end_sp = sp + sp_size;
-
-    static_cast<T *>(this)->walk_struct1(end_sp);
-
-    sp = end_sp;
-}
-
-template<typename T>
-void
-ctxt<T>::walk_res0() {
-    uint16_t dtor_offset = get_u16_bump(sp);
-    const rust_fn **resources =
-        reinterpret_cast<const rust_fn **>(tables->resources);
-    const rust_fn *dtor = resources[dtor_offset];
-
-    uint16_t sp_size = get_u16_bump(sp);
-    const uint8_t *end_sp = sp + sp_size;
-
-    static_cast<T *>(this)->walk_res1(dtor, end_sp);
-
-    sp = end_sp;
-}
-
-// A shape printer, useful for debugging
-
-class print : public ctxt<print> {
-public:
-    template<typename T>
-    print(const ctxt<T> &other,
-          const uint8_t *in_sp = NULL,
-          const rust_shape_tables *in_tables = NULL)
-    : ctxt<print>(other, in_sp, in_tables) {}
-
-    print(rust_task *in_task,
-          bool in_align,
-          const uint8_t *in_sp,
-          const rust_shape_tables *in_tables)
-    : ctxt<print>(in_task, in_align, in_sp, in_tables) {}
-
-    void walk_tag1(tag_info &tinfo);
-    void walk_struct1(const uint8_t *end_sp);
-    void walk_res1(const rust_fn *dtor, const uint8_t *end_sp);
-
-    void walk_vec1(bool is_pod) {
-        DPRINT("vec<"); walk(); DPRINT(">");
-    }
-    void walk_unboxed_vec1(bool is_pod) {
-        DPRINT("unboxed_vec<"); walk(); DPRINT(">");
-    }
-    void walk_uniq1() {
-        DPRINT("~<"); walk(); DPRINT(">");
-    }
-    void walk_box1() {
-        DPRINT("@<"); walk(); DPRINT(">");
-    }
-    void walk_rptr1() {
-        DPRINT("&<"); walk(); DPRINT(">");
-    }
-    void walk_fixedvec1(uint16_t n_elts, bool is_pod) {
-      DPRINT("fixedvec<%u, ", n_elts); walk(); DPRINT(">");
-    }
-    void walk_slice1(bool is_pod, bool is_str) {
-      DPRINT("slice<"); walk(); DPRINT(">");
-    }
-
-    void walk_fn1(char kind) {
-        switch(kind) {
-          case SHAPE_BARE_FN:  DPRINT("fn");  break;
-          case SHAPE_BOX_FN:   DPRINT("fn@"); break;
-          case SHAPE_UNIQ_FN:  DPRINT("fn~"); break;
-          case SHAPE_STACK_FN: DPRINT("fn&"); break;
-          default: abort();
-        }
-    }
-    void walk_trait1() { DPRINT("trait"); }
-
-    void walk_tydesc1(char kind) {
-        switch(kind) {
-          case SHAPE_TYDESC: DPRINT("tydesc"); break;
-          case SHAPE_SEND_TYDESC: DPRINT("send-tydesc"); break;
-          default: abort();
-        }
-    }
-
-    template<typename T>
-    void walk_number1() {}
-
-    template<typename T>
-    static void print_cx(const T *cx) {
-        print self(*cx);
-        self.align = false;
-        self.walk();
-    }
-};
-
-
-//
-// Size-of (which also computes alignment). Be warned: this is an expensive
-// operation.
-//
-// FIXME #2894: Maybe dynamic_size_of() should call into this somehow?
-//
-
-class size_of : public ctxt<size_of> {
-private:
-    size_align sa;
-
-public:
-    size_of(const size_of &other,
-            const uint8_t *in_sp = NULL,
-            const rust_shape_tables *in_tables = NULL)
-    : ctxt<size_of>(other, in_sp, in_tables) {}
-
-    template<typename T>
-    size_of(const ctxt<T> &other,
-            const uint8_t *in_sp = NULL,
-            const rust_shape_tables *in_tables = NULL)
-    : ctxt<size_of>(other, in_sp, in_tables) {}
-
-    void walk_tag1(tag_info &tinfo);
-    void walk_struct1(const uint8_t *end_sp);
-
-    void walk_uniq1()       { sa.set(sizeof(void *),   sizeof(void *)); }
-    void walk_rptr1()       { sa.set(sizeof(void *),   sizeof(void *)); }
-    void walk_slice1(bool,bool)
-                            { sa.set(sizeof(void *)*2, sizeof(void *)); }
-    void walk_box1()        { sa.set(sizeof(void *),   sizeof(void *)); }
-    void walk_fn1(char)     { sa.set(sizeof(void *)*2, sizeof(void *)); }
-    void walk_trait1()      { sa.set(sizeof(void *),   sizeof(void *)); }
-    void walk_tydesc1(char) { sa.set(sizeof(void *),   sizeof(void *)); }
-    void walk_closure1();
-
-    void walk_vec1(bool is_pod) {
-        sa.set(sizeof(void *), sizeof(void *));
-    }
-
-    void walk_unboxed_vec1(bool is_pod) {
-        assert(false &&
-               "trying to compute size of dynamically sized unboxed vector");
-    }
-
-    void walk_res1(const rust_fn *dtor, const uint8_t *end_sp) {
-        abort();    // FIXME #2895
-    }
-
-    void walk_fixedvec1(uint16_t n_elts, bool is_pod) {
-        size_of sub(*this);
-        sub.walk();
-        sa.set(sub.sa.size * n_elts, sub.sa.alignment);
-    }
-
-    template<typename T>
-    void walk_number1()  { sa.set(sizeof(T), rust_alignof<T>()); }
-
-    void compute_tag_size(tag_info &tinfo);
-
-    template<typename T>
-    static void compute_tag_size(const ctxt<T> &other_cx, tag_info &tinfo) {
-        size_of cx(other_cx);
-        cx.compute_tag_size(tinfo);
-    }
-
-    template<typename T>
-    static size_align get(const ctxt<T> &other_cx, unsigned back_up = 0) {
-        size_of cx(other_cx, other_cx.sp - back_up);
-        cx.align = false;
-        cx.walk();
-        assert(cx.sa.alignment > 0);
-        return cx.sa;
-    }
-};
-
-
-// Pointer wrappers for data traversals
-
-class ptr {
-private:
-    uint8_t *p;
-
-public:
-    template<typename T>
-    struct data { typedef T t; };
-
-    ptr() : p(NULL) {}
-    explicit ptr(uint8_t *in_p) : p(in_p) {}
-    explicit ptr(uintptr_t in_p) : p((uint8_t *)in_p) {}
-
-    inline ptr operator+(const size_t amount) const {
-        return make(p + amount);
-    }
-    inline ptr &operator+=(const size_t amount) { p += amount; return *this; }
-    inline bool operator<(const ptr other) { return p < other.p; }
-    inline ptr operator++() { ptr rv(*this); p++; return rv; }
-    inline uint8_t operator*() { return *p; }
-
-    template<typename T>
-    inline operator T *() { return (T *)p; }
-
-    inline operator bool() const { return p != NULL; }
-    inline operator uintptr_t() const { return (uintptr_t)p; }
-
-    inline const type_desc *box_body_td() const {
-        rust_opaque_box *box = *reinterpret_cast<rust_opaque_box**>(p);
-        assert(box->ref_count >= 1);
-        return box->td;
-    }
-
-    inline const type_desc *uniq_body_td() const {
-        rust_opaque_box *box = *reinterpret_cast<rust_opaque_box**>(p);
-        return box->td;
-    }
-
-    inline ptr box_body() const {
-        rust_opaque_box *box = *reinterpret_cast<rust_opaque_box**>(p);
-        return make((uint8_t*)::box_body(box));
-    }
-
-    static inline ptr make(uint8_t *in_p) {
-        ptr self(in_p);
-        return self;
-    }
-};
-
-template<typename T>
-static inline T
-bump_dp(ptr &dp) {
-    T x = *((T *)dp);
-    dp += sizeof(T);
-    return x;
-}
-
-template<typename T>
-static inline T
-get_dp(ptr dp) {
-    return *((T *)dp);
-}
-
-
-// Pointer pairs for structural comparison
-
-template<typename T>
-class data_pair {
-public:
-    T fst, snd;
-
-    data_pair() {}
-    data_pair(T &in_fst, T &in_snd) : fst(in_fst), snd(in_snd) {}
-
-    inline void operator=(const T rhs) { fst = snd = rhs; }
-
-    static data_pair<T> make(T &fst, T &snd) {
-          data_pair<T> data(fst, snd);
-        return data;
-    }
-};
-
-class ptr_pair {
-public:
-    uint8_t *fst, *snd;
-
-    template<typename T>
-    struct data { typedef data_pair<T> t; };
-
-    ptr_pair() : fst(NULL), snd(NULL) {}
-    ptr_pair(uint8_t *in_fst, uint8_t *in_snd) : fst(in_fst), snd(in_snd) {}
-    ptr_pair(data_pair<uint8_t *> &other) : fst(other.fst), snd(other.snd) {}
-
-    inline void operator=(uint8_t *rhs) { fst = snd = rhs; }
-
-    inline operator bool() const { return fst != NULL && snd != NULL; }
-
-    inline ptr_pair operator+(size_t n) const {
-        return make(fst + n, snd + n);
-    }
-
-    inline ptr_pair operator+=(size_t n) {
-        fst += n; snd += n;
-        return *this;
-    }
-
-    inline ptr_pair operator-(size_t n) const {
-        return make(fst - n, snd - n);
-    }
-
-    inline bool operator<(const ptr_pair &other) const {
-        return fst < other.fst && snd < other.snd;
-    }
-
-    static inline ptr_pair make(uint8_t *fst, uint8_t *snd) {
-        ptr_pair self(fst, snd);
-        return self;
-    }
-
-    static inline ptr_pair make(const data_pair<uint8_t *> &pair) {
-        ptr_pair self(pair.fst, pair.snd);
-        return self;
-    }
-
-    inline const type_desc *box_body_td() const {
-        // Here we assume that the two ptrs are both boxes with
-        // equivalent type descriptors.  This is safe because we only
-        // use ptr_pair in the cmp glue, and we only use the cmp glue
-        // when rust guarantees us that the boxes are of the same
-        // type.  As box types are not opaque to Rust, it is in a
-        // position to make this determination.
-        rust_opaque_box *box_fst = *reinterpret_cast<rust_opaque_box**>(fst);
-        assert(box_fst->ref_count >= 1);
-        return box_fst->td;
-    }
-
-    inline const type_desc *uniq_body_td() const {
-        rust_opaque_box *box_fst = *reinterpret_cast<rust_opaque_box**>(fst);
-        return box_fst->td;
-    }
-
-    inline ptr_pair box_body() const {
-        rust_opaque_box *box_fst = *reinterpret_cast<rust_opaque_box**>(fst);
-        rust_opaque_box *box_snd = *reinterpret_cast<rust_opaque_box**>(snd);
-        return make((uint8_t*)::box_body(box_fst),
-                    (uint8_t*)::box_body(box_snd));
-    }
-};
-
-// NB: This function does not align.
-template<typename T>
-inline data_pair<T>
-bump_dp(ptr_pair &ptr) {
-    data_pair<T> data(*reinterpret_cast<T *>(ptr.fst),
-                      *reinterpret_cast<T *>(ptr.snd));
-    ptr += sizeof(T);
-    return data;
-}
-
-template<typename T>
-inline data_pair<T>
-get_dp(ptr_pair &ptr) {
-    data_pair<T> data(*reinterpret_cast<T *>(ptr.fst),
-                      *reinterpret_cast<T *>(ptr.snd));
-    return data;
-}
-
-}   // end namespace shape
-
-
-inline shape::ptr_pair
-align_to(const shape::ptr_pair &pair, size_t n) {
-    return shape::ptr_pair::make(align_to(pair.fst, n),
-                                 align_to(pair.snd, n));
-}
-
-
-namespace shape {
-
-// An abstract class (again using the curiously recurring template pattern)
-// for methods that actually manipulate the data involved.
-
-#define ALIGN_TO(alignment) \
-    if (this->align) { \
-        dp = align_to(dp, (alignment)); \
-        if (this->end_dp && !(dp < this->end_dp)) \
-            return; \
-    }
-
-#define DATA_SIMPLE(ty, call) \
-    ALIGN_TO(rust_alignof<ty>()); \
-    U end_dp = dp + sizeof(ty); \
-    static_cast<T *>(this)->call; \
-    dp = end_dp;
-
-template<typename T,typename U>
-class data : public ctxt< data<T,U> > {
-public:
-    U dp;
-
-protected:
-    U end_dp;
-
-    void walk_box_contents1();
-    void walk_uniq_contents1();
-    void walk_rptr_contents1();
-    void walk_fn_contents1();
-    void walk_trait_contents1();
-    void walk_variant1(tag_info &tinfo, tag_variant_t variant);
-
-    static std::pair<uint8_t *,uint8_t *> get_vec_data_range(ptr dp);
-    static std::pair<ptr_pair,ptr_pair> get_vec_data_range(ptr_pair &dp);
-
-    static std::pair<uint8_t *,uint8_t *> get_unboxed_vec_data_range(ptr dp);
-    static std::pair<ptr_pair,ptr_pair>
-        get_unboxed_vec_data_range(ptr_pair &dp);
-    static ptr get_unboxed_vec_end(ptr dp);
-    static ptr_pair get_unboxed_vec_end(ptr_pair &dp);
-
-    static std::pair<uint8_t *,uint8_t *> get_slice_data_range(bool is_str,
-                                                               ptr dp);
-    static std::pair<ptr_pair,ptr_pair> get_slice_data_range(bool is_str,
-                                                             ptr_pair &dp);
-
-    static std::pair<uint8_t *,uint8_t *>
-        get_fixedvec_data_range(uint16_t n_elts, size_t elt_sz, ptr dp);
-    static std::pair<ptr_pair,ptr_pair>
-        get_fixedvec_data_range(uint16_t n_elts, size_t elt_sz, ptr_pair &dp);
-
-public:
-    data(rust_task *in_task,
-         bool in_align,
-         const uint8_t *in_sp,
-         const rust_shape_tables *in_tables,
-         U const &in_dp)
-    : ctxt< data<T,U> >(in_task, in_align, in_sp, in_tables),
-      dp(in_dp),
-      end_dp() {}
-
-    void walk_tag1(tag_info &tinfo);
-
-    void walk_struct1(const uint8_t *end_sp) {
-        // FIXME (probably won't fix before #1498): shouldn't we be aligning
-        // to the first element here?
-        static_cast<T *>(this)->walk_struct2(end_sp);
-    }
-
-    void walk_vec1(bool is_pod) {
-        DATA_SIMPLE(void *, walk_vec2(is_pod));
-    }
-
-    void walk_unboxed_vec1(bool is_pod) {
-        // align?
-        U next_dp = get_unboxed_vec_end(dp);
-        static_cast<T *>(this)->walk_unboxed_vec2(is_pod);
-        dp = next_dp;
-    }
-
-    void walk_slice1(bool is_pod, bool is_str) {
-        DATA_SIMPLE(void *, walk_slice2(is_pod, is_str));
-    }
-
-    void walk_fixedvec1(uint16_t n_elts, bool is_pod) {
-        size_align sa = size_of::get(*this);
-        ALIGN_TO(sa.alignment);
-        U next_dp = dp + (n_elts * sa.size);
-        static_cast<T *>(this)->walk_fixedvec2(n_elts, sa.size, is_pod);
-        dp = next_dp;
-    }
-
-    void walk_box1() { DATA_SIMPLE(void *, walk_box2()); }
-
-    void walk_uniq1() { DATA_SIMPLE(void *, walk_uniq2()); }
-
-    void walk_rptr1() { DATA_SIMPLE(void *, walk_rptr2()); }
-
-    void walk_fn1(char code) {
-        ALIGN_TO(rust_alignof<void *>());
-        U next_dp = dp + sizeof(void *) * 2;
-        static_cast<T *>(this)->walk_fn2(code);
-        dp = next_dp;
-    }
-
-    void walk_trait1() {
-        ALIGN_TO(rust_alignof<void *>());
-        U next_dp = dp + sizeof(void *);
-        static_cast<T *>(this)->walk_trait2();
-        dp = next_dp;
-    }
-
-    void walk_tydesc1(char kind) {
-        ALIGN_TO(rust_alignof<void *>());
-        U next_dp = dp + sizeof(void *);
-        static_cast<T *>(this)->walk_tydesc2(kind);
-        dp = next_dp;
-    }
-
-    void walk_res1(const rust_fn *dtor, const uint8_t *end_sp) {
-        // Delegate to the implementation.
-        static_cast<T *>(this)->walk_res2(dtor, end_sp);
-    }
-
-    template<typename WN>
-    void walk_number1() {
-        //DATA_SIMPLE(W, walk_number2<W>());
-        ALIGN_TO(rust_alignof<WN>());
-        U end_dp = dp + sizeof(WN);
-        T* t = static_cast<T *>(this);
-        t->template walk_number2<WN>();
-        dp = end_dp;
-    }
-};
-
-template<typename T,typename U>
-void
-data<T,U>::walk_box_contents1() {
-    const type_desc *body_td = dp.box_body_td();
-    if (body_td) {
-        U body_dp(dp.box_body());
-        arena arena;
-        T sub(*static_cast<T *>(this), body_td->shape,
-              body_td->shape_tables, body_dp);
-        sub.align = true;
-        static_cast<T *>(this)->walk_box_contents2(sub);
-    }
-}
-
-template<typename T,typename U>
-void
-data<T,U>::walk_uniq_contents1() {
-    const type_desc *body_td = dp.uniq_body_td();
-    if (body_td) {
-        U body_dp(dp.box_body());
-        arena arena;
-        T sub(*static_cast<T *>(this), /*body_td->shape,*/ this->sp,
-              body_td->shape_tables, body_dp);
-        sub.align = true;
-        static_cast<T *>(this)->walk_uniq_contents2(sub);
-    }
-}
-
-template<typename T,typename U>
-void
-data<T,U>::walk_rptr_contents1() {
-    typename U::template data<uint8_t *>::t box_ptr = bump_dp<uint8_t *>(dp);
-    U data_ptr(box_ptr);
-    T sub(*static_cast<T *>(this), data_ptr);
-    static_cast<T *>(this)->walk_rptr_contents2(sub);
-}
-
-template<typename T,typename U>
-void
-data<T,U>::walk_variant1(tag_info &tinfo, tag_variant_t variant_id) {
-    std::pair<const uint8_t *,const uint8_t *> variant_ptr_and_end =
-      this->get_variant_sp(tinfo, variant_id);
-    static_cast<T *>(this)->walk_variant2(tinfo, variant_id,
-                                          variant_ptr_and_end);
-}
-
-template<typename T,typename U>
-std::pair<uint8_t *,uint8_t *>
-data<T,U>::get_vec_data_range(ptr dp) {
-    rust_vec_box* ptr = bump_dp<rust_vec_box*>(dp);
-    uint8_t* data = &ptr->body.data[0];
-    return std::make_pair(data, data + ptr->body.fill);
-}
-
-template<typename T,typename U>
-std::pair<ptr_pair,ptr_pair>
-data<T,U>::get_vec_data_range(ptr_pair &dp) {
-    std::pair<uint8_t *,uint8_t *> fst =
-        get_vec_data_range(shape::ptr(dp.fst));
-    std::pair<uint8_t *,uint8_t *> snd =
-        get_vec_data_range(shape::ptr(dp.snd));
-    ptr_pair start(fst.first, snd.first);
-    ptr_pair end(fst.second, snd.second);
-    return std::make_pair(start, end);
-}
-
-template<typename T,typename U>
-std::pair<uint8_t *,uint8_t *>
-data<T,U>::get_unboxed_vec_data_range(ptr dp) {
-    rust_vec* ptr = (rust_vec*)dp;
-    uint8_t* data = &ptr->data[0];
-    return std::make_pair(data, data + ptr->fill);
-}
-
-template<typename T,typename U>
-std::pair<ptr_pair,ptr_pair>
-data<T,U>::get_unboxed_vec_data_range(ptr_pair &dp) {
-    std::pair<uint8_t *,uint8_t *> fst =
-        get_unboxed_vec_data_range(shape::ptr(dp.fst));
-    std::pair<uint8_t *,uint8_t *> snd =
-        get_unboxed_vec_data_range(shape::ptr(dp.snd));
-    ptr_pair start(fst.first, snd.first);
-    ptr_pair end(fst.second, snd.second);
-    return std::make_pair(start, end);
-}
-
-template<typename T,typename U>
-ptr data<T,U>::get_unboxed_vec_end(ptr dp) {
-    rust_vec* ptr = (rust_vec*)dp;
-    return dp + sizeof(rust_vec) + ptr->fill;
-}
-
-template<typename T,typename U>
-ptr_pair data<T,U>::get_unboxed_vec_end(ptr_pair &dp) {
-    return ptr_pair(get_unboxed_vec_end(ptr(dp.fst)),
-                    get_unboxed_vec_end(ptr(dp.snd)));
-}
-
-template<typename T,typename U>
-std::pair<uint8_t *,uint8_t *>
-data<T,U>::get_slice_data_range(bool is_str, ptr dp) {
-    uint8_t* ptr = bump_dp<uint8_t*>(dp);
-    size_t len = bump_dp<size_t>(dp);
-    if (is_str) len--;
-    return std::make_pair(ptr, ptr + len);
-}
-
-template<typename T,typename U>
-std::pair<ptr_pair,ptr_pair>
-data<T,U>::get_slice_data_range(bool is_str, ptr_pair &dp) {
-    std::pair<uint8_t *,uint8_t *> fst =
-        get_slice_data_range(is_str, shape::ptr(dp.fst));
-    std::pair<uint8_t *,uint8_t *> snd =
-        get_slice_data_range(is_str, shape::ptr(dp.snd));
-    ptr_pair start(fst.first, snd.first);
-    ptr_pair end(fst.second, snd.second);
-    return std::make_pair(start, end);
-}
-
-template<typename T,typename U>
-std::pair<uint8_t *,uint8_t *>
-data<T,U>::get_fixedvec_data_range(uint16_t n_elts, size_t elt_sz, ptr dp) {
-    uint8_t* ptr = (uint8_t*)(dp);
-    return std::make_pair(ptr, ptr + (((size_t)n_elts) * elt_sz));
-}
-
-template<typename T,typename U>
-std::pair<ptr_pair,ptr_pair>
-data<T,U>::get_fixedvec_data_range(uint16_t n_elts, size_t elt_sz,
-                                   ptr_pair &dp) {
-    std::pair<uint8_t *,uint8_t *> fst =
-        get_fixedvec_data_range(n_elts, elt_sz, shape::ptr(dp.fst));
-    std::pair<uint8_t *,uint8_t *> snd =
-        get_fixedvec_data_range(n_elts, elt_sz, shape::ptr(dp.snd));
-    ptr_pair start(fst.first, snd.first);
-    ptr_pair end(fst.second, snd.second);
-    return std::make_pair(start, end);
-}
-
-
-template<typename T,typename U>
-void
-data<T,U>::walk_tag1(tag_info &tinfo) {
-    size_of::compute_tag_size(*this, tinfo);
-
-    if (tinfo.variant_count > 1)
-        ALIGN_TO(rust_alignof<tag_align_t>());
-
-    U end_dp = dp + tinfo.tag_sa.size;
-
-    typename U::template data<tag_variant_t>::t tag_variant;
-    if (tinfo.variant_count > 1)
-        tag_variant = bump_dp<tag_variant_t>(dp);
-    else
-        tag_variant = 0;
-
-    static_cast<T *>(this)->walk_tag2(tinfo, tag_variant);
-
-    dp = end_dp;
-}
-
-template<typename T,typename U>
-void
-  data<T,U>::walk_fn_contents1() {
-    fn_env_pair pair = bump_dp<fn_env_pair>(dp);
-    if (!pair.env)
-        return;
-
-    arena arena;
-    const type_desc *closure_td = pair.env->td;
-    ptr closure_dp((uintptr_t)box_body(pair.env));
-    T sub(*static_cast<T *>(this), closure_td->shape,
-          closure_td->shape_tables, closure_dp);
-    sub.align = true;
-
-    sub.walk();
-}
-
-template<typename T,typename U>
-void
-data<T,U>::walk_trait_contents1() {
-    walk_box_contents1();
-}
-
-// Polymorphic logging, for convenience
-
-class log : public data<log,ptr> {
-    friend class data<log,ptr>;
-
-private:
-    std::ostream &out;
-    const char *prefix;
-    bool in_string;
-
-    log(log &other,
-        const uint8_t *in_sp,
-        const rust_shape_tables *in_tables = NULL)
-    : data<log,ptr>(other.task,
-                    other.align,
-                    in_sp,
-                    in_tables ? in_tables : other.tables,
-                    other.dp),
-      out(other.out),
-      prefix("") {}
-
-    log(log &other,
-        const uint8_t *in_sp,
-        const rust_shape_tables *in_tables,
-        ptr in_dp)
-    : data<log,ptr>(other.task,
-                    other.align,
-                    in_sp,
-                    in_tables,
-                    in_dp),
-      out(other.out),
-      prefix("") {}
-
-    log(log &other, ptr in_dp)
-    : data<log,ptr>(other.task,
-                    other.align,
-                    other.sp,
-                    other.tables,
-                    in_dp),
-      out(other.out),
-      prefix("") {}
-
-    void walk_vec2(bool is_pod) {
-        if (!get_dp<void *>(dp))
-            out << prefix << "(null)";
-        else
-            walk_vec2(is_pod, get_vec_data_range(dp));
-    }
-
-    void walk_unboxed_vec2(bool is_pod) {
-        walk_vec2(is_pod, get_unboxed_vec_data_range(dp));
-    }
-
-    void walk_slice2(bool is_pod, bool is_str) {
-        walk_vec2(is_pod, get_slice_data_range(is_str, dp));
-        out << "/&";
-    }
-
-    void walk_fixedvec2(uint16_t n_elts, size_t elt_sz, bool is_pod) {
-        walk_vec2(is_pod, get_fixedvec_data_range(n_elts, elt_sz, dp));
-        out << "/" << n_elts;
-    }
-
-    void walk_tag2(tag_info &tinfo, tag_variant_t tag_variant) {
-        // out << prefix << "tag" << tag_variant;
-        out << prefix << get_variant_name(tinfo, tag_variant);
-        data<log,ptr>::walk_variant1(tinfo, tag_variant);
-    }
-
-    void walk_box2() {
-        out << prefix << "@";
-        prefix = "";
-        data<log,ptr>::walk_box_contents1();
-    }
-
-    void walk_uniq2() {
-        out << prefix << "~";
-        prefix = "";
-        data<log,ptr>::walk_uniq_contents1();
-    }
-
-    void walk_rptr2() {
-        out << prefix << "&";
-        prefix = "";
-        data<log,ptr>::walk_rptr_contents1();
-    }
-
-    void walk_fn2(char kind) {
-        out << prefix << "fn";
-        prefix = "";
-        data<log,ptr>::walk_fn_contents1();
-    }
-
-    void walk_trait2() {
-        out << prefix << "trait(";
-        prefix = "";
-        data<log,ptr>::walk_trait_contents1();
-        out << prefix << ")";
-    }
-
-    void walk_tydesc2(char kind) {
-        out << prefix << "tydesc";
-    }
-
-    void walk_subcontext2(log &sub) { sub.walk(); }
-
-    void walk_box_contents2(log &sub) {
-        out << prefix;
-        rust_opaque_box *box_ptr = *(rust_opaque_box **) dp;
-        if (!box_ptr) {
-            out << "(null)";
-        } else {
-            sub.align = true;
-            sub.walk();
-        }
-    }
-
-    void walk_uniq_contents2(log &sub) {
-        out << prefix;
-        sub.align = true;
-        sub.walk();
-    }
-
-    void walk_rptr_contents2(log &sub) {
-        out << prefix;
-        sub.align = true;
-        sub.walk();
-    }
-
-    void walk_struct2(const uint8_t *end_sp);
-    void walk_vec2(bool is_pod, const std::pair<ptr,ptr> &data);
-    void walk_slice2(bool is_pod, const std::pair<ptr,ptr> &data);
-    void walk_variant2(tag_info &tinfo,
-                       tag_variant_t variant_id,
-                       const std::pair<const uint8_t *,const uint8_t *>
-                       variant_ptr_and_end);
-    void walk_string2(const std::pair<ptr,ptr> &data);
-    void walk_res2(const rust_fn *dtor, const uint8_t *end_sp);
-
-    template<typename T>
-    inline void walk_number2() {
-        out << prefix;
-        fmt_number(out, get_dp<T>(dp));
-    }
-
-public:
-    log(rust_task *in_task,
-        bool in_align,
-        const uint8_t *in_sp,
-        const rust_shape_tables *in_tables,
-        uint8_t *in_data,
-        std::ostream &in_out)
-        : data<log,ptr>(in_task, in_align, in_sp, in_tables,
-                        ptr(in_data)),
-      out(in_out),
-      prefix("") {}
-};
-
-}   // end namespace shape
-
-#endif
-
-//
-// Local Variables:
-// mode: C++
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// End:
-//
diff --git a/src/rt/rust_type.h b/src/rt/rust_type.h
index 036485825f1..9612c0dc409 100644
--- a/src/rt/rust_type.h
+++ b/src/rt/rust_type.h
@@ -17,11 +17,6 @@ struct type_desc;
 
 typedef void CDECL (glue_fn)(void *, void *, const type_desc **, void *);
 
-struct rust_shape_tables {
-    uint8_t *tags;
-    uint8_t *resources;
-};
-
 // Corresponds to the boxed data in the @ region.  The body follows the
 // header; you can obtain a ptr via box_body() below.
 struct rust_opaque_box {
@@ -52,8 +47,8 @@ struct type_desc {
     glue_fn *drop_glue;
     glue_fn *free_glue;
     glue_fn *visit_glue;
-    const uint8_t *shape;
-    const rust_shape_tables *shape_tables;
+    const uint8_t *unused;
+    const uint8_t *unused2;
 };
 
 extern "C" type_desc *rust_clone_type_desc(type_desc*);
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index afb62d52be7..0a9f0647789 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -301,12 +301,8 @@ rust_upcall_free(void* ptr) {
 
 extern "C" CDECL void
 upcall_validate_box(rust_opaque_box* ptr) {
-    if (ptr) {
-        assert(ptr->ref_count > 0);
-        assert(ptr->td != NULL);
-        assert(ptr->td->align <= 8);
-        assert(ptr->td->size <= 4096); // might not really be true...
-    }
+    // XXX: Remove after snapshot
+    abort();
 }
 
 /**********************************************************************/
@@ -365,52 +361,10 @@ upcall_rust_personality(int version,
     return args.retval;
 }
 
-extern "C" void
-shape_cmp_type(int8_t *result, const type_desc *tydesc,
-               uint8_t *data_0, uint8_t *data_1, uint8_t cmp_type);
-
-struct s_cmp_type_args {
-    int8_t *result;
-    const type_desc *tydesc;
-    uint8_t *data_0;
-    uint8_t *data_1;
-    uint8_t cmp_type;
-};
-
-extern "C" void
-upcall_s_cmp_type(s_cmp_type_args *args) {
-    shape_cmp_type(args->result, args->tydesc,
-                   args->data_0, args->data_1, args->cmp_type);
-}
-
-extern "C" void
-upcall_cmp_type(int8_t *result, const type_desc *tydesc,
-                uint8_t *data_0, uint8_t *data_1, uint8_t cmp_type) {
-    rust_task *task = rust_get_current_task();
-    s_cmp_type_args args = {result, tydesc,
-                            data_0, data_1, cmp_type};
-    UPCALL_SWITCH_STACK(task, &args, upcall_s_cmp_type);
-}
-
-extern "C" void
-shape_log_type(const type_desc *tydesc, uint8_t *data, uint32_t level);
-
-struct s_log_type_args {
-    const type_desc *tydesc;
-    uint8_t *data;
-    uint32_t level;
-};
-
-extern "C" void
-upcall_s_log_type(s_log_type_args *args) {
-    shape_log_type(args->tydesc, args->data, args->level);
-}
-
 extern "C" void
 upcall_log_type(const type_desc *tydesc, uint8_t *data, uint32_t level) {
-    rust_task *task = rust_get_current_task();
-    s_log_type_args args = {tydesc, data, level};
-    UPCALL_SWITCH_STACK(task, &args, upcall_s_log_type);
+    // XXX: Remove after snapshot
+    abort();
 }
 
 // NB: This needs to be blazing fast. Don't switch stacks
diff --git a/src/rt/rust_util.cpp b/src/rt/rust_util.cpp
index cd765184c1e..60e6cc3d842 100644
--- a/src/rt/rust_util.cpp
+++ b/src/rt/rust_util.cpp
@@ -1,19 +1,9 @@
 #include "rust_type.h"
-#include "rust_shape.h"
 
 
 // A hardcoded type descriptor for strings, since the runtime needs to
 // be able to create them.
 
-struct rust_shape_tables empty_shape_tables;
-
-uint8_t str_body_shape[] = {
-    shape::SHAPE_UNBOXED_VEC,
-    0x1, // is_pod
-    0x1, 0x0, // size field: 1
-    shape::SHAPE_U8
-};
-
 struct type_desc str_body_tydesc = {
     1, // size
     1, // align
@@ -21,8 +11,8 @@ struct type_desc str_body_tydesc = {
     NULL, // drop_glue
     NULL, // free_glue
     NULL, // visit_glue
-    str_body_shape, // shape
-    &empty_shape_tables, // shape_tables
+    NULL, // shape
+    NULL, // shape_tables
 };
 
 //
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index 8dac7d515b3..020008c3842 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -64,14 +64,12 @@ rust_get_stack_segment
 rust_task_weaken
 rust_task_unweaken
 rust_log_str
-shape_log_str
 start_task
 vec_reserve_shared_actual
 vec_reserve_shared
 task_clear_event_reject
 task_wait_event
 task_signal_event
-upcall_cmp_type
 upcall_fail
 upcall_trace
 upcall_free