diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index d9ba2c68f43..c6f375bbc1b 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -306,12 +306,13 @@ fn opt_eq(tcx: ty::ctxt, a: &Opt, b: &Opt) -> bool { } } -pub enum opt_result { - single_result(Result), - lower_bound(Result), - range_result(Result, Result), +pub enum opt_result<'a> { + single_result(Result<'a>), + lower_bound(Result<'a>), + range_result(Result<'a>, Result<'a>), } -fn trans_opt(bcx: @Block, o: &Opt) -> opt_result { + +fn trans_opt<'a>(bcx: &'a Block<'a>, o: &Opt) -> opt_result<'a> { let _icx = push_ctxt("match::trans_opt"); let ccx = bcx.ccx(); let bcx = bcx; @@ -346,8 +347,7 @@ fn trans_opt(bcx: @Block, o: &Opt) -> opt_result { } } -fn variant_opt(bcx: @Block, pat_id: ast::NodeId) - -> Opt { +fn variant_opt(bcx: &Block, pat_id: ast::NodeId) -> Opt { let ccx = bcx.ccx(); let def_map = ccx.tcx.def_map.borrow(); match def_map.get().get_copy(&pat_id) { @@ -397,8 +397,8 @@ struct BindingInfo { type BindingsMap = HashMap; #[deriving(Clone)] -struct ArmData<'a> { - bodycx: @Block, +struct ArmData<'a,'b> { + bodycx: &'b Block<'b>, arm: &'a ast::Arm, bindings_map: @BindingsMap } @@ -410,13 +410,13 @@ struct ArmData<'a> { * these pointers are stored in llmatch variables just before executing `data` arm. */ #[deriving(Clone)] -struct Match<'a> { +struct Match<'a,'b> { pats: ~[@ast::Pat], - data: ArmData<'a>, + data: ArmData<'a,'b>, bound_ptrs: ~[(Ident, ValueRef)] } -impl<'a> Repr for Match<'a> { +impl<'a,'b> Repr for Match<'a,'b> { fn repr(&self, tcx: ty::ctxt) -> ~str { if tcx.sess.verbose() { // for many programs, this just take too long to serialize @@ -437,11 +437,12 @@ fn has_nested_bindings(m: &[Match], col: uint) -> bool { return false; } -fn expand_nested_bindings<'r>(bcx: @Block, - m: &[Match<'r>], - col: uint, - val: ValueRef) - -> ~[Match<'r>] { +fn expand_nested_bindings<'r,'b>( + bcx: &'b Block<'b>, + m: &[Match<'r,'b>], + col: uint, + val: ValueRef) + -> ~[Match<'r,'b>] { debug!("expand_nested_bindings(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -471,7 +472,7 @@ fn expand_nested_bindings<'r>(bcx: @Block, }) } -fn assert_is_binding_or_wild(bcx: @Block, p: @ast::Pat) { +fn assert_is_binding_or_wild(bcx: &Block, p: @ast::Pat) { if !pat_is_binding_or_wild(bcx.tcx().def_map, p) { bcx.sess().span_bug( p.span, @@ -482,13 +483,14 @@ fn assert_is_binding_or_wild(bcx: @Block, p: @ast::Pat) { type enter_pat<'a> = 'a |@ast::Pat| -> Option<~[@ast::Pat]>; -fn enter_match<'r>(bcx: @Block, - dm: DefMap, - m: &[Match<'r>], - col: uint, - val: ValueRef, - e: enter_pat) - -> ~[Match<'r>] { +fn enter_match<'r,'b>( + bcx: &'b Block<'b>, + dm: DefMap, + m: &[Match<'r,'b>], + col: uint, + val: ValueRef, + e: enter_pat) + -> ~[Match<'r,'b>] { debug!("enter_match(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -531,13 +533,14 @@ fn enter_match<'r>(bcx: @Block, return result; } -fn enter_default<'r>(bcx: @Block, - dm: DefMap, - m: &[Match<'r>], - col: uint, - val: ValueRef, - chk: FailureHandler) - -> ~[Match<'r>] { +fn enter_default<'r,'b>( + bcx: &'b Block<'b>, + dm: DefMap, + m: &[Match<'r,'b>], + col: uint, + val: ValueRef, + chk: &FailureHandler) + -> ~[Match<'r,'b>] { debug!("enter_default(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -601,13 +604,14 @@ fn enter_default<'r>(bcx: @Block, // so all patterns must either be records (resp. tuples) or // wildcards -fn enter_opt<'r>(bcx: @Block, - m: &[Match<'r>], - opt: &Opt, - col: uint, - variant_size: uint, - val: ValueRef) - -> ~[Match<'r>] { +fn enter_opt<'r,'b>( + bcx: &'b Block<'b>, + m: &[Match<'r,'b>], + opt: &Opt, + col: uint, + variant_size: uint, + val: ValueRef) + -> ~[Match<'r,'b>] { debug!("enter_opt(bcx={}, m={}, opt={:?}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -744,13 +748,14 @@ fn enter_opt<'r>(bcx: @Block, }) } -fn enter_rec_or_struct<'r>(bcx: @Block, - dm: DefMap, - m: &[Match<'r>], - col: uint, - fields: &[ast::Ident], - val: ValueRef) - -> ~[Match<'r>] { +fn enter_rec_or_struct<'r,'b>( + bcx: &'b Block<'b>, + dm: DefMap, + m: &[Match<'r,'b>], + col: uint, + fields: &[ast::Ident], + val: ValueRef) + -> ~[Match<'r,'b>] { debug!("enter_rec_or_struct(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -779,13 +784,14 @@ fn enter_rec_or_struct<'r>(bcx: @Block, }) } -fn enter_tup<'r>(bcx: @Block, - dm: DefMap, - m: &[Match<'r>], - col: uint, - val: ValueRef, - n_elts: uint) - -> ~[Match<'r>] { +fn enter_tup<'r,'b>( + bcx: &'b Block<'b>, + dm: DefMap, + m: &[Match<'r,'b>], + col: uint, + val: ValueRef, + n_elts: uint) + -> ~[Match<'r,'b>] { debug!("enter_tup(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -805,13 +811,14 @@ fn enter_tup<'r>(bcx: @Block, }) } -fn enter_tuple_struct<'r>(bcx: @Block, - dm: DefMap, - m: &[Match<'r>], - col: uint, - val: ValueRef, - n_elts: uint) - -> ~[Match<'r>] { +fn enter_tuple_struct<'r,'b>( + bcx: &'b Block<'b>, + dm: DefMap, + m: &[Match<'r,'b>], + col: uint, + val: ValueRef, + n_elts: uint) + -> ~[Match<'r,'b>] { debug!("enter_tuple_struct(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -831,12 +838,13 @@ fn enter_tuple_struct<'r>(bcx: @Block, }) } -fn enter_box<'r>(bcx: @Block, - dm: DefMap, - m: &[Match<'r>], - col: uint, - val: ValueRef) - -> ~[Match<'r>] { +fn enter_box<'r,'b>( + bcx: &'b Block<'b>, + dm: DefMap, + m: &[Match<'r,'b>], + col: uint, + val: ValueRef) + -> ~[Match<'r,'b>] { debug!("enter_box(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -858,12 +866,13 @@ fn enter_box<'r>(bcx: @Block, }) } -fn enter_uniq<'r>(bcx: @Block, - dm: DefMap, - m: &[Match<'r>], - col: uint, - val: ValueRef) - -> ~[Match<'r>] { +fn enter_uniq<'r,'b>( + bcx: &'b Block<'b>, + dm: DefMap, + m: &[Match<'r,'b>], + col: uint, + val: ValueRef) + -> ~[Match<'r,'b>] { debug!("enter_uniq(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -885,12 +894,14 @@ fn enter_uniq<'r>(bcx: @Block, }) } -fn enter_region<'r>(bcx: @Block, - dm: DefMap, - m: &[Match<'r>], - col: uint, - val: ValueRef) - -> ~[Match<'r>] { +fn enter_region<'r, + 'b>( + bcx: &'b Block<'b>, + dm: DefMap, + m: &[Match<'r,'b>], + col: uint, + val: ValueRef) + -> ~[Match<'r,'b>] { debug!("enter_region(bcx={}, m={}, col={}, val={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -915,7 +926,7 @@ fn enter_region<'r>(bcx: @Block, // Returns the options in one column of matches. An option is something that // needs to be conditionally matched at runtime; for example, the discriminant // on a set of enum variants or a literal. -fn get_options(bcx: @Block, m: &[Match], col: uint) -> ~[Opt] { +fn get_options(bcx: &Block, m: &[Match], col: uint) -> ~[Opt] { let ccx = bcx.ccx(); fn add_to_set(tcx: ty::ctxt, set: &mut ~[Opt], val: Opt) { if set.iter().any(|l| opt_eq(tcx, l, &val)) {return;} @@ -1005,16 +1016,17 @@ fn get_options(bcx: @Block, m: &[Match], col: uint) -> ~[Opt] { return found; } -struct ExtractedBlock { +struct ExtractedBlock<'a> { vals: ~[ValueRef], - bcx: @Block + bcx: &'a Block<'a>, } -fn extract_variant_args(bcx: @Block, - repr: &adt::Repr, - disr_val: ty::Disr, - val: ValueRef) - -> ExtractedBlock { +fn extract_variant_args<'a>( + bcx: &'a Block<'a>, + repr: &adt::Repr, + disr_val: ty::Disr, + val: ValueRef) + -> ExtractedBlock<'a> { let _icx = push_ctxt("match::extract_variant_args"); let args = vec::from_fn(adt::num_args(repr, disr_val), |i| { adt::trans_field_ptr(bcx, repr, val, disr_val, i) @@ -1023,7 +1035,8 @@ fn extract_variant_args(bcx: @Block, ExtractedBlock { vals: args, bcx: bcx } } -fn match_datum(bcx: @Block, val: ValueRef, pat_id: ast::NodeId) -> Datum { +fn match_datum<'a>(bcx: &'a Block<'a>, val: ValueRef, pat_id: ast::NodeId) + -> Datum { //! Helper for converting from the ValueRef that we pass around in //! the match code, which is always by ref, into a Datum. Eventually //! we should just pass around a Datum and be done with it. @@ -1033,14 +1046,15 @@ fn match_datum(bcx: @Block, val: ValueRef, pat_id: ast::NodeId) -> Datum { } -fn extract_vec_elems(bcx: @Block, - pat_span: Span, - pat_id: ast::NodeId, - elem_count: uint, - slice: Option, - val: ValueRef, - count: ValueRef) - -> ExtractedBlock { +fn extract_vec_elems<'a>( + bcx: &'a Block<'a>, + pat_span: Span, + pat_id: ast::NodeId, + elem_count: uint, + slice: Option, + val: ValueRef, + count: ValueRef) + -> ExtractedBlock<'a> { let _icx = push_ctxt("match::extract_vec_elems"); let vec_datum = match_datum(bcx, val, pat_id); let (bcx, base, len) = vec_datum.get_vec_base_and_len(bcx, pat_span, pat_id, 0); @@ -1086,10 +1100,11 @@ fn extract_vec_elems(bcx: @Block, /// Function returns None if there is no struct pattern. /// Function doesn't collect fields from struct-like enum variants. /// Function can return empty list if there is only wildcard struct pattern. -fn collect_record_or_struct_fields(bcx: @Block, - m: &[Match], - col: uint) - -> Option<~[ast::Ident]> { +fn collect_record_or_struct_fields<'a>( + bcx: &'a Block<'a>, + m: &[Match], + col: uint) + -> Option<~[ast::Ident]> { let mut fields: ~[ast::Ident] = ~[]; let mut found = false; for br in m.iter() { @@ -1122,10 +1137,7 @@ fn collect_record_or_struct_fields(bcx: @Block, } } -fn pats_require_rooting(bcx: @Block, - m: &[Match], - col: uint) - -> bool { +fn pats_require_rooting(bcx: &Block, m: &[Match], col: uint) -> bool { m.iter().any(|br| { let pat_id = br.pats[col].id; let key = root_map_key {id: pat_id, derefs: 0u }; @@ -1134,11 +1146,12 @@ fn pats_require_rooting(bcx: @Block, }) } -fn root_pats_as_necessary(mut bcx: @Block, - m: &[Match], - col: uint, - val: ValueRef) - -> @Block { +fn root_pats_as_necessary<'r,'b>( + mut bcx: &'b Block<'b>, + m: &[Match<'r,'b>], + col: uint, + val: ValueRef) + -> &'b Block<'b> { for br in m.iter() { let pat_id = br.pats[col].id; if pat_id != 0 { @@ -1181,7 +1194,7 @@ fn any_tup_pat(m: &[Match], col: uint) -> bool { any_pat!(m, ast::PatTup(_)) } -fn any_tuple_struct_pat(bcx: @Block, m: &[Match], col: uint) -> bool { +fn any_tuple_struct_pat(bcx: &Block, m: &[Match], col: uint) -> bool { m.iter().any(|br| { let pat = br.pats[col]; match pat.node { @@ -1198,18 +1211,14 @@ fn any_tuple_struct_pat(bcx: @Block, m: &[Match], col: uint) -> bool { }) } -trait CustomFailureHandler { - fn handle_fail(&self) -> BasicBlockRef; -} - -struct DynamicFailureHandler { - bcx: @Block, +struct DynamicFailureHandler<'a> { + bcx: &'a Block<'a>, sp: Span, msg: @str, finished: @Cell>, } -impl CustomFailureHandler for DynamicFailureHandler { +impl<'a> DynamicFailureHandler<'a> { fn handle_fail(&self) -> BasicBlockRef { match self.finished.get() { Some(bb) => return bb, @@ -1224,13 +1233,13 @@ impl CustomFailureHandler for DynamicFailureHandler { } /// What to do when the pattern match fails. -enum FailureHandler { +enum FailureHandler<'a> { Infallible, JumpToBasicBlock(BasicBlockRef), - CustomFailureHandlerClass(@CustomFailureHandler), + DynamicFailureHandlerClass(~DynamicFailureHandler<'a>), } -impl FailureHandler { +impl<'a> FailureHandler<'a> { fn is_infallible(&self) -> bool { match *self { Infallible => true, @@ -1248,8 +1257,8 @@ impl FailureHandler { fail!("attempted to fail in infallible failure handler!") } JumpToBasicBlock(basic_block) => basic_block, - CustomFailureHandlerClass(custom_failure_handler) => { - custom_failure_handler.handle_fail() + DynamicFailureHandlerClass(ref dynamic_failure_handler) => { + dynamic_failure_handler.handle_fail() } } } @@ -1290,11 +1299,12 @@ pub enum branch_kind { no_branch, single, switch, compare, compare_vec_len, } // Compiles a comparison between two things. // // NB: This must produce an i1, not a Rust bool (i8). -fn compare_values(cx: @Block, - lhs: ValueRef, - rhs: ValueRef, - rhs_t: ty::t) - -> Result { +fn compare_values<'a>( + cx: &'a Block<'a>, + lhs: ValueRef, + rhs: ValueRef, + rhs_t: ty::t) + -> Result<'a> { let _icx = push_ctxt("compare_values"); if ty::type_is_scalar(rhs_t) { let rs = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::BiEq); @@ -1333,11 +1343,11 @@ fn compare_values(cx: @Block, } } -fn store_non_ref_bindings(bcx: @Block, +fn store_non_ref_bindings<'a>( + bcx: &'a Block<'a>, bindings_map: &BindingsMap, mut opt_temp_cleanups: Option<&mut ~[ValueRef]>) - -> @Block -{ + -> &'a Block<'a> { /*! * * For each copy/move binding, copy the value from the value @@ -1367,9 +1377,11 @@ fn store_non_ref_bindings(bcx: @Block, return bcx; } -fn insert_lllocals(bcx: @Block, +fn insert_lllocals<'a>( + bcx: &'a Block<'a>, bindings_map: &BindingsMap, - add_cleans: bool) -> @Block { + add_cleans: bool) + -> &'a Block<'a> { /*! * For each binding in `data.bindings_map`, adds an appropriate entry into * the `fcx.lllocals` map. If add_cleans is true, then adds cleanups for @@ -1413,13 +1425,15 @@ fn insert_lllocals(bcx: @Block, return bcx; } -fn compile_guard(bcx: @Block, - guard_expr: &ast::Expr, - data: &ArmData, - m: &[Match], - vals: &[ValueRef], - chk: FailureHandler) - -> @Block { +fn compile_guard<'r, + 'b>( + bcx: &'b Block<'b>, + guard_expr: &ast::Expr, + data: &ArmData, + m: &[Match<'r,'b>], + vals: &[ValueRef], + chk: &FailureHandler) + -> &'b Block<'b> { debug!("compile_guard(bcx={}, guard_expr={}, m={}, vals={})", bcx.to_str(), bcx.expr_to_str(guard_expr), @@ -1454,7 +1468,8 @@ fn compile_guard(bcx: @Block, bcx }); - fn drop_bindings(bcx: @Block, data: &ArmData) -> @Block { + fn drop_bindings<'a>(bcx: &'a Block<'a>, data: &ArmData) + -> &'a Block<'a> { let mut bcx = bcx; for (_, &binding_info) in data.bindings_map.iter() { match binding_info.trmode { @@ -1470,10 +1485,12 @@ fn compile_guard(bcx: @Block, } } -fn compile_submatch(bcx: @Block, - m: &[Match], +fn compile_submatch<'r, + 'b>( + bcx: &'b Block<'b>, + m: &[Match<'r,'b>], vals: &[ValueRef], - chk: FailureHandler) { + chk: &FailureHandler) { debug!("compile_submatch(bcx={}, m={}, vals={})", bcx.to_str(), m.repr(bcx.tcx()), @@ -1522,10 +1539,12 @@ fn compile_submatch(bcx: @Block, } } -fn compile_submatch_continue(mut bcx: @Block, - m: &[Match], +fn compile_submatch_continue<'r, + 'b>( + mut bcx: &'b Block<'b>, + m: &[Match<'r,'b>], vals: &[ValueRef], - chk: FailureHandler, + chk: &FailureHandler, col: uint, val: ValueRef) { let tcx = bcx.tcx(); @@ -1695,7 +1714,7 @@ fn compile_submatch_continue(mut bcx: @Block, // the failure case so that instead of failing, it proceeds to // try more matching. branch_chk, then, is the proper failure case // for the current conditional branch. - let mut branch_chk = chk; + let mut branch_chk = None; let mut opt_cx = else_cx; if !exhaustive || i+1 < len { opt_cx = sub_block(bcx, "match_case"); @@ -1791,7 +1810,7 @@ fn compile_submatch_continue(mut bcx: @Block, // If none of these subcases match, move on to the // next condition. - branch_chk = JumpToBasicBlock(bcx.llbb); + branch_chk = Some(JumpToBasicBlock(bcx.llbb)); CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb); } _ => () @@ -1825,7 +1844,13 @@ fn compile_submatch_continue(mut bcx: @Block, } let opt_ms = enter_opt(opt_cx, m, opt, col, size, val); let opt_vals = vec::append(unpacked, vals_left); - compile_submatch(opt_cx, opt_ms, opt_vals, branch_chk); + + match branch_chk { + None => compile_submatch(opt_cx, opt_ms, opt_vals, chk), + Some(branch_chk) => { + compile_submatch(opt_cx, opt_ms, opt_vals, &branch_chk) + } + } } // Compile the fall-through case, if any @@ -1839,18 +1864,20 @@ fn compile_submatch_continue(mut bcx: @Block, } } -pub fn trans_match(bcx: @Block, +pub fn trans_match<'a>( + bcx: &'a Block<'a>, match_expr: &ast::Expr, discr_expr: &ast::Expr, arms: &[ast::Arm], - dest: Dest) -> @Block { + dest: Dest) + -> &'a Block<'a> { let _icx = push_ctxt("match::trans_match"); with_scope(bcx, match_expr.info(), "match", |bcx| { trans_match_inner(bcx, discr_expr, arms, dest) }) } -fn create_bindings_map(bcx: @Block, pat: @ast::Pat) -> BindingsMap { +fn create_bindings_map(bcx: &Block, pat: @ast::Pat) -> BindingsMap { // Create the bindings map, which is a mapping from each binding name // to an alloca() that will be the value for that local variable. // Note that we use the names because each binding will have many ids @@ -1890,10 +1917,12 @@ fn create_bindings_map(bcx: @Block, pat: @ast::Pat) -> BindingsMap { return bindings_map; } -fn trans_match_inner(scope_cx: @Block, - discr_expr: &ast::Expr, - arms: &[ast::Arm], - dest: Dest) -> @Block { +fn trans_match_inner<'a>( + scope_cx: &'a Block<'a>, + discr_expr: &ast::Expr, + arms: &[ast::Arm], + dest: Dest) + -> &'a Block<'a> { let _icx = push_ctxt("match::trans_match_inner"); let mut bcx = scope_cx; let tcx = bcx.tcx(); @@ -1930,19 +1959,19 @@ fn trans_match_inner(scope_cx: @Block, if ty::type_is_empty(tcx, t) { // Special case for empty types let fail_cx = @Cell::new(None); - let fail_handler = @DynamicFailureHandler { + let fail_handler = ~DynamicFailureHandler { bcx: scope_cx, sp: discr_expr.span, msg: @"scrutinizing value that can't exist", finished: fail_cx, - } as @CustomFailureHandler; - CustomFailureHandlerClass(fail_handler) + }; + DynamicFailureHandlerClass(fail_handler) } else { Infallible } }; let lldiscr = discr_datum.to_ref_llval(bcx); - compile_submatch(bcx, matches, [lldiscr], chk); + compile_submatch(bcx, matches, [lldiscr], &chk); let mut arm_cxs = ~[]; for arm_data in arm_datas.iter() { @@ -1975,10 +2004,11 @@ enum IrrefutablePatternBindingMode { BindArgument } -pub fn store_local(bcx: @Block, +pub fn store_local<'a>( + bcx: &'a Block<'a>, pat: @ast::Pat, opt_init_expr: Option<@ast::Expr>) - -> @Block { + -> &'a Block<'a> { /*! * Generates code for a local variable declaration like * `let ;` or `let = `. @@ -2029,7 +2059,8 @@ pub fn store_local(bcx: @Block, } }; - fn create_dummy_locals(mut bcx: @Block, pat: @ast::Pat) -> @Block { + fn create_dummy_locals<'a>(mut bcx: &'a Block<'a>, pat: @ast::Pat) + -> &'a Block<'a> { // create dummy memory for the variables if we have no // value to store into them immediately let tcx = bcx.tcx(); @@ -2042,10 +2073,8 @@ pub fn store_local(bcx: @Block, } } -pub fn store_arg(mut bcx: @Block, - pat: @ast::Pat, - llval: ValueRef) - -> @Block { +pub fn store_arg<'a>(mut bcx: &'a Block<'a>, pat: @ast::Pat, llval: ValueRef) + -> &'a Block<'a> { /*! * Generates code for argument patterns like `fn foo(: T)`. * Creates entries in the `llargs` map for each of the bindings @@ -2090,12 +2119,16 @@ pub fn store_arg(mut bcx: @Block, return bcx; } -fn mk_binding_alloca(mut bcx: @Block, +fn mk_binding_alloca<'a>( + mut bcx: &'a Block<'a>, p_id: ast::NodeId, path: &ast::Path, binding_mode: IrrefutablePatternBindingMode, - populate: |@Block, ty::t, ValueRef| -> @Block) - -> @Block { + populate: |&'a Block<'a>, + ty::t, + ValueRef| + -> &'a Block<'a>) + -> &'a Block<'a> { let var_ty = node_id_type(bcx, p_id); let ident = ast_util::path_to_ident(path); let llval = alloc_ty(bcx, var_ty, bcx.ident(ident)); @@ -2109,11 +2142,12 @@ fn mk_binding_alloca(mut bcx: @Block, return bcx; } -fn bind_irrefutable_pat(bcx: @Block, +fn bind_irrefutable_pat<'a>( + bcx: &'a Block<'a>, pat: @ast::Pat, val: ValueRef, binding_mode: IrrefutablePatternBindingMode) - -> @Block { + -> &'a Block<'a> { /*! * A simple version of the pattern matching code that only handles * irrefutable patterns. This is used in let/argument patterns, diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 5d70a3ad266..296a99423c0 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -111,7 +111,7 @@ pub struct Struct { * these, for places in trans where the `ty::t` isn't directly * available. */ -pub fn represent_node(bcx: @Block, node: ast::NodeId) -> @Repr { +pub fn represent_node(bcx: &Block, node: ast::NodeId) -> @Repr { represent_type(bcx.ccx(), node_id_type(bcx, node)) } @@ -463,7 +463,7 @@ fn struct_llfields(cx: &CrateContext, st: &Struct, sizing: bool) -> ~[Type] { * * This should ideally be less tightly tied to `_match`. */ -pub fn trans_switch(bcx: @Block, r: &Repr, scrutinee: ValueRef) +pub fn trans_switch(bcx: &Block, r: &Repr, scrutinee: ValueRef) -> (_match::branch_kind, Option) { match *r { CEnum(..) | General(..) => { @@ -481,7 +481,7 @@ pub fn trans_switch(bcx: @Block, r: &Repr, scrutinee: ValueRef) /// Obtain the actual discriminant of a value. -pub fn trans_get_discr(bcx: @Block, r: &Repr, scrutinee: ValueRef, cast_to: Option) +pub fn trans_get_discr(bcx: &Block, r: &Repr, scrutinee: ValueRef, cast_to: Option) -> ValueRef { let signed; let val; @@ -510,7 +510,7 @@ pub fn trans_get_discr(bcx: @Block, r: &Repr, scrutinee: ValueRef, cast_to: Opti } } -fn nullable_bitdiscr(bcx: @Block, nonnull: &Struct, nndiscr: Disr, ptrfield: uint, +fn nullable_bitdiscr(bcx: &Block, nonnull: &Struct, nndiscr: Disr, ptrfield: uint, scrutinee: ValueRef) -> ValueRef { let cmp = if nndiscr == 0 { IntEQ } else { IntNE }; let llptr = Load(bcx, GEPi(bcx, scrutinee, [0, ptrfield])); @@ -519,7 +519,7 @@ fn nullable_bitdiscr(bcx: @Block, nonnull: &Struct, nndiscr: Disr, ptrfield: uin } /// Helper for cases where the discriminant is simply loaded. -fn load_discr(bcx: @Block, ity: IntType, ptr: ValueRef, min: Disr, max: Disr) +fn load_discr(bcx: &Block, ity: IntType, ptr: ValueRef, min: Disr, max: Disr) -> ValueRef { let llty = ll_inttype(bcx.ccx(), ity); assert_eq!(val_ty(ptr), llty.ptr_to()); @@ -547,7 +547,8 @@ fn load_discr(bcx: @Block, ity: IntType, ptr: ValueRef, min: Disr, max: Disr) * * This should ideally be less tightly tied to `_match`. */ -pub fn trans_case(bcx: @Block, r: &Repr, discr: Disr) -> _match::opt_result { +pub fn trans_case<'a>(bcx: &'a Block<'a>, r: &Repr, discr: Disr) + -> _match::opt_result<'a> { match *r { CEnum(ity, _, _) => { _match::single_result(rslt(bcx, C_integral(ll_inttype(bcx.ccx(), ity), @@ -572,7 +573,7 @@ pub fn trans_case(bcx: @Block, r: &Repr, discr: Disr) -> _match::opt_result { * representation. The fields, if any, should then be initialized via * `trans_field_ptr`. */ -pub fn trans_start_init(bcx: @Block, r: &Repr, val: ValueRef, discr: Disr) { +pub fn trans_start_init(bcx: &Block, r: &Repr, val: ValueRef, discr: Disr) { match *r { CEnum(ity, min, max) => { assert_discr_in_range(ity, min, max, discr); @@ -628,7 +629,7 @@ pub fn num_args(r: &Repr, discr: Disr) -> uint { } /// Access a field, at a point when the value's case is known. -pub fn trans_field_ptr(bcx: @Block, r: &Repr, val: ValueRef, discr: Disr, +pub fn trans_field_ptr(bcx: &Block, r: &Repr, val: ValueRef, discr: Disr, ix: uint) -> ValueRef { // Note: if this ever needs to generate conditionals (e.g., if we // decide to do some kind of cdr-coding-like non-unique repr @@ -661,7 +662,7 @@ pub fn trans_field_ptr(bcx: @Block, r: &Repr, val: ValueRef, discr: Disr, } } -fn struct_field_ptr(bcx: @Block, st: &Struct, val: ValueRef, ix: uint, +fn struct_field_ptr(bcx: &Block, st: &Struct, val: ValueRef, ix: uint, needs_cast: bool) -> ValueRef { let ccx = bcx.ccx(); @@ -677,7 +678,7 @@ fn struct_field_ptr(bcx: @Block, st: &Struct, val: ValueRef, ix: uint, } /// Access the struct drop flag, if present. -pub fn trans_drop_flag_ptr(bcx: @Block, r: &Repr, val: ValueRef) -> ValueRef { +pub fn trans_drop_flag_ptr(bcx: &Block, r: &Repr, val: ValueRef) -> ValueRef { match *r { Univariant(ref st, true) => GEPi(bcx, val, [0, st.fields.len() - 1]), _ => bcx.ccx().sess.bug("tried to get drop flag of non-droppable type") diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index 5dd7c0c3b44..974ef9cf99d 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -27,8 +27,8 @@ use middle::trans::type_::Type; use syntax::ast; // Take an inline assembly expression and splat it out via LLVM -pub fn trans_inline_asm(bcx: @Block, ia: &ast::inline_asm) -> @Block { - +pub fn trans_inline_asm<'a>(bcx: &'a Block<'a>, ia: &ast::inline_asm) + -> &'a Block<'a> { let mut bcx = bcx; let mut constraints = ~[]; let mut cleanups = ~[]; diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 53abbba2e89..9730d664189 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -68,13 +68,14 @@ use util::ppaux::{Repr, ty_to_str}; use util::sha2::Sha256; use middle::trans::type_::Type; +use extra::arena::TypedArena; +use extra::time; use std::c_str::ToCStr; use std::cell::{Cell, RefCell}; use std::hashmap::HashMap; use std::libc::c_uint; use std::vec; use std::local_data; -use extra::time; use syntax::ast::Name; use syntax::ast_map::{path, path_elt_to_str, path_name, path_pretty_name}; use syntax::ast_util::{local_def, is_local}; @@ -307,9 +308,8 @@ pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef, // known. // // The runtime equivalent is box_body() in "rust_internal.h". -pub fn opaque_box_body(bcx: @Block, - body_t: ty::t, - boxptr: ValueRef) -> ValueRef { +pub fn opaque_box_body(bcx: &Block, body_t: ty::t, boxptr: ValueRef) + -> ValueRef { let _icx = push_ctxt("opaque_box_body"); let ccx = bcx.ccx(); let ty = type_of(ccx, body_t); @@ -320,14 +320,16 @@ pub fn opaque_box_body(bcx: @Block, // malloc_raw_dyn: allocates a box to contain a given type, but with a // potentially dynamic size. -pub fn malloc_raw_dyn(bcx: @Block, +pub fn malloc_raw_dyn<'a>( + bcx: &'a Block, t: ty::t, heap: heap, - size: ValueRef) -> Result { + size: ValueRef) + -> Result<'a> { let _icx = push_ctxt("malloc_raw"); let ccx = bcx.ccx(); - fn require_alloc_fn(bcx: @Block, t: ty::t, it: LangItem) -> ast::DefId { + fn require_alloc_fn(bcx: &Block, t: ty::t, it: LangItem) -> ast::DefId { let li = &bcx.tcx().lang_items; match li.require(it) { Ok(id) => id, @@ -387,22 +389,27 @@ pub fn malloc_raw_dyn(bcx: @Block, // malloc_raw: expects an unboxed type and returns a pointer to // enough space for a box of that type. This includes a rust_opaque_box // header. -pub fn malloc_raw(bcx: @Block, t: ty::t, heap: heap) -> Result { +pub fn malloc_raw<'a>(bcx: &'a Block<'a>, t: ty::t, heap: heap) + -> Result<'a> { let ty = type_of(bcx.ccx(), t); let size = llsize_of(bcx.ccx(), ty); malloc_raw_dyn(bcx, t, heap, size) } -pub struct MallocResult { - bcx: @Block, +pub struct MallocResult<'a> { + bcx: &'a Block<'a>, smart_ptr: ValueRef, body: ValueRef } // malloc_general_dyn: usefully wraps malloc_raw_dyn; allocates a smart // pointer, and pulls out the body -pub fn malloc_general_dyn(bcx: @Block, t: ty::t, heap: heap, size: ValueRef) - -> MallocResult { +pub fn malloc_general_dyn<'a>( + bcx: &'a Block<'a>, + t: ty::t, + heap: heap, + size: ValueRef) + -> MallocResult<'a> { assert!(heap != heap_exchange); let _icx = push_ctxt("malloc_general"); let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, t, heap, size); @@ -415,13 +422,14 @@ pub fn malloc_general_dyn(bcx: @Block, t: ty::t, heap: heap, size: ValueRef) } } -pub fn malloc_general(bcx: @Block, t: ty::t, heap: heap) -> MallocResult { +pub fn malloc_general<'a>(bcx: &'a Block, t: ty::t, heap: heap) + -> MallocResult<'a> { let ty = type_of(bcx.ccx(), t); assert!(heap != heap_exchange); malloc_general_dyn(bcx, t, heap, llsize_of(bcx.ccx(), ty)) } -pub fn heap_for_unique(bcx: @Block, t: ty::t) -> heap { +pub fn heap_for_unique(bcx: &Block, t: ty::t) -> heap { if ty::type_contents(bcx.tcx(), t).owns_managed() { heap_managed_unique } else { @@ -429,7 +437,7 @@ pub fn heap_for_unique(bcx: @Block, t: ty::t) -> heap { } } -pub fn maybe_set_managed_unique_rc(bcx: @Block, bx: ValueRef, heap: heap) { +pub fn maybe_set_managed_unique_rc(bcx: &Block, bx: ValueRef, heap: heap) { assert!(heap != heap_exchange); if heap == heap_managed_unique { // In cases where we are looking at a unique-typed allocation in the @@ -597,12 +605,13 @@ pub fn maybe_name_value(cx: &CrateContext, v: ValueRef, s: &str) { pub enum scalar_type { nil_type, signed_int, unsigned_int, floating_point, } // NB: This produces an i1, not a Rust bool (i8). -pub fn compare_scalar_types(cx: @Block, +pub fn compare_scalar_types<'a>( + cx: &'a Block<'a>, lhs: ValueRef, rhs: ValueRef, t: ty::t, op: ast::BinOp) - -> Result { + -> Result<'a> { let f = |a| compare_scalar_values(cx, lhs, rhs, a, op); match ty::get(t).sty { @@ -629,14 +638,15 @@ pub fn compare_scalar_types(cx: @Block, // A helper function to do the actual comparison of scalar values. -pub fn compare_scalar_values(cx: @Block, +pub fn compare_scalar_values<'a>( + cx: &'a Block<'a>, lhs: ValueRef, rhs: ValueRef, nt: scalar_type, op: ast::BinOp) - -> ValueRef { + -> ValueRef { let _icx = push_ctxt("compare_scalar_values"); - fn die(cx: @Block) -> ! { + fn die(cx: &Block) -> ! { cx.tcx().sess.bug("compare_scalar_values: must be a\ comparison operator"); } @@ -690,25 +700,41 @@ pub fn compare_scalar_values(cx: @Block, } } -pub type val_and_ty_fn<'a> = 'a |@Block, ValueRef, ty::t| - -> @Block; +pub type val_and_ty_fn<'r,'b> = + 'r |&'b Block<'b>, ValueRef, ty::t| -> &'b Block<'b>; -pub fn load_inbounds(cx: @Block, p: ValueRef, idxs: &[uint]) -> ValueRef { +pub fn load_inbounds<'a>(cx: &'a Block<'a>, p: ValueRef, idxs: &[uint]) + -> ValueRef { return Load(cx, GEPi(cx, p, idxs)); } -pub fn store_inbounds(cx: @Block, v: ValueRef, p: ValueRef, idxs: &[uint]) { +pub fn store_inbounds<'a>( + cx: &'a Block<'a>, + v: ValueRef, + p: ValueRef, + idxs: &[uint]) { Store(cx, v, GEPi(cx, p, idxs)); } // Iterates through the elements of a structural type. -pub fn iter_structural_ty(cx: @Block, av: ValueRef, t: ty::t, - f: val_and_ty_fn) -> @Block { +pub fn iter_structural_ty<'r, + 'b>( + cx: &'b Block<'b>, + av: ValueRef, + t: ty::t, + f: val_and_ty_fn<'r,'b>) + -> &'b Block<'b> { let _icx = push_ctxt("iter_structural_ty"); - fn iter_variant(cx: @Block, repr: &adt::Repr, av: ValueRef, + fn iter_variant<'r, + 'b>( + cx: &'b Block<'b>, + repr: &adt::Repr, + av: ValueRef, variant: @ty::VariantInfo, - tps: &[ty::t], f: val_and_ty_fn) -> @Block { + tps: &[ty::t], + f: val_and_ty_fn<'r,'b>) + -> &'b Block<'b> { let _icx = push_ctxt("iter_variant"); let tcx = cx.tcx(); let mut cx = cx; @@ -794,8 +820,12 @@ pub fn iter_structural_ty(cx: @Block, av: ValueRef, t: ty::t, return cx; } -pub fn cast_shift_expr_rhs(cx: @Block, op: ast::BinOp, - lhs: ValueRef, rhs: ValueRef) -> ValueRef { +pub fn cast_shift_expr_rhs<'a>( + cx: &'a Block<'a>, + op: ast::BinOp, + lhs: ValueRef, + rhs: ValueRef) + -> ValueRef { cast_shift_rhs(op, lhs, rhs, |a,b| Trunc(cx, a, b), |a,b| ZExt(cx, a, b)) @@ -836,8 +866,13 @@ pub fn cast_shift_rhs(op: ast::BinOp, } } -pub fn fail_if_zero(cx: @Block, span: Span, divrem: ast::BinOp, - rhs: ValueRef, rhs_t: ty::t) -> @Block { +pub fn fail_if_zero<'a>( + cx: &'a Block<'a>, + span: Span, + divrem: ast::BinOp, + rhs: ValueRef, + rhs_t: ty::t) + -> &'a Block<'a> { let text = if divrem == ast::BiDiv { @"attempted to divide by zero" } else { @@ -895,12 +930,13 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val } } -pub fn invoke(bcx: @Block, +pub fn invoke<'a>( + bcx: &'a Block<'a>, llfn: ValueRef, llargs: ~[ValueRef], attributes: &[(uint, lib::llvm::Attribute)], call_info: Option) - -> (ValueRef, @Block) { + -> (ValueRef, &'a Block<'a>) { let _icx = push_ctxt("invoke_"); if bcx.unreachable.get() { return (C_null(Type::i8()), bcx); @@ -954,7 +990,7 @@ pub fn invoke(bcx: @Block, } } -pub fn need_invoke(bcx: @Block) -> bool { +pub fn need_invoke(bcx: &Block) -> bool { if bcx.ccx().sess.no_landing_pads() { return false; } @@ -997,7 +1033,7 @@ pub fn need_invoke(bcx: @Block) -> bool { } } -pub fn have_cached_lpad(bcx: @Block) -> bool { +pub fn have_cached_lpad(bcx: &Block) -> bool { let mut res = false; in_lpad_scope_cx(bcx, |inf| { match inf.landing_pad.get() { @@ -1008,7 +1044,7 @@ pub fn have_cached_lpad(bcx: @Block) -> bool { return res; } -pub fn in_lpad_scope_cx(bcx: @Block, f: |si: &ScopeInfo|) { +pub fn in_lpad_scope_cx<'a>(bcx: &'a Block<'a>, f: |si: &'a ScopeInfo<'a>|) { let mut bcx = bcx; let mut cur_scope = bcx.scope.get(); loop { @@ -1028,7 +1064,7 @@ pub fn in_lpad_scope_cx(bcx: @Block, f: |si: &ScopeInfo|) { } } -pub fn get_landing_pad(bcx: @Block) -> BasicBlockRef { +pub fn get_landing_pad<'a>(bcx: &'a Block<'a>) -> BasicBlockRef { let _icx = push_ctxt("get_landing_pad"); let mut cached = None; @@ -1074,7 +1110,8 @@ pub fn get_landing_pad(bcx: @Block) -> BasicBlockRef { return pad_bcx.llbb; } -pub fn find_bcx_for_scope(bcx: @Block, scope_id: ast::NodeId) -> @Block { +pub fn find_bcx_for_scope<'a>(bcx: &'a Block<'a>, scope_id: ast::NodeId) + -> &'a Block<'a> { let mut bcx_sid = bcx; let mut cur_scope = bcx_sid.scope.get(); loop { @@ -1103,7 +1140,7 @@ pub fn find_bcx_for_scope(bcx: @Block, scope_id: ast::NodeId) -> @Block { } -pub fn do_spill(bcx: @Block, v: ValueRef, t: ty::t) -> ValueRef { +pub fn do_spill(bcx: &Block, v: ValueRef, t: ty::t) -> ValueRef { if ty::type_is_bot(t) { return C_null(Type::i8p()); } @@ -1114,31 +1151,32 @@ pub fn do_spill(bcx: @Block, v: ValueRef, t: ty::t) -> ValueRef { // Since this function does *not* root, it is the caller's responsibility to // ensure that the referent is pointed to by a root. -pub fn do_spill_noroot(cx: @Block, v: ValueRef) -> ValueRef { +pub fn do_spill_noroot(cx: &Block, v: ValueRef) -> ValueRef { let llptr = alloca(cx, val_ty(v), ""); Store(cx, v, llptr); return llptr; } -pub fn spill_if_immediate(cx: @Block, v: ValueRef, t: ty::t) -> ValueRef { +pub fn spill_if_immediate(cx: &Block, v: ValueRef, t: ty::t) -> ValueRef { let _icx = push_ctxt("spill_if_immediate"); if type_is_immediate(cx.ccx(), t) { return do_spill(cx, v, t); } return v; } -pub fn load_if_immediate(cx: @Block, v: ValueRef, t: ty::t) -> ValueRef { +pub fn load_if_immediate(cx: &Block, v: ValueRef, t: ty::t) -> ValueRef { let _icx = push_ctxt("load_if_immediate"); if type_is_immediate(cx.ccx(), t) { return Load(cx, v); } return v; } -pub fn ignore_lhs(_bcx: @Block, local: &ast::Local) -> bool { +pub fn ignore_lhs(_bcx: &Block, local: &ast::Local) -> bool { match local.pat.node { ast::PatWild => true, _ => false } } -pub fn init_local(bcx: @Block, local: &ast::Local) -> @Block { +pub fn init_local<'a>(bcx: &'a Block<'a>, local: &ast::Local) + -> &'a Block<'a> { debug!("init_local(bcx={}, local.id={:?})", bcx.to_str(), local.id); @@ -1159,7 +1197,7 @@ pub fn init_local(bcx: @Block, local: &ast::Local) -> @Block { _match::store_local(bcx, local.pat, local.init) } -pub fn trans_stmt(cx: @Block, s: &ast::Stmt) -> @Block { +pub fn trans_stmt<'a>(cx: &'a Block<'a>, s: &ast::Stmt) -> &'a Block<'a> { let _icx = push_ctxt("trans_stmt"); debug!("trans_stmt({})", stmt_to_str(s, cx.tcx().sess.intr())); @@ -1192,22 +1230,19 @@ pub fn trans_stmt(cx: @Block, s: &ast::Stmt) -> @Block { // You probably don't want to use this one. See the // next three functions instead. -pub fn new_block(cx: @FunctionContext, - parent: Option<@Block>, - scope: Option<@ScopeInfo>, +pub fn new_block<'a>( + cx: &'a FunctionContext<'a>, + parent: Option<&'a Block<'a>>, + scope: Option<&'a ScopeInfo<'a>>, is_lpad: bool, name: &str, opt_node_info: Option) - -> @Block { + -> &'a Block<'a> { unsafe { let llbb = name.with_c_str(|buf| { llvm::LLVMAppendBasicBlockInContext(cx.ccx.llcx, cx.llfn, buf) }); - let bcx = @Block::new(llbb, - parent, - is_lpad, - opt_node_info, - cx); + let bcx = Block::new(llbb, parent, is_lpad, opt_node_info, cx); bcx.scope.set(scope); for cx in parent.iter() { if cx.unreachable.get() { @@ -1219,10 +1254,12 @@ pub fn new_block(cx: @FunctionContext, } } -pub fn simple_block_scope(parent: Option<@ScopeInfo>, +pub fn simple_block_scope<'a>( + fcx: &'a FunctionContext<'a>, + parent: Option<&'a ScopeInfo<'a>>, node_info: Option) - -> @ScopeInfo { - @ScopeInfo { + -> &'a ScopeInfo<'a> { + fcx.scope_info_arena.alloc(ScopeInfo { parent: parent, loop_break: None, loop_label: None, @@ -1230,51 +1267,74 @@ pub fn simple_block_scope(parent: Option<@ScopeInfo>, cleanup_paths: RefCell::new(~[]), landing_pad: Cell::new(None), node_info: node_info, - } + }) } // Use this when you're at the top block of a function or the like. -pub fn top_scope_block(fcx: @FunctionContext, opt_node_info: Option) - -> @Block { - return new_block(fcx, None, Some(simple_block_scope(None, opt_node_info)), false, - "function top level", opt_node_info); +pub fn top_scope_block<'a>( + fcx: &'a FunctionContext<'a>, + opt_node_info: Option) + -> &'a Block<'a> { + new_block(fcx, + None, + Some(simple_block_scope(fcx, None, opt_node_info)), + false, + "function top level", + opt_node_info) } -pub fn scope_block(bcx: @Block, +pub fn scope_block<'a>( + bcx: &'a Block<'a>, opt_node_info: Option, - n: &str) -> @Block { - return new_block(bcx.fcx, Some(bcx), Some(simple_block_scope(None, opt_node_info)), bcx.is_lpad, - n, opt_node_info); + n: &str) + -> &'a Block<'a> { + new_block(bcx.fcx, + Some(bcx), + Some(simple_block_scope(bcx.fcx, None, opt_node_info)), + bcx.is_lpad, + n, + opt_node_info) } -pub fn loop_scope_block(bcx: @Block, - loop_break: @Block, +pub fn loop_scope_block<'a>( + bcx: &'a Block<'a>, + loop_break: &'a Block<'a>, loop_label: Option, n: &str, - opt_node_info: Option) -> @Block { - return new_block(bcx.fcx, Some(bcx), Some(@ScopeInfo { - parent: None, - loop_break: Some(loop_break), - loop_label: loop_label, - cleanups: RefCell::new(~[]), - cleanup_paths: RefCell::new(~[]), - landing_pad: Cell::new(None), - node_info: opt_node_info, - }), bcx.is_lpad, n, opt_node_info); + opt_node_info: Option) + -> &'a Block<'a> { + new_block(bcx.fcx, + Some(bcx), + Some(bcx.fcx.scope_info_arena.alloc(ScopeInfo { + parent: None, + loop_break: Some(loop_break), + loop_label: loop_label, + cleanups: RefCell::new(~[]), + cleanup_paths: RefCell::new(~[]), + landing_pad: Cell::new(None), + node_info: opt_node_info, + })), + bcx.is_lpad, + n, + opt_node_info) } // Use this when creating a block for the inside of a landing pad. -pub fn lpad_block(bcx: @Block, n: &str) -> @Block { +pub fn lpad_block<'a>(bcx: &'a Block<'a>, n: &str) -> &'a Block<'a> { new_block(bcx.fcx, Some(bcx), None, true, n, None) } // Use this when you're making a general CFG BB within a scope. -pub fn sub_block(bcx: @Block, n: &str) -> @Block { +pub fn sub_block<'a>(bcx: &'a Block<'a>, n: &str) -> &'a Block<'a> { new_block(bcx.fcx, Some(bcx), None, bcx.is_lpad, n, None) } -pub fn raw_block(fcx: @FunctionContext, is_lpad: bool, llbb: BasicBlockRef) -> @Block { - @Block::new(llbb, None, is_lpad, None, fcx) +pub fn raw_block<'a>( + fcx: &'a FunctionContext<'a>, + is_lpad: bool, + llbb: BasicBlockRef) + -> &'a Block<'a> { + Block::new(llbb, None, is_lpad, None, fcx) } @@ -1285,14 +1345,16 @@ pub fn raw_block(fcx: @FunctionContext, is_lpad: bool, llbb: BasicBlockRef) -> @ // need to make sure those variables go out of scope when the block ends. We // do that by running a 'cleanup' function for each variable. // trans_block_cleanups runs all the cleanup functions for the block. -pub fn trans_block_cleanups(bcx: @Block, cleanups: ~[cleanup]) -> @Block { +pub fn trans_block_cleanups<'a>(bcx: &'a Block<'a>, cleanups: ~[cleanup]) + -> &'a Block<'a> { trans_block_cleanups_(bcx, cleanups, false) } -pub fn trans_block_cleanups_(bcx: @Block, +pub fn trans_block_cleanups_<'a>( + bcx: &'a Block<'a>, cleanups: &[cleanup], - /* cleanup_cx: block, */ - is_lpad: bool) -> @Block { + is_lpad: bool) + -> &'a Block<'a> { let _icx = push_ctxt("trans_block_cleanups"); // NB: Don't short-circuit even if this block is unreachable because // GC-based cleanup needs to the see that the roots are live. @@ -1318,7 +1380,8 @@ pub fn trans_block_cleanups_(bcx: @Block, // In the last argument, Some(block) mean jump to this block, and none means // this is a landing pad and leaving should be accomplished with a resume // instruction. -pub fn cleanup_and_leave(bcx: @Block, +pub fn cleanup_and_leave<'a>( + bcx: &'a Block<'a>, upto: Option, leave: Option) { let _icx = push_ctxt("cleanup_and_leave"); @@ -1398,7 +1461,8 @@ pub fn cleanup_and_leave(bcx: @Block, } } -pub fn cleanup_block(bcx: @Block, upto: Option) -> @Block{ +pub fn cleanup_block<'a>(bcx: &'a Block<'a>, upto: Option) + -> &'a Block<'a> { let _icx = push_ctxt("cleanup_block"); let mut cur = bcx; let mut bcx = bcx; @@ -1431,12 +1495,16 @@ pub fn cleanup_block(bcx: @Block, upto: Option) -> @Block{ bcx } -pub fn cleanup_and_Br(bcx: @Block, upto: @Block, target: BasicBlockRef) { +pub fn cleanup_and_Br<'a>( + bcx: &'a Block<'a>, + upto: &'a Block<'a>, + target: BasicBlockRef) { let _icx = push_ctxt("cleanup_and_Br"); cleanup_and_leave(bcx, Some(upto.llbb), Some(target)); } -pub fn leave_block(bcx: @Block, out_of: @Block) -> @Block { +pub fn leave_block<'a>(bcx: &'a Block<'a>, out_of: &'a Block<'a>) + -> &'a Block<'a> { let _icx = push_ctxt("leave_block"); let next_cx = sub_block(block_parent(out_of), "next"); if bcx.unreachable.get() { @@ -1446,18 +1514,19 @@ pub fn leave_block(bcx: @Block, out_of: @Block) -> @Block { next_cx } -pub fn with_scope(bcx: @Block, +pub fn with_scope<'a>( + bcx: &'a Block<'a>, opt_node_info: Option, name: &str, - f: |@Block| -> @Block) - -> @Block { + f: |&'a Block<'a>| -> &'a Block<'a>) + -> &'a Block<'a> { let _icx = push_ctxt("with_scope"); debug!("with_scope(bcx={}, opt_node_info={:?}, name={})", bcx.to_str(), opt_node_info, name); let _indenter = indenter(); - let scope = simple_block_scope(bcx.scope.get(), opt_node_info); + let scope = simple_block_scope(bcx.fcx, bcx.scope.get(), opt_node_info); bcx.scope.set(Some(scope)); let ret = f(bcx); let ret = trans_block_cleanups_(ret, scope.cleanups.get(), false); @@ -1465,14 +1534,15 @@ pub fn with_scope(bcx: @Block, ret } -pub fn with_scope_result(bcx: @Block, +pub fn with_scope_result<'a>( + bcx: &'a Block<'a>, opt_node_info: Option, _name: &str, - f: |@Block| -> Result) - -> Result { + f: |&'a Block<'a>| -> Result<'a>) + -> Result<'a> { let _icx = push_ctxt("with_scope_result"); - let scope = simple_block_scope(bcx.scope.get(), opt_node_info); + let scope = simple_block_scope(bcx.fcx, bcx.scope.get(), opt_node_info); bcx.scope.set(Some(scope)); let Result { bcx: out_bcx, val } = f(bcx); let out_bcx = trans_block_cleanups_(out_bcx, scope.cleanups.get(), false); @@ -1481,11 +1551,12 @@ pub fn with_scope_result(bcx: @Block, rslt(out_bcx, val) } -pub fn with_scope_datumblock(bcx: @Block, +pub fn with_scope_datumblock<'a>( + bcx: &'a Block<'a>, opt_node_info: Option, name: &str, - f: |@Block| -> datum::DatumBlock) - -> datum::DatumBlock { + f: |&'a Block| -> datum::DatumBlock<'a>) + -> datum::DatumBlock<'a> { use middle::trans::datum::DatumBlock; let _icx = push_ctxt("with_scope_result"); @@ -1509,10 +1580,11 @@ pub fn block_locals(b: &ast::Block, it: |@ast::Local|) { } } -pub fn with_cond(bcx: @Block, +pub fn with_cond<'a>( + bcx: &'a Block<'a>, val: ValueRef, - f: |@Block| -> @Block) - -> @Block { + f: |&'a Block<'a>| -> &'a Block<'a>) + -> &'a Block<'a> { let _icx = push_ctxt("with_cond"); let next_cx = base::sub_block(bcx, "next"); let cond_cx = base::sub_block(bcx, "cond"); @@ -1524,7 +1596,7 @@ pub fn with_cond(bcx: @Block, next_cx } -pub fn call_memcpy(cx: @Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) { +pub fn call_memcpy(cx: &Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) { let _icx = push_ctxt("call_memcpy"); let ccx = cx.ccx(); let key = match ccx.sess.targ_cfg.arch { @@ -1540,7 +1612,7 @@ pub fn call_memcpy(cx: @Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, Call(cx, memcpy, [dst_ptr, src_ptr, size, align, volatile], []); } -pub fn memcpy_ty(bcx: @Block, dst: ValueRef, src: ValueRef, t: ty::t) { +pub fn memcpy_ty(bcx: &Block, dst: ValueRef, src: ValueRef, t: ty::t) { let _icx = push_ctxt("memcpy_ty"); let ccx = bcx.ccx(); if ty::type_is_structural(t) { @@ -1553,7 +1625,7 @@ pub fn memcpy_ty(bcx: @Block, dst: ValueRef, src: ValueRef, t: ty::t) { } } -pub fn zero_mem(cx: @Block, llptr: ValueRef, t: ty::t) { +pub fn zero_mem(cx: &Block, llptr: ValueRef, t: ty::t) { if cx.unreachable.get() { return; } let _icx = push_ctxt("zero_mem"); let bcx = cx; @@ -1585,7 +1657,7 @@ pub fn memzero(b: &Builder, llptr: ValueRef, ty: Type) { b.call(llintrinsicfn, [llptr, llzeroval, size, align, volatile], []); } -pub fn alloc_ty(bcx: @Block, t: ty::t, name: &str) -> ValueRef { +pub fn alloc_ty(bcx: &Block, t: ty::t, name: &str) -> ValueRef { let _icx = push_ctxt("alloc_ty"); let ccx = bcx.ccx(); let ty = type_of::type_of(ccx, t); @@ -1594,11 +1666,11 @@ pub fn alloc_ty(bcx: @Block, t: ty::t, name: &str) -> ValueRef { return val; } -pub fn alloca(cx: @Block, ty: Type, name: &str) -> ValueRef { +pub fn alloca(cx: &Block, ty: Type, name: &str) -> ValueRef { alloca_maybe_zeroed(cx, ty, name, false) } -pub fn alloca_maybe_zeroed(cx: @Block, ty: Type, name: &str, zero: bool) -> ValueRef { +pub fn alloca_maybe_zeroed(cx: &Block, ty: Type, name: &str, zero: bool) -> ValueRef { let _icx = push_ctxt("alloca"); if cx.unreachable.get() { unsafe { @@ -1615,7 +1687,7 @@ pub fn alloca_maybe_zeroed(cx: @Block, ty: Type, name: &str, zero: bool) -> Valu p } -pub fn arrayalloca(cx: @Block, ty: Type, v: ValueRef) -> ValueRef { +pub fn arrayalloca(cx: &Block, ty: Type, v: ValueRef) -> ValueRef { let _icx = push_ctxt("arrayalloca"); if cx.unreachable.get() { unsafe { @@ -1650,7 +1722,8 @@ pub fn mk_return_basic_block(llfn: ValueRef) -> BasicBlockRef { // Creates and returns space for, or returns the argument representing, the // slot where the return value of the function must go. -pub fn make_return_pointer(fcx: @FunctionContext, output_type: ty::t) -> ValueRef { +pub fn make_return_pointer(fcx: &FunctionContext, output_type: ty::t) + -> ValueRef { unsafe { if type_of::return_uses_outptr(fcx.ccx, output_type) { llvm::LLVMGetParam(fcx.llfn, 0) @@ -1668,16 +1741,17 @@ pub fn make_return_pointer(fcx: @FunctionContext, output_type: ty::t) -> ValueRe // - create_llargs_for_fn_args. // - new_fn_ctxt // - trans_args +// +// Be warned! You must call `init_function` before doing anything with the +// returned function context. pub fn new_fn_ctxt_w_id(ccx: @CrateContext, path: path, llfndecl: ValueRef, id: ast::NodeId, output_type: ty::t, - skip_retptr: bool, param_substs: Option<@param_substs>, - opt_node_info: Option, sp: Option) - -> @FunctionContext { + -> FunctionContext { for p in param_substs.iter() { p.validate(); } debug!("new_fn_ctxt_w_id(path={}, id={:?}, \ @@ -1695,7 +1769,7 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext, let uses_outptr = type_of::return_uses_outptr(ccx, substd_output_type); let debug_context = debuginfo::create_function_debug_context(ccx, id, param_substs, llfndecl); - let fcx = @FunctionContext { + let fcx = FunctionContext { llfn: llfndecl, llenv: unsafe { Cell::new(llvm::LLVMGetUndef(Type::i8p().to_ref())) @@ -1714,6 +1788,8 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext, param_substs: param_substs, span: sp, path: path, + block_arena: TypedArena::new(), + scope_info_arena: TypedArena::new(), ccx: ccx, debug_context: debug_context, }; @@ -1721,6 +1797,17 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext, llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint) }); + fcx +} + +/// Performs setup on a newly created function, creating the entry scope block +/// and allocating space for the return pointer. +pub fn init_function<'a>( + fcx: &'a FunctionContext<'a>, + skip_retptr: bool, + output_type: ty::t, + param_substs: Option<@param_substs>, + opt_node_info: Option) { unsafe { let entry_bcx = top_scope_block(fcx, opt_node_info); Load(entry_bcx, C_null(Type::i8p())); @@ -1730,10 +1817,20 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext, llvm::LLVMGetFirstInstruction(entry_bcx.llbb))); } - if !ty::type_is_voidish(ccx.tcx, substd_output_type) { + let substd_output_type = match param_substs { + None => output_type, + Some(substs) => { + ty::subst_tps(fcx.ccx.tcx, + substs.tys, + substs.self_ty, + output_type) + } + }; + + if !ty::type_is_voidish(fcx.ccx.tcx, substd_output_type) { // If the function returns nil/bot, there is no real return // value, so do not set `llretptr`. - if !skip_retptr || uses_outptr { + if !skip_retptr || fcx.caller_expects_out_pointer { // Otherwise, we normally allocate the llretptr, unless we // have been instructed to skip it for immediate return // values. @@ -1741,7 +1838,6 @@ pub fn new_fn_ctxt_w_id(ccx: @CrateContext, substd_output_type))); } } - fcx } pub fn new_fn_ctxt(ccx: @CrateContext, @@ -1749,8 +1845,10 @@ pub fn new_fn_ctxt(ccx: @CrateContext, llfndecl: ValueRef, output_type: ty::t, sp: Option) - -> @FunctionContext { - new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, false, None, None, sp) + -> FunctionContext { + // FIXME(#11385): Do not call `init_function` here; it will typecheck + // but segfault. + new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, None, sp) } // NB: must keep 4 fns in sync: @@ -1767,10 +1865,10 @@ pub fn new_fn_ctxt(ccx: @CrateContext, // spaces that have been created for them (by code in the llallocas field of // the function's fn_ctxt). create_llargs_for_fn_args populates the llargs // field of the fn_ctxt with -pub fn create_llargs_for_fn_args(cx: @FunctionContext, +pub fn create_llargs_for_fn_args(cx: &FunctionContext, self_arg: self_arg, args: &[ast::arg]) - -> ~[ValueRef] { + -> ~[ValueRef] { let _icx = push_ctxt("create_llargs_for_fn_args"); match self_arg { @@ -1791,11 +1889,13 @@ pub fn create_llargs_for_fn_args(cx: @FunctionContext, }) } -pub fn copy_args_to_allocas(fcx: @FunctionContext, - bcx: @Block, +pub fn copy_args_to_allocas<'a>( + fcx: &FunctionContext<'a>, + bcx: &'a Block<'a>, args: &[ast::arg], raw_llargs: &[ValueRef], - arg_tys: &[ty::t]) -> @Block { + arg_tys: &[ty::t]) + -> &'a Block<'a> { debug!("copy_args_to_allocas: raw_llargs={} arg_tys={}", raw_llargs.llrepr(fcx.ccx), arg_tys.repr(fcx.ccx.tcx)); @@ -1855,7 +1955,7 @@ pub fn copy_args_to_allocas(fcx: @FunctionContext, // Ties up the llstaticallocas -> llloadenv -> lltop edges, // and builds the return block. -pub fn finish_fn(fcx: @FunctionContext, last_bcx: @Block) { +pub fn finish_fn(fcx: &FunctionContext, last_bcx: &Block) { let _icx = push_ctxt("finish_fn"); let ret_cx = match fcx.llreturn.get() { @@ -1873,7 +1973,7 @@ pub fn finish_fn(fcx: @FunctionContext, last_bcx: @Block) { } // Builds the return block for a function. -pub fn build_return_block(fcx: &FunctionContext, ret_cx: @Block) { +pub fn build_return_block(fcx: &FunctionContext, ret_cx: &Block) { // Return the value if this function immediate; otherwise, return void. if fcx.llretptr.get().is_none() || fcx.caller_expects_out_pointer { return RetVoid(ret_cx); @@ -1916,7 +2016,7 @@ pub fn trans_closure(ccx: @CrateContext, id: ast::NodeId, _attributes: &[ast::Attribute], output_type: ty::t, - maybe_load_env: |@FunctionContext|) { + maybe_load_env: |&FunctionContext|) { ccx.stats.n_closures.set(ccx.stats.n_closures.get() + 1); let _icx = push_ctxt("trans_closure"); @@ -1930,10 +2030,9 @@ pub fn trans_closure(ccx: @CrateContext, llfndecl, id, output_type, - false, param_substs, - body.info(), Some(body.span)); + init_function(&fcx, false, output_type, param_substs, body.info()); // Create the first basic block in the function and keep a handle on it to // pass to finish_fn later. @@ -1943,16 +2042,16 @@ pub fn trans_closure(ccx: @CrateContext, // Set up arguments to the function. let arg_tys = ty::ty_fn_args(node_id_type(bcx, id)); - let raw_llargs = create_llargs_for_fn_args(fcx, self_arg, decl.inputs); + let raw_llargs = create_llargs_for_fn_args(&fcx, self_arg, decl.inputs); - bcx = copy_args_to_allocas(fcx, bcx, decl.inputs, raw_llargs, arg_tys); + bcx = copy_args_to_allocas(&fcx, bcx, decl.inputs, raw_llargs, arg_tys); - maybe_load_env(fcx); + maybe_load_env(&fcx); // Up until here, IR instructions for this function have explicitly not been annotated with // source code location, so we don't step into call setup code. From here on, source location // emitting should be enabled. - debuginfo::start_emitting_source_locations(fcx); + debuginfo::start_emitting_source_locations(&fcx); // This call to trans_block is the place where we bridge between // translation calls that don't have a return value (trans_crate, @@ -1980,7 +2079,7 @@ pub fn trans_closure(ccx: @CrateContext, } // Insert the mandatory first few basic blocks before lltop. - finish_fn(fcx, bcx); + finish_fn(&fcx, bcx); } // trans_fn: creates an LLVM function corresponding to a source language @@ -2015,10 +2114,9 @@ pub fn trans_fn(ccx: @CrateContext, |_fcx| { }); } -fn insert_synthetic_type_entries(bcx: @Block, +fn insert_synthetic_type_entries(bcx: &Block, fn_args: &[ast::arg], - arg_tys: &[ty::t]) -{ + arg_tys: &[ty::t]) { /*! * For tuple-like structs and enum-variants, we generate * synthetic AST nodes for the arguments. These have no types @@ -2143,19 +2241,18 @@ pub fn trans_enum_variant_or_tuple_like_struct( llfndecl, ctor_id, result_ty, - false, param_substs, - None, None); + init_function(&fcx, false, result_ty, param_substs, None); let arg_tys = ty::ty_fn_args(ctor_ty); - let raw_llargs = create_llargs_for_fn_args(fcx, no_self, fn_args); + let raw_llargs = create_llargs_for_fn_args(&fcx, no_self, fn_args); let bcx = fcx.entry_bcx.get().unwrap(); insert_synthetic_type_entries(bcx, fn_args, arg_tys); - let bcx = copy_args_to_allocas(fcx, bcx, fn_args, raw_llargs, arg_tys); + let bcx = copy_args_to_allocas(&fcx, bcx, fn_args, raw_llargs, arg_tys); let repr = adt::represent_type(ccx, result_ty); adt::trans_start_init(bcx, repr, fcx.llretptr.get().unwrap(), disr); @@ -2172,7 +2269,7 @@ pub fn trans_enum_variant_or_tuple_like_struct( let arg_ty = arg_tys[i]; memcpy_ty(bcx, lldestptr, llarg, arg_ty); } - finish_fn(fcx, bcx); + finish_fn(&fcx, bcx); } pub fn trans_enum_def(ccx: @CrateContext, enum_definition: &ast::enum_def, @@ -2471,7 +2568,9 @@ pub fn create_entry_wrapper(ccx: @CrateContext, } } -pub fn fill_fn_pair(bcx: @Block, pair: ValueRef, llfn: ValueRef, +pub fn fill_fn_pair(bcx: &Block, + pair: ValueRef, + llfn: ValueRef, llenvptr: ValueRef) { let ccx = bcx.ccx(); let code_cell = GEPi(bcx, pair, [0u, abi::fn_field_code]); @@ -2798,7 +2897,7 @@ pub fn register_method(ccx: @CrateContext, llfn } -pub fn vp2i(cx: @Block, v: ValueRef) -> ValueRef { +pub fn vp2i(cx: &Block, v: ValueRef) -> ValueRef { let ccx = cx.ccx(); return PtrToInt(cx, v, ccx.int_type); } @@ -2966,7 +3065,7 @@ pub fn declare_dbg_intrinsics(llmod: ModuleRef, intrinsics: &mut HashMap<&'stati "llvm.dbg.value", [Type::metadata(), Type::i64(), Type::metadata()], Type::void()); } -pub fn trap(bcx: @Block) { +pub fn trap(bcx: &Block) { match bcx.ccx().intrinsics.find_equiv(& &"llvm.trap") { Some(&x) => { Call(bcx, x, [], []); }, _ => bcx.sess().bug("unbound llvm.trap in trap") diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 7a0e319e505..0dd0d1589ff 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -54,28 +54,30 @@ pub fn RetVoid(cx: &Block) { B(cx).ret_void(); } -pub fn Ret(cx: @Block, V: ValueRef) { +pub fn Ret(cx: &Block, V: ValueRef) { if cx.unreachable.get() { return; } check_not_terminated(cx); terminate(cx, "Ret"); B(cx).ret(V); } -pub fn AggregateRet(cx: @Block, RetVals: &[ValueRef]) { +pub fn AggregateRet(cx: &Block, RetVals: &[ValueRef]) { if cx.unreachable.get() { return; } check_not_terminated(cx); terminate(cx, "AggregateRet"); B(cx).aggregate_ret(RetVals); } -pub fn Br(cx: @Block, Dest: BasicBlockRef) { +pub fn Br(cx: &Block, Dest: BasicBlockRef) { if cx.unreachable.get() { return; } check_not_terminated(cx); terminate(cx, "Br"); B(cx).br(Dest); } -pub fn CondBr(cx: @Block, If: ValueRef, Then: BasicBlockRef, +pub fn CondBr(cx: &Block, + If: ValueRef, + Then: BasicBlockRef, Else: BasicBlockRef) { if cx.unreachable.get() { return; } check_not_terminated(cx); @@ -105,13 +107,13 @@ pub fn IndirectBr(cx: &Block, Addr: ValueRef, NumDests: uint) { B(cx).indirect_br(Addr, NumDests); } -pub fn Invoke(cx: @Block, +pub fn Invoke(cx: &Block, Fn: ValueRef, Args: &[ValueRef], Then: BasicBlockRef, Catch: BasicBlockRef, attributes: &[(uint, lib::llvm::Attribute)]) - -> ValueRef { + -> ValueRef { if cx.unreachable.get() { return C_null(Type::i8()); } @@ -762,7 +764,7 @@ pub fn SetCleanup(cx: &Block, LandingPad: ValueRef) { B(cx).set_cleanup(LandingPad) } -pub fn Resume(cx: @Block, Exn: ValueRef) -> ValueRef { +pub fn Resume(cx: &Block, Exn: ValueRef) -> ValueRef { check_not_terminated(cx); terminate(cx, "Resume"); B(cx).resume(Exn) diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 05b3e8275a3..6bf1babb9e5 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -70,12 +70,12 @@ pub enum CalleeData { Method(MethodData) } -pub struct Callee { - bcx: @Block, +pub struct Callee<'a> { + bcx: &'a Block<'a>, data: CalleeData } -pub fn trans(bcx: @Block, expr: &ast::Expr) -> Callee { +pub fn trans<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> { let _icx = push_ctxt("trans_callee"); debug!("callee::trans(expr={})", expr.repr(bcx.tcx())); @@ -90,7 +90,7 @@ pub fn trans(bcx: @Block, expr: &ast::Expr) -> Callee { // any other expressions are closures: return datum_callee(bcx, expr); - fn datum_callee(bcx: @Block, expr: &ast::Expr) -> Callee { + fn datum_callee<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> Callee<'a> { let DatumBlock {bcx, datum} = expr::trans_to_datum(bcx, expr); match ty::get(datum.ty).sty { ty::ty_bare_fn(..) => { @@ -109,11 +109,12 @@ pub fn trans(bcx: @Block, expr: &ast::Expr) -> Callee { } } - fn fn_callee(bcx: @Block, fd: FnData) -> Callee { + fn fn_callee<'a>(bcx: &'a Block<'a>, fd: FnData) -> Callee<'a> { return Callee {bcx: bcx, data: Fn(fd)}; } - fn trans_def(bcx: @Block, def: ast::Def, ref_expr: &ast::Expr) -> Callee { + fn trans_def<'a>(bcx: &'a Block<'a>, def: ast::Def, ref_expr: &ast::Expr) + -> Callee<'a> { match def { ast::DefFn(did, _) | ast::DefStaticMethod(did, ast::FromImpl(_), _) => { @@ -158,16 +159,17 @@ pub fn trans(bcx: @Block, expr: &ast::Expr) -> Callee { } } -pub fn trans_fn_ref_to_callee(bcx: @Block, +pub fn trans_fn_ref_to_callee<'a>( + bcx: &'a Block<'a>, def_id: ast::DefId, - ref_id: ast::NodeId) -> Callee { + ref_id: ast::NodeId) + -> Callee<'a> { Callee {bcx: bcx, data: Fn(trans_fn_ref(bcx, def_id, ref_id))} } -pub fn trans_fn_ref(bcx: @Block, - def_id: ast::DefId, - ref_id: ast::NodeId) -> FnData { +pub fn trans_fn_ref(bcx: &Block, def_id: ast::DefId, ref_id: ast::NodeId) + -> FnData { /*! * * Translates a reference (with id `ref_id`) to the fn/method @@ -184,19 +186,19 @@ pub fn trans_fn_ref(bcx: @Block, trans_fn_ref_with_vtables(bcx, def_id, ref_id, type_params, vtables) } -pub fn trans_fn_ref_with_vtables_to_callee( - bcx: @Block, - def_id: ast::DefId, - ref_id: ast::NodeId, - type_params: &[ty::t], - vtables: Option) - -> Callee { +pub fn trans_fn_ref_with_vtables_to_callee<'a>( + bcx: &'a Block<'a>, + def_id: ast::DefId, + ref_id: ast::NodeId, + type_params: &[ty::t], + vtables: Option) + -> Callee<'a> { Callee {bcx: bcx, data: Fn(trans_fn_ref_with_vtables(bcx, def_id, ref_id, type_params, vtables))} } -fn resolve_default_method_vtables(bcx: @Block, +fn resolve_default_method_vtables(bcx: &Block, impl_id: ast::DefId, method: &ty::Method, substs: &ty::substs, @@ -239,7 +241,7 @@ fn resolve_default_method_vtables(bcx: @Block, pub fn trans_fn_ref_with_vtables( - bcx: @Block, // + bcx: &Block, // def_id: ast::DefId, // def id of fn ref_id: ast::NodeId, // node id of use of fn; may be zero if N/A type_params: &[ty::t], // values for fn's ty params @@ -447,13 +449,14 @@ pub fn trans_fn_ref_with_vtables( // ______________________________________________________________________ // Translating calls -pub fn trans_call(in_cx: @Block, +pub fn trans_call<'a>( + in_cx: &'a Block<'a>, call_ex: &ast::Expr, f: &ast::Expr, args: CallArgs, id: ast::NodeId, dest: expr::Dest) - -> @Block { + -> &'a Block<'a> { let _icx = push_ctxt("trans_call"); trans_call_inner(in_cx, call_ex.info(), @@ -465,13 +468,14 @@ pub fn trans_call(in_cx: @Block, DontAutorefArg).bcx } -pub fn trans_method_call(in_cx: @Block, +pub fn trans_method_call<'a>( + in_cx: &'a Block<'a>, call_ex: &ast::Expr, callee_id: ast::NodeId, rcvr: &ast::Expr, args: CallArgs, dest: expr::Dest) - -> @Block { + -> &'a Block<'a> { let _icx = push_ctxt("trans_method_call"); debug!("trans_method_call(call_ex={}, rcvr={})", call_ex.repr(in_cx.tcx()), @@ -507,11 +511,12 @@ pub fn trans_method_call(in_cx: @Block, DontAutorefArg).bcx } -pub fn trans_lang_call(bcx: @Block, +pub fn trans_lang_call<'a>( + bcx: &'a Block<'a>, did: ast::DefId, args: &[ValueRef], dest: Option) - -> Result { + -> Result<'a> { let fty = if did.crate == ast::LOCAL_CRATE { ty::node_id_to_type(bcx.ccx().tcx, did.node) } else { @@ -534,12 +539,13 @@ pub fn trans_lang_call(bcx: @Block, DontAutorefArg) } -pub fn trans_lang_call_with_type_params(bcx: @Block, +pub fn trans_lang_call_with_type_params<'a>( + bcx: &'a Block<'a>, did: ast::DefId, args: &[ValueRef], type_params: &[ty::t], dest: expr::Dest) - -> @Block { + -> &'a Block<'a> { let fty; if did.crate == ast::LOCAL_CRATE { fty = ty::node_id_to_type(bcx.tcx(), did.node); @@ -574,15 +580,16 @@ pub fn trans_lang_call_with_type_params(bcx: @Block, ArgVals(args), Some(dest), DontAutorefArg).bcx; } -pub fn trans_call_inner(in_cx: @Block, +pub fn trans_call_inner<'a>( + in_cx: &'a Block<'a>, call_info: Option, callee_ty: ty::t, ret_ty: ty::t, - get_callee: |@Block| -> Callee, + get_callee: |&'a Block<'a>| -> Callee<'a>, args: CallArgs, dest: Option, autoref_arg: AutorefArg) - -> Result { + -> Result<'a> { /*! * This behemoth of a function translates function calls. * Unfortunately, in order to generate more efficient LLVM @@ -762,12 +769,13 @@ pub enum CallArgs<'a> { ArgVals(&'a [ValueRef]) } -pub fn trans_args(cx: @Block, +pub fn trans_args<'a>( + cx: &'a Block<'a>, args: CallArgs, fn_ty: ty::t, autoref_arg: AutorefArg, - llargs: &mut ~[ValueRef]) -> @Block -{ + llargs: &mut ~[ValueRef]) + -> &'a Block<'a> { let _icx = push_ctxt("trans_args"); let mut temp_cleanups = ~[]; let arg_tys = ty::ty_fn_args(fn_ty); @@ -821,12 +829,14 @@ pub enum AutorefArg { // temp_cleanups: cleanups that should run only if failure occurs before the // call takes place: -pub fn trans_arg_expr(bcx: @Block, +pub fn trans_arg_expr<'a>( + bcx: &'a Block<'a>, formal_arg_ty: ty::t, self_mode: ty::SelfMode, arg_expr: &ast::Expr, temp_cleanups: &mut ~[ValueRef], - autoref_arg: AutorefArg) -> Result { + autoref_arg: AutorefArg) + -> Result<'a> { let _icx = push_ctxt("trans_arg_expr"); let ccx = bcx.ccx(); diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 1d56601cfba..44bce6b2a2a 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -155,7 +155,7 @@ pub fn mk_closure_tys(tcx: ty::ctxt, return cdata_ty; } -fn heap_for_unique_closure(bcx: @Block, t: ty::t) -> heap { +fn heap_for_unique_closure(bcx: &Block, t: ty::t) -> heap { if ty::type_contents(bcx.tcx(), t).owns_managed() { heap_managed_unique } else { @@ -163,8 +163,11 @@ fn heap_for_unique_closure(bcx: @Block, t: ty::t) -> heap { } } -pub fn allocate_cbox(bcx: @Block, sigil: ast::Sigil, cdata_ty: ty::t) - -> Result { +pub fn allocate_cbox<'a>( + bcx: &'a Block<'a>, + sigil: ast::Sigil, + cdata_ty: ty::t) + -> Result<'a> { let _icx = push_ctxt("closure::allocate_cbox"); let ccx = bcx.ccx(); let tcx = ccx.tcx; @@ -185,20 +188,21 @@ pub fn allocate_cbox(bcx: @Block, sigil: ast::Sigil, cdata_ty: ty::t) } } -pub struct ClosureResult { - llbox: ValueRef, // llvalue of ptr to closure - cdata_ty: ty::t, // type of the closure data - bcx: @Block // final bcx +pub struct ClosureResult<'a> { + llbox: ValueRef, // llvalue of ptr to closure + cdata_ty: ty::t, // type of the closure data + bcx: &'a Block<'a> // final bcx } // Given a block context and a list of tydescs and values to bind // construct a closure out of them. If copying is true, it is a // heap allocated closure that copies the upvars into environment. // Otherwise, it is stack allocated and copies pointers to the upvars. -pub fn store_environment(bcx: @Block, +pub fn store_environment<'a>( + bcx: &'a Block<'a>, bound_values: ~[EnvValue], sigil: ast::Sigil) - -> ClosureResult { + -> ClosureResult<'a> { let _icx = push_ctxt("closure::store_environment"); let ccx = bcx.ccx(); let tcx = ccx.tcx; @@ -257,9 +261,11 @@ pub fn store_environment(bcx: @Block, // Given a context and a list of upvars, build a closure. This just // collects the upvars and packages them up for store_environment. -pub fn build_closure(bcx0: @Block, +pub fn build_closure<'a>( + bcx0: &'a Block<'a>, cap_vars: &[moves::CaptureVar], - sigil: ast::Sigil) -> ClosureResult { + sigil: ast::Sigil) + -> ClosureResult<'a> { let _icx = push_ctxt("closure::build_closure"); // If we need to, package up the iterator body to call @@ -293,7 +299,7 @@ pub fn build_closure(bcx0: @Block, // Given an enclosing block context, a new function context, a closure type, // and a list of upvars, generate code to load and populate the environment // with the upvars and type descriptors. -pub fn load_environment(fcx: @FunctionContext, +pub fn load_environment(fcx: &FunctionContext, cdata_ty: ty::t, cap_vars: &[moves::CaptureVar], sigil: ast::Sigil) { @@ -349,13 +355,15 @@ pub fn load_environment(fcx: @FunctionContext, } } -pub fn trans_expr_fn(bcx: @Block, +pub fn trans_expr_fn<'a>( + bcx: &'a Block<'a>, sigil: ast::Sigil, decl: &ast::fn_decl, body: &ast::Block, outer_id: ast::NodeId, user_id: ast::NodeId, - dest: expr::Dest) -> @Block { + dest: expr::Dest) + -> &'a Block<'a> { /*! * * Translates the body of a closure expression. @@ -429,12 +437,13 @@ pub fn trans_expr_fn(bcx: @Block, return bcx; } -pub fn make_closure_glue(cx: @Block, +pub fn make_closure_glue<'a>( + cx: &'a Block<'a>, v: ValueRef, t: ty::t, - glue_fn: |@Block, v: ValueRef, t: ty::t| - -> @Block) - -> @Block { + glue_fn: |&'a Block<'a>, v: ValueRef, t: ty::t| + -> &'a Block<'a>) + -> &'a Block<'a> { let _icx = push_ctxt("closure::make_closure_glue"); let bcx = cx; let tcx = cx.tcx(); @@ -453,11 +462,11 @@ pub fn make_closure_glue(cx: @Block, } } -pub fn make_opaque_cbox_drop_glue( - bcx: @Block, - sigil: ast::Sigil, - cboxptr: ValueRef) // ptr to the opaque closure - -> @Block { +pub fn make_opaque_cbox_drop_glue<'a>( + bcx: &'a Block<'a>, + sigil: ast::Sigil, + cboxptr: ValueRef) // opaque closure ptr + -> &'a Block<'a> { let _icx = push_ctxt("closure::make_opaque_cbox_drop_glue"); match sigil { ast::BorrowedSigil => bcx, @@ -473,10 +482,11 @@ pub fn make_opaque_cbox_drop_glue( } /// `cbox` is a pointer to a pointer to an opaque closure. -pub fn make_opaque_cbox_free_glue(bcx: @Block, +pub fn make_opaque_cbox_free_glue<'a>( + bcx: &'a Block<'a>, sigil: ast::Sigil, cbox: ValueRef) - -> @Block { + -> &'a Block<'a> { let _icx = push_ctxt("closure::make_opaque_cbox_free_glue"); match sigil { ast::BorrowedSigil => { diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 973d2003ecb..4baae9279b1 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -23,13 +23,14 @@ use middle::trans::build; use middle::trans::datum; use middle::trans::glue; use middle::trans::debuginfo; +use middle::trans::type_::Type; use middle::ty::substs; use middle::ty; use middle::typeck; use util::ppaux::Repr; -use middle::trans::type_::Type; +use extra::arena::TypedArena; use std::c_str::ToCStr; use std::cast::transmute; use std::cast; @@ -195,7 +196,7 @@ impl Repr for param_substs { // Function context. Every LLVM function we create will have one of // these. -pub struct FunctionContext { +pub struct FunctionContext<'a> { // The ValueRef returned from a call to llvm::LLVMAddFunction; the // address of the first instruction in the sequence of // instructions for this function that will go in the .text @@ -212,7 +213,7 @@ pub struct FunctionContext { // always be Some. llretptr: Cell>, - entry_bcx: RefCell>, + entry_bcx: RefCell>>, // These elements: "hoisted basic blocks" containing // administrative activities that have to happen in only one place in @@ -258,6 +259,12 @@ pub struct FunctionContext { span: Option, path: path, + // The arena that blocks are allocated from. + block_arena: TypedArena>, + + // The arena that scope info is allocated from. + scope_info_arena: TypedArena>, + // This function's enclosing crate context. ccx: @CrateContext, @@ -265,7 +272,7 @@ pub struct FunctionContext { debug_context: debuginfo::FunctionDebugContext, } -impl FunctionContext { +impl<'a> FunctionContext<'a> { pub fn arg_pos(&self, arg: uint) -> uint { if self.caller_expects_out_pointer { arg + 2u @@ -332,7 +339,7 @@ pub enum cleantype { /// A cleanup function: a built-in destructor. pub trait CleanupFunction { - fn clean(&self, block: @Block) -> @Block; + fn clean<'a>(&self, block: &'a Block<'a>) -> &'a Block<'a>; } /// A cleanup function that calls the "drop glue" (destructor function) on @@ -343,7 +350,7 @@ pub struct TypeDroppingCleanupFunction { } impl CleanupFunction for TypeDroppingCleanupFunction { - fn clean(&self, block: @Block) -> @Block { + fn clean<'a>(&self, block: &'a Block<'a>) -> &'a Block<'a> { glue::drop_ty(block, self.val, self.t) } } @@ -356,7 +363,7 @@ pub struct ImmediateTypeDroppingCleanupFunction { } impl CleanupFunction for ImmediateTypeDroppingCleanupFunction { - fn clean(&self, block: @Block) -> @Block { + fn clean<'a>(&self, block: &'a Block<'a>) -> &'a Block<'a> { glue::drop_ty_immediate(block, self.val, self.t) } } @@ -367,7 +374,7 @@ pub struct GCHeapFreeingCleanupFunction { } impl CleanupFunction for GCHeapFreeingCleanupFunction { - fn clean(&self, bcx: @Block) -> @Block { + fn clean<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a> { glue::trans_free(bcx, self.ptr) } } @@ -378,7 +385,7 @@ pub struct ExchangeHeapFreeingCleanupFunction { } impl CleanupFunction for ExchangeHeapFreeingCleanupFunction { - fn clean(&self, bcx: @Block) -> @Block { + fn clean<'a>(&self, bcx: &'a Block) -> &'a Block<'a> { glue::trans_exchange_free(bcx, self.ptr) } } @@ -432,7 +439,7 @@ pub fn cleanup_type(cx: ty::ctxt, ty: ty::t) -> cleantype { } } -pub fn add_clean(bcx: @Block, val: ValueRef, t: ty::t) { +pub fn add_clean(bcx: &Block, val: ValueRef, t: ty::t) { if !ty::type_needs_drop(bcx.tcx(), t) { return } @@ -453,7 +460,7 @@ pub fn add_clean(bcx: @Block, val: ValueRef, t: ty::t) { }) } -pub fn add_clean_temp_immediate(cx: @Block, val: ValueRef, ty: ty::t) { +pub fn add_clean_temp_immediate(cx: &Block, val: ValueRef, ty: ty::t) { if !ty::type_needs_drop(cx.tcx(), ty) { return; } debug!("add_clean_temp_immediate({}, {}, {})", cx.to_str(), cx.val_to_str(val), @@ -473,18 +480,18 @@ pub fn add_clean_temp_immediate(cx: @Block, val: ValueRef, ty: ty::t) { }) } -pub fn add_clean_temp_mem(bcx: @Block, val: ValueRef, t: ty::t) { +pub fn add_clean_temp_mem(bcx: &Block, val: ValueRef, t: ty::t) { add_clean_temp_mem_in_scope_(bcx, None, val, t); } -pub fn add_clean_temp_mem_in_scope(bcx: @Block, +pub fn add_clean_temp_mem_in_scope(bcx: &Block, scope_id: ast::NodeId, val: ValueRef, t: ty::t) { add_clean_temp_mem_in_scope_(bcx, Some(scope_id), val, t); } -pub fn add_clean_temp_mem_in_scope_(bcx: @Block, scope_id: Option, +pub fn add_clean_temp_mem_in_scope_(bcx: &Block, scope_id: Option, val: ValueRef, t: ty::t) { if !ty::type_needs_drop(bcx.tcx(), t) { return; } debug!("add_clean_temp_mem({}, {}, {})", @@ -505,7 +512,7 @@ pub fn add_clean_temp_mem_in_scope_(bcx: @Block, scope_id: Option, }) } -pub fn add_clean_free(cx: @Block, ptr: ValueRef, heap: heap) { +pub fn add_clean_free(cx: &Block, ptr: ValueRef, heap: heap) { let free_fn = match heap { heap_managed | heap_managed_unique => { @GCHeapFreeingCleanupFunction { @@ -533,7 +540,7 @@ pub fn add_clean_free(cx: @Block, ptr: ValueRef, heap: heap) { // to a system where we can also cancel the cleanup on local variables, but // this will be more involved. For now, we simply zero out the local, and the // drop glue checks whether it is zero. -pub fn revoke_clean(cx: @Block, val: ValueRef) { +pub fn revoke_clean(cx: &Block, val: ValueRef) { in_scope_cx(cx, None, |scope_info| { let cleanup_pos = { let mut cleanups = scope_info.cleanups.borrow_mut(); @@ -564,9 +571,9 @@ pub fn block_cleanups(bcx: &Block) -> ~[cleanup] { } } -pub struct ScopeInfo { - parent: Option<@ScopeInfo>, - loop_break: Option<@Block>, +pub struct ScopeInfo<'a> { + parent: Option<&'a ScopeInfo<'a>>, + loop_break: Option<&'a Block<'a>>, loop_label: Option, // A list of functions that must be run at when leaving this // block, cleaning up any variables that were introduced in the @@ -581,7 +588,7 @@ pub struct ScopeInfo { node_info: Option, } -impl ScopeInfo { +impl<'a> ScopeInfo<'a> { pub fn empty_cleanups(&self) -> bool { let cleanups = self.cleanups.borrow(); cleanups.get().is_empty() @@ -625,7 +632,7 @@ pub struct NodeInfo { // code. Each basic block we generate is attached to a function, typically // with many basic blocks per function. All the basic blocks attached to a // function are organized as a directed graph. -pub struct Block { +pub struct Block<'a> { // The BasicBlockRef returned from a call to // llvm::LLVMAppendBasicBlock(llfn, name), which adds a basic // block to the function pointed to by llfn. We insert @@ -634,26 +641,27 @@ pub struct Block { llbb: BasicBlockRef, terminated: Cell, unreachable: Cell, - parent: Option<@Block>, + parent: Option<&'a Block<'a>>, // The current scope within this basic block - scope: RefCell>, + scope: RefCell>>, // Is this block part of a landing pad? is_lpad: bool, // info about the AST node this block originated from, if any node_info: Option, // The function context for the function to which this block is // attached. - fcx: @FunctionContext + fcx: &'a FunctionContext<'a>, } -impl Block { - pub fn new(llbb: BasicBlockRef, - parent: Option<@Block>, +impl<'a> Block<'a> { + pub fn new<'a>( + llbb: BasicBlockRef, + parent: Option<&'a Block<'a>>, is_lpad: bool, node_info: Option, - fcx: @FunctionContext) - -> Block { - Block { + fcx: &'a FunctionContext<'a>) + -> &'a Block<'a> { + fcx.block_arena.alloc(Block { llbb: llbb, terminated: Cell::new(false), unreachable: Cell::new(false), @@ -661,12 +669,14 @@ impl Block { scope: RefCell::new(None), is_lpad: is_lpad, node_info: node_info, - fcx: fcx - } + fcx: fcx, + }) } pub fn ccx(&self) -> @CrateContext { self.fcx.ccx } - pub fn tcx(&self) -> ty::ctxt { self.fcx.ccx.tcx } + pub fn tcx(&self) -> ty::ctxt { + self.fcx.ccx.tcx + } pub fn sess(&self) -> Session { self.fcx.ccx.sess } pub fn ident(&self, ident: Ident) -> @str { @@ -722,17 +732,20 @@ impl Block { } } -pub struct Result { - bcx: @Block, +pub struct Result<'a> { + bcx: &'a Block<'a>, val: ValueRef } -pub fn rslt(bcx: @Block, val: ValueRef) -> Result { - Result {bcx: bcx, val: val} +pub fn rslt<'a>(bcx: &'a Block<'a>, val: ValueRef) -> Result<'a> { + Result { + bcx: bcx, + val: val, + } } -impl Result { - pub fn unpack(&self, bcx: &mut @Block) -> ValueRef { +impl<'a> Result<'a> { + pub fn unpack(&self, bcx: &mut &'a Block<'a>) -> ValueRef { *bcx = self.bcx; return self.val; } @@ -744,9 +757,10 @@ pub fn val_ty(v: ValueRef) -> Type { } } -pub fn in_scope_cx(cx: @Block, +pub fn in_scope_cx<'a>( + cx: &'a Block<'a>, scope_id: Option, - f: |si: &ScopeInfo|) { + f: |si: &'a ScopeInfo<'a>|) { let mut cur = cx; let mut cur_scope = cur.scope.get(); loop { @@ -776,7 +790,7 @@ pub fn in_scope_cx(cx: @Block, } } -pub fn block_parent(cx: @Block) -> @Block { +pub fn block_parent<'a>(cx: &'a Block<'a>) -> &'a Block<'a> { match cx.parent { Some(b) => b, None => cx.sess().bug(format!("block_parent called on root block {:?}", @@ -1048,17 +1062,17 @@ pub struct mono_id_ { pub type mono_id = @mono_id_; -pub fn umax(cx: @Block, a: ValueRef, b: ValueRef) -> ValueRef { +pub fn umax(cx: &Block, a: ValueRef, b: ValueRef) -> ValueRef { let cond = build::ICmp(cx, lib::llvm::IntULT, a, b); return build::Select(cx, cond, b, a); } -pub fn umin(cx: @Block, a: ValueRef, b: ValueRef) -> ValueRef { +pub fn umin(cx: &Block, a: ValueRef, b: ValueRef) -> ValueRef { let cond = build::ICmp(cx, lib::llvm::IntULT, a, b); return build::Select(cx, cond, a, b); } -pub fn align_to(cx: @Block, off: ValueRef, align: ValueRef) -> ValueRef { +pub fn align_to(cx: &Block, off: ValueRef, align: ValueRef) -> ValueRef { let mask = build::Sub(cx, align, C_int(cx.ccx(), 1)); let bumped = build::Add(cx, off, mask); return build::And(cx, bumped, build::Not(cx, mask)); @@ -1132,7 +1146,7 @@ pub fn node_id_type_params(bcx: &Block, id: ast::NodeId) -> ~[ty::t] { } } -pub fn node_vtables(bcx: @Block, id: ast::NodeId) +pub fn node_vtables(bcx: &Block, id: ast::NodeId) -> Option { let vtable_map = bcx.ccx().maps.vtable_map.borrow(); let raw_vtables = vtable_map.get().find(&id); @@ -1233,8 +1247,8 @@ pub fn dummy_substs(tps: ~[ty::t]) -> ty::substs { } } -pub fn filename_and_line_num_from_span(bcx: @Block, - span: Span) -> (ValueRef, ValueRef) { +pub fn filename_and_line_num_from_span(bcx: &Block, span: Span) + -> (ValueRef, ValueRef) { let loc = bcx.sess().parse_sess.cm.lookup_char_pos(span.lo); let filename_cstr = C_cstr(bcx.ccx(), loc.file.name); let filename = build::PointerCast(bcx, filename_cstr, Type::i8p()); @@ -1243,12 +1257,15 @@ pub fn filename_and_line_num_from_span(bcx: @Block, } // Casts a Rust bool value to an i1. -pub fn bool_to_i1(bcx: @Block, llval: ValueRef) -> ValueRef { +pub fn bool_to_i1(bcx: &Block, llval: ValueRef) -> ValueRef { build::ICmp(bcx, lib::llvm::IntNE, llval, C_bool(false)) } -pub fn langcall(bcx: @Block, span: Option, msg: &str, - li: LangItem) -> ast::DefId { +pub fn langcall(bcx: &Block, + span: Option, + msg: &str, + li: LangItem) + -> ast::DefId { match bcx.tcx().lang_items.require(li) { Ok(id) => id, Err(s) => { diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index 0770e52f90a..97e338eab85 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -28,7 +28,8 @@ use syntax::ast_util; use syntax::codemap::Span; use syntax::visit::Visitor; -pub fn trans_block(bcx: @Block, b: &ast::Block, dest: expr::Dest) -> @Block { +pub fn trans_block<'a>(bcx: &'a Block<'a>, b: &ast::Block, dest: expr::Dest) + -> &'a Block<'a> { let _icx = push_ctxt("trans_block"); let mut bcx = bcx; for s in b.stmts.iter() { @@ -45,12 +46,13 @@ pub fn trans_block(bcx: @Block, b: &ast::Block, dest: expr::Dest) -> @Block { return bcx; } -pub fn trans_if(bcx: @Block, - cond: &ast::Expr, - thn: ast::P, - els: Option<@ast::Expr>, - dest: expr::Dest) - -> @Block { +pub fn trans_if<'a>( + bcx: &'a Block<'a>, + cond: &ast::Expr, + thn: ast::P, + els: Option<@ast::Expr>, + dest: expr::Dest) + -> &'a Block<'a> { debug!("trans_if(bcx={}, cond={}, thn={:?}, dest={})", bcx.to_str(), bcx.expr_to_str(cond), thn.id, dest.to_str(bcx.ccx())); @@ -137,8 +139,12 @@ pub fn trans_if(bcx: @Block, return next_bcx; // trans `else [ if { .. } ... | { .. } ]` - fn trans_if_else(else_bcx_in: @Block, elexpr: @ast::Expr, - dest: expr::Dest, cleanup: bool) -> @Block { + fn trans_if_else<'a>( + else_bcx_in: &'a Block<'a>, + elexpr: @ast::Expr, + dest: expr::Dest, + cleanup: bool) + -> &'a Block<'a> { let else_bcx_out = match elexpr.node { ast::ExprIf(_, _, _) => { let elseif_blk = ast_util::block_from_expr(elexpr); @@ -159,7 +165,10 @@ pub fn trans_if(bcx: @Block, } } -pub fn join_blocks(parent_bcx: @Block, in_cxs: &[@Block]) -> @Block { +pub fn join_blocks<'a>( + parent_bcx: &'a Block<'a>, + in_cxs: &[&'a Block<'a>]) + -> &'a Block<'a> { let out = sub_block(parent_bcx, "join"); let mut reachable = false; for bcx in in_cxs.iter() { @@ -174,7 +183,11 @@ pub fn join_blocks(parent_bcx: @Block, in_cxs: &[@Block]) -> @Block { return out; } -pub fn trans_while(bcx: @Block, cond: &ast::Expr, body: &ast::Block) -> @Block { +pub fn trans_while<'a>( + bcx: &'a Block<'a>, + cond: &ast::Expr, + body: &ast::Block) + -> &'a Block<'a> { let _icx = push_ctxt("trans_while"); let next_bcx = sub_block(bcx, "while next"); @@ -213,10 +226,11 @@ pub fn trans_while(bcx: @Block, cond: &ast::Expr, body: &ast::Block) -> @Block { return next_bcx; } -pub fn trans_loop(bcx:@Block, +pub fn trans_loop<'a>( + bcx: &'a Block<'a>, body: &ast::Block, opt_label: Option) - -> @Block { + -> &'a Block<'a> { let _icx = push_ctxt("trans_loop"); let next_bcx = sub_block(bcx, "next"); let body_bcx_in = loop_scope_block(bcx, next_bcx, opt_label, "`loop`", @@ -227,10 +241,11 @@ pub fn trans_loop(bcx:@Block, return next_bcx; } -pub fn trans_break_cont(bcx: @Block, +pub fn trans_break_cont<'a>( + bcx: &'a Block<'a>, opt_label: Option, to_end: bool) - -> @Block { + -> &'a Block<'a> { let _icx = push_ctxt("trans_break_cont"); // Locate closest loop block, outputting cleanup as we go. let mut unwind = bcx; @@ -238,7 +253,7 @@ pub fn trans_break_cont(bcx: @Block, let mut target; loop { cur_scope = match cur_scope { - Some(@ScopeInfo { + Some(&ScopeInfo { loop_break: Some(brk), loop_label: l, parent, @@ -283,15 +298,18 @@ pub fn trans_break_cont(bcx: @Block, return bcx; } -pub fn trans_break(bcx: @Block, label_opt: Option) -> @Block { +pub fn trans_break<'a>(bcx: &'a Block<'a>, label_opt: Option) + -> &'a Block<'a> { return trans_break_cont(bcx, label_opt, true); } -pub fn trans_cont(bcx: @Block, label_opt: Option) -> @Block { +pub fn trans_cont<'a>(bcx: &'a Block<'a>, label_opt: Option) + -> &'a Block<'a> { return trans_break_cont(bcx, label_opt, false); } -pub fn trans_ret(bcx: @Block, e: Option<@ast::Expr>) -> @Block { +pub fn trans_ret<'a>(bcx: &'a Block<'a>, e: Option<@ast::Expr>) + -> &'a Block<'a> { let _icx = push_ctxt("trans_ret"); let mut bcx = bcx; let dest = match bcx.fcx.llretptr.get() { @@ -309,10 +327,11 @@ pub fn trans_ret(bcx: @Block, e: Option<@ast::Expr>) -> @Block { return bcx; } -pub fn trans_fail_expr(bcx: @Block, +pub fn trans_fail_expr<'a>( + bcx: &'a Block<'a>, sp_opt: Option, fail_expr: Option<@ast::Expr>) - -> @Block { + -> &'a Block<'a> { let _icx = push_ctxt("trans_fail_expr"); let mut bcx = bcx; match fail_expr { @@ -337,19 +356,21 @@ pub fn trans_fail_expr(bcx: @Block, } } -pub fn trans_fail(bcx: @Block, +pub fn trans_fail<'a>( + bcx: &'a Block<'a>, sp_opt: Option, fail_str: @str) - -> @Block { + -> &'a Block<'a> { let _icx = push_ctxt("trans_fail"); let V_fail_str = C_cstr(bcx.ccx(), fail_str); return trans_fail_value(bcx, sp_opt, V_fail_str); } -fn trans_fail_value(bcx: @Block, +fn trans_fail_value<'a>( + bcx: &'a Block<'a>, sp_opt: Option, V_fail_str: ValueRef) - -> @Block { + -> &'a Block<'a> { let _icx = push_ctxt("trans_fail_value"); let ccx = bcx.ccx(); let (V_filename, V_line) = match sp_opt { @@ -372,8 +393,12 @@ fn trans_fail_value(bcx: @Block, return bcx; } -pub fn trans_fail_bounds_check(bcx: @Block, sp: Span, - index: ValueRef, len: ValueRef) -> @Block { +pub fn trans_fail_bounds_check<'a>( + bcx: &'a Block<'a>, + sp: Span, + index: ValueRef, + len: ValueRef) + -> &'a Block<'a> { let _icx = push_ctxt("trans_fail_bounds_check"); let (filename, line) = filename_and_line_num_from_span(bcx, sp); let args = ~[filename, line, index, len]; diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 5fb2f5d41dc..b34e68d9a57 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -125,8 +125,8 @@ pub struct Datum { mode: DatumMode, } -pub struct DatumBlock { - bcx: @Block, +pub struct DatumBlock<'a> { + bcx: &'a Block<'a>, datum: Datum, } @@ -163,14 +163,16 @@ pub fn immediate_rvalue(val: ValueRef, ty: ty::t) -> Datum { return Datum {val: val, ty: ty, mode: ByValue}; } -pub fn immediate_rvalue_bcx(bcx: @Block, - val: ValueRef, - ty: ty::t) - -> DatumBlock { - return DatumBlock {bcx: bcx, datum: immediate_rvalue(val, ty)}; +pub fn immediate_rvalue_bcx<'a>(bcx: &'a Block<'a>, val: ValueRef, ty: ty::t) + -> DatumBlock<'a> { + DatumBlock { + bcx: bcx, + datum: immediate_rvalue(val, ty), + } } -pub fn scratch_datum(bcx: @Block, ty: ty::t, name: &str, zero: bool) -> Datum { +pub fn scratch_datum(bcx: &Block, ty: ty::t, name: &str, zero: bool) + -> Datum { /*! * Allocates temporary space on the stack using alloca() and * returns a by-ref Datum pointing to it. If `zero` is true, the @@ -203,11 +205,12 @@ pub fn appropriate_mode(ccx: &CrateContext, ty: ty::t) -> DatumMode { } impl Datum { - pub fn store_to(&self, - bcx: @Block, + pub fn store_to<'a>( + &self, + bcx: &'a Block<'a>, action: CopyAction, dst: ValueRef) - -> @Block { + -> &'a Block<'a> { /*! * * Stores this value into its final home. This moves if @@ -221,10 +224,8 @@ impl Datum { } } - pub fn store_to_dest(&self, - bcx: @Block, - dest: expr::Dest) - -> @Block { + pub fn store_to_dest<'a>(&self, bcx: &'a Block<'a>, dest: expr::Dest) + -> &'a Block<'a> { match dest { expr::Ignore => { return bcx; @@ -235,31 +236,44 @@ impl Datum { } } - pub fn store_to_datum(&self, - bcx: @Block, + pub fn store_to_datum<'a>( + &self, + bcx: &'a Block<'a>, action: CopyAction, datum: Datum) - -> @Block { + -> &'a Block<'a> { debug!("store_to_datum(self={}, action={:?}, datum={})", self.to_str(bcx.ccx()), action, datum.to_str(bcx.ccx())); assert!(datum.mode.is_by_ref()); self.store_to(bcx, action, datum.val) } - pub fn move_to_datum(&self, bcx: @Block, action: CopyAction, datum: Datum) - -> @Block { + pub fn move_to_datum<'a>( + &self, + bcx: &'a Block<'a>, + action: CopyAction, + datum: Datum) + -> &'a Block<'a> { assert!(datum.mode.is_by_ref()); self.move_to(bcx, action, datum.val) } - pub fn copy_to_datum(&self, bcx: @Block, action: CopyAction, datum: Datum) - -> @Block { + pub fn copy_to_datum<'a>( + &self, + bcx: &'a Block<'a>, + action: CopyAction, + datum: Datum) + -> &'a Block<'a> { assert!(datum.mode.is_by_ref()); self.copy_to(bcx, action, datum.val) } - pub fn copy_to(&self, bcx: @Block, action: CopyAction, dst: ValueRef) - -> @Block { + pub fn copy_to<'a>( + &self, + bcx: &'a Block<'a>, + action: CopyAction, + dst: ValueRef) + -> &'a Block<'a> { /*! * * Copies the value into `dst`, which should be a pointer to a @@ -301,11 +315,12 @@ impl Datum { } } - pub fn copy_to_no_check(&self, - bcx: @Block, + pub fn copy_to_no_check<'a>( + &self, + bcx: &'a Block<'a>, action: CopyAction, dst: ValueRef) - -> @Block { + -> &'a Block<'a> { /*! * * A helper for `copy_to()` which does not check to see if we @@ -333,8 +348,12 @@ impl Datum { // This works like copy_val, except that it deinitializes the source. // Since it needs to zero out the source, src also needs to be an lval. // - pub fn move_to(&self, bcx: @Block, action: CopyAction, dst: ValueRef) - -> @Block { + pub fn move_to<'a>( + &self, + bcx: &'a Block<'a>, + action: CopyAction, + dst: ValueRef) + -> &'a Block<'a> { let _icx = push_ctxt("move_to"); let mut bcx = bcx; @@ -363,7 +382,7 @@ impl Datum { return bcx; } - pub fn add_clean(&self, bcx: @Block) { + pub fn add_clean(&self, bcx: &Block) { /*! * Schedules this datum for cleanup in `bcx`. The datum * must be an rvalue. @@ -383,7 +402,7 @@ impl Datum { } } - pub fn cancel_clean(&self, bcx: @Block) { + pub fn cancel_clean(&self, bcx: &Block) { if ty::type_needs_drop(bcx.tcx(), self.ty) { match self.mode { ByValue | @@ -408,7 +427,7 @@ impl Datum { self.mode) } - pub fn to_value_datum(&self, bcx: @Block) -> Datum { + pub fn to_value_datum(&self, bcx: &Block) -> Datum { /*! * * Yields a by-value form of this datum. This may involve @@ -425,7 +444,7 @@ impl Datum { } } - pub fn to_value_llval(&self, bcx: @Block) -> ValueRef { + pub fn to_value_llval(&self, bcx: &Block) -> ValueRef { /*! * * Yields the value itself. */ @@ -446,7 +465,7 @@ impl Datum { } } - pub fn to_ref_datum(&self, bcx: @Block) -> Datum { + pub fn to_ref_datum(&self, bcx: &Block) -> Datum { /*! * Yields a by-ref form of this datum. This may involve * creation of a temporary stack slot. The value returned by @@ -463,7 +482,7 @@ impl Datum { } } - pub fn to_ref_llval(&self, bcx: @Block) -> ValueRef { + pub fn to_ref_llval(&self, bcx: &Block) -> ValueRef { match self.mode { ByRef(_) => self.val, ByValue => { @@ -496,7 +515,7 @@ impl Datum { appropriate_mode(ccx, self.ty) } - pub fn to_appropriate_llval(&self, bcx: @Block) -> ValueRef { + pub fn to_appropriate_llval(&self, bcx: &Block) -> ValueRef { /*! * * Yields an llvalue with the `appropriate_mode()`. */ @@ -507,7 +526,7 @@ impl Datum { } } - pub fn to_appropriate_datum(&self, bcx: @Block) -> Datum { + pub fn to_appropriate_datum(&self, bcx: &Block) -> Datum { /*! * * Yields a datum with the `appropriate_mode()`. */ @@ -519,7 +538,7 @@ impl Datum { } pub fn get_element(&self, - bcx: @Block, + bcx: &Block, ty: ty::t, source: DatumCleanup, gep: |ValueRef| -> ValueRef) @@ -532,7 +551,7 @@ impl Datum { } } - pub fn drop_val(&self, bcx: @Block) -> @Block { + pub fn drop_val<'a>(&self, bcx: &'a Block<'a>) -> &'a Block<'a> { if !ty::type_needs_drop(bcx.tcx(), self.ty) { return bcx; } @@ -543,7 +562,7 @@ impl Datum { }; } - pub fn box_body(&self, bcx: @Block) -> Datum { + pub fn box_body(&self, bcx: &Block) -> Datum { /*! * * This datum must represent an @T or ~T box. Returns a new @@ -576,7 +595,7 @@ impl Datum { } } - pub fn to_rptr(&self, bcx: @Block) -> Datum { + pub fn to_rptr(&self, bcx: &Block) -> Datum { //! Returns a new datum of region-pointer type containing the //! the same ptr as this datum (after converting to by-ref //! using `to_ref_llval()`). @@ -596,13 +615,14 @@ impl Datum { /// expr_id: ID of deref expr. /// derefs: Number of times deref'd already. /// is_auto: If true, only deref if auto-derefable. - pub fn try_deref(&self, - bcx: @Block, + pub fn try_deref<'a>( + &self, + bcx: &'a Block<'a>, span: Span, expr_id: ast::NodeId, derefs: uint, is_auto: bool) - -> (Option, @Block) { + -> (Option, &'a Block<'a>) { debug!("try_deref(expr_id={:?}, derefs={:?}, is_auto={}, self={:?})", expr_id, derefs, is_auto, self.to_str(bcx.ccx())); @@ -629,7 +649,7 @@ impl Datum { } } - fn deref_ptr(bcx: @Block, lv: &Datum, ty: ty::t) -> Datum { + fn deref_ptr(bcx: &Block, lv: &Datum, ty: ty::t) -> Datum { Datum { val: lv.to_value_llval(bcx), ty: ty, @@ -639,8 +659,12 @@ impl Datum { } /// expr: The deref expression. - pub fn deref(&self, bcx: @Block, expr: &ast::Expr, derefs: uint) - -> DatumBlock { + pub fn deref<'a>( + &self, + bcx: &'a Block<'a>, + expr: &ast::Expr, + derefs: uint) + -> DatumBlock<'a> { match self.try_deref(bcx, expr.span, expr.id, derefs, false) { (Some(lvres), bcx) => DatumBlock { bcx: bcx, datum: lvres }, (None, _) => { @@ -650,12 +674,13 @@ impl Datum { } } - pub fn autoderef(&self, - bcx: @Block, + pub fn autoderef<'a>( + &self, + bcx: &'a Block<'a>, span: Span, expr_id: ast::NodeId, max: uint) - -> DatumBlock { + -> DatumBlock<'a> { let _icx = push_ctxt("autoderef"); debug!("autoderef(expr_id={}, max={:?}, self={:?})", @@ -683,12 +708,13 @@ impl Datum { DatumBlock { bcx: bcx, datum: datum } } - pub fn get_vec_base_and_byte_len(&self, - mut bcx: @Block, + pub fn get_vec_base_and_byte_len<'a>( + &self, + mut bcx: &'a Block<'a>, span: Span, expr_id: ast::NodeId, derefs: uint) - -> (@Block, ValueRef, ValueRef) { + -> (&'a Block<'a>, ValueRef, ValueRef) { //! Converts a vector into the slice pair. Performs rooting //! and write guards checks. @@ -698,7 +724,7 @@ impl Datum { (bcx, base, len) } - pub fn get_vec_base_and_byte_len_no_root(&self, bcx: @Block) + pub fn get_vec_base_and_byte_len_no_root(&self, bcx: &Block) -> (ValueRef, ValueRef) { //! Converts a vector into the slice pair. Des not root //! nor perform write guard checks. @@ -707,12 +733,13 @@ impl Datum { tvec::get_base_and_byte_len(bcx, llval, self.ty) } - pub fn get_vec_base_and_len(&self, - mut bcx: @Block, - span: Span, - expr_id: ast::NodeId, - derefs: uint) - -> (@Block, ValueRef, ValueRef) { + pub fn get_vec_base_and_len<'a>( + &self, + mut bcx: &'a Block<'a>, + span: Span, + expr_id: ast::NodeId, + derefs: uint) + -> (&'a Block<'a>, ValueRef, ValueRef) { //! Converts a vector into the slice pair. Performs rooting //! and write guards checks. @@ -722,8 +749,8 @@ impl Datum { (bcx, base, len) } - pub fn get_vec_base_and_len_no_root(&self, bcx: @Block) - -> (ValueRef, ValueRef) { + pub fn get_vec_base_and_len_no_root<'a>(&self, bcx: &'a Block<'a>) + -> (ValueRef, ValueRef) { //! Converts a vector into the slice pair. Des not root //! nor perform write guard checks. @@ -731,47 +758,48 @@ impl Datum { tvec::get_base_and_len(bcx, llval, self.ty) } - pub fn root_and_write_guard(&self, - bcx: @Block, + pub fn root_and_write_guard<'a>( + &self, + bcx: &'a Block<'a>, span: Span, expr_id: ast::NodeId, derefs: uint) - -> @Block { + -> &'a Block<'a> { write_guard::root_and_write_guard(self, bcx, span, expr_id, derefs) } - pub fn to_result(&self, bcx: @Block) -> common::Result { + pub fn to_result<'a>(&self, bcx: &'a Block<'a>) -> common::Result<'a> { rslt(bcx, self.to_appropriate_llval(bcx)) } } -impl DatumBlock { - pub fn unpack(&self, bcx: &mut @Block) -> Datum { +impl<'a> DatumBlock<'a> { + pub fn unpack(&self, bcx: &mut &'a Block<'a>) -> Datum { *bcx = self.bcx; return self.datum; } - pub fn assert_by_ref(&self) -> DatumBlock { + pub fn assert_by_ref(&self) -> DatumBlock<'a> { assert!(self.datum.mode.is_by_ref()); *self } - pub fn drop_val(&self) -> @Block { + pub fn drop_val(&self) -> &'a Block<'a> { self.datum.drop_val(self.bcx) } - pub fn store_to(&self, - action: CopyAction, - dst: ValueRef) - -> @Block { + pub fn store_to(&self, action: CopyAction, dst: ValueRef) + -> &'a Block<'a> { self.datum.store_to(self.bcx, action, dst) } - pub fn copy_to(&self, action: CopyAction, dst: ValueRef) -> @Block { + pub fn copy_to(&self, action: CopyAction, dst: ValueRef) + -> &'a Block<'a> { self.datum.copy_to(self.bcx, action, dst) } - pub fn move_to(&self, action: CopyAction, dst: ValueRef) -> @Block { + pub fn move_to(&self, action: CopyAction, dst: ValueRef) + -> &'a Block<'a> { self.datum.move_to(self.bcx, action, dst) } @@ -779,7 +807,7 @@ impl DatumBlock { self.datum.to_value_llval(self.bcx) } - pub fn to_result(&self) -> common::Result { + pub fn to_result(&self) -> common::Result<'a> { rslt(self.bcx, self.datum.to_appropriate_llval(self.bcx)) } diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 2deff5bc5ee..549e5d18fbe 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -270,8 +270,7 @@ pub fn finalize(cx: @CrateContext) { /// Creates debug information for the given local variable. /// /// Adds the created metadata nodes directly to the crate's IR. -pub fn create_local_var_metadata(bcx: @Block, - local: &ast::Local) { +pub fn create_local_var_metadata(bcx: &Block, local: &ast::Local) { if fn_should_be_ignored(bcx.fcx) { return; } @@ -310,7 +309,7 @@ pub fn create_local_var_metadata(bcx: @Block, /// Creates debug information for a variable captured in a closure. /// /// Adds the created metadata nodes directly to the crate's IR. -pub fn create_captured_var_metadata(bcx: @Block, +pub fn create_captured_var_metadata(bcx: &Block, node_id: ast::NodeId, env_data_type: ty::t, env_pointer: ValueRef, @@ -380,7 +379,7 @@ pub fn create_captured_var_metadata(bcx: @Block, /// Creates debug information for a local variable introduced in the head of a match-statement arm. /// /// Adds the created metadata nodes directly to the crate's IR. -pub fn create_match_binding_metadata(bcx: @Block, +pub fn create_match_binding_metadata(bcx: &Block, variable_ident: ast::Ident, node_id: ast::NodeId, variable_type: ty::t, @@ -417,7 +416,7 @@ pub fn create_match_binding_metadata(bcx: @Block, /// Creates debug information for the self argument of a method. /// /// Adds the created metadata nodes directly to the crate's IR. -pub fn create_self_argument_metadata(bcx: @Block, +pub fn create_self_argument_metadata(bcx: &Block, type_of_self: ty::t, llptr: ValueRef) { if fn_should_be_ignored(bcx.fcx) { @@ -495,8 +494,7 @@ pub fn create_self_argument_metadata(bcx: @Block, /// Creates debug information for the given function argument. /// /// Adds the created metadata nodes directly to the crate's IR. -pub fn create_argument_metadata(bcx: @Block, - arg: &ast::arg) { +pub fn create_argument_metadata(bcx: &Block, arg: &ast::arg) { if fn_should_be_ignored(bcx.fcx) { return; } @@ -973,7 +971,7 @@ fn compile_unit_metadata(cx: @CrateContext) { }); } -fn declare_local(bcx: @Block, +fn declare_local(bcx: &Block, variable_ident: ast::Ident, variable_type: ty::t, scope_metadata: DIScope, diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 640f9339a7d..422e7042505 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -175,7 +175,8 @@ impl Dest { } } -pub fn trans_to_datum(bcx: @Block, expr: &ast::Expr) -> DatumBlock { +pub fn trans_to_datum<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) + -> DatumBlock<'a> { debug!("trans_to_datum(expr={})", bcx.expr_to_str(expr)); let mut bcx = bcx; @@ -249,13 +250,15 @@ pub fn trans_to_datum(bcx: @Block, expr: &ast::Expr) -> DatumBlock { debug!("after adjustments, datum={}", datum.to_str(bcx.ccx())); return DatumBlock {bcx: bcx, datum: datum}; - fn auto_ref(bcx: @Block, datum: Datum) -> DatumBlock { + fn auto_ref<'a>(bcx: &'a Block<'a>, datum: Datum) -> DatumBlock<'a> { DatumBlock {bcx: bcx, datum: datum.to_rptr(bcx)} } - fn auto_borrow_fn(bcx: @Block, + fn auto_borrow_fn<'a>( + bcx: &'a Block<'a>, adjusted_ty: ty::t, - datum: Datum) -> DatumBlock { + datum: Datum) + -> DatumBlock<'a> { // Currently, all closure types are represented precisely the // same, so no runtime adjustment is required, but we still // must patchup the type. @@ -264,10 +267,12 @@ pub fn trans_to_datum(bcx: @Block, expr: &ast::Expr) -> DatumBlock { mode: datum.mode}} } - fn auto_slice(bcx: @Block, + fn auto_slice<'a>( + bcx: &'a Block<'a>, autoderefs: uint, expr: &ast::Expr, - datum: Datum) -> DatumBlock { + datum: Datum) + -> DatumBlock<'a> { // This is not the most efficient thing possible; since slices // are two words it'd be better if this were compiled in // 'dest' mode, but I can't find a nice way to structure the @@ -293,7 +298,8 @@ pub fn trans_to_datum(bcx: @Block, expr: &ast::Expr) -> DatumBlock { DatumBlock {bcx: bcx, datum: scratch} } - fn add_env(bcx: @Block, expr: &ast::Expr, datum: Datum) -> DatumBlock { + fn add_env<'a>(bcx: &'a Block<'a>, expr: &ast::Expr, datum: Datum) + -> DatumBlock<'a> { // This is not the most efficient thing possible; since closures // are two words it'd be better if this were compiled in // 'dest' mode, but I can't find a nice way to structure the @@ -312,18 +318,22 @@ pub fn trans_to_datum(bcx: @Block, expr: &ast::Expr) -> DatumBlock { DatumBlock {bcx: bcx, datum: scratch} } - fn auto_slice_and_ref(bcx: @Block, + fn auto_slice_and_ref<'a>( + bcx: &'a Block<'a>, autoderefs: uint, expr: &ast::Expr, - datum: Datum) -> DatumBlock { + datum: Datum) + -> DatumBlock<'a> { let DatumBlock { bcx, datum } = auto_slice(bcx, autoderefs, expr, datum); auto_ref(bcx, datum) } - fn auto_borrow_obj(mut bcx: @Block, + fn auto_borrow_obj<'a>( + mut bcx: &'a Block<'a>, autoderefs: uint, expr: &ast::Expr, - source_datum: Datum) -> DatumBlock { + source_datum: Datum) + -> DatumBlock<'a> { let tcx = bcx.tcx(); let target_obj_ty = expr_ty_adjusted(bcx, expr); debug!("auto_borrow_obj(target={})", @@ -428,7 +438,8 @@ pub fn trans_to_datum(bcx: @Block, expr: &ast::Expr) -> DatumBlock { } } -pub fn trans_into(bcx: @Block, expr: &ast::Expr, dest: Dest) -> @Block { +pub fn trans_into<'a>(bcx: &'a Block<'a>, expr: &ast::Expr, dest: Dest) + -> &'a Block<'a> { let adjustment_found = { let adjustments = bcx.tcx().adjustments.borrow(); adjustments.get().contains_key(&expr.id) @@ -446,7 +457,11 @@ pub fn trans_into(bcx: @Block, expr: &ast::Expr, dest: Dest) -> @Block { trans_into_unadjusted(bcx, expr, dest) } -pub fn trans_into_unadjusted(bcx: @Block, expr: &ast::Expr, dest: Dest) -> @Block { +pub fn trans_into_unadjusted<'a>( + bcx: &'a Block<'a>, + expr: &ast::Expr, + dest: Dest) + -> &'a Block<'a> { let ty = expr_ty(bcx, expr); debug!("trans_into_unadjusted(expr={}, dest={})", @@ -494,7 +509,7 @@ pub fn trans_into_unadjusted(bcx: @Block, expr: &ast::Expr, dest: Dest) -> @Bloc }; } -fn trans_lvalue(bcx: @Block, expr: &ast::Expr) -> DatumBlock { +fn trans_lvalue<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) -> DatumBlock<'a> { /*! * * Translates an lvalue expression, always yielding a by-ref @@ -517,7 +532,8 @@ fn trans_lvalue(bcx: @Block, expr: &ast::Expr) -> DatumBlock { } } -fn trans_to_datum_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock { +fn trans_to_datum_unadjusted<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) + -> DatumBlock<'a> { /*! * Translates an expression into a datum. If this expression * is an rvalue, this will result in a temporary value being @@ -577,13 +593,17 @@ fn trans_to_datum_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock { } } - fn nil(bcx: @Block, ty: ty::t) -> DatumBlock { + fn nil<'a>(bcx: &'a Block<'a>, ty: ty::t) -> DatumBlock<'a> { let datum = immediate_rvalue(C_nil(), ty); - DatumBlock {bcx: bcx, datum: datum} + DatumBlock { + bcx: bcx, + datum: datum, + } } } -fn trans_rvalue_datum_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock { +fn trans_rvalue_datum_unadjusted<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) + -> DatumBlock<'a> { let _icx = push_ctxt("trans_rvalue_datum_unadjusted"); match expr.node { @@ -636,7 +656,8 @@ fn trans_rvalue_datum_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock { } } -fn trans_rvalue_stmt_unadjusted(bcx: @Block, expr: &ast::Expr) -> @Block { +fn trans_rvalue_stmt_unadjusted<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) + -> &'a Block<'a> { let mut bcx = bcx; let _icx = push_ctxt("trans_rvalue_stmt"); @@ -688,8 +709,11 @@ fn trans_rvalue_stmt_unadjusted(bcx: @Block, expr: &ast::Expr) -> @Block { }; } -fn trans_rvalue_dps_unadjusted(bcx: @Block, expr: &ast::Expr, - dest: Dest) -> @Block { +fn trans_rvalue_dps_unadjusted<'a>( + bcx: &'a Block<'a>, + expr: &ast::Expr, + dest: Dest) + -> &'a Block<'a> { let _icx = push_ctxt("trans_rvalue_dps_unadjusted"); let tcx = bcx.tcx(); @@ -813,8 +837,12 @@ fn trans_rvalue_dps_unadjusted(bcx: @Block, expr: &ast::Expr, } } -fn trans_def_dps_unadjusted(bcx: @Block, ref_expr: &ast::Expr, - def: ast::Def, dest: Dest) -> @Block { +fn trans_def_dps_unadjusted<'a>( + bcx: &'a Block<'a>, + ref_expr: &ast::Expr, + def: ast::Def, + dest: Dest) + -> &'a Block<'a> { let _icx = push_ctxt("trans_def_dps_unadjusted"); let ccx = bcx.ccx(); @@ -863,10 +891,11 @@ fn trans_def_dps_unadjusted(bcx: @Block, ref_expr: &ast::Expr, } } -fn trans_def_datum_unadjusted(bcx: @Block, +fn trans_def_datum_unadjusted<'a>( + bcx: &'a Block<'a>, ref_expr: &ast::Expr, - def: ast::Def) -> DatumBlock -{ + def: ast::Def) + -> DatumBlock<'a> { let _icx = push_ctxt("trans_def_datum_unadjusted"); let fn_data = match def { @@ -898,7 +927,8 @@ fn trans_def_datum_unadjusted(bcx: @Block, } } -fn trans_lvalue_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock { +fn trans_lvalue_unadjusted<'a>(bcx: &'a Block<'a>, expr: &ast::Expr) + -> DatumBlock<'a> { /*! * * Translates an lvalue expression, always yielding a by-ref @@ -935,9 +965,11 @@ fn trans_lvalue_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock { } }; - fn trans_rec_field(bcx: @Block, + fn trans_rec_field<'a>( + bcx: &'a Block<'a>, base: &ast::Expr, - field: ast::Ident) -> DatumBlock { + field: ast::Ident) + -> DatumBlock<'a> { //! Translates `base.field`. let mut bcx = bcx; @@ -959,10 +991,12 @@ fn trans_lvalue_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock { }) } - fn trans_index(bcx: @Block, + fn trans_index<'a>( + bcx: &'a Block<'a>, index_expr: &ast::Expr, base: &ast::Expr, - idx: &ast::Expr) -> DatumBlock { + idx: &ast::Expr) + -> DatumBlock<'a> { //! Translates `base[idx]`. let _icx = push_ctxt("trans_index"); @@ -1013,11 +1047,11 @@ fn trans_lvalue_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock { }; } - fn trans_def_lvalue(bcx: @Block, + fn trans_def_lvalue<'a>( + bcx: &'a Block<'a>, ref_expr: &ast::Expr, def: ast::Def) - -> DatumBlock - { + -> DatumBlock<'a> { //! Translates a reference to a path. let _icx = push_ctxt("trans_def_lvalue"); @@ -1034,7 +1068,7 @@ fn trans_lvalue_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock { } } - fn get_val(bcx: @Block, did: ast::DefId, const_ty: ty::t) + fn get_val(bcx: &Block, did: ast::DefId, const_ty: ty::t) -> ValueRef { // For external constants, we don't inline. if did.crate == ast::LOCAL_CRATE { @@ -1094,7 +1128,7 @@ fn trans_lvalue_unadjusted(bcx: @Block, expr: &ast::Expr) -> DatumBlock { } } -pub fn trans_local_var(bcx: @Block, def: ast::Def) -> Datum { +pub fn trans_local_var(bcx: &Block, def: ast::Def) -> Datum { let _icx = push_ctxt("trans_local_var"); return match def { @@ -1149,9 +1183,10 @@ pub fn trans_local_var(bcx: @Block, def: ast::Def) -> Datum { } }; - fn take_local(bcx: @Block, + fn take_local(bcx: &Block, table: &HashMap, - nid: ast::NodeId) -> Datum { + nid: ast::NodeId) + -> Datum { let v = match table.find(&nid) { Some(&v) => v, None => { @@ -1222,13 +1257,14 @@ pub fn with_field_tys( } } -fn trans_rec_or_struct(bcx: @Block, +fn trans_rec_or_struct<'a>( + bcx: &'a Block<'a>, fields: &[ast::Field], base: Option<@ast::Expr>, expr_span: codemap::Span, id: ast::NodeId, - dest: Dest) -> @Block -{ + dest: Dest) + -> &'a Block<'a> { let _icx = push_ctxt("trans_rec"); let bcx = bcx; @@ -1301,10 +1337,14 @@ struct StructBaseInfo { * - `optbase` contains information on the base struct (if any) from * which remaining fields are copied; see comments on `StructBaseInfo`. */ -fn trans_adt(bcx: @Block, repr: &adt::Repr, discr: ty::Disr, +fn trans_adt<'a>( + bcx: &'a Block<'a>, + repr: &adt::Repr, + discr: ty::Disr, fields: &[(uint, @ast::Expr)], optbase: Option, - dest: Dest) -> @Block { + dest: Dest) + -> &'a Block<'a> { let _icx = push_ctxt("trans_adt"); let mut bcx = bcx; let addr = match dest { @@ -1349,18 +1389,23 @@ fn trans_adt(bcx: @Block, repr: &adt::Repr, discr: ty::Disr, } -fn trans_immediate_lit(bcx: @Block, expr: &ast::Expr, - lit: ast::lit) -> DatumBlock { +fn trans_immediate_lit<'a>( + bcx: &'a Block<'a>, + expr: &ast::Expr, + lit: ast::lit) + -> DatumBlock<'a> { // must not be a string constant, that is a RvalueDpsExpr let _icx = push_ctxt("trans_immediate_lit"); let ty = expr_ty(bcx, expr); immediate_rvalue_bcx(bcx, consts::const_lit(bcx.ccx(), expr, lit), ty) } -fn trans_unary_datum(bcx: @Block, +fn trans_unary_datum<'a>( + bcx: &'a Block<'a>, un_expr: &ast::Expr, op: ast::UnOp, - sub_expr: &ast::Expr) -> DatumBlock { + sub_expr: &ast::Expr) + -> DatumBlock<'a> { let _icx = push_ctxt("trans_unary_datum"); // if deref, would be LvalueExpr @@ -1419,11 +1464,13 @@ fn trans_unary_datum(bcx: @Block, } }; - fn trans_boxed_expr(bcx: @Block, + fn trans_boxed_expr<'a>( + bcx: &'a Block<'a>, box_ty: ty::t, contents: &ast::Expr, contents_ty: ty::t, - heap: heap) -> DatumBlock { + heap: heap) + -> DatumBlock<'a> { let _icx = push_ctxt("trans_boxed_expr"); if heap == heap_exchange { let llty = type_of::type_of(bcx.ccx(), contents_ty); @@ -1448,8 +1495,11 @@ fn trans_unary_datum(bcx: @Block, } } -fn trans_addr_of(bcx: @Block, expr: &ast::Expr, - subexpr: &ast::Expr) -> DatumBlock { +fn trans_addr_of<'a>( + bcx: &'a Block<'a>, + expr: &ast::Expr, + subexpr: &ast::Expr) + -> DatumBlock<'a> { let _icx = push_ctxt("trans_addr_of"); let mut bcx = bcx; let sub_datum = unpack_datum!(bcx, trans_to_datum(bcx, subexpr)); @@ -1459,13 +1509,14 @@ fn trans_addr_of(bcx: @Block, expr: &ast::Expr, // Important to get types for both lhs and rhs, because one might be _|_ // and the other not. -fn trans_eager_binop(bcx: @Block, +fn trans_eager_binop<'a>( + bcx: &'a Block<'a>, binop_expr: &ast::Expr, binop_ty: ty::t, op: ast::BinOp, lhs_datum: &Datum, rhs_datum: &Datum) - -> DatumBlock { + -> DatumBlock<'a> { let _icx = push_ctxt("trans_eager_binop"); let lhs = lhs_datum.to_appropriate_llval(bcx); @@ -1560,13 +1611,18 @@ fn trans_eager_binop(bcx: @Block, } // refinement types would obviate the need for this -enum lazy_binop_ty { lazy_and, lazy_or } +enum lazy_binop_ty { + lazy_and, + lazy_or, +} -fn trans_lazy_binop(bcx: @Block, +fn trans_lazy_binop<'a>( + bcx: &'a Block<'a>, binop_expr: &ast::Expr, op: lazy_binop_ty, a: &ast::Expr, - b: &ast::Expr) -> DatumBlock { + b: &ast::Expr) + -> DatumBlock<'a> { let _icx = push_ctxt("trans_lazy_binop"); let binop_ty = expr_ty(bcx, binop_expr); let bcx = bcx; @@ -1607,12 +1663,13 @@ fn trans_lazy_binop(bcx: @Block, return immediate_rvalue_bcx(join, phi, binop_ty); } -fn trans_binary(bcx: @Block, +fn trans_binary<'a>( + bcx: &'a Block<'a>, binop_expr: &ast::Expr, op: ast::BinOp, lhs: &ast::Expr, - rhs: &ast::Expr) -> DatumBlock -{ + rhs: &ast::Expr) + -> DatumBlock<'a> { let _icx = push_ctxt("trans_binary"); match op { @@ -1633,14 +1690,15 @@ fn trans_binary(bcx: @Block, } } -fn trans_overloaded_op(bcx: @Block, +fn trans_overloaded_op<'a>( + bcx: &'a Block<'a>, expr: &ast::Expr, callee_id: ast::NodeId, rcvr: &ast::Expr, args: ~[@ast::Expr], ret_ty: ty::t, dest: Dest) - -> @Block { + -> &'a Block<'a> { let origin = { let method_map = bcx.ccx().maps.method_map.borrow(); method_map.get().get_copy(&expr.id) @@ -1661,8 +1719,12 @@ fn trans_overloaded_op(bcx: @Block, DoAutorefArg).bcx } -fn int_cast(bcx: @Block, lldsttype: Type, llsrctype: Type, - llsrc: ValueRef, signed: bool) -> ValueRef { +fn int_cast(bcx: &Block, + lldsttype: Type, + llsrctype: Type, + llsrc: ValueRef, + signed: bool) + -> ValueRef { let _icx = push_ctxt("int_cast"); unsafe { let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype.to_ref()); @@ -1679,8 +1741,11 @@ fn int_cast(bcx: @Block, lldsttype: Type, llsrctype: Type, } } -fn float_cast(bcx: @Block, lldsttype: Type, llsrctype: Type, - llsrc: ValueRef) -> ValueRef { +fn float_cast(bcx: &Block, + lldsttype: Type, + llsrctype: Type, + llsrc: ValueRef) + -> ValueRef { let _icx = push_ctxt("float_cast"); let srcsz = llsrctype.float_width(); let dstsz = lldsttype.float_width(); @@ -1715,8 +1780,8 @@ pub fn cast_type_kind(t: ty::t) -> cast_kind { } } -fn trans_imm_cast(bcx: @Block, expr: &ast::Expr, - id: ast::NodeId) -> DatumBlock { +fn trans_imm_cast<'a>(bcx: &'a Block<'a>, expr: &ast::Expr, id: ast::NodeId) + -> DatumBlock<'a> { let _icx = push_ctxt("trans_cast"); let ccx = bcx.ccx(); @@ -1790,13 +1855,14 @@ fn trans_imm_cast(bcx: @Block, expr: &ast::Expr, return immediate_rvalue_bcx(bcx, newval, t_out); } -fn trans_assign_op(bcx: @Block, +fn trans_assign_op<'a>( + bcx: &'a Block<'a>, expr: &ast::Expr, callee_id: ast::NodeId, op: ast::BinOp, dst: &ast::Expr, - src: @ast::Expr) -> @Block -{ + src: @ast::Expr) + -> &'a Block<'a> { let _icx = push_ctxt("trans_assign_op"); let mut bcx = bcx; @@ -1835,7 +1901,7 @@ fn trans_assign_op(bcx: @Block, return result_datum.copy_to_datum(bcx, DROP_EXISTING, dst_datum); } -pub fn trans_log_level(bcx: @Block) -> DatumBlock { +pub fn trans_log_level<'a>(bcx: &'a Block<'a>) -> DatumBlock<'a> { let _icx = push_ctxt("trans_log_level"); let ccx = bcx.ccx(); @@ -1891,3 +1957,4 @@ pub fn trans_log_level(bcx: @Block) -> DatumBlock { return immediate_rvalue_bcx(bcx, Load(bcx, global), ty::mk_u32()); } + diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 7c4c9f8937f..b9d4defc5be 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -161,12 +161,14 @@ pub fn register_foreign_item_fn(ccx: @CrateContext, return llfn; } -pub fn trans_native_call(bcx: @Block, +pub fn trans_native_call<'a>( + bcx: &'a Block<'a>, callee_ty: ty::t, llfn: ValueRef, llretptr: ValueRef, llargs_rust: &[ValueRef], - passed_arg_tys: ~[ty::t]) -> @Block { + passed_arg_tys: ~[ty::t]) + -> &'a Block<'a> { /*! * Prepares a call to a native function. This requires adapting * from the Rust argument passing rules to the native rules. diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 85efd2d40d0..c93c0db8c3f 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -41,7 +41,7 @@ use std::cell::Cell; use std::libc::c_uint; use syntax::ast; -pub fn trans_free(cx: @Block, v: ValueRef) -> @Block { +pub fn trans_free<'a>(cx: &'a Block<'a>, v: ValueRef) -> &'a Block<'a> { let _icx = push_ctxt("trans_free"); callee::trans_lang_call(cx, langcall(cx, None, "", FreeFnLangItem), @@ -49,7 +49,8 @@ pub fn trans_free(cx: @Block, v: ValueRef) -> @Block { Some(expr::Ignore)).bcx } -pub fn trans_exchange_free(cx: @Block, v: ValueRef) -> @Block { +pub fn trans_exchange_free<'a>(cx: &'a Block<'a>, v: ValueRef) + -> &'a Block<'a> { let _icx = push_ctxt("trans_exchange_free"); callee::trans_lang_call(cx, langcall(cx, None, "", ExchangeFreeFnLangItem), @@ -57,7 +58,8 @@ pub fn trans_exchange_free(cx: @Block, v: ValueRef) -> @Block { Some(expr::Ignore)).bcx } -pub fn take_ty(cx: @Block, v: ValueRef, t: ty::t) -> @Block { +pub fn take_ty<'a>(cx: &'a Block<'a>, v: ValueRef, t: ty::t) + -> &'a Block<'a> { // NB: v is an *alias* of type t here, not a direct value. let _icx = push_ctxt("take_ty"); if ty::type_needs_drop(cx.tcx(), t) { @@ -66,7 +68,8 @@ pub fn take_ty(cx: @Block, v: ValueRef, t: ty::t) -> @Block { return cx; } -pub fn drop_ty(cx: @Block, v: ValueRef, t: ty::t) -> @Block { +pub fn drop_ty<'a>(cx: &'a Block<'a>, v: ValueRef, t: ty::t) + -> &'a Block<'a> { // NB: v is an *alias* of type t here, not a direct value. let _icx = push_ctxt("drop_ty"); if ty::type_needs_drop(cx.tcx(), t) { @@ -75,14 +78,16 @@ pub fn drop_ty(cx: @Block, v: ValueRef, t: ty::t) -> @Block { return cx; } -pub fn drop_ty_immediate(bcx: @Block, v: ValueRef, t: ty::t) -> @Block { +pub fn drop_ty_immediate<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) + -> &'a Block<'a> { let _icx = push_ctxt("drop_ty_immediate"); let vp = alloca(bcx, type_of(bcx.ccx(), t), ""); Store(bcx, v, vp); drop_ty(bcx, vp, t) } -pub fn free_ty(cx: @Block, v: ValueRef, t: ty::t) -> @Block { +pub fn free_ty<'a>(cx: &'a Block<'a>, v: ValueRef, t: ty::t) + -> &'a Block<'a> { // NB: v is an *alias* of type t here, not a direct value. let _icx = push_ctxt("free_ty"); if ty::type_needs_drop(cx.tcx(), t) { @@ -91,7 +96,8 @@ pub fn free_ty(cx: @Block, v: ValueRef, t: ty::t) -> @Block { return cx; } -pub fn free_ty_immediate(bcx: @Block, v: ValueRef, t: ty::t) -> @Block { +pub fn free_ty_immediate<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) + -> &'a Block<'a> { let _icx = push_ctxt("free_ty_immediate"); match ty::get(t).sty { ty::ty_uniq(_) | @@ -269,7 +275,7 @@ pub fn lazily_emit_tydesc_glue(ccx: @CrateContext, } // See [Note-arg-mode] -pub fn call_tydesc_glue_full(bcx: @Block, +pub fn call_tydesc_glue_full(bcx: &Block, v: ValueRef, tydesc: ValueRef, field: uint, @@ -328,15 +334,20 @@ pub fn call_tydesc_glue_full(bcx: @Block, } // See [Note-arg-mode] -pub fn call_tydesc_glue(cx: @Block, v: ValueRef, t: ty::t, field: uint) - -> @Block { +pub fn call_tydesc_glue<'a>( + cx: &'a Block<'a>, + v: ValueRef, + t: ty::t, + field: uint) + -> &'a Block<'a> { let _icx = push_ctxt("call_tydesc_glue"); let ti = get_tydesc(cx.ccx(), t); call_tydesc_glue_full(cx, v, ti.tydesc, field, Some(ti)); return cx; } -pub fn make_visit_glue(bcx: @Block, v: ValueRef, t: ty::t) -> @Block { +pub fn make_visit_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) + -> &'a Block<'a> { let _icx = push_ctxt("make_visit_glue"); with_scope(bcx, None, "visitor cleanup", |bcx| { let mut bcx = bcx; @@ -355,7 +366,8 @@ pub fn make_visit_glue(bcx: @Block, v: ValueRef, t: ty::t) -> @Block { }) } -pub fn make_free_glue(bcx: @Block, v: ValueRef, t: ty::t) -> @Block { +pub fn make_free_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) + -> &'a Block<'a> { // NB: v0 is an *alias* of type t here, not a direct value. let _icx = push_ctxt("make_free_glue"); match ty::get(t).sty { @@ -392,8 +404,14 @@ pub fn make_free_glue(bcx: @Block, v: ValueRef, t: ty::t) -> @Block { } } -pub fn trans_struct_drop_flag(bcx: @Block, t: ty::t, v0: ValueRef, dtor_did: ast::DefId, - class_did: ast::DefId, substs: &ty::substs) -> @Block { +pub fn trans_struct_drop_flag<'a>( + bcx: &'a Block<'a>, + t: ty::t, + v0: ValueRef, + dtor_did: ast::DefId, + class_did: ast::DefId, + substs: &ty::substs) + -> &'a Block<'a> { let repr = adt::represent_type(bcx.ccx(), t); let drop_flag = adt::trans_drop_flag_ptr(bcx, repr, v0); with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag)), |cx| { @@ -401,8 +419,14 @@ pub fn trans_struct_drop_flag(bcx: @Block, t: ty::t, v0: ValueRef, dtor_did: ast }) } -pub fn trans_struct_drop(bcx: @Block, t: ty::t, v0: ValueRef, dtor_did: ast::DefId, - class_did: ast::DefId, substs: &ty::substs) -> @Block { +pub fn trans_struct_drop<'a>( + bcx: &'a Block<'a>, + t: ty::t, + v0: ValueRef, + dtor_did: ast::DefId, + class_did: ast::DefId, + substs: &ty::substs) + -> &'a Block<'a> { let repr = adt::represent_type(bcx.ccx(), t); // Find and call the actual destructor @@ -439,7 +463,8 @@ pub fn trans_struct_drop(bcx: @Block, t: ty::t, v0: ValueRef, dtor_did: ast::Def }) } -pub fn make_drop_glue(bcx: @Block, v0: ValueRef, t: ty::t) -> @Block { +pub fn make_drop_glue<'a>(bcx: &'a Block<'a>, v0: ValueRef, t: ty::t) + -> &'a Block<'a> { // NB: v0 is an *alias* of type t here, not a direct value. let _icx = push_ctxt("make_drop_glue"); let ccx = bcx.ccx(); @@ -510,10 +535,12 @@ pub fn make_drop_glue(bcx: @Block, v0: ValueRef, t: ty::t) -> @Block { } // box_ptr_ptr is optional, it is constructed if not supplied. -pub fn decr_refcnt_maybe_free(bcx: @Block, box_ptr: ValueRef, +pub fn decr_refcnt_maybe_free<'a>( + bcx: &'a Block<'a>, + box_ptr: ValueRef, box_ptr_ptr: Option, t: ty::t) - -> @Block { + -> &'a Block<'a> { let _icx = push_ctxt("decr_refcnt_maybe_free"); let ccx = bcx.ccx(); @@ -539,7 +566,8 @@ pub fn decr_refcnt_maybe_free(bcx: @Block, box_ptr: ValueRef, } -pub fn make_take_glue(bcx: @Block, v: ValueRef, t: ty::t) -> @Block { +pub fn make_take_glue<'a>(bcx: &'a Block<'a>, v: ValueRef, t: ty::t) + -> &'a Block<'a> { let _icx = push_ctxt("make_take_glue"); // NB: v is a *pointer* to type t here, not a direct value. match ty::get(t).sty { @@ -580,7 +608,7 @@ pub fn make_take_glue(bcx: @Block, v: ValueRef, t: ty::t) -> @Block { } } -pub fn incr_refcnt_of_boxed(cx: @Block, box_ptr: ValueRef) { +pub fn incr_refcnt_of_boxed(cx: &Block, box_ptr: ValueRef) { let _icx = push_ctxt("incr_refcnt_of_boxed"); let ccx = cx.ccx(); let rc_ptr = GEPi(cx, box_ptr, [0u, abi::box_field_refcnt]); @@ -644,8 +672,8 @@ pub fn declare_tydesc(ccx: &CrateContext, t: ty::t) -> @tydesc_info { return inf; } -pub type glue_helper<'a> = 'a |@Block, ValueRef, ty::t| - -> @Block; +pub type glue_helper<'a> = + 'a |&'a Block<'a>, ValueRef, ty::t| -> &'a Block<'a>; pub fn declare_generic_glue(ccx: &CrateContext, t: ty::t, llfnty: Type, name: &str) -> ValueRef { @@ -663,7 +691,10 @@ pub fn make_generic_glue_inner(ccx: @CrateContext, helper: glue_helper) -> ValueRef { let _icx = push_ctxt("make_generic_glue_inner"); + let fcx = new_fn_ctxt(ccx, ~[], llfn, ty::mk_nil(), None); + init_function(&fcx, false, ty::mk_nil(), None, None); + lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage); ccx.stats.n_glues_created.set(ccx.stats.n_glues_created.get() + 1u); // All glue functions take values passed *by alias*; this is a @@ -679,7 +710,7 @@ pub fn make_generic_glue_inner(ccx: @CrateContext, let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) }; let bcx = helper(bcx, llrawptr0, t); - finish_fn(fcx, bcx); + finish_fn(&fcx, bcx); return llfn; } diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs index c1096f73322..fe9d227f053 100644 --- a/src/librustc/middle/trans/intrinsic.rs +++ b/src/librustc/middle/trans/intrinsic.rs @@ -38,7 +38,7 @@ pub fn trans_intrinsic(ccx: @CrateContext, ref_id: Option) { debug!("trans_intrinsic(item.ident={})", ccx.sess.str_of(item.ident)); - fn simple_llvm_intrinsic(bcx: @Block, name: &'static str, num_args: uint) { + fn simple_llvm_intrinsic(bcx: &Block, name: &'static str, num_args: uint) { assert!(num_args <= 4); let mut args = [0 as ValueRef, ..4]; let first_real_arg = bcx.fcx.arg_pos(0u); @@ -50,7 +50,7 @@ pub fn trans_intrinsic(ccx: @CrateContext, Ret(bcx, llcall); } - fn with_overflow_instrinsic(bcx: @Block, name: &'static str, t: ty::t) { + fn with_overflow_instrinsic(bcx: &Block, name: &'static str, t: ty::t) { let first_real_arg = bcx.fcx.arg_pos(0u); let a = get_param(bcx.fcx.llfn, first_real_arg); let b = get_param(bcx.fcx.llfn, first_real_arg + 1); @@ -73,7 +73,7 @@ pub fn trans_intrinsic(ccx: @CrateContext, } } - fn volatile_load_intrinsic(bcx: @Block) { + fn volatile_load_intrinsic(bcx: &Block) { let first_real_arg = bcx.fcx.arg_pos(0u); let src = get_param(bcx.fcx.llfn, first_real_arg); @@ -81,7 +81,7 @@ pub fn trans_intrinsic(ccx: @CrateContext, Ret(bcx, val); } - fn volatile_store_intrinsic(bcx: @Block) { + fn volatile_store_intrinsic(bcx: &Block) { let first_real_arg = bcx.fcx.arg_pos(0u); let dst = get_param(bcx.fcx.llfn, first_real_arg); let val = get_param(bcx.fcx.llfn, first_real_arg + 1); @@ -90,7 +90,7 @@ pub fn trans_intrinsic(ccx: @CrateContext, RetVoid(bcx); } - fn copy_intrinsic(bcx: @Block, allow_overlap: bool, tp_ty: ty::t) { + fn copy_intrinsic(bcx: &Block, allow_overlap: bool, tp_ty: ty::t) { let ccx = bcx.ccx(); let lltp_ty = type_of::type_of(ccx, tp_ty); let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); @@ -121,7 +121,7 @@ pub fn trans_intrinsic(ccx: @CrateContext, RetVoid(bcx); } - fn memset_intrinsic(bcx: @Block, tp_ty: ty::t) { + fn memset_intrinsic(bcx: &Block, tp_ty: ty::t) { let ccx = bcx.ccx(); let lltp_ty = type_of::type_of(ccx, tp_ty); let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); @@ -143,7 +143,7 @@ pub fn trans_intrinsic(ccx: @CrateContext, RetVoid(bcx); } - fn count_zeros_intrinsic(bcx: @Block, name: &'static str) { + fn count_zeros_intrinsic(bcx: &Block, name: &'static str) { let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u)); let y = C_i1(false); let llfn = bcx.ccx().intrinsics.get_copy(&name); @@ -158,10 +158,9 @@ pub fn trans_intrinsic(ccx: @CrateContext, decl, item.id, output_type, - true, Some(substs), - None, Some(item.span)); + init_function(&fcx, true, output_type, Some(substs), None); set_always_inline(fcx.llfn); diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index ae756aa75ac..8740aaa5cee 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -138,10 +138,12 @@ pub fn trans_method(ccx: @CrateContext, []); } -pub fn trans_self_arg(bcx: @Block, +pub fn trans_self_arg<'a>( + bcx: &'a Block<'a>, base: &ast::Expr, temp_cleanups: &mut ~[ValueRef], - mentry: typeck::method_map_entry) -> Result { + mentry: typeck::method_map_entry) + -> Result<'a> { let _icx = push_ctxt("impl::trans_self_arg"); // self is passed as an opaque box in the environment slot @@ -154,11 +156,12 @@ pub fn trans_self_arg(bcx: @Block, DontAutorefArg) } -pub fn trans_method_callee(bcx: @Block, +pub fn trans_method_callee<'a>( + bcx: &'a Block<'a>, callee_id: ast::NodeId, this: &ast::Expr, mentry: typeck::method_map_entry) - -> Callee { + -> Callee<'a> { let _icx = push_ctxt("impl::trans_method_callee"); debug!("trans_method_callee(callee_id={:?}, this={}, mentry={})", @@ -212,11 +215,11 @@ pub fn trans_method_callee(bcx: @Block, } } -pub fn trans_static_method_callee(bcx: @Block, +pub fn trans_static_method_callee(bcx: &Block, method_id: ast::DefId, trait_id: ast::DefId, callee_id: ast::NodeId) - -> FnData { + -> FnData { let _icx = push_ctxt("impl::trans_static_method_callee"); let ccx = bcx.ccx(); @@ -322,14 +325,15 @@ pub fn method_with_name(ccx: &CrateContext, meth.def_id } -pub fn trans_monomorphized_callee(bcx: @Block, +pub fn trans_monomorphized_callee<'a>( + bcx: &'a Block<'a>, callee_id: ast::NodeId, base: &ast::Expr, mentry: typeck::method_map_entry, trait_id: ast::DefId, n_method: uint, vtbl: typeck::vtable_origin) - -> Callee { + -> Callee<'a> { let _icx = push_ctxt("impl::trans_monomorphized_callee"); return match vtbl { typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => { @@ -379,7 +383,7 @@ pub fn trans_monomorphized_callee(bcx: @Block, } -pub fn combine_impl_and_methods_tps(bcx: @Block, +pub fn combine_impl_and_methods_tps(bcx: &Block, mth_did: ast::DefId, callee_id: ast::NodeId, rcvr_substs: &[ty::t], @@ -428,11 +432,12 @@ pub fn combine_impl_and_methods_tps(bcx: @Block, return (ty_substs, vtables); } -pub fn trans_trait_callee(bcx: @Block, +pub fn trans_trait_callee<'a>( + bcx: &'a Block<'a>, callee_id: ast::NodeId, n_method: uint, self_expr: &ast::Expr) - -> Callee { + -> Callee<'a> { /*! * Create a method callee where the method is coming from a trait * object (e.g., @Trait type). In this case, we must pull the fn @@ -470,12 +475,13 @@ pub fn trans_trait_callee(bcx: @Block, Some(self_scratch.val)) } -pub fn trans_trait_callee_from_llval(bcx: @Block, +pub fn trans_trait_callee_from_llval<'a>( + bcx: &'a Block<'a>, callee_ty: ty::t, n_method: uint, llpair: ValueRef, temp_cleanup: Option) - -> Callee { + -> Callee<'a> { /*! * Same as `trans_trait_callee()` above, except that it is given * a by-ref pointer to the object pair. @@ -541,7 +547,7 @@ pub fn vtable_id(ccx: @CrateContext, /// Creates a returns a dynamic vtable for the given type and vtable origin. /// This is used only for objects. -pub fn get_vtable(bcx: @Block, +pub fn get_vtable(bcx: &Block, self_ty: ty::t, origins: typeck::vtable_param_res) -> ValueRef { @@ -604,7 +610,7 @@ pub fn make_vtable(ccx: &CrateContext, } } -fn emit_vtable_methods(bcx: @Block, +fn emit_vtable_methods(bcx: &Block, impl_id: ast::DefId, substs: &[ty::t], vtables: typeck::vtable_res) @@ -642,13 +648,14 @@ fn emit_vtable_methods(bcx: @Block, }) } -pub fn trans_trait_cast(bcx: @Block, +pub fn trans_trait_cast<'a>( + bcx: &'a Block<'a>, val: &ast::Expr, id: ast::NodeId, dest: expr::Dest, _store: ty::TraitStore, do_adjustments: bool) - -> @Block { + -> &'a Block<'a> { let mut bcx = bcx; let _icx = push_ctxt("impl::trans_cast"); diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index f0ec7fb75dd..181fad4f7e6 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -34,15 +34,15 @@ use syntax::parse::token::special_idents; use middle::trans::type_::Type; -pub struct Reflector { +pub struct Reflector<'a> { visitor_val: ValueRef, visitor_methods: @~[@ty::Method], - final_bcx: @Block, + final_bcx: &'a Block<'a>, tydesc_ty: Type, - bcx: @Block + bcx: &'a Block<'a> } -impl Reflector { +impl<'a> Reflector<'a> { pub fn c_uint(&mut self, u: uint) -> ValueRef { C_uint(self.bcx.ccx(), u) } @@ -301,6 +301,8 @@ impl Reflector { llfdecl, ty::mk_u64(), None); + init_function(&fcx, false, ty::mk_u64(), None, None); + let arg = unsafe { // // we know the return type of llfdecl is an int here, so @@ -317,7 +319,7 @@ impl Reflector { Some(llreturn) => cleanup_and_Br(bcx, bcx, llreturn), None => bcx = cleanup_block(bcx, Some(bcx.llbb)) }; - finish_fn(fcx, bcx); + finish_fn(&fcx, bcx); llfdecl }; @@ -385,11 +387,12 @@ impl Reflector { } // Emit a sequence of calls to visit_ty::visit_foo -pub fn emit_calls_to_trait_visit_ty(bcx: @Block, +pub fn emit_calls_to_trait_visit_ty<'a>( + bcx: &'a Block<'a>, t: ty::t, visitor_val: ValueRef, visitor_trait_id: DefId) - -> @Block { + -> &'a Block<'a> { let final = sub_block(bcx, "final"); let tydesc_ty = ty::get_tydesc_ty(bcx.ccx().tcx).unwrap(); let tydesc_ty = type_of(bcx.ccx(), tydesc_ty); diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 17423c1dd02..18bfe52f643 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -53,18 +53,20 @@ pub fn expand_boxed_vec_ty(tcx: ty::ctxt, t: ty::t) -> ty::t { } } -pub fn get_fill(bcx: @Block, vptr: ValueRef) -> ValueRef { +pub fn get_fill(bcx: &Block, vptr: ValueRef) -> ValueRef { let _icx = push_ctxt("tvec::get_fill"); Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_fill])) } -pub fn set_fill(bcx: @Block, vptr: ValueRef, fill: ValueRef) { + +pub fn set_fill(bcx: &Block, vptr: ValueRef, fill: ValueRef) { Store(bcx, fill, GEPi(bcx, vptr, [0u, abi::vec_elt_fill])); } -pub fn get_alloc(bcx: @Block, vptr: ValueRef) -> ValueRef { + +pub fn get_alloc(bcx: &Block, vptr: ValueRef) -> ValueRef { Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_alloc])) } -pub fn get_bodyptr(bcx: @Block, vptr: ValueRef, t: ty::t) -> ValueRef { +pub fn get_bodyptr(bcx: &Block, vptr: ValueRef, t: ty::t) -> ValueRef { if ty::type_contents(bcx.tcx(), t).owns_managed() { GEPi(bcx, vptr, [0u, abi::box_field_body]) } else { @@ -72,20 +74,25 @@ pub fn get_bodyptr(bcx: @Block, vptr: ValueRef, t: ty::t) -> ValueRef { } } -pub fn get_dataptr(bcx: @Block, vptr: ValueRef) -> ValueRef { +pub fn get_dataptr(bcx: &Block, vptr: ValueRef) -> ValueRef { let _icx = push_ctxt("tvec::get_dataptr"); GEPi(bcx, vptr, [0u, abi::vec_elt_elems, 0u]) } -pub fn pointer_add_byte(bcx: @Block, ptr: ValueRef, bytes: ValueRef) -> ValueRef { +pub fn pointer_add_byte(bcx: &Block, ptr: ValueRef, bytes: ValueRef) -> ValueRef { let _icx = push_ctxt("tvec::pointer_add_byte"); let old_ty = val_ty(ptr); let bptr = PointerCast(bcx, ptr, Type::i8p()); return PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty); } -pub fn alloc_raw(bcx: @Block, unit_ty: ty::t, - fill: ValueRef, alloc: ValueRef, heap: heap) -> Result { +pub fn alloc_raw<'a>( + bcx: &'a Block<'a>, + unit_ty: ty::t, + fill: ValueRef, + alloc: ValueRef, + heap: heap) + -> Result<'a> { let _icx = push_ctxt("tvec::alloc_uniq"); let ccx = bcx.ccx(); @@ -107,16 +114,21 @@ pub fn alloc_raw(bcx: @Block, unit_ty: ty::t, } } -pub fn alloc_uniq_raw(bcx: @Block, unit_ty: ty::t, - fill: ValueRef, alloc: ValueRef) -> Result { +pub fn alloc_uniq_raw<'a>( + bcx: &'a Block<'a>, + unit_ty: ty::t, + fill: ValueRef, + alloc: ValueRef) + -> Result<'a> { alloc_raw(bcx, unit_ty, fill, alloc, base::heap_for_unique(bcx, unit_ty)) } -pub fn alloc_vec(bcx: @Block, +pub fn alloc_vec<'a>( + bcx: &'a Block<'a>, unit_ty: ty::t, elts: uint, heap: heap) - -> Result { + -> Result<'a> { let _icx = push_ctxt("tvec::alloc_uniq"); let ccx = bcx.ccx(); let llunitty = type_of::type_of(ccx, unit_ty); @@ -130,8 +142,11 @@ pub fn alloc_vec(bcx: @Block, return rslt(bcx, vptr); } -pub fn make_drop_glue_unboxed(bcx: @Block, vptr: ValueRef, vec_ty: ty::t) -> - @Block { +pub fn make_drop_glue_unboxed<'a>( + bcx: &'a Block<'a>, + vptr: ValueRef, + vec_ty: ty::t) + -> &'a Block<'a> { let _icx = push_ctxt("tvec::make_drop_glue_unboxed"); let tcx = bcx.tcx(); let unit_ty = ty::sequence_element_type(tcx, vec_ty); @@ -160,11 +175,12 @@ impl VecTypes { } } -pub fn trans_fixed_vstore(bcx: @Block, +pub fn trans_fixed_vstore<'a>( + bcx: &'a Block<'a>, vstore_expr: &ast::Expr, content_expr: &ast::Expr, dest: expr::Dest) - -> @Block { + -> &'a Block<'a> { //! // // [...] allocates a fixed-size array and moves it around "by value". @@ -189,11 +205,12 @@ pub fn trans_fixed_vstore(bcx: @Block, }; } -pub fn trans_slice_vstore(bcx: @Block, +pub fn trans_slice_vstore<'a>( + bcx: &'a Block<'a>, vstore_expr: &ast::Expr, content_expr: &ast::Expr, dest: expr::Dest) - -> @Block { + -> &'a Block<'a> { //! // // &[...] allocates memory on the stack and writes the values into it, @@ -247,11 +264,12 @@ pub fn trans_slice_vstore(bcx: @Block, return bcx; } -pub fn trans_lit_str(bcx: @Block, +pub fn trans_lit_str<'a>( + bcx: &'a Block<'a>, lit_expr: &ast::Expr, str_lit: @str, dest: Dest) - -> @Block { + -> &'a Block<'a> { //! // // Literal strings translate to slices into static memory. This is @@ -282,8 +300,12 @@ pub fn trans_lit_str(bcx: @Block, } -pub fn trans_uniq_or_managed_vstore(bcx: @Block, heap: heap, vstore_expr: &ast::Expr, - content_expr: &ast::Expr) -> DatumBlock { +pub fn trans_uniq_or_managed_vstore<'a>( + bcx: &'a Block<'a>, + heap: heap, + vstore_expr: &ast::Expr, + content_expr: &ast::Expr) + -> DatumBlock<'a> { //! // // @[...] or ~[...] (also @"..." or ~"...") allocate boxes in the @@ -343,12 +365,13 @@ pub fn trans_uniq_or_managed_vstore(bcx: @Block, heap: heap, vstore_expr: &ast:: return immediate_rvalue_bcx(bcx, val, vt.vec_ty); } -pub fn write_content(bcx: @Block, +pub fn write_content<'a>( + bcx: &'a Block<'a>, vt: &VecTypes, vstore_expr: &ast::Expr, content_expr: &ast::Expr, dest: Dest) - -> @Block { + -> &'a Block<'a> { let _icx = push_ctxt("tvec::write_content"); let mut bcx = bcx; @@ -433,12 +456,12 @@ pub fn write_content(bcx: @Block, } } -pub fn vec_types_from_expr(bcx: @Block, vec_expr: &ast::Expr) -> VecTypes { +pub fn vec_types_from_expr(bcx: &Block, vec_expr: &ast::Expr) -> VecTypes { let vec_ty = node_id_type(bcx, vec_expr.id); vec_types(bcx, vec_ty) } -pub fn vec_types(bcx: @Block, vec_ty: ty::t) -> VecTypes { +pub fn vec_types(bcx: &Block, vec_ty: ty::t) -> VecTypes { let ccx = bcx.ccx(); let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty); let llunit_ty = type_of::type_of(ccx, unit_ty); @@ -452,7 +475,7 @@ pub fn vec_types(bcx: @Block, vec_ty: ty::t) -> VecTypes { llunit_alloc_size: llunit_alloc_size} } -pub fn elements_required(bcx: @Block, content_expr: &ast::Expr) -> uint { +pub fn elements_required(bcx: &Block, content_expr: &ast::Expr) -> uint { //! Figure out the number of elements we need to store this content match content_expr.node { @@ -468,8 +491,8 @@ pub fn elements_required(bcx: @Block, content_expr: &ast::Expr) -> uint { } } -pub fn get_base_and_byte_len(bcx: @Block, llval: ValueRef, - vec_ty: ty::t) -> (ValueRef, ValueRef) { +pub fn get_base_and_byte_len(bcx: &Block, llval: ValueRef, vec_ty: ty::t) + -> (ValueRef, ValueRef) { //! // // Converts a vector into the slice pair. The vector should be stored in @@ -505,7 +528,8 @@ pub fn get_base_and_byte_len(bcx: @Block, llval: ValueRef, } } -pub fn get_base_and_len(bcx: @Block, llval: ValueRef, vec_ty: ty::t) -> (ValueRef, ValueRef) { +pub fn get_base_and_len(bcx: &Block, llval: ValueRef, vec_ty: ty::t) + -> (ValueRef, ValueRef) { //! // // Converts a vector into the slice pair. The vector should be stored in @@ -539,15 +563,17 @@ pub fn get_base_and_len(bcx: @Block, llval: ValueRef, vec_ty: ty::t) -> (ValueRe } } -pub type iter_vec_block<'a> = 'a |@Block, ValueRef, ty::t| - -> @Block; +pub type iter_vec_block<'r,'b> = + 'r |&'b Block<'b>, ValueRef, ty::t| -> &'b Block<'b>; -pub fn iter_vec_loop(bcx: @Block, +pub fn iter_vec_loop<'r, + 'b>( + bcx: &'b Block<'b>, data_ptr: ValueRef, vt: &VecTypes, count: ValueRef, - f: iter_vec_block - ) -> @Block { + f: iter_vec_block<'r,'b>) + -> &'b Block<'b> { let _icx = push_ctxt("tvec::iter_vec_loop"); let next_bcx = sub_block(bcx, "iter_vec_loop: while next"); @@ -597,8 +623,14 @@ pub fn iter_vec_loop(bcx: @Block, next_bcx } -pub fn iter_vec_raw(bcx: @Block, data_ptr: ValueRef, vec_ty: ty::t, - fill: ValueRef, f: iter_vec_block) -> @Block { +pub fn iter_vec_raw<'r, + 'b>( + bcx: &'b Block<'b>, + data_ptr: ValueRef, + vec_ty: ty::t, + fill: ValueRef, + f: iter_vec_block<'r,'b>) + -> &'b Block<'b> { let _icx = push_ctxt("tvec::iter_vec_raw"); let vt = vec_types(bcx, vec_ty); @@ -632,15 +664,26 @@ pub fn iter_vec_raw(bcx: @Block, data_ptr: ValueRef, vec_ty: ty::t, } } -pub fn iter_vec_uniq(bcx: @Block, vptr: ValueRef, vec_ty: ty::t, - fill: ValueRef, f: iter_vec_block) -> @Block { +pub fn iter_vec_uniq<'r, + 'b>( + bcx: &'b Block<'b>, + vptr: ValueRef, + vec_ty: ty::t, + fill: ValueRef, + f: iter_vec_block<'r,'b>) + -> &'b Block<'b> { let _icx = push_ctxt("tvec::iter_vec_uniq"); let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr, vec_ty)); iter_vec_raw(bcx, data_ptr, vec_ty, fill, f) } -pub fn iter_vec_unboxed(bcx: @Block, body_ptr: ValueRef, vec_ty: ty::t, - f: iter_vec_block) -> @Block { +pub fn iter_vec_unboxed<'r, + 'b>( + bcx: &'b Block<'b>, + body_ptr: ValueRef, + vec_ty: ty::t, + f: iter_vec_block<'r,'b>) + -> &'b Block<'b> { let _icx = push_ctxt("tvec::iter_vec_unboxed"); let fill = get_fill(bcx, body_ptr); let dataptr = get_dataptr(bcx, body_ptr); diff --git a/src/librustc/middle/trans/uniq.rs b/src/librustc/middle/trans/uniq.rs index a184ecda20d..91ac5f9f3b4 100644 --- a/src/librustc/middle/trans/uniq.rs +++ b/src/librustc/middle/trans/uniq.rs @@ -17,8 +17,11 @@ use middle::trans::datum::immediate_rvalue; use middle::trans::glue; use middle::ty; -pub fn make_free_glue(bcx: @Block, vptrptr: ValueRef, box_ty: ty::t) - -> @Block { +pub fn make_free_glue<'a>( + bcx: &'a Block<'a>, + vptrptr: ValueRef, + box_ty: ty::t) + -> &'a Block<'a> { let _icx = push_ctxt("uniq::make_free_glue"); let box_datum = immediate_rvalue(Load(bcx, vptrptr), box_ty); diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs index d7c952a38f6..b3d467661e8 100644 --- a/src/librustc/middle/trans/write_guard.rs +++ b/src/librustc/middle/trans/write_guard.rs @@ -22,11 +22,13 @@ use middle::trans::datum::*; use syntax::codemap::Span; use syntax::ast; -pub fn root_and_write_guard(datum: &Datum, - bcx: @Block, +pub fn root_and_write_guard<'a>( + datum: &Datum, + bcx: &'a Block<'a>, span: Span, expr_id: ast::NodeId, - derefs: uint) -> @Block { + derefs: uint) + -> &'a Block<'a> { let key = root_map_key { id: expr_id, derefs: derefs }; debug!("write_guard::root_and_write_guard(key={:?})", key); @@ -41,11 +43,13 @@ pub fn root_and_write_guard(datum: &Datum, } } -fn root(datum: &Datum, - bcx: @Block, +fn root<'a>( + datum: &Datum, + bcx: &'a Block<'a>, _: Span, root_key: root_map_key, - root_info: RootInfo) -> @Block { + root_info: RootInfo) + -> &'a Block<'a> { //! In some cases, borrowck will decide that an @T/@[]/@str //! value must be rooted for the program to be safe. In that //! case, we will call this function, which will stash a copy