Skip to content

Commit 0730b94

Browse files
committed
Refactored librustc_trans to avoid stack-crossing ref cycle.
Namely, `BlockS` used to carry an `fcx: &'blk FunctionContext`, while the `FunctionContext` carries a reference to the arena that holds the blocks. This creates a chicken/egg problem where we are attempting to assign the lifetime `'blk` to both the `FunctionContext` and to the arena's blocks, which does not work under the new lifetime rules for `Drop`, since there has to be some order in which the two are torn down. To resolve this, I removed the `fcx` from the `BlockS`, and instead turn the `Block` type (which was formerly `&'blk BlockS`) into a struct carrying both the pointer to the `BlockS` as well as the `fcx`.
1 parent 3bf41da commit 0730b94

19 files changed

+724
-719
lines changed

src/librustc_trans/trans/_match.rs

+74-73
Large diffs are not rendered by default.

src/librustc_trans/trans/adt.rs

+16-17
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ pub struct Struct<'tcx> {
130130
/// Convenience for `represent_type`. There should probably be more or
131131
/// these, for places in trans where the `Ty` isn't directly
132132
/// available.
133-
pub fn represent_node<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
133+
pub fn represent_node<'fcx, 'blk, 'tcx>(bcx: Block<'fcx, 'blk, 'tcx>,
134134
node: ast::NodeId) -> Rc<Repr<'tcx>> {
135135
represent_type(bcx.ccx(), node_id_type(bcx, node))
136136
}
@@ -710,7 +710,7 @@ fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, st: &Struct<'tcx>,
710710
/// destructuring; this may or may not involve the actual discriminant.
711711
///
712712
/// This should ideally be less tightly tied to `_match`.
713-
pub fn trans_switch<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
713+
pub fn trans_switch<'fcx, 'blk, 'tcx>(bcx: Block<'fcx, 'blk, 'tcx>,
714714
r: &Repr<'tcx>, scrutinee: ValueRef)
715715
-> (_match::BranchKind, Option<ValueRef>) {
716716
match *r {
@@ -727,7 +727,7 @@ pub fn trans_switch<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
727727

728728

729729
/// Obtain the actual discriminant of a value.
730-
pub fn trans_get_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
730+
pub fn trans_get_discr<'fcx, 'blk, 'tcx>(bcx: Block<'fcx, 'blk, 'tcx>, r: &Repr<'tcx>,
731731
scrutinee: ValueRef, cast_to: Option<Type>)
732732
-> ValueRef {
733733
let signed;
@@ -798,8 +798,8 @@ fn load_discr(bcx: Block, ity: IntType, ptr: ValueRef, min: Disr, max: Disr)
798798
/// discriminant-like value returned by `trans_switch`.
799799
///
800800
/// This should ideally be less tightly tied to `_match`.
801-
pub fn trans_case<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr, discr: Disr)
802-
-> _match::OptResult<'blk, 'tcx> {
801+
pub fn trans_case<'fcx, 'blk, 'tcx>(bcx: Block<'fcx, 'blk, 'tcx>, r: &Repr, discr: Disr)
802+
-> _match::OptResult<'fcx, 'blk, 'tcx> {
803803
match *r {
804804
CEnum(ity, _, _) => {
805805
_match::SingleResult(Result::new(bcx, C_integral(ll_inttype(bcx.ccx(), ity),
@@ -822,7 +822,7 @@ pub fn trans_case<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr, discr: Disr)
822822

823823
/// Set the discriminant for a new value of the given case of the given
824824
/// representation.
825-
pub fn trans_set_discr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
825+
pub fn trans_set_discr<'fcx, 'blk, 'tcx>(bcx: Block<'fcx, 'blk, 'tcx>, r: &Repr<'tcx>,
826826
val: ValueRef, discr: Disr) {
827827
match *r {
828828
CEnum(ity, min, max) => {
@@ -892,7 +892,7 @@ pub fn num_args(r: &Repr, discr: Disr) -> uint {
892892
}
893893

894894
/// Access a field, at a point when the value's case is known.
895-
pub fn trans_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
895+
pub fn trans_field_ptr<'fcx, 'blk, 'tcx>(bcx: Block<'fcx, 'blk, 'tcx>, r: &Repr<'tcx>,
896896
val: ValueRef, discr: Disr, ix: uint) -> ValueRef {
897897
// Note: if this ever needs to generate conditionals (e.g., if we
898898
// decide to do some kind of cdr-coding-like non-unique repr
@@ -931,7 +931,7 @@ pub fn trans_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>,
931931
}
932932
}
933933

934-
pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, val: ValueRef,
934+
pub fn struct_field_ptr<'fcx, 'blk, 'tcx>(bcx: Block<'fcx, 'blk, 'tcx>, st: &Struct<'tcx>, val: ValueRef,
935935
ix: uint, needs_cast: bool) -> ValueRef {
936936
let val = if needs_cast {
937937
let ccx = bcx.ccx();
@@ -945,12 +945,12 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v
945945
GEPi(bcx, val, &[0, ix])
946946
}
947947

948-
pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
948+
pub fn fold_variants<'fcx, 'blk, 'tcx, F>(bcx: Block<'fcx, 'blk, 'tcx>,
949949
r: &Repr<'tcx>,
950950
value: ValueRef,
951951
mut f: F)
952-
-> Block<'blk, 'tcx> where
953-
F: FnMut(Block<'blk, 'tcx>, &Struct<'tcx>, ValueRef) -> Block<'blk, 'tcx>,
952+
-> Block<'fcx, 'blk, 'tcx> where
953+
F: FnMut(Block<'fcx, 'blk, 'tcx>, &Struct<'tcx>, ValueRef) -> Block<'fcx, 'blk, 'tcx>,
954954
{
955955
let fcx = bcx.fcx;
956956
match *r {
@@ -963,23 +963,23 @@ pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
963963
Unreachable(unr_cx);
964964

965965
let discr_val = trans_get_discr(bcx, r, value, None);
966-
let llswitch = Switch(bcx, discr_val, unr_cx.llbb, cases.len());
966+
let llswitch = Switch(bcx, discr_val, unr_cx.data.llbb, cases.len());
967967
let bcx_next = fcx.new_temp_block("enum-variant-iter-next");
968968

969969
for (discr, case) in cases.iter().enumerate() {
970970
let mut variant_cx = fcx.new_temp_block(
971971
&format!("enum-variant-iter-{}", &discr.to_string())[]
972972
);
973973
let rhs_val = C_integral(ll_inttype(ccx, ity), discr as u64, true);
974-
AddCase(llswitch, rhs_val, variant_cx.llbb);
974+
AddCase(llswitch, rhs_val, variant_cx.data.llbb);
975975

976976
let fields = case.fields.iter().map(|&ty|
977977
type_of::type_of(bcx.ccx(), ty)).collect::<Vec<_>>();
978978
let real_ty = Type::struct_(ccx, &fields[], case.packed);
979979
let variant_value = PointerCast(variant_cx, value, real_ty.ptr_to());
980980

981981
variant_cx = f(variant_cx, case, variant_value);
982-
Br(variant_cx, bcx_next.llbb);
982+
Br(variant_cx, bcx_next.data.llbb);
983983
}
984984

985985
bcx_next
@@ -989,9 +989,8 @@ pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
989989
}
990990

991991
/// Access the struct drop flag, if present.
992-
pub fn trans_drop_flag_ptr<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>, val: ValueRef)
993-
-> datum::DatumBlock<'blk, 'tcx, datum::Expr>
994-
{
992+
pub fn trans_drop_flag_ptr<'fcx, 'blk, 'tcx>(mut bcx: Block<'fcx, 'blk, 'tcx>, r: &Repr<'tcx>, val: ValueRef)
993+
-> datum::DatumBlock<'fcx, 'blk, 'tcx, datum::Expr> {
995994
let tcx = bcx.tcx();
996995
let ptr_ty = ty::mk_imm_ptr(bcx.tcx(), tcx.types.bool);
997996
match *r {

src/librustc_trans/trans/asm.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ use std::ffi::CString;
2525
use libc::{c_uint, c_char};
2626

2727
// Take an inline assembly expression and splat it out via LLVM
28-
pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
29-
-> Block<'blk, 'tcx> {
28+
pub fn trans_inline_asm<'fcx, 'blk, 'tcx>(bcx: Block<'fcx, 'blk, 'tcx>, ia: &ast::InlineAsm)
29+
-> Block<'fcx, 'blk, 'tcx> {
3030
let fcx = bcx.fcx;
3131
let mut bcx = bcx;
3232
let mut constraints = Vec::new();

0 commit comments

Comments
 (0)