Skip to content

Commit 8bbd780

Browse files
committed
Handle self correctly when translating classes
This change uses the same code for handling the "self" reference for classes as is already used for impls/ifaces. This allows removing the extra maybe_self_id argument (which was just for classes) to trans_closure that I added before. I also rewrote the translation for class ctors so that it doesn't generate new AST nodes (instead translating directly). Also changed visit so that it visits class ctors correctly with visit_fn, and changed typestate to not do return-checking when visiting a class ctor.
1 parent 713b358 commit 8bbd780

File tree

10 files changed

+99
-105
lines changed

10 files changed

+99
-105
lines changed

src/rustc/metadata/astencode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ fn visit_ids(item: ast::inlined_item, vfn: fn@(ast::node_id)) {
201201

202202
alt fk {
203203
visit::fk_item_fn(_, tps) |
204-
visit::fk_res(_, tps) {
204+
visit::fk_res(_, tps) | visit::fk_ctor(_, tps) {
205205
vec::iter(tps) {|tp| vfn(tp.id)}
206206
}
207207
visit::fk_method(_, tps, m) {

src/rustc/middle/resolve.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,8 @@ fn visit_fn_with_scope(e: @env, fk: visit::fn_kind, decl: ast::fn_decl,
570570
for c: @ast::constr in decl.constraints { resolve_constr(e, c, sc, v); }
571571
let scope = alt fk {
572572
visit::fk_item_fn(_, tps) | visit::fk_res(_, tps) |
573-
visit::fk_method(_, tps, _) { scope_bare_fn(decl, id, tps) }
573+
visit::fk_method(_, tps, _) | visit::fk_ctor(_, tps)
574+
{ scope_bare_fn(decl, id, tps) }
574575
visit::fk_anon(ast::proto_bare) { scope_bare_fn(decl, id, []) }
575576
visit::fk_anon(_) | visit::fk_fn_block { scope_fn_expr(decl, id, []) }
576577
};

src/rustc/middle/trans/base.rs

Lines changed: 79 additions & 88 deletions
Large diffs are not rendered by default.

src/rustc/middle/trans/closure.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ fn trans_expr_fn(bcx: block,
383383
ccx.tcx, id, proto, cap_clause);
384384
let {llbox, cdata_ty, bcx} = build_closure(bcx, cap_vars, ck, id);
385385
trans_closure(ccx, sub_path, decl, body, llfn, no_self,
386-
bcx.fcx.param_substs, id, none, {|fcx|
386+
bcx.fcx.param_substs, id, {|fcx|
387387
load_environment(fcx, cdata_ty, cap_vars, ck);
388388
});
389389
llbox
@@ -395,7 +395,7 @@ fn trans_expr_fn(bcx: block,
395395
ast::proto_uniq { trans_closure_env(ty::ck_uniq) }
396396
ast::proto_bare {
397397
trans_closure(ccx, sub_path, decl, body, llfn, no_self, none,
398-
id, none, {|_fcx|});
398+
id, {|_fcx|});
399399
C_null(T_opaque_box_ptr(ccx))
400400
}
401401
};

src/rustc/middle/trans/common.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ type crate_ctxt = {
119119
shape_cx: shape::ctxt,
120120
crate_map: ValueRef,
121121
dbg_cx: option<debuginfo::debug_ctxt>,
122+
// Mapping from class constructors to parent class --
123+
// used in base::trans_closure
124+
class_ctors: hashmap<ast::node_id, ast::node_id>,
122125
mutable do_not_commit_warning_issued: bool};
123126

124127
// Types used for llself.
@@ -175,10 +178,6 @@ type fn_ctxt = @{
175178
// a user-defined function.
176179
id: ast::node_id,
177180

178-
// The expr for the "self" object (only if this function corresponds
179-
// to a class constructor function)
180-
self_id: option<@ast::expr>,
181-
182181
// If this function is being monomorphized, this contains the type
183182
// substitutions used.
184183
param_substs: option<param_substs>,

src/rustc/middle/trans/impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
2424
let llfn = get_item_val(ccx, m.id);
2525
trans_fn(ccx, sub_path + [path_name(m.ident)], m.decl, m.body,
2626
llfn, impl_self(ty::node_id_to_type(ccx.tcx, m.self_id)),
27-
none, m.id, none);
27+
none, m.id);
2828
}
2929
}
3030
}

src/rustc/middle/trans/native.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -818,8 +818,7 @@ fn trans_crust_fn(ccx: @crate_ctxt, path: ast_map::path, decl: ast::fn_decl,
818818
ccx, path + [ast_map::path_name("__rust_abi")]);
819819
let llty = type_of_fn_from_ty(ccx, t);
820820
let llfndecl = decl_internal_cdecl_fn(ccx.llmod, ps, llty);
821-
trans_fn(ccx, path, decl, body, llfndecl, no_self, none, id,
822-
none);
821+
trans_fn(ccx, path, decl, body, llfndecl, no_self, none, id);
823822
ret llfndecl;
824823
}
825824

src/rustc/middle/tstate/ck.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ fn check_states_against_conditions(fcx: fn_ctxt,
111111

112112
/* Check that the return value is initialized */
113113
let post = aux::block_poststate(fcx.ccx, f_body);
114-
if !promises(fcx, post, fcx.enclosing.i_return) &&
114+
let is_ctor = alt fk { visit::fk_ctor(_,_) { true } _ { false } };
115+
if !is_ctor && !promises(fcx, post, fcx.enclosing.i_return) &&
115116
!ty::type_is_nil(ty::ty_fn_ret(ty::node_id_to_type(
116117
fcx.ccx.tcx, id))) &&
117118
f_decl.cf == return_val {

src/rustc/syntax/visit.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,21 @@ enum fn_kind {
1818
fk_res(ident, [ty_param]),
1919
fk_anon(proto), //< an anonymous function like fn@(...)
2020
fk_fn_block, //< a block {||...}
21+
fk_ctor(ident, [ty_param]) // class constructor
2122
}
2223

2324
fn name_of_fn(fk: fn_kind) -> ident {
2425
alt fk {
25-
fk_item_fn(name, _) | fk_method(name, _, _) | fk_res(name, _) { name }
26+
fk_item_fn(name, _) | fk_method(name, _, _) | fk_res(name, _)
27+
| fk_ctor(name, _) { name }
2628
fk_anon(_) | fk_fn_block { "anon" }
2729
}
2830
}
2931

3032
fn tps_of_fn(fk: fn_kind) -> [ty_param] {
3133
alt fk {
32-
fk_item_fn(_, tps) | fk_method(_, tps, _) | fk_res(_, tps) { tps }
34+
fk_item_fn(_, tps) | fk_method(_, tps, _) | fk_res(_, tps)
35+
| fk_ctor(_, tps) { tps }
3336
fk_anon(_) | fk_fn_block { [] }
3437
}
3538
}
@@ -138,8 +141,9 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
138141
for m in members {
139142
v.visit_class_item(m.span, m.node.privacy, m.node.decl, e, v);
140143
}
141-
visit_fn_decl(ctor.node.dec, e, v);
142-
v.visit_block(ctor.node.body, e, v);
144+
// make up a fake fn so as to call visit_fn on the ctor
145+
v.visit_fn(fk_ctor(i.ident, tps), ctor.node.dec,
146+
ctor.node.body, ctor.span, ctor.node.id, e, v);
143147
}
144148
item_iface(tps, methods) {
145149
v.visit_ty_params(tps, e, v);

src/test/run-pass/class-methods.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// xfail-test
21
class cat {
32
priv {
43
let mutable meows : uint;

0 commit comments

Comments
 (0)