Skip to content

Commit 7236097

Browse files
committed
Change trans::common::block to be a class
And replace trans::common::block_parent with option<block>. To handle the recursive self-reference in the block_ class, I had to add a newtype-like enum "block" which is equivalent to @block_ -- which due to an interaction with borrowck, resulted in having to change a few functions in trans::base to take their block argument in ++ mode, irritatingly enough (but not that irritatingly, since we're supposed to get rid of modes).
1 parent d1ec1d4 commit 7236097

File tree

3 files changed

+69
-60
lines changed

3 files changed

+69
-60
lines changed

src/rustc/middle/trans/base.rs

Lines changed: 30 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import type_of::type_of; // Issue #1873
5050
import syntax::ast_map::{path, path_mod, path_name};
5151

5252
import std::smallintmap;
53+
import option::is_none;
5354

5455
// Destinations
5556

@@ -1207,7 +1208,8 @@ fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
12071208
}
12081209
}
12091210

1210-
fn call_tydesc_glue_full(cx: block, v: ValueRef, tydesc: ValueRef,
1211+
// See [Note-arg-mode]
1212+
fn call_tydesc_glue_full(++cx: block, v: ValueRef, tydesc: ValueRef,
12111213
field: uint, static_ti: option<@tydesc_info>) {
12121214
let _icx = cx.insn_ctxt("call_tydesc_glue_full");
12131215
lazily_emit_tydesc_glue(cx.ccx(), field, static_ti);
@@ -1245,8 +1247,9 @@ fn call_tydesc_glue_full(cx: block, v: ValueRef, tydesc: ValueRef,
12451247
C_null(T_ptr(T_ptr(cx.ccx().tydesc_type))), llrawptr]);
12461248
}
12471249

