about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2012-05-03 12:56:55 -0700
committerGraydon Hoare <graydon@mozilla.com>2012-05-03 13:09:02 -0700
commit11a5d10bf2958c642ae6a7c4afff8e181aa2167d (patch)
tree94e14a4863f8ff951f82556485146960d5584b8a
parente1fc7d5f0126e4c213cac589bf301814e0327b9e (diff)
downloadrust-11a5d10bf2958c642ae6a7c4afff8e181aa2167d.tar.gz
rust-11a5d10bf2958c642ae6a7c4afff8e181aa2167d.zip
Implement better shape code for evec, estr.
-rw-r--r--src/rt/rust_box_annihilator.cpp12
-rw-r--r--src/rt/rust_cc.cpp61
-rw-r--r--src/rt/rust_shape.cpp23
-rw-r--r--src/rt/rust_shape.h163
-rw-r--r--src/rustc/middle/trans/shape.rs53
-rw-r--r--src/test/run-pass/estr-internal.rs22
-rw-r--r--src/test/run-pass/estr-slice.rs48
7 files changed, 336 insertions, 46 deletions
diff --git a/src/rt/rust_box_annihilator.cpp b/src/rt/rust_box_annihilator.cpp
index 6322c528791..bc5e0dfdda5 100644
--- a/src/rt/rust_box_annihilator.cpp
+++ b/src/rt/rust_box_annihilator.cpp
@@ -49,8 +49,16 @@ class annihilator : public shape::data<annihilator,shape::ptr> {
         task->kernel->free(vec);
     }
 
