about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-06-24 15:09:57 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-06-24 15:09:57 -0700
commit487cbf8e906f73589df9501004abeb570b24f121 (patch)
tree7203f78ddc8930c8627966e2d292d7237c1a4a6d /src
parent60a748a1d8e9631df9b04235881917c0a80c9e03 (diff)
downloadrust-487cbf8e906f73589df9501004abeb570b24f121.tar.gz
rust-487cbf8e906f73589df9501004abeb570b24f121.zip
Remove resources
Also fixed shapes for classes with dtors, as well as handling
offsets for classes with dtors correctly in take glue.

Closes #2485
Diffstat (limited to 'src')
-rw-r--r--src/libsyntax/ast.rs3
-rw-r--r--src/libsyntax/ast_map.rs21
-rw-r--r--src/libsyntax/ast_util.rs4
-rw-r--r--src/libsyntax/fold.rs8
-rw-r--r--src/libsyntax/parse/parser.rs25
-rw-r--r--src/libsyntax/parse/token.rs3
-rw-r--r--src/libsyntax/print/pprust.rs49
-rw-r--r--src/libsyntax/visit.rs11
-rw-r--r--src/rt/rust_box_annihilator.cpp7
-rw-r--r--src/rt/rust_cc.cpp6
-rw-r--r--src/rt/rust_shape.cpp8
-rw-r--r--src/rt/rust_shape.h5
-rw-r--r--src/rustc/metadata/encoder.rs39
-rw-r--r--src/rustc/metadata/tydecode.rs8
-rw-r--r--src/rustc/metadata/tyencode.rs8
-rw-r--r--src/rustc/middle/borrowck.rs5
-rw-r--r--src/rustc/middle/borrowck/categorization.rs4
-rw-r--r--src/rustc/middle/borrowck/check_loans.rs2
-rw-r--r--src/rustc/middle/borrowck/loan.rs3
-rw-r--r--src/rustc/middle/borrowck/preserve.rs3
-rw-r--r--src/rustc/middle/kind.rs6
-rw-r--r--src/rustc/middle/region.rs2
-rw-r--r--src/rustc/middle/resolve.rs20
-rw-r--r--src/rustc/middle/trans/base.rs202
-rw-r--r--src/rustc/middle/trans/debuginfo.rs15
-rw-r--r--src/rustc/middle/trans/reachable.rs12
-rw-r--r--src/rustc/middle/trans/reflect.rs1
-rw-r--r--src/rustc/middle/trans/shape.rs32
-rw-r--r--src/rustc/middle/trans/type_of.rs4
-rw-r--r--src/rustc/middle/trans/type_use.rs4
-rw-r--r--src/rustc/middle/tstate/pre_post_conditions.rs8
-rw-r--r--src/rustc/middle/ty.rs67
-rw-r--r--src/rustc/middle/typeck/check.rs4
-rw-r--r--src/rustc/middle/typeck/collect.rs65
-rw-r--r--src/rustc/middle/typeck/infer.rs10
-rw-r--r--src/rustc/util/ppaux.rs4
-rw-r--r--src/rustdoc/demo.rs6
-rw-r--r--src/rustdoc/doc.rs22
-rw-r--r--src/rustdoc/extract.rs19
-rw-r--r--src/rustdoc/fold.rs21
-rw-r--r--src/rustdoc/markdown_pass.rs9
-rw-r--r--src/rustdoc/prune_unexported_pass.rs13
-rw-r--r--src/rustdoc/reexport_pass.rs6
-rw-r--r--src/rustdoc/sort_item_type_pass.rs3
-rw-r--r--src/rustdoc/text_pass.rs12
-rw-r--r--src/rustdoc/tystr_pass.rs28
-rw-r--r--src/test/compile-fail/regions-in-rsrcs.rs8
-rw-r--r--src/test/run-pass/resource-cycle.rs40
-rw-r--r--src/test/run-pass/resource-cycle2.rs8
49 files changed, 145 insertions, 728 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 9d3dcb0f23e..fd7c3aa9e71 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -670,9 +670,6 @@ enum item_ {
     item_native_mod(native_mod),
     item_ty(@ty, [ty_param], region_param),
     item_enum([variant], [ty_param], region_param),
-    item_res(fn_decl /* dtor */, [ty_param], blk /* dtor body */,
-             node_id /* dtor id */, node_id /* ctor id */,
-             region_param),
     item_class([ty_param], /* ty params for class */
                [@iface_ref],   /* ifaces this class implements */
                [@class_member], /* methods, etc. */
diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs
index 9355da5779e..219769dd28c 100644
--- a/src/libsyntax/ast_map.rs
+++ b/src/libsyntax/ast_map.rs
@@ -43,18 +43,14 @@ enum ast_node {
     // order they are introduced.
     node_arg(arg, uint),
     node_local(uint),
-    // Constructor for either a resource or a class
-    node_ctor(ident, [ty_param], a_ctor, @path),
+    // Constructor for a class
+    // def_id is parent id
+    node_ctor(ident, [ty_param], @class_ctor, def_id, @path),
     // Destructor for a class
     node_dtor([ty_param], @class_dtor, def_id, @path),
     node_block(blk),
 }
 
-enum a_ctor {
-  res_ctor(fn_decl, node_id, codemap::span),
-  class_ctor(@class_ctor, def_id /* ID for parent class */),
-}
-
 type map = std::map::hashmap<node_id, ast_node>;
 type ctx = {map: map, mut path: path,
             mut local_id: uint, diag: span_handler};
@@ -138,7 +134,7 @@ fn map_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
                     span: sp};
           cx.map.insert(id, node_ctor(/* FIXME (#2543) */ copy nm,
                                       /* FIXME (#2543) */ copy tps,
-                                      class_ctor(ct, parent_id),
+                                      ct, parent_id,
                                       @/* FIXME (#2543) */ copy cx.path));
        }
       visit::fk_dtor(tps, self_id, parent_id) {
@@ -199,15 +195,6 @@ fn map_item(i: @item, cx: ctx, v: vt) {
                        cx);
         }
       }