1248-
fn call_tydesc_glue(cx: block, v: ValueRef, t: ty::t, field: uint) ->
1249-
block {
1250+
// See [Note-arg-mode]
1251+
fn call_tydesc_glue(++cx: block, v: ValueRef, t: ty::t, field: uint)
1252+
-> block {
12501253
let _icx = cx.insn_ctxt("call_tydesc_glue");
12511254
let mut ti = none;
12521255
let td = get_tydesc(cx.ccx(), t, ti);
@@ -3111,8 +3114,9 @@ fn body_contains_ret(body: ast::blk) -> bool {
31113114
cx.found
31123115
}
31133116

3117+
// See [Note-arg-mode]
31143118
fn trans_call_inner(
3115-
in_cx: block,
3119+
++in_cx: block,
31163120
call_info: option<node_info>,
31173121
fn_expr_ty: ty::t,
31183122
ret_ty: ty::t,
@@ -3240,8 +3244,8 @@ fn need_invoke(bcx: block) -> bool {
32403244
_ { }
32413245
}
32423246
cur = alt cur.parent {
3243-
parent_some(next) { next }
3244-
parent_none { ret false; }
3247+
some(next) { next }
3248+
none { ret false; }
32453249
}
32463250
}
32473251
}
@@ -3262,7 +3266,7 @@ fn in_lpad_scope_cx(bcx: block, f: fn(scope_info)) {
32623266
loop {
32633267
alt bcx.kind {
32643268
block_scope(inf) {
3265-
if inf.cleanups.len() > 0u || bcx.parent == parent_none {
3269+
if inf.cleanups.len() > 0u || is_none(bcx.parent) {
32663270
f(inf); ret;
32673271
}
32683272
}
@@ -3471,11 +3475,11 @@ fn add_root_cleanup(bcx: block, scope_id: ast::node_id,
34713475
some({id, _}) if id == scope_id { ret bcx_sid; }
34723476
_ {
34733477
alt bcx_sid.parent {
3474-
parent_none {
3478+
none {
34753479
bcx.tcx().sess.bug(
34763480
#fmt["no enclosing scope with id %d", scope_id]);
34773481
}
3478-
parent_some(bcx_par) { bcx_par }
3482+
some(bcx_par) { bcx_par }
34793483
}
34803484
}
34813485
}
@@ -3785,7 +3789,10 @@ fn do_spill(bcx: block, v: ValueRef, t: ty::t) -> ValueRef {
37853789

37863790
// Since this function does *not* root, it is the caller's responsibility to
37873791
// ensure that the referent is pointed to by a root.
3788-
fn do_spill_noroot(cx: block, v: ValueRef) -> ValueRef {
3792+
// [Note-arg-mode]
3793+
// ++ mode is temporary, due to how borrowck treats enums. With hope,
3794+
// will go away anyway when we get rid of modes.
3795+
fn do_spill_noroot(++cx: block, v: ValueRef) -> ValueRef {
37893796
let llptr = alloca(cx, val_ty(v));
37903797
Store(cx, v, llptr);
37913798
ret llptr;
@@ -3970,9 +3977,9 @@ fn trans_break_cont(bcx: block, to_end: bool)
39703977
_ {}
39713978
}
39723979
unwind = alt unwind.parent {
3973-
parent_some(cx) { cx }
3980+
some(cx) { cx }
39743981
// This is a return from a loop body block
3975-
parent_none {
3982+
none {
39763983
Store(bcx, C_bool(!to_end), bcx.fcx.llretptr);
39773984
cleanup_and_leave(bcx, none, some(bcx.fcx.llreturn));
39783985
Unreachable(bcx);
@@ -4090,7 +4097,7 @@ fn trans_stmt(cx: block, s: ast::stmt) -> block {
40904097

40914098
// You probably don't want to use this one. See the
40924099
// next three functions instead.
4093-
fn new_block(cx: fn_ctxt, parent: block_parent, +kind: block_kind,
4100+
fn new_block(cx: fn_ctxt, parent: option<block>, +kind: block_kind,
40944101
name: str, opt_node_info: option<node_info>) -> block {
40954102

40964103
let s = if cx.ccx.sess.opts.save_temps || cx.ccx.sess.opts.debuginfo {
@@ -4099,19 +4106,10 @@ fn new_block(cx: fn_ctxt, parent: block_parent, +kind: block_kind,
40994106
let llbb: BasicBlockRef = str::as_c_str(s, {|buf|
41004107
llvm::LLVMAppendBasicBlock(cx.llfn, buf)
41014108
});
4102-
let bcx = @{llbb: llbb,
4103-
mut terminated: false,
4104-
mut unreachable: false,
4105-
parent: parent,
4106-
kind: kind,
4107-
node_info: opt_node_info,
4108-
fcx: cx};
4109-
alt parent {
4110-
parent_some(cx) {
4109+
let bcx = mk_block(llbb, parent, kind, opt_node_info, cx);
4110+
option::iter(parent) {|cx|
41114111
if cx.unreachable { Unreachable(bcx); }
4112-
}
4113-
_ {}
4114-
}
4112+
};
41154113
ret bcx;
41164114
}
41174115

@@ -4122,20 +4120,20 @@ fn simple_block_scope() -> block_kind {
41224120

41234121
// Use this when you're at the top block of a function or the like.
41244122
fn top_scope_block(fcx: fn_ctxt, opt_node_info: option<node_info>) -> block {
4125-
ret new_block(fcx, parent_none, simple_block_scope(),
4123+
ret new_block(fcx, none, simple_block_scope(),
41264124
"function top level", opt_node_info);
41274125
}
41284126

41294127
fn scope_block(bcx: block,
41304128
opt_node_info: option<node_info>,
41314129
n: str) -> block {
4132-
ret new_block(bcx.fcx, parent_some(bcx), simple_block_scope(),
4130+
ret new_block(bcx.fcx, some(bcx), simple_block_scope(),
41334131
n, opt_node_info);
41344132
}
41354133

41364134
fn loop_scope_block(bcx: block, loop_break: block, n: str,
41374135
opt_node_info: option<node_info>) -> block {
4138-
ret new_block(bcx.fcx, parent_some(bcx), block_scope({
4136+
ret new_block(bcx.fcx, some(bcx), block_scope({
41394137
loop_break: some(loop_break),
41404138
mut cleanups: [],
41414139
mut cleanup_paths: [],
@@ -4146,17 +4144,11 @@ fn loop_scope_block(bcx: block, loop_break: block, n: str,
41464144

41474145
// Use this when you're making a general CFG BB within a scope.
41484146
fn sub_block(bcx: block, n: str) -> block {
4149-
ret new_block(bcx.fcx, parent_some(bcx), block_non_scope, n, none);
4147+
new_block(bcx.fcx, some(bcx), block_non_scope, n, none)
41504148
}
41514149

41524150
fn raw_block(fcx: fn_ctxt, llbb: BasicBlockRef) -> block {
4153-
ret @{llbb: llbb,
4154-
mut terminated: false,
4155-
mut unreachable: false,
4156-
parent: parent_none,
4157-
kind: block_non_scope,
4158-
node_info: none,
4159-
fcx: fcx};
4151+
mk_block(llbb, none, block_non_scope, none, fcx)
41604152
}
41614153

41624154

@@ -4231,8 +4223,8 @@ fn cleanup_and_leave(bcx: block, upto: option<BasicBlockRef>,
42314223
_ {}
42324224
}
42334225
cur = alt cur.parent {
4234-
parent_some(next) { next }
4235-
parent_none { assert option::is_none(upto); break; }
4226+
some(next) { next }
4227+
none { assert is_none(upto); break; }
42364228
};
42374229
}
42384230
alt leave {

src/rustc/middle/trans/common.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -350,32 +350,44 @@ type node_info = {
350350
// code. Each basic block we generate is attached to a function, typically
351351
// with many basic blocks per function. All the basic blocks attached to a
352352
// function are organized as a directed graph.
353-
type block = @{
353+
class block_ {
354354
// The BasicBlockRef returned from a call to
355355
// llvm::LLVMAppendBasicBlock(llfn, name), which adds a basic
356356
// block to the function pointed to by llfn. We insert
357357
// instructions into that block by way of this block context.
358358
// The block pointing to this one in the function's digraph.
359-
llbb: BasicBlockRef,
360-
mut terminated: bool,
361-
mut unreachable: bool,
362-
parent: block_parent,
359+
let llbb: BasicBlockRef;
360+
let mut terminated: bool;
361+
let mut unreachable: bool;
362+
let parent: option<block>;
363363
// The 'kind' of basic block this is.
364-
kind: block_kind,
364+
let kind: block_kind;
365365
// info about the AST node this block originated from, if any
366-
node_info: option<node_info>,
366+
let node_info: option<node_info>;
367367
// The function context for the function to which this block is
368368
// attached.
369-
fcx: fn_ctxt
370-
};
369+
let fcx: fn_ctxt;
370+
new(llbb: BasicBlockRef, parent: option<block>, -kind: block_kind,
371+
node_info: option<node_info>, fcx: fn_ctxt) {
372+
// sigh
373+
self.llbb = llbb; self.terminated = false; self.unreachable = false;
374+
self.parent = parent; self.kind = kind; self.node_info = node_info;
375+
self.fcx = fcx;
376+
}
377+
}
378+
379+
/* This must be enum and not type, or trans goes into an infinite loop (#2572)
380+
*/
381+
enum block = @block_;
382+
383+
fn mk_block(llbb: BasicBlockRef, parent: option<block>, -kind: block_kind,
384+
node_info: option<node_info>, fcx: fn_ctxt) -> block {
385+
block(@block_(llbb, parent, kind, node_info, fcx))
386+
}
371387

372388
// First two args are retptr, env
373389
const first_real_arg: uint = 2u;
374390

375-
// FIXME move blocks to a class once those are finished, and simply use
376-
// option<block> for this. (#2532)
377-
enum block_parent { parent_none, parent_some(block), }
378-
379391
type result = {bcx: block, val: ValueRef};
380392
type result_t = {bcx: block, val: ValueRef, ty: ty::t};
381393

@@ -412,7 +424,11 @@ fn in_scope_cx(cx: block, f: fn(scope_info)) {
412424
}
413425

414426
fn block_parent(cx: block) -> block {
415-
alt check cx.parent { parent_some(b) { b } }
427+
alt cx.parent {
428+
some(b) { b }
429+
none { cx.sess().bug(#fmt("block_parent called on root block %?",
430+
cx)); }
431+
}
416432
}
417433

418434
// Accessors

src/rustc/middle/trans/debuginfo.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,8 @@ fn create_block(cx: block) -> @metadata<block_md> {
236236
let mut cx = cx;
237237
while option::is_none(cx.node_info) {
238238
alt cx.parent {
239-
parent_some(b) { cx = b; }
240-
parent_none { fail; }
239+
some(b) { cx = b; }
240+
none { fail; }
241241
}
242242
}
243243
let sp = option::get(cx.node_info).span;
@@ -254,8 +254,8 @@ fn create_block(cx: block) -> @metadata<block_md> {
254254
}*/
255255

256256
let parent = alt cx.parent {
257-
parent_none { create_function(cx.fcx).node }
258-
parent_some(bcx) { create_block(bcx).node }
257+
none { create_function(cx.fcx).node }
258+
some(bcx) { create_block(bcx).node }
259259
};
260260
let file_node = create_file(cx.ccx(), fname);
261261
let unique_id = alt cache.find(LexicalBlockTag) {
@@ -658,8 +658,8 @@ fn create_local_var(bcx: block, local: @ast::local)
658658
let tymd = create_ty(cx, ty, local.node.ty);
659659
let filemd = create_file(cx, loc.file.name);
660660
let context = alt bcx.parent {
661-
parent_none { create_function(bcx.fcx).node }
662-
parent_some(_) { create_block(bcx).node }
661+
none { create_function(bcx.fcx).node }
662+
some(_) { create_block(bcx).node }
663663
};
664664
let mdnode = create_var(tg, context, name, filemd.node,
665665
loc.line as int, tymd.node);
@@ -761,9 +761,10 @@ fn create_function(fcx: fn_ctxt) -> @metadata<subprogram_md> {
761761
(nm, decl.output, ctor_id)
762762
}
763763
ast_map::class_ctor(ctor,_) {
764-
fcx.ccx.sess.span_bug(ctor.span, "create_function: \
765-
expected a resource ctor here"); }
764+
// FIXME: output type may be wrong (#2194)
765+
(nm, ctor.node.dec.output, ctor.node.id)
766766
}
767+
}
767768
}
768769
ast_map::node_expr(expr) {
769770
alt expr.node {

0 commit comments

Comments
 (0)