+    void walk_fixedvec2(uint16_t sz, bool is_pod) {
+        walk_vec2(is_pod, get_fixedvec_data_range(sz, dp));
+    }
+
     void walk_vec2(bool is_pod,
                   const std::pair<shape::ptr,shape::ptr> &data_range) {
+
+        if (is_pod)
+            return;
+
         annihilator sub(*this, data_range.first);
         shape::ptr data_end = sub.end_dp = data_range.second;
         while (sub.dp < data_end) {
@@ -64,6 +72,10 @@ class annihilator : public shape::data<annihilator,shape::ptr> {
           ::walk_variant1(tinfo, tag_variant);
     }
 
+    void walk_rptr2() { }
+
+    void walk_slice2(bool, bool) { }
+
     void walk_uniq2() {
         void *x = *((void **)dp);
         // free contents first:
diff --git a/src/rt/rust_cc.cpp b/src/rt/rust_cc.cpp
index 0b75d856f81..4e3facd0413 100644
--- a/src/rt/rust_cc.cpp
+++ b/src/rt/rust_cc.cpp
@@ -73,19 +73,37 @@ class irc : public shape::data<irc,shape::ptr> {
                                   in_tables, in_data),
       ircs(in_ircs) {}
 
-    void walk_vec2(bool is_pod) {
-        if (is_pod || shape::get_dp<void *>(dp) == NULL)
-            return;     // There can't be any outbound pointers from this.
 
-        std::pair<uint8_t *,uint8_t *> data_range(get_vec_data_range(dp));
+    void walk_vec2(bool is_pod, std::pair<uint8_t *,uint8_t *> data_range) {
+
+        // There can't be any outbound pointers from pod.
+        if (is_pod)
+            return;
+
         irc sub(*this, data_range.first);
         shape::ptr data_end = sub.end_dp = data_range.second;
         while (sub.dp < data_end) {
             sub.walk_reset();
+            // FIXME: shouldn't this be 'sub.align = true;'?
             align = true;
         }
     }
 
+    void walk_vec2(bool is_pod) {
+        if (shape::get_dp<void *>(dp) == NULL)
+            return;
+
+        walk_vec2(is_pod, get_vec_data_range(dp));
+    }
+
+    void walk_slice2(bool is_pod, bool is_str) {
+        walk_vec2(is_pod, get_slice_data_range(is_str, dp));
+    }
+
+    void walk_fixedvec2(uint16_t sz, bool is_pod) {
+        walk_vec2(is_pod, get_fixedvec_data_range(sz, dp));
+    }
+
     void walk_tag2(shape::tag_info &tinfo, uint32_t tag_variant) {
         shape::data<irc,shape::ptr>::walk_variant1(tinfo, tag_variant);
     }
@@ -102,6 +120,10 @@ class irc : public shape::data<irc,shape::ptr> {
         shape::data<irc,shape::ptr>::walk_uniq_contents1();
     }
 
+    void walk_rptr2() {
+        shape::data<irc,shape::ptr>::walk_rptr_contents1();
+    }
+
     void walk_fn2(char code) {
         switch (code) {
           case shape::SHAPE_BOX_FN: {
@@ -137,6 +159,8 @@ class irc : public shape::data<irc,shape::ptr> {
 
     void walk_uniq_contents2(irc &sub) { sub.walk(); }
 
+    void walk_rptr_contents2(irc &sub) { sub.walk(); }
+
     void walk_box_contents2(irc &sub) {
         maybe_record_irc();
 
@@ -305,11 +329,12 @@ class mark : public shape::data<mark,shape::ptr> {
                                    in_tables, in_data),
       marked(in_marked) {}
 
-    void walk_vec2(bool is_pod) {
-        if (is_pod || shape::get_dp<void *>(dp) == NULL)
-            return;     // There can't be any outbound pointers from this.
+    void walk_vec2(bool is_pod, std::pair<uint8_t *,uint8_t *> data_range) {
+
+        // There can't be any outbound pointers from pod.
+        if (is_pod)
+            return;
 
-        std::pair<uint8_t *,uint8_t *> data_range(get_vec_data_range(dp));
         if (data_range.second - data_range.first > 100000)
             abort();    // FIXME: Temporary sanity check.
 
@@ -321,6 +346,20 @@ class mark : public shape::data<mark,shape::ptr> {
         }
     }
 
+    void walk_vec2(bool is_pod) {
+        if (shape::get_dp<void *>(dp) == NULL)
+            return;
+        walk_vec2(is_pod, get_vec_data_range(dp));
+    }
+
+    void walk_slice2(bool is_pod, bool is_str) {
+        walk_vec2(is_pod, get_slice_data_range(is_str, dp));
+    }
+
+    void walk_fixedvec2(uint16_t sz, bool is_pod) {
+        walk_vec2(is_pod, get_fixedvec_data_range(sz, dp));
+    }
+
     void walk_tag2(shape::tag_info &tinfo, uint32_t tag_variant) {
         shape::data<mark,shape::ptr>::walk_variant1(tinfo, tag_variant);
     }
@@ -337,6 +376,10 @@ class mark : public shape::data<mark,shape::ptr> {
         shape::data<mark,shape::ptr>::walk_uniq_contents1();
     }
 
+    void walk_rptr2() {
+        shape::data<mark,shape::ptr>::walk_rptr_contents1();
+    }
+
     void walk_fn2(char code) {
         switch (code) {
           case shape::SHAPE_BOX_FN: {
@@ -372,6 +415,8 @@ class mark : public shape::data<mark,shape::ptr> {
 
     void walk_uniq_contents2(mark &sub) { sub.walk(); }
 
+    void walk_rptr_contents2(mark &sub) { sub.walk(); }
+
     void walk_box_contents2(mark &sub) {
         rust_opaque_box *box_ptr = *(rust_opaque_box **) dp;
 
diff --git a/src/rt/rust_shape.cpp b/src/rt/rust_shape.cpp
index 0413b7f9493..9f3fbbed89e 100644
--- a/src/rt/rust_shape.cpp
+++ b/src/rt/rust_shape.cpp
@@ -254,6 +254,9 @@ 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);
 
@@ -274,6 +277,12 @@ private:
         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);
@@ -341,6 +350,16 @@ public:
         walk_vec2(is_pod, get_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 sz, bool is_pod) {
+        // Fixedvecs compare just like vecs.
+        walk_vec2(is_pod, get_fixedvec_data_range(sz, dp));
+    }
+
     void walk_box2() {
         data<cmp,ptr_pair>::walk_box_contents1();
     }
@@ -349,6 +368,10 @@ public:
         data<cmp,ptr_pair>::walk_uniq_contents1();
     }
 
+    void walk_rptr2() {
+        data<cmp,ptr_pair>::walk_rptr_contents1();
+    }
+
     void walk_iface2() {
         data<cmp,ptr_pair>::walk_box_contents1();
     }
diff --git a/src/rt/rust_shape.h b/src/rt/rust_shape.h
index ee9b6400cd4..112a61ee239 100644
--- a/src/rt/rust_shape.h
+++ b/src/rt/rust_shape.h
@@ -59,6 +59,8 @@ 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;
 
 #ifdef _LP64
 const uint8_t SHAPE_PTR = SHAPE_U64;
@@ -279,6 +281,9 @@ private:
     void walk_struct0();
     void walk_res0();
     void walk_var0();
+    void walk_rptr0();
+    void walk_fixedvec0();
+    void walk_slice0();
 };
 
 
@@ -377,8 +382,11 @@ ctxt<T>::walk() {
     case SHAPE_UNIQ_FN:
     case SHAPE_STACK_FN:
     case SHAPE_BARE_FN:  static_cast<T*>(this)->walk_fn1(s); break;
-    case SHAPE_SEND_TYDESC:
-    case SHAPE_TYDESC:   static_cast<T*>(this)->walk_tydesc1(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;
     default:             abort();
     }
 }
@@ -504,6 +512,44 @@ ctxt<T>::walk_uniq0() {
 
 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 vec_size = 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(vec_size, 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;
@@ -580,6 +626,15 @@ public:
     void walk_box1() {
         DPRINT("@<"); walk(); DPRINT(">");
     }
+    void walk_rptr1() {
+        DPRINT("&<"); walk(); DPRINT(">");
+    }
+    void walk_fixedvec1(uint16_t sz, bool is_pod) {
+      DPRINT("fixedvec<%u, ", sz); walk(); DPRINT(">");
+    }
+    void walk_slice1(bool is_pod, bool is_str) {
+      DPRINT("slice<"); walk(); DPRINT(">");
+    }
 
     void walk_fn1(char kind) {
         switch(kind) {
@@ -641,6 +696,9 @@ public:
     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_iface1()      { sa.set(sizeof(void *),   sizeof(void *)); }
@@ -663,6 +721,12 @@ public:
         abort();    // TODO
     }
 
+    void walk_fixedvec1(uint16_t sz, bool is_pod) {
+        size_of sub(*this);
+        sub.walk();
+        sa.set(sub.sa.size * sz, sub.sa.alignment);
+    }
+
     template<typename T>
     void walk_number1()  { sa.set(sizeof(T), rust_alignof<T>()); }
 
@@ -881,6 +945,7 @@ protected:
 
     void walk_box_contents1();
     void walk_uniq_contents1();
+    void walk_rptr_contents1();
     void walk_fn_contents1();
     void walk_iface_contents1();
     void walk_variant1(tag_info &tinfo, tag_variant_t variant);
@@ -888,6 +953,16 @@ protected:
     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_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 sz, ptr dp);
+    static std::pair<ptr_pair,ptr_pair>
+        get_fixedvec_data_range(uint16_t sz, ptr_pair &dp);
+
 public:
     data(rust_task *in_task,
          bool in_align,
@@ -902,6 +977,7 @@ public:
     void walk_tag1(tag_info &tinfo);
 
     void walk_struct1(const uint8_t *end_sp) {
+        // FIXME: shouldn't we be aligning to the first element here?
         static_cast<T *>(this)->walk_struct2(end_sp);
     }
 
@@ -909,10 +985,22 @@ public:
         DATA_SIMPLE(void *, walk_vec2(is_pod));
     }
 
+    void walk_slice1(bool is_pod, bool is_str) {
+        DATA_SIMPLE(void *, walk_slice2(is_pod, is_str));
+    }
+
+    void walk_fixedvec1(uint16_t sz, bool is_pod) {
+        size_align sa = size_of::get(*this);
+        ALIGN_TO(sa.alignment);
+        static_cast<T *>(this)->walk_fixedvec2(sz, is_pod);
+    }
+
     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;
@@ -987,6 +1075,15 @@ data<T,U>::walk_uniq_contents1() {
 
 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);
@@ -1013,6 +1110,45 @@ data<T,U>::get_vec_data_range(ptr_pair &dp) {
 }
 
 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, dp.fst);
+    std::pair<uint8_t *,uint8_t *> snd =
+        get_slice_data_range(is_str, 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 sz, ptr dp) {
+    uint8_t* ptr = (uint8_t*)(dp);
+    return std::make_pair(ptr, ptr + sz);
+}
+
+template<typename T,typename U>
+std::pair<ptr_pair,ptr_pair>
+data<T,U>::get_fixedvec_data_range(uint16_t sz, ptr_pair &dp) {
+    std::pair<uint8_t *,uint8_t *> fst = get_fixedvec_data_range(sz, dp.fst);
+    std::pair<uint8_t *,uint8_t *> snd = get_fixedvec_data_range(sz, 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);
@@ -1111,6 +1247,16 @@ private:
             walk_vec2(is_pod, get_vec_data_range(dp));
     }
 
+    void walk_slice2(bool is_pod, bool is_str) {
+        walk_vec2(is_pod, get_slice_data_range(dp, is_str));
+        out << "/&";
+    }
+
+    void walk_fixedvec2(uint16_t sz, bool is_pod) {
+        walk_vec2(is_pod, get_fixedvec_data_range(sz, dp));
+        out << "/" << sz;
+    }
+
     void walk_tag2(tag_info &tinfo, tag_variant_t tag_variant) {
         // out << prefix << "tag" << tag_variant;
         out << prefix << get_variant_name(tinfo, tag_variant);
@@ -1129,6 +1275,12 @@ private:
         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 = "";
@@ -1165,8 +1317,15 @@ private:
         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 *>
diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs
index 68166cbf728..ce6afcd844d 100644
--- a/src/rustc/middle/trans/shape.rs
+++ b/src/rustc/middle/trans/shape.rs
@@ -361,50 +361,39 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
         s
       }
 
-      // FIXME: grotesque hacks for encoding fixed-size evecs and estrs.
-
       ty::ty_estr(ty::vstore_fixed(n)) {
-        let mut s = [shape_struct], sub = [];
-        let mut i = 0u;
+        let mut s = [shape_fixedvec];
         let u8_t = ty::mk_mach_uint(ccx.tcx, ast::ty_u8);
-        while i < n {
-            sub += shape_of(ccx, u8_t, ty_param_map);
-            i += 1u;
-        }
-        add_substr(s, sub);
+        assert (n + 1u) <= 0xffffu;
+        add_u16(s, (n + 1u) as u16);
+        add_bool(s, true);
+        add_substr(s, shape_of(ccx, u8_t, ty_param_map));
         s
       }
 
       ty::ty_evec(mt, ty::vstore_fixed(n)) {
-        let mut s = [shape_struct], sub = [];
-        let mut i = 0u;
-        while i < n {
-            sub += shape_of(ccx, mt.ty, ty_param_map);
-            i += 1u;
-        }
-        add_substr(s, sub);
+        let mut s = [shape_fixedvec];
+        assert n <= 0xffffu;
+        add_u16(s, n as u16);
+        add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty));
+        add_substr(s, shape_of(ccx, mt.ty, ty_param_map));
         s
       }
 
-
-      // FIXME: slightly-less-grotesque hack for encoding slic,e evecs and
-      // estrs.
-
       ty::ty_estr(ty::vstore_slice(r)) {
-        let mut s = [shape_struct], sub = [];
-        let u8_mt = {ty: ty::mk_mach_uint(ccx.tcx, ast::ty_u8),
-                     mutbl: ast::m_imm };
-        sub += shape_of(ccx, ty::mk_rptr(ccx.tcx, r, u8_mt), ty_param_map);
-        sub += shape_of(ccx, ty::mk_uint(ccx.tcx), ty_param_map);
-        add_substr(s, sub);
+        let mut s = [shape_slice];
+        let u8_t = ty::mk_mach_uint(ccx.tcx, ast::ty_u8);
+        add_bool(s, true); // is_pod
+        add_bool(s, true); // is_str
+        add_substr(s, shape_of(ccx, u8_t, ty_param_map));
         s
       }
 
       ty::ty_evec(mt, ty::vstore_slice(r)) {
-        let mut s = [shape_struct], sub = [];
-        sub += shape_of(ccx, ty::mk_rptr(ccx.tcx, r, mt), ty_param_map);
-        sub += shape_of(ccx, ty::mk_uint(ccx.tcx), ty_param_map);
-        add_substr(s, sub);
+        let mut s = [shape_slice];
+        add_bool(s, ty::type_is_pod(ccx.tcx, mt.ty));
+        add_bool(s, false); // is_str
+        add_substr(s, shape_of(ccx, mt.ty, ty_param_map));
         s
       }
 
@@ -434,9 +423,9 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t, ty_param_map: [uint]) -> [u8] {
         add_substr(s, sub);
         s
       }
-      ty::ty_rptr(_, tm) {
+      ty::ty_rptr(_, mt) {
         let mut s = [shape_rptr];
-        add_substr(s, shape_of(ccx, tm.ty, ty_param_map));
+        add_substr(s, shape_of(ccx, mt.ty, ty_param_map));
         s
       }
       ty::ty_res(did, raw_subt, substs) {
diff --git a/src/test/run-pass/estr-internal.rs b/src/test/run-pass/estr-internal.rs
index d7f7fd6b41a..b5290f3c0ab 100644
--- a/src/test/run-pass/estr-internal.rs
+++ b/src/test/run-pass/estr-internal.rs
@@ -5,4 +5,26 @@ fn main() {
     z = x;
     assert z[0] == ('h' as u8);
     assert z[4] == ('o' as u8);
+
+    let a = "aaaa"/_;
+    let b = "bbbb"/_;
+    let c = "cccc"/_;
+
+    log(debug, a);
+
+    assert a < b;
+    assert a <= b;
+    assert a != b;
+    assert b >= a;
+    assert b > a;
+
+    log(debug, b);
+
+    assert a < c;
+    assert a <= c;
+    assert a != c;
+    assert c >= a;
+    assert c > a;
+
+    log(debug, c);
 }
diff --git a/src/test/run-pass/estr-slice.rs b/src/test/run-pass/estr-slice.rs
index f91474cba8b..af31e546c6a 100644
--- a/src/test/run-pass/estr-slice.rs
+++ b/src/test/run-pass/estr-slice.rs
@@ -1,7 +1,47 @@
+
 fn main() {
     let x = "hello"/&;
-    let mut y = "there"/&;
-    y = x;
-    assert y[0] == 'h' as u8;
-    assert y[4] == 'o' as u8;
+    let v = "hello"/&;
+    let mut y : str/& = "there"/&;
+
+    log(debug, x);
+    log(debug, y);
+
+    assert x[0] == 'h' as u8;
+    assert x[4] == 'o' as u8;
+
+    let z : str/& = "thing"/&;
+    assert v == x;
+    assert x != z;
+
+    let a = "aaaa"/&;
+    let b = "bbbb"/&;
+    let c = "cccc"/&;
+    let cc = "ccccc"/&;
+
+    log(debug, a);
+
+    assert a < b;
+    assert a <= b;
+    assert a != b;
+    assert b >= a;
+    assert b > a;
+
+    log(debug, b);
+
+    assert a < c;
+    assert a <= c;
+    assert a != c;
+    assert c >= a;
+    assert c > a;
+
+    log(debug, c);
+
+    assert c < cc;
+    assert c <= cc;
+    assert c != cc;
+    assert cc >= c;
+    assert cc > c;
+
+    log(debug, cc);
 }
\ No newline at end of file