-      item_res(decl, tps, _, dtor_id, ctor_id, _) {
-        cx.map.insert(ctor_id, node_ctor(/* FIXME (#2543) */ copy i.ident,
-                                         /* FIXME (#2543) */ copy tps,
-                                         res_ctor(/* FIXME (#2543) */
-                                                  copy decl,
-                                                  ctor_id, i.span),
-                                         item_path));
-        cx.map.insert(dtor_id, node_item(i, item_path));
-      }
       item_enum(vs, _, _) {
         for vs.each {|v|
             cx.map.insert(v.node.id, node_variant(
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 8ce34a06329..f402e1f6ab5 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -425,7 +425,6 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> {
         visit_item: fn@(i: @item) {
             vfn(i.id);
             alt i.node {
-              item_res(_, _, _, d_id, c_id, _) { vfn(d_id); vfn(c_id); }
               item_enum(vs, _, _) { for vs.each {|v| vfn(v.node.id); } }
               _ {}
             }
@@ -497,8 +496,7 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> {
                 vfn(self_id);
                 vfn(parent_id.node);
               }
-              visit::fk_item_fn(_, tps) |
-              visit::fk_res(_, tps, _) {
+              visit::fk_item_fn(_, tps) {
                 vec::iter(tps) {|tp| vfn(tp.id)}
               }
               visit::fk_method(_, tps, m) {
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index ff296eb5aad..492210a55b8 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -281,14 +281,6 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
                        rp,
                        /* FIXME (#2543) */ copy methods)
           }
-          item_res(decl, typms, body, did, cid, rp) {
-            item_res(fold_fn_decl(decl, fld),
-                     fold_ty_params(typms, fld),
-                     fld.fold_block(body),
-                     fld.new_id(did),
-                     fld.new_id(cid),
-                     rp)
-          }
         };
 }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 46e838fd4be..2196ae9d4be 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1917,29 +1917,6 @@ class parser {
         (ident, item_impl(tps, rp, ifce, ty, meths), none)
     }
 
-    fn parse_item_res() -> item_info {
-        let ident = self.parse_value_ident();
-        let rp = self.parse_region_param();
-        let ty_params = self.parse_ty_params();
-        self.expect(token::LPAREN);
-        let arg_ident = self.parse_value_ident();
-        self.expect(token::COLON);
-        let t = self.parse_ty(false);
-        self.expect(token::RPAREN);
-        let dtor = self.parse_block_no_value();
-        let decl = {
-            inputs: [{mode: expl(by_ref), ty: t,
-                      ident: arg_ident, id: self.get_id()}],
-            output: @{id: self.get_id(), node: ty_nil,
-                      span: ast_util::dummy_sp()},
-            purity: impure_fn,
-            cf: return_val,
-            constraints: []
-        };
-        (ident, item_res(decl, ty_params, dtor,
-                         self.get_id(), self.get_id(), rp), none)
-    }
-
     // Instantiates ident <i> with references to <typarams> as arguments.
     // Used to create a path that refers to a class which will be defined as
     // the return type of the ctor function.
@@ -2341,8 +2318,6 @@ class parser {
             self.parse_item_iface()
         } else if self.eat_keyword("impl") {
             self.parse_item_impl()
-        } else if self.eat_keyword("resource") {
-            self.parse_item_res()
         } else if self.eat_keyword("class") {
             self.parse_item_class()
         } else { ret none; };
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 39327f1efad..478d7f53658 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -293,8 +293,7 @@ fn restricted_keyword_table() -> hashmap<str, ()> {
         "let", "log", "loop",
         "mod", "mut",
         "native", "new",
-        "pure",
-        "resource", "ret",
+        "pure", "ret",
         "true", "trait", "type",
         "unchecked", "unsafe",
         "while"
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 89f3b2d3aba..54864c287ae 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -130,38 +130,6 @@ fn test_fun_to_str() {
     assert fun_to_str(decl, "a", []) == "fn a()";
 }
 
-fn res_to_str(decl: ast::fn_decl, name: ast::ident,
-              params: [ast::ty_param], rp: ast::region_param) -> str {
-    let buffer = io::mem_buffer();
-    let s = rust_printer(io::mem_buffer_writer(buffer));
-    print_res(s, decl, name, params, rp);
-    end(s); // Close the head box
-    end(s); // Close the outer box
-    eof(s.s);
-    io::mem_buffer_str(buffer)
-}
-
-#[test]
-fn test_res_to_str() {
-    let decl: ast::fn_decl = {
-        inputs: [{
-            mode: ast::expl(ast::by_val),
-            ty: @{id: 0,
-                  node: ast::ty_nil,
-                  span: ast_util::dummy_sp()},
-            ident: "b",
-            id: 0
-        }],
-        output: @{id: 0,
-                  node: ast::ty_nil,
-                  span: ast_util::dummy_sp()},
-        purity: ast::impure_fn,
-        cf: ast::return_val,
-        constraints: []
-    };
-    assert res_to_str(decl, "a", []) == "resource a(b: ())";
-}
-
 fn block_to_str(blk: ast::blk) -> str {
     let buffer = io::mem_buffer();
     let s = rust_printer(io::mem_buffer_writer(buffer));
@@ -615,27 +583,10 @@ fn print_item(s: ps, &&item: @ast::item) {
         for methods.each {|meth| print_ty_method(s, meth); }
         bclose(s, item.span);
       }
-      ast::item_res(decl, tps, body, dt_id, ct_id, rp) {
-        print_res(s, decl, item.ident, tps, rp);
-        print_block(s, body);
-      }
     }
     s.ann.post(ann_node);
 }
 
-fn print_res(s: ps, decl: ast::fn_decl, name: ast::ident,
-             typarams: [ast::ty_param], rp: ast::region_param) {
-    head(s, "resource");
-    word(s.s, *name);
-    print_region_param(s, rp);
-    print_type_params(s, typarams);
-    popen(s);
-    word_space(s, *decl.inputs[0].ident + ":");
-    print_type(s, decl.inputs[0].ty);
-    pclose(s);
-    space(s.s);
-}
-
 fn print_variant(s: ps, v: ast::variant) {
     word(s.s, *v.node.name);
     if vec::len(v.node.args) > 0u {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 5d27ee1452f..714097d356d 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -15,7 +15,6 @@ enum vt<E> { mk_vt(visitor<E>), }
 enum fn_kind {
     fk_item_fn(ident, [ty_param]), //< an item declared with fn()
     fk_method(ident, [ty_param], @method),
-    fk_res(ident, [ty_param], region_param),
     fk_anon(proto, capture_clause),  //< an anonymous function like fn@(...)
     fk_fn_block(capture_clause),     //< a block {||...}
     fk_ctor(ident, [ty_param], node_id /* self id */,
@@ -27,7 +26,7 @@ enum fn_kind {
 
 fn name_of_fn(fk: fn_kind) -> ident {
     alt fk {
-      fk_item_fn(name, _) | fk_method(name, _, _) | fk_res(name, _, _)
+      fk_item_fn(name, _) | fk_method(name, _, _)
           | fk_ctor(name, _, _, _) { /* FIXME (#2543) */ copy name }
       fk_anon(*) | fk_fn_block(*) { @"anon" }
       fk_dtor(*)                  { @"drop" }
@@ -36,7 +35,7 @@ fn name_of_fn(fk: fn_kind) -> ident {
 
 fn tps_of_fn(fk: fn_kind) -> [ty_param] {
     alt fk {
-      fk_item_fn(_, tps) | fk_method(_, tps, _) | fk_res(_, tps, _)
+      fk_item_fn(_, tps) | fk_method(_, tps, _)
               | fk_ctor(_, tps, _, _) | fk_dtor(tps, _, _) {
           /* FIXME (#2543) */ copy tps
       }
@@ -130,12 +129,6 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
         v.visit_ty(t, e, v);
         v.visit_ty_params(tps, e, v);
       }
-      item_res(decl, tps, body, dtor_id, _, rp) {
-        v.visit_fn(fk_res(/* FIXME (#2543) */ copy i.ident,
-                          /* FIXME (#2543) */ copy tps,
-                          rp),
-                   decl, body, i.span, dtor_id, e, v);
-      }
       item_enum(variants, tps, _) {
         v.visit_ty_params(tps, e, v);
         for variants.each {|vr|
diff --git a/src/rt/rust_box_annihilator.cpp b/src/rt/rust_box_annihilator.cpp
index 20058a8a9db..1ac0ac78ca7 100644
--- a/src/rt/rust_box_annihilator.cpp
+++ b/src/rt/rust_box_annihilator.cpp
@@ -138,15 +138,14 @@ class annihilator : public shape::data<annihilator,shape::ptr> {
         void *data;
     };
 
-    typedef void (*dtor)(void **retptr, void *env, void *dptr);
+    typedef void (*dtor)(void **retptr, void *dptr);
 
     static void run_dtor(run_dtor_args *args) {
         dtor f = (dtor)args->dtor;
-        f(NULL, args->dtor->env, args->data);
+        f(NULL, args->data);
     }
 
-    void walk_res2(const shape::rust_fn *dtor, const uint8_t *end_sp,
-                   bool live) {
+    void walk_res2(const shape::rust_fn *dtor, const uint8_t *end_sp) {
         void *data = (void*)(uintptr_t)dp;
         // Switch back to the Rust stack to run the destructor
         run_dtor_args args = {dtor, data};
diff --git a/src/rt/rust_cc.cpp b/src/rt/rust_cc.cpp
index ed31ddd9dad..1d3ae3ccccf 100644
--- a/src/rt/rust_cc.cpp
+++ b/src/rt/rust_cc.cpp
@@ -147,8 +147,7 @@ class irc : public shape::data<irc,shape::ptr> {
     void walk_tydesc2(char) {
     }
 
-    void walk_res2(const shape::rust_fn *dtor, const uint8_t *end_sp,
-                   bool live) {
+    void walk_res2(const shape::rust_fn *dtor, const uint8_t *end_sp) {
         while (this->sp != end_sp) {
             this->walk();
             align = true;
@@ -394,8 +393,7 @@ class mark : public shape::data<mark,shape::ptr> {
         }
     }
 
-    void walk_res2(const shape::rust_fn *dtor, const uint8_t *end_sp,
-                   bool live) {
+    void walk_res2(const shape::rust_fn *dtor, const uint8_t *end_sp) {
         while (this->sp != end_sp) {
             this->walk();
             align = true;
diff --git a/src/rt/rust_shape.cpp b/src/rt/rust_shape.cpp
index 444bcc9e088..b0f6f1f77a4 100644
--- a/src/rt/rust_shape.cpp
+++ b/src/rt/rust_shape.cpp
@@ -304,8 +304,7 @@ public:
     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,
-                   const data_pair<uintptr_t> &live);
+    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 *>
@@ -356,8 +355,7 @@ cmp::walk_struct2(const uint8_t *end_sp) {
 }
 
 void
-cmp::walk_res2(const rust_fn *dtor, const uint8_t *end_sp,
-              const data_pair<uintptr_t> &live) {
+cmp::walk_res2(const rust_fn *dtor, const uint8_t *end_sp) {
     abort();    // TODO
 }
 
@@ -463,7 +461,7 @@ log::walk_variant2(tag_info &tinfo,
 }
 
 void
-log::walk_res2(const rust_fn *dtor, const uint8_t *end_sp, bool live) {
+log::walk_res2(const rust_fn *dtor, const uint8_t *end_sp) {
     out << prefix << "res";
 
     if (this->sp == end_sp)
diff --git a/src/rt/rust_shape.h b/src/rt/rust_shape.h
index cfac33008b9..26f775c9fac 100644
--- a/src/rt/rust_shape.h
+++ b/src/rt/rust_shape.h
@@ -950,9 +950,8 @@ public:
     }
 
     void walk_res1(const rust_fn *dtor, const uint8_t *end_sp) {
-        typename U::template data<uintptr_t>::t live = bump_dp<uintptr_t>(dp);
         // Delegate to the implementation.
-        static_cast<T *>(this)->walk_res2(dtor, end_sp, live);
+        static_cast<T *>(this)->walk_res2(dtor, end_sp);
     }
 
     template<typename WN>
@@ -1287,7 +1286,7 @@ private:
                        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, bool live);
+    void walk_res2(const rust_fn *dtor, const uint8_t *end_sp);
 
     template<typename T>
     inline void walk_number2() {
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index 62c4a078952..7f2474e57ca 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -186,17 +186,6 @@ fn encode_module_item_paths(ebml_w: ebml::writer, ecx: @encode_ctxt,
               encode_name_and_def_id(ebml_w, it.ident, it.id);
             }
           }
-          item_res(_, tps, _, _, ctor_id, _) {
-            ebml_w.wr_tag(tag_paths_data_item) {||
-                encode_name_and_def_id(ebml_w, it.ident, ctor_id);
-            }
-            // The same ident has to be added twice (with different positions)
-            // because it's for both the ctor and the dtor.
-            add_to_index(ebml_w, path, index, it.ident);
-            ebml_w.wr_tag(tag_paths_data_item) {||
-                encode_name_and_def_id(ebml_w, it.ident, it.id);
-            }
-          }
           item_class(_, _, items, ctor, m_dtor, _) {
             ebml_w.wr_tag(tag_paths_data_item) {||
                 encode_name_and_def_id(ebml_w, it.ident, it.id);
@@ -698,34 +687,6 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
         encode_index(ebml_w, bkts, write_int);
         ebml_w.end_tag();
       }
-      item_res(_, tps, _, _, ctor_id, rp) {
-        add_to_index();
-        let fn_ty = node_id_to_type(tcx, ctor_id);
-
-        ebml_w.start_tag(tag_items_data_item);
-        encode_def_id(ebml_w, local_def(ctor_id));
-        encode_family(ebml_w, 'y');
-        encode_type_param_bounds(ebml_w, ecx, tps);
-        encode_type(ecx, ebml_w, ty::ty_fn_ret(fn_ty));
-        encode_name(ebml_w, item.ident);
-        ecx.encode_inlined_item(ecx, ebml_w, path, ii_item(item));
-        if (tps.len() == 0u) {
-            encode_symbol(ecx, ebml_w, item.id);
-        }
-        encode_path(ebml_w, path, ast_map::path_name(item.ident));
-        encode_region_param(ebml_w, rp);
-        ebml_w.end_tag();
-
-        *index += [{val: ctor_id, pos: ebml_w.writer.tell()}];
-        ebml_w.start_tag(tag_items_data_item);
-        encode_def_id(ebml_w, local_def(ctor_id));
-        encode_family(ebml_w, 'f');
-        encode_type_param_bounds(ebml_w, ecx, tps);
-        encode_type(ecx, ebml_w, fn_ty);
-        encode_parent_item(ebml_w, local_def(item.id));
-        encode_path(ebml_w, path, ast_map::path_name(item.ident));
-        ebml_w.end_tag();
-      }
       item_impl(tps, rp, ifce, _, methods) {
         add_to_index();
         ebml_w.start_tag(tag_items_data_item);
diff --git a/src/rustc/metadata/tydecode.rs b/src/rustc/metadata/tydecode.rs
index f7c4628e51c..794af5577e7 100644
--- a/src/rustc/metadata/tydecode.rs
+++ b/src/rustc/metadata/tydecode.rs
@@ -338,14 +338,6 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
       'f' {
         parse_ty_rust_fn(st, conv)
       }
-      'r' {
-        assert next(st) == '[';
-        let def = parse_def(st, conv);
-        let inner = parse_ty(st, conv);
-        let substs = parse_substs(st, conv);
-        assert next(st) == ']';
-        ret ty::mk_res(st.tcx, def, inner, substs);
-      }
       'X' {
         ret ty::mk_var(st.tcx, ty::tv_vid(parse_int(st) as uint));
       }
diff --git a/src/rustc/metadata/tyencode.rs b/src/rustc/metadata/tyencode.rs
index f21b3850a98..dc1cbac434b 100644
--- a/src/rustc/metadata/tyencode.rs
+++ b/src/rustc/metadata/tyencode.rs
@@ -265,14 +265,6 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
       ty::ty_fn(f) {
         enc_ty_fn(w, cx, f);
       }
-      ty::ty_res(def, ty, substs) {
-        w.write_str("r["/&);
-        w.write_str(cx.ds(def));
-        w.write_char('|');
-        enc_ty(w, cx, ty);
-        enc_substs(w, cx, substs);
-        w.write_char(']');
-      }
       ty::ty_var(id) {
         w.write_char('X');
         w.write_uint(id.to_uint());
diff --git a/src/rustc/middle/borrowck.rs b/src/rustc/middle/borrowck.rs
index 9818c1c648b..7ce20dbd82f 100644
--- a/src/rustc/middle/borrowck.rs
+++ b/src/rustc/middle/borrowck.rs
@@ -249,7 +249,6 @@ enum ptr_kind {uniq_ptr, gc_ptr, region_ptr, unsafe_ptr}
 // structure accessible without a dereference":
 enum comp_kind {
     comp_tuple,                  // elt in a tuple
-    comp_res,                    // data for a resource
     comp_variant(ast::def_id),   // internals to a variant of given enum
     comp_field(ast::ident,       // name of field
                ast::mutability), // declared mutability of field
@@ -423,7 +422,6 @@ impl to_str_methods for borrowck_ctxt {
           comp_field(fld, _) { *fld }
           comp_index(*) { "[]" }
           comp_tuple { "()" }
-          comp_res { "<res>" }
           comp_variant(_) { "<enum>" }
         }
     }
@@ -483,7 +481,6 @@ impl to_str_methods for borrowck_ctxt {
           }
           cat_comp(_, comp_field(*)) { mut_str + " field" }
           cat_comp(_, comp_tuple) { "tuple content" }
-          cat_comp(_, comp_res) { "resource content" }
           cat_comp(_, comp_variant(_)) { "enum content" }
           cat_comp(_, comp_index(t, _)) {
             alt ty::get(t).struct {
@@ -530,7 +527,7 @@ impl to_str_methods for borrowck_ctxt {
 // mutable structure.
 fn inherent_mutability(ck: comp_kind) -> mutability {
     alt ck {
-      comp_tuple | comp_res | comp_variant(_) {m_imm}
+      comp_tuple | comp_variant(_)        {m_imm}
       comp_field(_, m) | comp_index(_, m) {m}
     }
 }
diff --git a/src/rustc/middle/borrowck/categorization.rs b/src/rustc/middle/borrowck/categorization.rs
index b7143706fc3..9e8ac411a1f 100644
--- a/src/rustc/middle/borrowck/categorization.rs
+++ b/src/rustc/middle/borrowck/categorization.rs
@@ -71,10 +71,6 @@ fn opt_deref_kind(t: ty::t) -> option<deref_kind> {
         some(deref_comp(comp_variant(did)))
       }
 
-      ty::ty_res(*) {
-        some(deref_comp(comp_res))
-      }
-
       ty::ty_evec(mt, ty::vstore_fixed(_)) {
         some(deref_comp(comp_index(t, mt.mutbl)))
       }
diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs
index bae0f4648d2..af5055368c8 100644
--- a/src/rustc/middle/borrowck/check_loans.rs
+++ b/src/rustc/middle/borrowck/check_loans.rs
@@ -532,7 +532,7 @@ fn check_loans_in_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk,
                   }
                   visit::fk_anon(*) | visit::fk_fn_block(*) |
                   visit::fk_method(*) | visit::fk_item_fn(*) |
-                  visit::fk_res(*) | visit::fk_dtor(*) {
+                  visit::fk_dtor(*) {
                     self.in_ctor = false;
                     self.declared_purity = decl.purity;
                     self.fn_args = @decl.inputs.map({|i| i.id});
diff --git a/src/rustc/middle/borrowck/loan.rs b/src/rustc/middle/borrowck/loan.rs
index bbeca851742..84f7f5a9d15 100644
--- a/src/rustc/middle/borrowck/loan.rs
+++ b/src/rustc/middle/borrowck/loan.rs
@@ -57,8 +57,7 @@ impl loan_methods for loan_ctxt {
           }
           cat_comp(cmt_base, comp_field(*)) |
           cat_comp(cmt_base, comp_index(*)) |
-          cat_comp(cmt_base, comp_tuple) |
-          cat_comp(cmt_base, comp_res) {
+          cat_comp(cmt_base, comp_tuple) {
             // For most components, the type of the embedded data is
             // stable.  Therefore, the base structure need only be
             // const---unless the component must be immutable.  In
diff --git a/src/rustc/middle/borrowck/preserve.rs b/src/rustc/middle/borrowck/preserve.rs
index cbe9c4e3a4a..7ec2520cd59 100644
--- a/src/rustc/middle/borrowck/preserve.rs
+++ b/src/rustc/middle/borrowck/preserve.rs
@@ -43,8 +43,7 @@ impl public_methods for borrowck_ctxt {
           }
           cat_comp(cmt_base, comp_field(*)) |
           cat_comp(cmt_base, comp_index(*)) |
-          cat_comp(cmt_base, comp_tuple) |
-          cat_comp(cmt_base, comp_res) {
+          cat_comp(cmt_base, comp_tuple) {
             // Most embedded components: if the base is stable, the
             // type never changes.
             self.preserve(cmt_base, opt_scope_id)
diff --git a/src/rustc/middle/kind.rs b/src/rustc/middle/kind.rs
index 2f9e8472022..465799c850c 100644
--- a/src/rustc/middle/kind.rs
+++ b/src/rustc/middle/kind.rs
@@ -22,8 +22,8 @@ import lint::{non_implicitly_copyable_typarams,implicit_copies};
 //  const: Things thare are deeply immutable. They are guaranteed never to
 //    change, and can be safely shared without copying between tasks.
 //
-// Send includes scalar types, resources and unique types containing only
-// sendable types.
+// Send includes scalar types as well as classes and unique types containing
+// only sendable types.
 //
 // Copy includes boxes, closure and unique types containing copyable types.
 //
@@ -160,7 +160,7 @@ fn check_fn(fk: visit::fn_kind, decl: fn_decl, body: blk, sp: span,
         let cap_clause = alt fk {
           visit::fk_anon(_, cc) | visit::fk_fn_block(cc) { cc }
           visit::fk_item_fn(*) | visit::fk_method(*) |
-          visit::fk_res(*) | visit::fk_ctor(*) | visit::fk_dtor(*) { @[] }
+          visit::fk_ctor(*) | visit::fk_dtor(*) { @[] }
         };
         let captured_vars = (*cap_clause).map { |cap_item|
             let cap_def = cx.tcx.def_map.get(cap_item.id);
diff --git a/src/rustc/middle/region.rs b/src/rustc/middle/region.rs
index 50f38b16e09..e17343a0b9e 100644
--- a/src/rustc/middle/region.rs
+++ b/src/rustc/middle/region.rs
@@ -359,7 +359,7 @@ fn resolve_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk,
               visitor: visit::vt<ctxt>) {
 
     let fn_cx = alt fk {
-      visit::fk_item_fn(*) | visit::fk_method(*) | visit::fk_res(*) |
+      visit::fk_item_fn(*) | visit::fk_method(*) |
       visit::fk_ctor(*) | visit::fk_dtor(*) {
         // Top-level functions are a root scope.
         {parent: some(id) with cx}
diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs
index 0ae04c25ccd..b693d83e193 100644
--- a/src/rustc/middle/resolve.rs
+++ b/src/rustc/middle/resolve.rs
@@ -639,9 +639,8 @@ fn visit_fn_with_scope(e: @env, fk: visit::fn_kind, decl: ast::fn_decl,
     // for f's constrs in the table.
     for decl.constraints.each {|c| resolve_constr(e, c, sc, v); }
     let scope = alt fk {
-      visit::fk_item_fn(_, tps) | visit::fk_res(_, tps, _) |
-      visit::fk_method(_, tps, _) | visit::fk_ctor(_, tps, _, _)  |
-      visit::fk_dtor(tps, _, _) {
+      visit::fk_item_fn(_, tps) | visit::fk_method(_, tps, _)
+      | visit::fk_ctor(_, tps, _, _) | visit::fk_dtor(tps, _, _) {
         scope_bare_fn(decl, id, tps) }
       visit::fk_anon(ast::proto_bare, _) {
         scope_bare_fn(decl, id, []) }
@@ -1333,15 +1332,6 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option<def> {
       ast::item_ty(*) | item_iface(*) | item_enum(*) {
         if ns == ns_type { ret some(ast::def_ty(local_def(i.id))); }
       }
-      ast::item_res(_, _, _, _, ctor_id, _) {
-        alt ns {
-          ns_val {
-            ret some(ast::def_fn(local_def(ctor_id), ast::impure_fn));
-          }
-          ns_type { ret some(ast::def_ty(local_def(i.id))); }
-          _ { }
-        }
-      }
       ast::item_class(_, _, _members, ct, _, _) {
           alt ns {
              ns_type {
@@ -1644,7 +1634,7 @@ fn index_mod(md: ast::_mod) -> mod_index {
         alt it.node {
           ast::item_const(_, _) | ast::item_fn(_, _, _) | ast::item_mod(_) |
           ast::item_native_mod(_) | ast::item_ty(_, _, _) |
-          ast::item_res(*) | ast::item_impl(*) | ast::item_iface(*) {
+          ast::item_impl(*) | ast::item_iface(*) {
             add_to_index(index, it.ident, mie_item(it));
           }
           ast::item_enum(variants, _, _) {
@@ -1868,10 +1858,6 @@ fn check_block(e: @env, b: ast::blk, &&x: (), v: vt<()>) {
                   ast::item_ty(*) | ast::item_iface(*) {
                     add_name(types, it.span, it.ident);
                   }
-                  ast::item_res(*) {
-                    add_name(types, it.span, it.ident);
-                    add_name(values, it.span, it.ident);
-                  }
                   _ { }
                 }
               }
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index dc4e681dc16..13201d4e673 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -50,7 +50,7 @@ import type_of::type_of; // Issue #1873
 import syntax::ast_map::{path, path_mod, path_name};
 
 import std::smallintmap;
-import option::is_none;
+import option::{is_none, is_some};
 
 // Destinations
 
@@ -758,8 +758,7 @@ fn trans_class_drop(bcx: block, v0: ValueRef, dtor_did: ast::def_id,
       // We have to cast v0
      let classptr = GEPi(bcx, v0, [0u, 1u]);
      // Find and call the actual destructor
-     let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did, some(class_did),
-                                  substs.tps);
+     let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did, class_did, substs.tps);
      // The second argument is the "self" argument for drop
      let params = lib::llvm::fn_ty_param_tys
          (llvm::LLVMGetElementType
@@ -799,9 +798,6 @@ fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
       ty::ty_unboxed_vec(_) {
         tvec::make_drop_glue_unboxed(bcx, v0, t)
       }
-      ty::ty_res(did, inner, substs) {
-        trans_res_drop(bcx, v0, did, inner, substs.tps)
-      }
       ty::ty_class(did, substs) {
         let tcx = bcx.tcx();
         alt ty::ty_dtor(tcx, did) {
@@ -835,10 +831,7 @@ fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
 }
 
 fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id,
-                // Parent ID is an option because resources don't
-                // have one. We can make this a def_id when
-                // resources get removed.
-                opt_id: option<ast::def_id>, substs: [ty::t])
+                parent_id: ast::def_id, substs: [ty::t])
    -> ValueRef {
     let _icx = ccx.insn_ctxt("trans_res_dtor");
     if (substs.len() > 0u) {
@@ -850,54 +843,13 @@ fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id,
     } else if did.crate == ast::local_crate {
         get_item_val(ccx, did.node)
     } else {
-        alt opt_id {
-           some(parent_id) {
-             let tcx = ccx.tcx;
-             let name = csearch::get_symbol(ccx.sess.cstore, did);
-             let class_ty = ty::subst_tps(tcx, substs,
-                              ty::lookup_item_type(tcx, parent_id).ty);
-             let llty = type_of_dtor(ccx, class_ty);
-             get_extern_fn(ccx.externs, ccx.llmod, name, lib::llvm::CCallConv,
-                           llty)
-           }
-           none {
-             let fty = ty::mk_fn(ccx.tcx, {purity: ast::impure_fn,
-                                       proto: ast::proto_bare,
-                                     inputs: [{mode: ast::expl(ast::by_ref),
-                                                ty: ty::mk_nil_ptr(ccx.tcx)}],
-                                      output: ty::mk_nil(ccx.tcx),
-                                      ret_style: ast::return_val,
-                                      constraints: []});
-             trans_external_path(ccx, did, fty)
-           }
-      }
-    }
-}
-
-fn trans_res_drop(bcx: block, rs: ValueRef, did: ast::def_id,
-                  inner_t: ty::t, tps: [ty::t]) -> block {
-    let _icx = bcx.insn_ctxt("trans_res_drop");
-    let ccx = bcx.ccx();
-    let inner_t_s = ty::subst_tps(ccx.tcx, tps, inner_t);
-
-    let drop_flag = GEPi(bcx, rs, [0u, 0u]);
-    with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag))) {|bcx|
-        let valptr = GEPi(bcx, rs, [0u, 1u]);
-        // Find and call the actual destructor.
-        let dtor_addr = get_res_dtor(ccx, did, none, tps);
-        let args = [bcx.fcx.llretptr, null_env_ptr(bcx)];
-        // Kludge to work around the fact that we know the precise type of the
-        // value here, but the dtor expects a type that might have opaque
-        // boxes and such.
-        let val_llty = lib::llvm::fn_ty_param_tys
-            (llvm::LLVMGetElementType
-             (llvm::LLVMTypeOf(dtor_addr)))[args.len()];
-        let val_cast = BitCast(bcx, valptr, val_llty);
-        Call(bcx, dtor_addr, args + [val_cast]);
-
-        let bcx = drop_ty(bcx, valptr, inner_t_s);
-        Store(bcx, C_u8(0u), drop_flag);
-        bcx
+        let tcx = ccx.tcx;
+        let name = csearch::get_symbol(ccx.sess.cstore, did);
+        let class_ty = ty::subst_tps(tcx, substs,
+                          ty::lookup_item_type(tcx, parent_id).ty);
+        let llty = type_of_dtor(ccx, class_ty);
+        get_extern_fn(ccx.externs, ccx.llmod, name, lib::llvm::CCallConv,
+                      llty)
     }
 }
 
@@ -1086,12 +1038,6 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
             cx = f(cx, llfld_a, arg);
         }
       }
-      ty::ty_res(_, inner, substs) {
-        let tcx = cx.tcx();
-        let inner1 = ty::subst(tcx, substs, inner);
-        let llfld_a = GEPi(cx, av, [0u, 1u]);
-        ret f(cx, llfld_a, inner1);
-      }
       ty::ty_enum(tid, substs) {
         let variants = ty::enum_variants(cx.tcx(), tid);
         let n_variants = (*variants).len();
@@ -1130,10 +1076,15 @@ fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
         ret next_cx;
       }
       ty::ty_class(did, substs) {
+          // Take the drop bit into account
+          let classptr = if is_some(ty::ty_dtor(cx.tcx(), did)) {
+                  GEPi(cx, av, [0u, 1u])
+              }
+          else { av };
         for vec::eachi(ty::class_items_as_mutable_fields(cx.tcx(), did,
                                                          substs))
            {|i, fld|
-               let llfld_a = GEPi(cx, av, [0u, i]);
+               let llfld_a = GEPi(cx, classptr, [0u, i]);
                cx = f(cx, llfld_a, fld.mt.ty);
            }
       }
@@ -1895,10 +1846,6 @@ fn autoderef(cx: block, e_id: ast::node_id,
             t1 = mt.ty;
             v1 = v;
           }
-          ty::ty_res(did, inner, substs) {
-            t1 = ty::subst(ccx.tcx, substs, inner);
-            v1 = GEPi(cx, v1, [0u, 1u]);
-          }
           ty::ty_enum(did, substs) {
             let variants = ty::enum_variants(ccx.tcx, did);
             if (*variants).len() != 1u || variants[0].args.len() != 1u {
@@ -2221,15 +2168,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, real_substs: [ty::t],
         crate?)", fn_id)});
     // Get the path so that we can create a symbol
     let (pt, name, span) = alt map_node {
-      ast_map::node_item(i, pt) {
-        alt i.node {
-          ast::item_res(_, _, _, dtor_id, _, _) {
-            item_ty = ty::node_id_to_type(ccx.tcx, dtor_id);
-          }
-          _ {}
-        }
-        (pt, i.ident, i.span)
-      }
+      ast_map::node_item(i, pt) { (pt, i.ident, i.span) }
       ast_map::node_variant(v, enm, pt) { (pt, v.node.name, enm.span) }
       ast_map::node_method(m, _, pt) { (pt, m.ident, m.span) }
       ast_map::node_native_item(i, ast::native_abi_rust_intrinsic, pt)
@@ -2239,9 +2178,7 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, real_substs: [ty::t],
         ret {val: get_item_val(ccx, fn_id.node),
              must_cast: true};
       }
-      ast_map::node_ctor(nm, _, ct, pt) { (pt, nm, alt ct {
-                  ast_map::res_ctor(_, _, sp) { sp }
-                  ast_map::class_ctor(ct_, _) { ct_.span }}) }
+      ast_map::node_ctor(nm, _, ct, _, pt) { (pt, nm, ct.span) }
       ast_map::node_dtor(_, dtor, _, pt) {(pt, @"drop", dtor.span)}
       ast_map::node_expr(*) { ccx.tcx.sess.bug("Can't monomorphize an expr") }
       ast_map::node_export(*) {
@@ -2285,12 +2222,6 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, real_substs: [ty::t],
         trans_fn(ccx, pt, decl, body, d, no_self, psubsts, fn_id.node);
         d
       }
-      ast_map::node_item(
-          @{node: ast::item_res(dt, _, body, d_id, _, _), _}, _) {
-          let d = mk_lldecl();
-          trans_fn(ccx, pt, dt, body, d, no_self, psubsts, d_id);
-          d
-      }
       ast_map::node_item(*) {
           ccx.tcx.sess.bug("Can't monomorphize this kind of item")
       }
@@ -2319,24 +2250,15 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, real_substs: [ty::t],
                  impl_self(selfty), psubsts, fn_id.node);
         d
       }
-      ast_map::node_ctor(nm, tps, ct, _) {
+      ast_map::node_ctor(nm, tps, ctor, parent_id, _) {
+        // ctors don't have attrs, at least not right now
         let d = mk_lldecl();
-        alt ct {
-          ast_map::res_ctor(decl,_, _) {
-            set_inline_hint(d);
-            trans_res_ctor(ccx, pt, decl, fn_id.node, psubsts, d);
-            d
-          }
-          ast_map::class_ctor(ctor, parent_id) {
-            // ctors don't have attrs, at least not right now
-            let tp_tys: [ty::t] = ty::ty_params_to_tys(ccx.tcx, tps);
-            trans_class_ctor(ccx, pt, ctor.node.dec, ctor.node.body, d,
-                 option::get_default(psubsts,
-                   {tys:tp_tys, vtables: none, bounds: @[]}),
-              fn_id.node, parent_id, ctor.span);
-            d
-          }
-        }
+        let tp_tys: [ty::t] = ty::ty_params_to_tys(ccx.tcx, tps);
+        trans_class_ctor(ccx, pt, ctor.node.dec, ctor.node.body, d,
+               option::get_default(psubsts,
+                        {tys:tp_tys, vtables: none, bounds: @[]}),
+                         fn_id.node, parent_id, ctor.span);
+        d
       }
       ast_map::node_dtor(_, dtor, _, pt) {
         let parent_id = alt ty::ty_to_def_id(ty::node_id_to_type(ccx.tcx,
@@ -2412,9 +2334,6 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
                     ccx.external.insert(there.id, some(here.id.node));
                 }
               }
-              ast::item_res(_, _, _, _, ctor_id, _) {
-                my_id = ctor_id;
-              }
             }
             trans_item(ccx, *item);
             local_def(my_id)
@@ -2639,8 +2558,13 @@ fn trans_rec_field_inner(bcx: block, val: ValueRef, ty: ty::t,
        _ { bcx.tcx().sess.span_bug(sp, "trans_rec_field:\
                  base expr has non-record type"); }
     };
+    // seems wrong? Doesn't take into account the field
+    // sizes
+
     let ix = field_idx_strict(bcx.tcx(), sp, field, fields);
 
+    #debug("val = %s ix = %u", bcx.val_str(val), ix);
+
     /* self is a class with a dtor, which means we
        have to select out the object itself
        (If any other code does the same thing, that's
@@ -2789,9 +2713,6 @@ fn trans_lval(cx: block, e: @ast::expr) -> lval_result {
                 let non_gc_val = non_gc_box_cast(sub.bcx, sub.val);
                 GEPi(sub.bcx, non_gc_val, [0u, abi::box_field_body])
               }
-              ty::ty_res(_, _, _) {
-                GEPi(sub.bcx, sub.val, [0u, 1u])
-              }
               ty::ty_enum(_, _) {
                 let ety = expr_ty(cx, e);
                 let ellty = T_ptr(type_of(ccx, ety));
@@ -4683,34 +4604,6 @@ fn trans_fn(ccx: @crate_ctxt,
     }
 }
 
-fn trans_res_ctor(ccx: @crate_ctxt, path: path, dtor: ast::fn_decl,
-                  ctor_id: ast::node_id,
-                  param_substs: option<param_substs>, llfndecl: ValueRef) {
-    let _icx = ccx.insn_ctxt("trans_res_ctor");
-    // Create a function for the constructor
-    let fcx = new_fn_ctxt_w_id(ccx, path, llfndecl, ctor_id, param_substs,
-                               none);
-    create_llargs_for_fn_args(fcx, no_self, dtor.inputs);
-    let mut bcx = top_scope_block(fcx, none), lltop = bcx.llbb;
-    let fty = node_id_type(bcx, ctor_id);
-    let arg_t = ty::ty_fn_args(fty)[0].ty;
-    let arg = alt fcx.llargs.find(dtor.inputs[0].id) {
-      some(local_mem(x)) { x }
-      _ { ccx.sess.bug("Someone forgot to document an invariant \
-            in trans_res_ctor"); }
-    };
-    let llretptr = fcx.llretptr;
-
-    let dst = GEPi(bcx, llretptr, [0u, 1u]);
-    memmove_ty(bcx, dst, arg, arg_t);
-    let flag = GEPi(bcx, llretptr, [0u, 0u]);
-    let one = C_u8(1u);
-    Store(bcx, one, flag);
-    build_return(bcx);
-    finish_fn(fcx, lltop);
-}
-
-
 fn trans_enum_variant(ccx: @crate_ctxt, enum_id: ast::node_id,
                       variant: ast::variant, disr: int, is_degen: bool,
                       param_substs: option<param_substs>,
@@ -5029,16 +4922,6 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
       ast::item_impl(tps, _rp, _, _, ms) {
         impl::trans_impl(ccx, *path, item.ident, ms, tps);
       }
-      ast::item_res(decl, tps, body, dtor_id, ctor_id, _) {
-        if tps.len() == 0u {
-            let llctor_decl = get_item_val(ccx, ctor_id);
-            trans_res_ctor(ccx, *path, decl, ctor_id, none, llctor_decl);
-
-            let lldtor_decl = get_item_val(ccx, item.id);
-            trans_fn(ccx, *path + [path_name(item.ident)], decl, body,
-                     lldtor_decl, no_self, none, dtor_id);
-        }
-      }
       ast::item_mod(m) {
         trans_mod(ccx, m);
       }
@@ -5293,16 +5176,6 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
                 set_inline_hint_if_appr(i.attrs, llfn);
                 llfn
               }
-              ast::item_res(_, _, _, dtor_id, _, _) {
-                // Note that the destructor is associated with the item's id,
-                // not the dtor_id. This is a bit counter-intuitive, but
-                // simplifies ty_res, which would have to carry around two
-                // def_ids otherwise -- one to identify the type, and one to
-                // find the dtor symbol.
-                let t = ty::node_id_to_type(ccx.tcx, dtor_id);
-                register_fn_full(ccx, i.span, my_path + [path_name(@"dtor")],
-                                 i.id, t)
-              }
             }
           }
           ast_map::node_method(m, impl_id, pth) {
@@ -5318,18 +5191,9 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
             exprt = true;
             register_fn(ccx, ni.span, *pth + [path_name(ni.ident)], ni.id)
           }
-          ast_map::node_ctor(nm, tps, ct, pt) {
+          ast_map::node_ctor(nm, tps, ctor, _, pt) {
             let my_path = *pt + [path_name(nm)];
-            alt ct {
-              ast_map::res_ctor(_,_,sp) {
-                let llctor = register_fn(ccx, sp, my_path, id);
-                set_inline_hint(llctor);
-                llctor
-              }
-              ast_map::class_ctor(ctor, _) {
-                register_fn(ccx, ctor.span, my_path, ctor.node.id)
-              }
-            }
+            register_fn(ccx, ctor.span, my_path, ctor.node.id)
           }
           ast_map::node_dtor(tps, dt, parent_id, pt) {
             /*
diff --git a/src/rustc/middle/trans/debuginfo.rs b/src/rustc/middle/trans/debuginfo.rs
index e90590f0228..48a087d0c27 100644
--- a/src/rustc/middle/trans/debuginfo.rs
+++ b/src/rustc/middle/trans/debuginfo.rs
@@ -743,7 +743,7 @@ fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> {
     let (ident, ret_ty, id) = alt cx.tcx.items.get(fcx.id) {
       ast_map::node_item(item, _) {
         alt item.node {
-          ast::item_fn(decl, _, _) | ast::item_res(decl, _, _, _, _, _) {
+          ast::item_fn(decl, _, _) {
             (item.ident, decl.output, item.id)
           }
           _ { fcx.ccx.sess.span_bug(item.span, "create_function: item \
@@ -753,16 +753,9 @@ fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> {
       ast_map::node_method(method, _, _) {
           (method.ident, method.decl.output, method.id)
       }
-      ast_map::node_ctor(nm, _, ct, _) {
-        alt ct {
-          ast_map::res_ctor(decl, ctor_id, _) {
-            (nm, decl.output, ctor_id)
-          }
-          ast_map::class_ctor(ctor,_) {
-            // FIXME: output type may be wrong (#2194)
-            (nm, ctor.node.dec.output, ctor.node.id)
-          }
-        }
+      ast_map::node_ctor(nm, _, ctor, _, _) {
+        // FIXME: output type may be wrong (#2194)
+        (nm, ctor.node.dec.output, ctor.node.id)
       }
       ast_map::node_expr(expr) {
         alt expr.node {
diff --git a/src/rustc/middle/trans/reachable.rs b/src/rustc/middle/trans/reachable.rs
index ed4f34eb75f..86da0c72ecc 100644
--- a/src/rustc/middle/trans/reachable.rs
+++ b/src/rustc/middle/trans/reachable.rs
@@ -69,8 +69,8 @@ fn traverse_def_id(cx: ctx, did: def_id) {
       ast_map::node_method(_, impl_id, _) { traverse_def_id(cx, impl_id); }
       ast_map::node_native_item(item, _, _) { cx.rmap.insert(item.id, ()); }
       ast_map::node_variant(v, _, _) { cx.rmap.insert(v.node.id, ()); }
-      // If it's a class ctor, consider the parent reachable
-      ast_map::node_ctor(_, _, ast_map::class_ctor(_, parent_id), _) {
+      // If it's a ctor, consider the parent reachable
+      ast_map::node_ctor(_, _, _, parent_id, _) {
         traverse_def_id(cx, parent_id);
       }
       _ {}
@@ -94,10 +94,6 @@ fn traverse_public_item(cx: ctx, item: @item) {
               for vec::each(nm.items) {|item| cx.rmap.insert(item.id, ()); }
           }
       }
-      item_res(_, tps, blk, _, _, _) {
-        // resources seem to be unconditionally inlined
-        traverse_inline_body(cx, blk);
-      }
       item_fn(_, tps, blk) {
         if tps.len() > 0u ||
            attr::find_inline_attr(item.attrs) != attr::ia_none {
@@ -209,10 +205,6 @@ fn traverse_all_resources(cx: ctx, crate_mod: _mod) {
         visit_item: {|i, cx, v|
             visit::visit_item(i, cx, v);
             alt i.node {
-              item_res(*) {
-                traverse_public_item(cx, i);
-              }
-              // Classes with dtors too!
               item_class(_, _, _, _, some(_), _) {
                 traverse_public_item(cx, i);
               }
diff --git a/src/rustc/middle/trans/reflect.rs b/src/rustc/middle/trans/reflect.rs
index 740d53ed773..0ca89ac6a94 100644
--- a/src/rustc/middle/trans/reflect.rs
+++ b/src/rustc/middle/trans/reflect.rs
@@ -255,7 +255,6 @@ impl methods for reflector {
 
           // Miscallaneous extra types
           ty::ty_iface(_, _) { self.leaf("iface") }
-          ty::ty_res(_, t, _) { self.bracketed_t("res", t, []) }
           ty::ty_var(_) { self.leaf("var") }
           ty::ty_var_integral(_) { self.leaf("var_integral") }
           ty::ty_param(n, _) { self.visit("param", [self.c_uint(n)]) }
diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs
index f28d0b53e53..d7e7020f20d 100644
--- a/src/rustc/middle/trans/shape.rs
+++ b/src/rustc/middle/trans/shape.rs
@@ -335,7 +335,6 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
             [shape_res]
           }
           else { [shape_struct] };
-        let mut sub = [];
         option::iter(m_dtor_did) {|dtor_did|
           let ri = @{did: dtor_did, parent_id: some(did), tps: tps};
           let id = interner::intern(ccx.shape_cx.resources, ri);
@@ -346,9 +345,8 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
           add_u16(s, 0_u16);
         };
         for ty::class_items_as_mutable_fields(ccx.tcx, did, substs).each {|f|
-            sub += shape_of(ccx, f.mt.ty);
+           add_substr(s, shape_of(ccx, f.mt.ty));
         }
-        add_substr(s, sub);
         s
       }
       ty::ty_rptr(_, mt) {
@@ -356,25 +354,6 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
         add_substr(s, shape_of(ccx, mt.ty));
         s
       }
-      ty::ty_res(did, raw_subt, substs) {
-        #debug["ty_res(%?, %?, %?)",
-               did,
-               ty_to_str(ccx.tcx, raw_subt),
-               substs.tps.map({|t| ty_to_str(ccx.tcx, t) })];
-        for substs.tps.each() {|t| assert !ty::type_has_params(t); }
-        let subt = ty::subst(ccx.tcx, substs, raw_subt);
-        let tps = substs.tps;
-        let ri = @{did: did, parent_id: none, tps: tps};
-        let id = interner::intern(ccx.shape_cx.resources, ri);
-
-        let mut s = [shape_res];
-        add_u16(s, id as u16);
-        // Hack: always encode 0 tps, since the shape glue format
-        // hasn't changed since we started monomorphizing.
-        add_u16(s, 0_u16);
-        add_substr(s, shape_of(ccx, subt));
-        s
-      }
       ty::ty_param(*) {
         ccx.tcx.sess.bug("non-monomorphized type parameter");
       }
@@ -599,8 +578,9 @@ fn gen_resource_shapes(ccx: @crate_ctxt) -> ValueRef {
     for uint::range(0u, len) {|i|
         let ri = interner::get(ccx.shape_cx.resources, i);
         for ri.tps.each() {|s| assert !ty::type_has_params(s); }
-        dtors += [trans::base::get_res_dtor(ccx, ri.did, ri.parent_id,
-                                            ri.tps)];
+        option::iter(ri.parent_id) {|id|
+            dtors += [trans::base::get_res_dtor(ccx, ri.did, id, ri.tps)];
+        }
     }
     ret mk_global(ccx, "resource_shapes", C_struct(dtors), true);
 }
@@ -744,10 +724,6 @@ fn simplify_type(tcx: ty::ctxt, typ: ty::t) -> ty::t {
           ty::ty_estr(ty::vstore_uniq) | ty::ty_estr(ty::vstore_box) |
           ty::ty_ptr(_) | ty::ty_rptr(_,_) { nilptr(tcx) }
           ty::ty_fn(_) { ty::mk_tup(tcx, [nilptr(tcx), nilptr(tcx)]) }
-          ty::ty_res(_, sub, substs) {
-            let sub1 = ty::subst(tcx, substs, sub);
-            ty::mk_tup(tcx, [ty::mk_int(tcx), simplify_type(tcx, sub1)])
-          }
           ty::ty_evec(_, ty::vstore_slice(_)) |
           ty::ty_estr(ty::vstore_slice(_)) {
             ty::mk_tup(tcx, [nilptr(tcx), ty::mk_int(tcx)])
diff --git a/src/rustc/middle/trans/type_of.rs b/src/rustc/middle/trans/type_of.rs
index dc8dc1b92cf..2b610a99662 100644
--- a/src/rustc/middle/trans/type_of.rs
+++ b/src/rustc/middle/trans/type_of.rs
@@ -141,10 +141,6 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
           }
           ty::ty_fn(_) { T_fn_pair(cx, type_of_fn_from_ty(cx, t)) }
           ty::ty_iface(_, _) { T_opaque_iface(cx) }
-          ty::ty_res(_, sub, substs) {
-            let sub1 = ty::subst(cx.tcx, substs, sub);
-            ret T_struct([T_i8(), type_of(cx, sub1)]);
-          }
           ty::ty_type { T_ptr(cx.tydesc_type) }
           ty::ty_tup(elts) {
             let mut tys = [];
diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs
index 628d407fead..fb0b983ae65 100644
--- a/src/rustc/middle/trans/type_use.rs
+++ b/src/rustc/middle/trans/type_use.rs
@@ -66,11 +66,9 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
     };
     alt check map_node {
       ast_map::node_item(@{node: item_fn(_, _, body), _}, _) |
-      ast_map::node_item(@{node: item_res(_, _, body, _, _, _), _}, _) |
       ast_map::node_method(@{body, _}, _, _) {
         handle_body(cx, body);
       }
-      ast_map::node_ctor(_, _, ast_map::res_ctor(_, _, _), _) |
       ast_map::node_variant(_, _, _) {
         for uint::range(0u, n_tps) {|n| cx.uses[n] |= use_repr;}
       }
@@ -88,7 +86,7 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
             for uint::range(0u, n_tps) {|n| cx.uses[n] |= flags;}
         }
       }
-      ast_map::node_ctor(_, _, ast_map::class_ctor(ctor, _), _){
+      ast_map::node_ctor(_, _, ctor, _, _){
         handle_body(cx, ctor.node.body);
       }
       ast_map::node_dtor(_, dtor, _, _){
diff --git a/src/rustc/middle/tstate/pre_post_conditions.rs b/src/rustc/middle/tstate/pre_post_conditions.rs
index e1d0bf332c0..aa7a3d6e344 100644
--- a/src/rustc/middle/tstate/pre_post_conditions.rs
+++ b/src/rustc/middle/tstate/pre_post_conditions.rs
@@ -49,14 +49,6 @@ fn find_pre_post_item(ccx: crate_ctxt, i: item) {
       item_mod(m) { find_pre_post_mod(m); }
       item_native_mod(nm) { find_pre_post_native_mod(nm); }
       item_ty(*) | item_enum(*) | item_iface(*) { ret; }
-      item_res(_, _, body, dtor_id, _, _) {
-        let fcx =
-            {enclosing: ccx.fm.get(dtor_id),
-             id: dtor_id,
-             name: i.ident,
-             ccx: ccx};
-        find_pre_post_fn(fcx, body);
-      }
       item_class(*) {
           fail "find_pre_post_item: shouldn't be called on item_class";
       }
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index 3083563d220..1c0f5ed053c 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -93,7 +93,6 @@ export ty_unboxed_vec, mk_unboxed_vec, mk_mut_unboxed_vec;
 export vstore, vstore_fixed, vstore_uniq, vstore_box, vstore_slice;
 export ty_nil, mk_nil, type_is_nil;
 export ty_iface, mk_iface;
-export ty_res, mk_res;
 export ty_param, mk_param, ty_params_to_tys;
 export ty_ptr, mk_ptr, mk_mut_ptr, mk_imm_ptr, mk_nil_ptr, type_is_unsafe_ptr;
 export ty_rptr, mk_rptr;
@@ -366,7 +365,6 @@ enum sty {
     ty_fn(fn_ty),
     ty_iface(def_id, substs),
     ty_class(def_id, substs),
-    ty_res(def_id, t, substs),
     ty_tup([t]),
 
     ty_var(tv_vid), // type variable during typechecking
@@ -598,11 +596,6 @@ fn mk_t_with_id(cx: ctxt, st: sty, o_def_id: option<ast::def_id>) -> t {
         for f.inputs.each {|a| flags |= get(a.ty).flags; }
         flags |= get(f.output).flags;
       }
-      ty_res(_, tt, substs) {
-        flags |= (has_resources as uint);
-        flags |= get(tt).flags;
-        flags |= sflags(substs);
-      }
       ty_constr(tt, _) {
         flags |= get(tt).flags;
       }
@@ -716,11 +709,6 @@ fn mk_class(cx: ctxt, class_id: ast::def_id, substs: substs) -> t {
     mk_t(cx, ty_class(class_id, substs))
 }
 
-fn mk_res(cx: ctxt, did: ast::def_id,
-          inner: t, substs: substs) -> t {
-    mk_t(cx, ty_res(did, inner, substs))
-}
-
 fn mk_var(cx: ctxt, v: tv_vid) -> t { mk_t(cx, ty_var(v)) }
 
 fn mk_var_integral(cx: ctxt, v: tvi_vid) -> t {
@@ -795,10 +783,6 @@ fn maybe_walk_ty(ty: t, f: fn(t) -> bool) {
         for ft.inputs.each {|a| maybe_walk_ty(a.ty, f); }
         maybe_walk_ty(ft.output, f);
       }
-      ty_res(_, sub, substs) {
-        maybe_walk_ty(sub, f);
-        for substs.tps.each {|tp| maybe_walk_ty(tp, f); }
-      }
       ty_constr(sub, _) { maybe_walk_ty(sub, f); }
       ty_uniq(tm) { maybe_walk_ty(tm.ty, f); }
     }
@@ -860,10 +844,6 @@ fn fold_sty(sty: sty, fldop: fn(t) -> t) -> sty {
         let new_output = fldop(f.output);
         ty_fn({inputs: new_args, output: new_output with f})
       }
-      ty_res(did, subty, substs) {
-        ty_res(did, fldop(subty),
-               fold_substs(substs, fldop))
-      }
       ty_rptr(r, tm) {
         ty_rptr(r, {ty: fldop(tm.ty), mutbl: tm.mutbl})
       }
@@ -944,10 +924,6 @@ fn fold_regions_and_ty(
       ty_iface(def_id, substs) {
         ty::mk_iface(cx, def_id, fold_substs(substs, fldr, fldt))
       }
-      ty_res(def_id, t, substs) {
-        ty::mk_res(cx, def_id, fldt(t),
-                   fold_substs(substs, fldr, fldt))
-      }
       sty @ ty_fn(_) {
         fold_sty_to_ty(cx, sty) {|t|
             fldfnt(t)
@@ -1100,8 +1076,8 @@ fn type_is_bool(ty: t) -> bool { get(ty).struct == ty_bool }
 
 fn type_is_structural(ty: t) -> bool {
     alt get(ty).struct {
-      ty_rec(_) | ty_class(_, _) | ty_tup(_) | ty_enum(_, _) | ty_fn(_) |
-      ty_iface(_, _) | ty_res(_, _, _) | ty_evec(_, vstore_fixed(_))
+      ty_rec(_) | ty_class(*) | ty_tup(_) | ty_enum(*) | ty_fn(_) |
+      ty_iface(*) | ty_evec(_, vstore_fixed(_))
       | ty_estr(vstore_fixed(_)) { true }
       _ { false }
     }
@@ -1318,7 +1294,7 @@ fn type_needs_unwind_cleanup_(cx: ctxt, ty: t,
             }
             !needs_unwind_cleanup
           }
-          ty_uniq(_) | ty_str | ty_vec(_) | ty_res(_, _, _) |
+          ty_uniq(_) | ty_str | ty_vec(_) |
           ty_estr(vstore_uniq) |
           ty_estr(vstore_box) |
           ty_evec(_, vstore_uniq) |
@@ -1605,10 +1581,6 @@ fn type_kind(cx: ctxt, ty: t) -> kind {
         }
         lowest
       }
-      ty_res(did, inner, tps) {
-        let inner = subst(cx, tps, inner);
-        (kind_const() | kind_send_only()) & type_kind(cx, inner)
-      }
       ty_param(_, did) {
         param_bounds_to_kind(cx.ty_param_bounds.get(did.node))
       }
@@ -1713,18 +1685,6 @@ fn is_instantiable(cx: ctxt, r_ty: t) -> bool {
             r
           }
 
-          ty_res(did, _, _) if vec::contains(*seen, did) {
-            false
-          }
-
-          ty_res(did, sub, substs) {
-            vec::push(*seen, did);
-            let sty = subst(cx, substs, sub);
-            let r = type_requires(cx, seen, r_ty, sty);
-            vec::pop(*seen);
-            r
-          }
-
           ty_tup(ts) {
             vec::any(ts) {|t|
                 type_requires(cx, seen, r_ty, t)
@@ -1787,10 +1747,6 @@ fn type_structurally_contains(cx: ctxt, ty: t, test: fn(sty) -> bool) ->
         }
         ret false;
       }
-      ty_res(_, sub, substs) {
-        let sty = subst(cx, substs, sub);
-        ret type_structurally_contains(cx, sty, test);
-      }
       ty_evec(mt, vstore_fixed(_)) {
         ret type_structurally_contains(cx, mt.ty, test);
       }
@@ -1895,9 +1851,6 @@ fn type_is_pod(cx: ctxt, ty: t) -> bool {
       ty_evec(mt, vstore_fixed(_)) | ty_unboxed_vec(mt) {
         result = type_is_pod(cx, mt.ty);
       }
-      ty_res(_, inner, substs) {
-        result = type_is_pod(cx, subst(cx, substs, inner));
-      }
       ty_constr(subt, _) { result = type_is_pod(cx, subt); }
       ty_param(_, _) { result = false; }
       ty_opaque_closure_ptr(_) { result = true; }
@@ -1966,11 +1919,6 @@ fn deref_sty(cx: ctxt, sty: sty, expl: bool) -> option<mt> {
         some(mt)
       }
 
-      ty_res(_, inner, substs) {
-        let inner = subst(cx, substs, inner);
-        some({ty: inner, mutbl: ast::m_imm})
-      }
-
       ty_enum(did, substs) {
         let variants = enum_variants(cx, did);
         if vec::len(*variants) == 1u && vec::len(variants[0].args) == 1u {
@@ -2111,10 +2059,6 @@ fn hash_type_structure(st: sty) -> uint {
         h
       }
       ty_uniq(mt) { hash_subty(37u, mt.ty) }
-      ty_res(did, sub, substs) {
-        let mut h = hash_subty(hash_def(38u, did), sub);
-        hash_substs(h, substs)
-      }
       ty_iface(did, substs) {
         let mut h = hash_def(40u, did);
         hash_substs(h, substs)
@@ -2452,7 +2396,6 @@ fn ty_sort_str(cx: ctxt, t: t) -> str {
       ty_fn(_) { "fn" }
       ty_iface(id, _) { #fmt["iface %s", item_path_str(cx, id)] }
       ty_class(id, _) { #fmt["class %s", item_path_str(cx, id)] }
-      ty_res(id, _, _) { #fmt["resource %s", item_path_str(cx, id)] }
       ty_tup(_) { "tuple" }
       ty_var(_) { "variable" }
       ty_var_integral(_) { "integral variable" }
@@ -2606,7 +2549,7 @@ fn impl_iface(cx: ctxt, id: ast::def_id) -> option<t> {
 
 fn ty_to_def_id(ty: t) -> option<ast::def_id> {
     alt get(ty).struct {
-      ty_iface(id, _) | ty_class(id, _) | ty_res(id, _, _) | ty_enum(id, _) {
+      ty_iface(id, _) | ty_class(id, _) | ty_enum(id, _) {
         some(id)
       }
       _ { none }
@@ -2685,7 +2628,7 @@ fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path {
             vec::init(*path) + [ast_map::path_name(variant.node.name)]
           }
 
-          ast_map::node_ctor(nm, _, _, path) {
+          ast_map::node_ctor(nm, _, _, _, path) {
               *path + [ast_map::path_name(nm)]
           }
           ast_map::node_dtor(_, _, _, path) {
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index e3f6ba40aef..86d105adb99 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/src/rustc/middle/typeck/check.rs
@@ -354,10 +354,6 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
       ast::item_fn(decl, tps, body) {
         check_bare_fn(ccx, decl, body, it.id, none);
       }
-      ast::item_res(decl, tps, body, dtor_id, _, rp) {
-        check_instantiable(ccx.tcx, it.span, it.id);
-        check_bare_fn(ccx, decl, body, dtor_id, none);
-      }
       ast::item_impl(tps, rp, _, ty, ms) {
         let self_ty = ccx.to_ty(rscope::type_rscope(rp), ty);
         for ms.each {|m| check_method(ccx, m, self_ty);}
diff --git a/src/rustc/middle/typeck/collect.rs b/src/rustc/middle/typeck/collect.rs
index b693ddb8492..ea04fd96b27 100644
--- a/src/rustc/middle/typeck/collect.rs
+++ b/src/rustc/middle/typeck/collect.rs
@@ -261,11 +261,6 @@ fn convert_class_item(ccx: @crate_ctxt,
                       rp: ast::region_param,
                       bounds: @[ty::param_bounds],
                       v: ast_util::ivar) {
-    /* we want to do something here, b/c within the
-    scope of the class, it's ok to refer to fields &
-    methods unqualified */
-    /* they have these types *within the scope* of the
-    class. outside the class, it's done with expr_field */
     let tt = ccx.to_ty(type_rscope(rp), v.ty);
     write_ty_to_tcx(ccx.tcx, v.id, tt);
     /* add the field to the tcache */
@@ -322,37 +317,6 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
             check_methods_against_iface(ccx, tps, rp, selfty, t, cms);
         }
       }
-      ast::item_res(decl, tps, _, dtor_id, ctor_id, rp) {
-        let {bounds, substs} = mk_substs(ccx, tps, rp);
-        let def_id = local_def(it.id);
-        let t_arg = ty_of_arg(ccx, type_rscope(rp),
-                                       decl.inputs[0], none);
-        let t_res = ty::mk_res(tcx, def_id, t_arg.ty, substs);
-
-        let t_ctor = ty::mk_fn(tcx, {
-            purity: ast::pure_fn,
-            proto: ast::proto_box,
-            inputs: [{mode: ast::expl(ast::by_copy), ty: t_arg.ty}],
-            output: t_res,
-            ret_style: ast::return_val, constraints: []
-        });
-        let t_dtor = ty::mk_fn(tcx, {
-            purity: ast::impure_fn,
-            proto: ast::proto_box,
-            inputs: [t_arg], output: ty::mk_nil(tcx),
-            ret_style: ast::return_val, constraints: []
-        });
-        write_ty_to_tcx(tcx, it.id, t_res);
-        write_ty_to_tcx(tcx, ctor_id, t_ctor);
-        tcx.tcache.insert(local_def(ctor_id),
-                          {bounds: bounds,
-                           rp: rp,
-                           ty: t_ctor});
-        tcx.tcache.insert(def_id, {bounds: bounds,
-                                   rp: rp,
-                                   ty: t_res});
-        write_ty_to_tcx(tcx, dtor_id, t_dtor);
-      }
       ast::item_iface(*) {
         let tpt = ty_of_item(ccx, it);
         #debug["item_iface(it.id=%d, tpt.ty=%s)",
@@ -366,11 +330,21 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
         write_ty_to_tcx(tcx, it.id, tpt.ty);
         tcx.tcache.insert(local_def(it.id), tpt);
         // Write the ctor type
-        let t_ctor =
-            ty::mk_fn(
-                tcx,
-                ty_of_fn_decl(ccx, type_rscope(rp), ast::proto_any,
-                              ctor.node.dec, none));
+        let t_args = ctor.node.dec.inputs.map {|a|
+                           ty_of_arg(ccx, type_rscope(rp), a, none)};
+        let t_res = ty::mk_class(tcx, local_def(it.id),
+                                 {self_r: alt rp {
+                       ast::rp_none { none }
+                       ast::rp_self { some(ty::re_bound(ty::br_self)) }
+                                     },
+                                  self_ty: none,
+                                  tps: ty::ty_params_to_tys(tcx, tps)});
+        let t_ctor = ty::mk_fn(tcx, {purity: ast::impure_fn,
+              proto: ast::proto_any,
+              inputs: t_args,
+              output: t_res,
+              ret_style: ast::return_val,
+              constraints: []}); // tjc TODO
         write_ty_to_tcx(tcx, ctor.node.id, t_ctor);
         tcx.tcache.insert(local_def(ctor.node.id),
                           {bounds: tpt.bounds,
@@ -538,15 +512,6 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item)
         tcx.tcache.insert(local_def(it.id), tpt);
         ret tpt;
       }
-      ast::item_res(decl, tps, _, _, _, rp) {
-        let {bounds, substs} = mk_substs(ccx, tps, rp);
-        let t_arg = ty_of_arg(ccx, type_rscope(rp),
-                                       decl.inputs[0], none);
-        let t = ty::mk_res(tcx, local_def(it.id), t_arg.ty, substs);
-        let t_res = {bounds: bounds, rp: rp, ty: t};
-        tcx.tcache.insert(local_def(it.id), t_res);
-        ret t_res;
-      }
       ast::item_enum(_, tps, rp) {
         // Create a new generic polytype.
         let {bounds, substs} = mk_substs(ccx, tps, rp);
diff --git a/src/rustc/middle/typeck/infer.rs b/src/rustc/middle/typeck/infer.rs
index e948e999e5c..1225908abb8 100644
--- a/src/rustc/middle/typeck/infer.rs
+++ b/src/rustc/middle/typeck/infer.rs
@@ -1851,16 +1851,6 @@ fn super_tys<C:combine>(
         }
       }
 
-      (ty::ty_res(a_id, a_t, a_substs),
-       ty::ty_res(b_id, b_t, b_substs))
-      if a_id == b_id {
-        self.tys(a_t, b_t).chain {|t|
-            self.substs(a_substs, b_substs).chain {|substs|
-                ok(ty::mk_res(tcx, a_id, t, substs))
-            }
-        }
-      }
-
       (ty::ty_rec(as), ty::ty_rec(bs)) {
         if check vec::same_length(as, bs) {
             map_vec2(as, bs) {|a,b|
diff --git a/src/rustc/util/ppaux.rs b/src/rustc/util/ppaux.rs
index 83167597bb8..f44d43d35ed 100644
--- a/src/rustc/util/ppaux.rs
+++ b/src/rustc/util/ppaux.rs
@@ -6,7 +6,7 @@ import middle::ty::{mt, re_bound, re_free, re_scope, re_var, region, t};
 import middle::ty::{ty_bool, ty_bot, ty_box, ty_class, ty_constr, ty_enum};
 import middle::ty::{ty_estr, ty_evec, ty_float, ty_fn, ty_iface, ty_int};
 import middle::ty::{ty_nil, ty_opaque_box, ty_opaque_closure_ptr, ty_param};
-import middle::ty::{ty_ptr, ty_rec, ty_res, ty_rptr, ty_self, ty_str, ty_tup};
+import middle::ty::{ty_ptr, ty_rec, ty_rptr, ty_self, ty_str, ty_tup};
 import middle::ty::{ty_type, ty_uniq, ty_uint, ty_var, ty_var_integral};
 import middle::ty::{ty_vec, ty_unboxed_vec, vid};
 import metadata::encoder;
@@ -208,7 +208,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
         "'" + str::from_bytes([('a' as u8) + (id as u8)])
       }
       ty_self { "self" }
-      ty_enum(did, substs) | ty_res(did, _, substs) | ty_class(did, substs) {
+      ty_enum(did, substs) | ty_class(did, substs) {
         let path = ty::item_path(cx, did);
         let base = ast_map::path_to_str(path);
         parameterized(cx, base, substs.self_r, substs.tps)
diff --git a/src/rustdoc/demo.rs b/src/rustdoc/demo.rs
index f39fe1f8120..9c700a23720 100644
--- a/src/rustdoc/demo.rs
+++ b/src/rustdoc/demo.rs
@@ -115,8 +115,10 @@ eget ante feugiat tortor congue auctor ac quis ante. Proin
 condimentum lacinia tincidunt.
 
 "]
-resource bored(bored: bool) {
-    log(error, bored);
+class bored {
+  let bored: bool;
+  new(bored: bool) { self.bored = bored; }
+  drop { log(error, self.bored); }
 }
 
 #[doc = "
diff --git a/src/rustdoc/doc.rs b/src/rustdoc/doc.rs
index 84d7c8c31fd..12ee7e6ca70 100644
--- a/src/rustdoc/doc.rs
+++ b/src/rustdoc/doc.rs
@@ -33,7 +33,6 @@ enum itemtag {
     consttag(constdoc),
     fntag(fndoc),
     enumtag(enumdoc),
-    restag(resdoc),
     ifacetag(ifacedoc),
     impltag(impldoc),
     tytag(tydoc)
@@ -82,8 +81,6 @@ type variantdoc = {
     sig: option<str>
 };
 
-type resdoc = simpleitemdoc;
-
 type ifacedoc = {
     item: itemdoc,
     methods: [methoddoc]
@@ -192,15 +189,6 @@ impl util for moddoc {
         }
     }
 
-    fn resources() -> [resdoc] {
-        vec::filter_map(self.items) {|itemtag|
-            alt itemtag {
-              restag(resdoc) { some(resdoc) }
-              _ { none }
-            }
-        }
-    }
-
     fn ifaces() -> [ifacedoc] {
         vec::filter_map(self.items) {|itemtag|
             alt itemtag {
@@ -276,15 +264,6 @@ impl util for [page] {
         }
     }
 
-    fn resources() -> [resdoc] {
-        vec::filter_map(self) {|page|
-            alt page {
-              itempage(restag(resdoc)) { some(resdoc) }
-              _ { none }
-            }
-        }
-    }
-
     fn ifaces() -> [ifacedoc] {
         vec::filter_map(self) {|page|
             alt page {
@@ -325,7 +304,6 @@ impl of item for itemtag {
           doc::fntag(doc) { doc.item }
           doc::consttag(doc) { doc.item }
           doc::enumtag(doc) { doc.item }
-          doc::restag(doc) { doc.item }
           doc::ifacetag(doc) { doc.item }
           doc::impltag(doc) { doc.item }
           doc::tytag(doc) { doc.item }
diff --git a/src/rustdoc/extract.rs b/src/rustdoc/extract.rs
index 35e9fd5ea31..99663adf32f 100644
--- a/src/rustdoc/extract.rs
+++ b/src/rustdoc/extract.rs
@@ -83,11 +83,6 @@ fn moddoc_from_mod(
                     enumdoc_from_enum(itemdoc, variants)
                 ))
               }
-              ast::item_res(_, _, _, _, _, _) {
-                some(doc::restag(
-                    resdoc_from_resource(itemdoc)
-                ))
-              }
               ast::item_iface(_, _, methods) {
                 some(doc::ifacetag(
                     ifacedoc_from_iface(itemdoc, methods)
@@ -188,20 +183,6 @@ fn should_extract_enum_variants() {
     assert doc.cratemod().enums()[0].variants[0].name == "v";
 }
 
-fn resdoc_from_resource(itemdoc: doc::itemdoc) -> doc::resdoc {
-    {
-        item: itemdoc,
-        sig: none
-    }
-}
-
-#[test]
-fn should_extract_resources() {
-    let doc = test::mk_doc("resource r(b: bool) { }");
-    assert doc.cratemod().resources()[0].id() != 0;
-    assert doc.cratemod().resources()[0].name() == "r";
-}
-
 fn ifacedoc_from_iface(
     itemdoc: doc::itemdoc,
     methods: [ast::ty_method]
diff --git a/src/rustdoc/fold.rs b/src/rustdoc/fold.rs
index 02d98164d10..e502bb7ce41 100644
--- a/src/rustdoc/fold.rs
+++ b/src/rustdoc/fold.rs
@@ -8,7 +8,6 @@ export default_seq_fold_nmod;
 export default_seq_fold_fn;
 export default_seq_fold_const;
 export default_seq_fold_enum;
-export default_seq_fold_res;
 export default_seq_fold_iface;
 export default_seq_fold_impl;
 export default_seq_fold_type;
@@ -29,7 +28,6 @@ type fold_nmod<T> = fn~(fold: fold<T>, doc: doc::nmoddoc) -> doc::nmoddoc;
 type fold_fn<T> = fn~(fold: fold<T>, doc: doc::fndoc) -> doc::fndoc;
 type fold_const<T> = fn~(fold: fold<T>, doc: doc::constdoc) -> doc::constdoc;
 type fold_enum<T> = fn~(fold: fold<T>, doc: doc::enumdoc) -> doc::enumdoc;
-type fold_res<T> = fn~(fold: fold<T>, doc: doc::resdoc) -> doc::resdoc;
 type fold_iface<T> = fn~(fold: fold<T>, doc: doc::ifacedoc) -> doc::ifacedoc;
 type fold_impl<T> = fn~(fold: fold<T>, doc: doc::impldoc) -> doc::impldoc;
 type fold_type<T> = fn~(fold: fold<T>, doc: doc::tydoc) -> doc::tydoc;
@@ -44,7 +42,6 @@ type t<T> = {
     fold_fn: fold_fn<T>,
     fold_const: fold_const<T>,
     fold_enum: fold_enum<T>,
-    fold_res: fold_res<T>,
     fold_iface: fold_iface<T>,
     fold_impl: fold_impl<T>,
     fold_type: fold_type<T>
@@ -63,7 +60,6 @@ fn mk_fold<T:copy>(
     +fold_fn: fold_fn<T>,
     +fold_const: fold_const<T>,
     +fold_enum: fold_enum<T>,
-    +fold_res: fold_res<T>,
     +fold_iface: fold_iface<T>,
     +fold_impl: fold_impl<T>,
     +fold_type: fold_type<T>
@@ -78,7 +74,6 @@ fn mk_fold<T:copy>(
         fold_fn: fold_fn,
         fold_const: fold_const,
         fold_enum: fold_enum,
-        fold_res: fold_res,
         fold_iface: fold_iface,
         fold_impl: fold_impl,
         fold_type: fold_type
@@ -96,7 +91,6 @@ fn default_any_fold<T:send copy>(ctxt: T) -> fold<T> {
         {|f, d| default_seq_fold_fn(f, d)},
         {|f, d| default_seq_fold_const(f, d)},
         {|f, d| default_seq_fold_enum(f, d)},
-        {|f, d| default_seq_fold_res(f, d)},
         {|f, d| default_seq_fold_iface(f, d)},
         {|f, d| default_seq_fold_impl(f, d)},
         {|f, d| default_seq_fold_type(f, d)}
@@ -114,7 +108,6 @@ fn default_seq_fold<T:copy>(ctxt: T) -> fold<T> {
         {|f, d| default_seq_fold_fn(f, d)},
         {|f, d| default_seq_fold_const(f, d)},
         {|f, d| default_seq_fold_enum(f, d)},
-        {|f, d| default_seq_fold_res(f, d)},
         {|f, d| default_seq_fold_iface(f, d)},
         {|f, d| default_seq_fold_impl(f, d)},
         {|f, d| default_seq_fold_type(f, d)}
@@ -132,7 +125,6 @@ fn default_par_fold<T:send copy>(ctxt: T) -> fold<T> {
         {|f, d| default_seq_fold_fn(f, d)},
         {|f, d| default_seq_fold_const(f, d)},
         {|f, d| default_seq_fold_enum(f, d)},
-        {|f, d| default_seq_fold_res(f, d)},
         {|f, d| default_seq_fold_iface(f, d)},
         {|f, d| default_seq_fold_impl(f, d)},
         {|f, d| default_seq_fold_type(f, d)}
@@ -266,9 +258,6 @@ fn fold_itemtag<T>(fold: fold<T>, doc: doc::itemtag) -> doc::itemtag {
       doc::enumtag(enumdoc) {
         doc::enumtag(fold.fold_enum(fold, enumdoc))
       }
-      doc::restag(resdoc) {
-        doc::restag(fold.fold_res(fold, resdoc))
-      }
       doc::ifacetag(ifacedoc) {
         doc::ifacetag(fold.fold_iface(fold, ifacedoc))
       }
@@ -311,16 +300,6 @@ fn default_seq_fold_enum<T>(
     }
 }
 
-fn default_seq_fold_res<T>(
-    fold: fold<T>,
-    doc: doc::resdoc
-) -> doc::resdoc {
-    {
-        item: fold.fold_item(fold, doc.item)
-        with doc
-    }
-}
-
 fn default_seq_fold_iface<T>(
     fold: fold<T>,
     doc: doc::ifacedoc
diff --git a/src/rustdoc/markdown_pass.rs b/src/rustdoc/markdown_pass.rs
index b98690f4fd9..ec700b755e7 100644
--- a/src/rustdoc/markdown_pass.rs
+++ b/src/rustdoc/markdown_pass.rs
@@ -198,9 +198,6 @@ fn header_kind(doc: doc::itemtag) -> str {
       doc::enumtag(_) {
         "Enum"
       }
-      doc::restag(_) {
-        "Resource"
-      }
       doc::ifacetag(_) {
         "Interface"
       }
@@ -352,7 +349,6 @@ fn write_item_(ctxt: ctxt, doc: doc::itemtag, write_header: bool) {
       doc::fntag(fndoc) { write_fn(ctxt, fndoc) }
       doc::consttag(constdoc) { write_const(ctxt, constdoc) }
       doc::enumtag(enumdoc) { write_enum(ctxt, enumdoc) }
-      doc::restag(resdoc) { write_res(ctxt, resdoc) }
       doc::ifacetag(ifacedoc) { write_iface(ctxt, ifacedoc) }
       doc::impltag(impldoc) { write_impl(ctxt, impldoc) }
       doc::tytag(tydoc) { write_type(ctxt, tydoc) }
@@ -643,11 +639,6 @@ fn should_write_variant_list_with_signatures() {
          \n* `c(int)` - a\n\n");
 }
 
-fn write_res(ctxt: ctxt, doc: doc::resdoc) {
-    write_sig(ctxt, doc.sig);
-    write_common(ctxt, doc.desc(), doc.sections());
-}
-
 #[test]
 fn should_write_resource_header() {
     let markdown = test::render("resource r(a: bool) { }");
diff --git a/src/rustdoc/prune_unexported_pass.rs b/src/rustdoc/prune_unexported_pass.rs
index d581ead494a..f0eac40a297 100644
--- a/src/rustdoc/prune_unexported_pass.rs
+++ b/src/rustdoc/prune_unexported_pass.rs
@@ -202,19 +202,6 @@ fn should_prune_unexported_variants() {
 }
 
 #[test]
-fn should_prune_unexported_resources_from_top_mod() {
-    let doc = test::mk_doc("export a; mod a { } resource r(a: bool) { }");
-    assert vec::is_empty(doc.cratemod().resources());
-}
-
-#[test]
-fn should_prune_unexported_resources() {
-    let doc = test::mk_doc(
-        "mod a { export a; mod a { } resource r(a: bool) { } }");
-    assert vec::is_empty(doc.cratemod().mods()[0].resources());
-}
-
-#[test]
 fn should_prune_unexported_ifaces_from_top_mod() {
     let doc = test::mk_doc("export a; mod a { } iface b { fn c(); }");
     assert vec::is_empty(doc.cratemod().ifaces());
diff --git a/src/rustdoc/reexport_pass.rs b/src/rustdoc/reexport_pass.rs
index b79d8e88f50..54beb013960 100644
--- a/src/rustdoc/reexport_pass.rs
+++ b/src/rustdoc/reexport_pass.rs
@@ -374,12 +374,6 @@ fn merge_reexports(
                 with doc
             })
           }
-          doc::restag(doc @ {item, _}) {
-            doc::restag({
-                item: reexport(item, name)
-                with doc
-            })
-          }
           doc::ifacetag(doc @ {item, _}) {
             doc::ifacetag({
                 item: reexport(item, name)
diff --git a/src/rustdoc/sort_item_type_pass.rs b/src/rustdoc/sort_item_type_pass.rs
index a01c914b8a4..96c438a0678 100644
--- a/src/rustdoc/sort_item_type_pass.rs
+++ b/src/rustdoc/sort_item_type_pass.rs
@@ -9,7 +9,6 @@ fn mk_pass() -> pass {
               doc::consttag(_) { 0 }
               doc::tytag(_) { 1 }
               doc::enumtag(_) { 2 }
-              doc::restag(_) { 3 }
               doc::ifacetag(_) { 4 }
               doc::impltag(_) { 5 }
               doc::fntag(_) { 6 }
@@ -30,7 +29,6 @@ fn test() {
          const iconst: int = 0; \
          fn ifn() { } \
          enum ienum { ivar } \
-         resource ires(a: bool) { } \
          iface iiface { fn a(); } \
          impl iimpl for int { fn a() { } } \
          type itype = int;";
@@ -40,7 +38,6 @@ fn test() {
         assert doc.cratemod().items[0].name() == "iconst";
         assert doc.cratemod().items[1].name() == "itype";
         assert doc.cratemod().items[2].name() == "ienum";
-        assert doc.cratemod().items[3].name() == "ires";
         assert doc.cratemod().items[4].name() == "iiface";
         assert doc.cratemod().items[5].name() == "iimpl";
         assert doc.cratemod().items[6].name() == "ifn";
diff --git a/src/rustdoc/text_pass.rs b/src/rustdoc/text_pass.rs
index fa14367a316..bbeaf4b9d2f 100644
--- a/src/rustdoc/text_pass.rs
+++ b/src/rustdoc/text_pass.rs
@@ -115,18 +115,6 @@ fn should_execute_op_on_variant_desc() {
 }
 
 #[test]
-fn should_execute_op_on_resource_brief() {
-    let doc = test::mk_doc("#[doc = \" a \"] resource r(a: bool) { }");
-    assert doc.cratemod().resources()[0].brief() == some("a");
-}
-
-#[test]
-fn should_execute_op_on_resource_desc() {
-    let doc = test::mk_doc("#[doc = \" a \"] resource r(a: bool) { }");
-    assert doc.cratemod().resources()[0].desc() == some("a");
-}
-
-#[test]
 fn should_execute_op_on_iface_brief() {
     let doc = test::mk_doc(
         "#[doc = \" a \"] iface i { fn a(); }");
diff --git a/src/rustdoc/tystr_pass.rs b/src/rustdoc/tystr_pass.rs
index 85740205ffa..e18be9b4301 100644
--- a/src/rustdoc/tystr_pass.rs
+++ b/src/rustdoc/tystr_pass.rs
@@ -23,7 +23,6 @@ fn run(
         fold_fn: fold_fn,
         fold_const: fold_const,
         fold_enum: fold_enum,
-        fold_res: fold_res,
         fold_iface: fold_iface,
         fold_impl: fold_impl,
         fold_type: fold_type
@@ -139,33 +138,6 @@ fn should_add_variant_sigs() {
     assert doc.cratemod().enums()[0].variants[0].sig == some("b(int)");
 }
 
-fn fold_res(
-    fold: fold::fold<astsrv::srv>,
-    doc: doc::resdoc
-) -> doc::resdoc {
-    let srv = fold.ctxt;
-
-    {
-        sig: some(astsrv::exec(srv) {|ctxt|
-            alt check ctxt.ast_map.get(doc.id()) {
-              ast_map::node_item(@{
-                node: ast::item_res(decl, tys, _, _, _, rp), _
-              }, _) {
-                pprust::res_to_str(decl, @doc.name(), tys, rp)
-              }
-            }
-        })
-        with doc
-    }
-}
-
-#[test]
-fn should_add_resource_sigs() {
-    let doc = test::mk_doc("resource r<T>(b: bool) { }");
-    assert doc.cratemod().resources()[0].sig
-        == some("resource r<T>(b: bool)");
-}
-
 fn fold_iface(
     fold: fold::fold<astsrv::srv>,
     doc: doc::ifacedoc
diff --git a/src/test/compile-fail/regions-in-rsrcs.rs b/src/test/compile-fail/regions-in-rsrcs.rs
index b190491e6d6..fe1482f92e8 100644
--- a/src/test/compile-fail/regions-in-rsrcs.rs
+++ b/src/test/compile-fail/regions-in-rsrcs.rs
@@ -1,17 +1,17 @@
 class no0 {
-  let x: &uint;
+  let x: &uint; //! ERROR to use region types here, the containing type must be declared with a region bound
   new(x: &uint) { self.x = x; } //! ERROR to use region types here, the containing type must be declared with a region bound
   drop {}
 }
 
 class no1 {
-  let x: &self.uint;
+  let x: &self.uint; //! ERROR to use region types here, the containing type must be declared with a region bound
   new(x: &self.uint) { self.x = x; } //! ERROR to use region types here, the containing type must be declared with a region bound
   drop {}
 }
 
 class no2 {
-  let x: &foo.uint;
+  let x: &foo.uint; //! ERROR named regions other than `self` are not allowed as part of a type declaration
   new(x: &foo.uint) { self.x = x; } //! ERROR named regions other than `self` are not allowed as part of a type declaration
   drop {}
 }
@@ -29,7 +29,7 @@ class yes1/& {
 }
 
 class yes2/& {
-  let x: &foo.uint;
+  let x: &foo.uint; //! ERROR named regions other than `self` are not allowed as part of a type declaration
   new(x: &foo.uint) { self.x = x; } //! ERROR named regions other than `self` are not allowed as part of a type declaration
   drop {}
 }
diff --git a/src/test/run-pass/resource-cycle.rs b/src/test/run-pass/resource-cycle.rs
index d991fc2dffa..a20d18ea61e 100644
--- a/src/test/run-pass/resource-cycle.rs
+++ b/src/test/run-pass/resource-cycle.rs
@@ -1,7 +1,20 @@
 // Don't leak the unique pointers
 
-resource r(v: *int) unsafe {
-    let v2: ~int = unsafe::reinterpret_cast(v);
+class r {
+  let v: *int;
+  new(v: *int) unsafe {
+    self.v = v;
+    #debug("r's ctor: v = %x, self = %x, self.v = %x",
+           unsafe::reinterpret_cast::<*int, uint>(v),
+           unsafe::reinterpret_cast::<*r, uint>(ptr::addr_of(self)),
+           unsafe::reinterpret_cast::<**int, uint>(ptr::addr_of(self.v)));
+     }
+  drop unsafe {
+    #debug("r's dtor: self = %x, self.v = %x, self.v's value = %x",
+           unsafe::reinterpret_cast::<*r, uint>(ptr::addr_of(self)),
+           unsafe::reinterpret_cast::<**int, uint>(ptr::addr_of(self.v)),
+           unsafe::reinterpret_cast::<*int, uint>(self.v));
+    let v2: ~int = unsafe::reinterpret_cast(self.v); }
 }
 
 enum t = {
@@ -19,12 +32,31 @@ fn main() unsafe {
 
     let x1 = @t({
         mut next: none,
-        r: r(i1p)
+          r: {
+          let rs = r(i1p);
+          #debug("r = %x",
+                 unsafe::reinterpret_cast::<*r, uint>(ptr::addr_of(rs)));
+          rs }
     });
+    
+    #debug("x1 = %x, x1.r = %x",
+        unsafe::reinterpret_cast::<@t, uint>(x1),
+        unsafe::reinterpret_cast::<*r, uint>(ptr::addr_of(x1.r)));
+
     let x2 = @t({
         mut next: none,
-        r: r(i2p)
+          r: {
+          let rs = r(i2p);
+          #debug("r2 = %x",
+                 unsafe::reinterpret_cast::<*r, uint>(ptr::addr_of(rs)));
+          rs
+            }
     });
+    
+    #debug("x2 = %x, x2.r = %x",
+           unsafe::reinterpret_cast::<@t, uint>(x2),
+           unsafe::reinterpret_cast::<*r, uint>(ptr::addr_of(x2.r)));
+
     x1.next = some(x2);
     x2.next = some(x1);
 }
diff --git a/src/test/run-pass/resource-cycle2.rs b/src/test/run-pass/resource-cycle2.rs
index 85bfc195bd4..4f0f87908cf 100644
--- a/src/test/run-pass/resource-cycle2.rs
+++ b/src/test/run-pass/resource-cycle2.rs
@@ -6,8 +6,12 @@ type u = {
     c: *int
 };
 
-resource r(v: u) unsafe {
-    let v2: ~int = unsafe::reinterpret_cast(v.c);
+class r {
+  let v: u;
+  new(v: u) { self.v = v; }
+  drop unsafe {
+    let v2: ~int = unsafe::reinterpret_cast(self.v.c);
+  }
 }
 
 enum t = {