Remove resources
Also fixed shapes for classes with dtors, as well as handling offsets for classes with dtors correctly in take glue. Closes #2485
This commit is contained in:
parent
60a748a1d8
commit
487cbf8e90
@ -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. */
|
||||
|
@ -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(
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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; };
|
||||
|
@ -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"
|
||||
|
@ -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 {
|
||||
|
@ -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|
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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}
|
||||
}
|
||||
}
|
||||
|
@ -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)))
|
||||
}
|
||||
|
@ -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});
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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}
|
||||
|
@ -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);
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
/*
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)]) }
|
||||
|
@ -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)])
|
||||
|
@ -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 = [];
|
||||
|
@ -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, _, _){
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);}
|
||||
|
@ -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);
|
||||
|
@ -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|
|
||||
|
@ -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)
|
||||
|
@ -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 = "
|
||||
|
@ -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 }
|
||||
|
@ -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]
|
||||
|
@ -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
|
||||
|
@ -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) { }");
|
||||
|
@ -201,19 +201,6 @@ fn should_prune_unexported_variants() {
|
||||
assert vec::len(doc.cratemod().mods()[0].enums()[0].variants) == 0u;
|
||||
}
|
||||
|
||||
#[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(); }");
|
||||
|
@ -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)
|
||||
|
@ -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";
|
||||
|
@ -114,18 +114,6 @@ fn should_execute_op_on_variant_desc() {
|
||||
assert doc.cratemod().enums()[0].variants[0].desc == some("a");
|
||||
}
|
||||
|
||||
#[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(
|
||||
|
@ -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
|
||||
|
@ -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 {}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 = {
|
||||
|
Loading…
Reference in New Issue
Block a user