about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2015-02-04 17:16:59 +0100
committerMichael Woerister <michaelwoerister@posteo>2015-02-06 21:22:41 +0100
commitd98d50832c8520e7e0284c4d199b305ec0066de2 (patch)
treea014f94ec1290cfaa3727d93542cc6a815e6066f /src
parent7884eb8e2ff8f0796a95aa0216e69241934ce14f (diff)
downloadrust-d98d50832c8520e7e0284c4d199b305ec0066de2.tar.gz
rust-d98d50832c8520e7e0284c4d199b305ec0066de2.zip
debuginfo: Assign debuginfo source locations to lang-item calls.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_trans/trans/_match.rs113
-rw-r--r--src/librustc_trans/trans/base.rs15
-rw-r--r--src/librustc_trans/trans/callee.rs87
-rw-r--r--src/librustc_trans/trans/cleanup.rs15
-rw-r--r--src/librustc_trans/trans/controlflow.rs19
-rw-r--r--src/librustc_trans/trans/debuginfo.rs2
-rw-r--r--src/librustc_trans/trans/expr.rs29
-rw-r--r--src/librustc_trans/trans/glue.rs38
-rw-r--r--src/librustc_trans/trans/meth.rs2
-rw-r--r--src/librustc_trans/trans/tvec.rs6
10 files changed, 199 insertions, 127 deletions
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs
index 1fea8f6aa3b..b171f00d74f 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -244,25 +244,29 @@ impl<'a> ConstantExpr<'a> {
 // An option identifying a branch (either a literal, an enum variant or a range)
 #[derive(Debug)]
 enum Opt<'a, 'tcx> {
-    ConstantValue(ConstantExpr<'a>),
-    ConstantRange(ConstantExpr<'a>, ConstantExpr<'a>),
-    Variant(ty::Disr, Rc<adt::Repr<'tcx>>, ast::DefId),
-    SliceLengthEqual(uint),
-    SliceLengthGreaterOrEqual(/* prefix length */ uint, /* suffix length */ uint),
+    ConstantValue(ConstantExpr<'a>, DebugLoc),
+    ConstantRange(ConstantExpr<'a>, ConstantExpr<'a>, DebugLoc),
+    Variant(ty::Disr, Rc<adt::Repr<'tcx>>, ast::DefId, DebugLoc),
+    SliceLengthEqual(uint, DebugLoc),
+    SliceLengthGreaterOrEqual(/* prefix length */ uint,
+                              /* suffix length */ uint,
+                              DebugLoc),
 }
 
 impl<'a, 'tcx> Opt<'a, 'tcx> {
     fn eq(&self, other: &Opt<'a, 'tcx>, tcx: &ty::ctxt<'tcx>) -> bool {
         match (self, other) {
-            (&ConstantValue(a), &ConstantValue(b)) => a.eq(b, tcx),
-            (&ConstantRange(a1, a2), &ConstantRange(b1, b2)) => {
+            (&ConstantValue(a, _), &ConstantValue(b, _)) => a.eq(b, tcx),
+            (&ConstantRange(a1, a2, _), &ConstantRange(b1, b2, _)) => {
                 a1.eq(b1, tcx) && a2.eq(b2, tcx)
             }
-            (&Variant(a_disr, ref a_repr, a_def), &Variant(b_disr, ref b_repr, b_def)) => {
+            (&Variant(a_disr, ref a_repr, a_def, _),
+             &Variant(b_disr, ref b_repr, b_def, _)) => {
                 a_disr == b_disr && *a_repr == *b_repr && a_def == b_def
             }
-            (&SliceLengthEqual(a), &SliceLengthEqual(b)) => a == b,
-            (&SliceLengthGreaterOrEqual(a1, a2), &SliceLengthGreaterOrEqual(b1, b2)) => {
+            (&SliceLengthEqual(a, _), &SliceLengthEqual(b, _)) => a == b,
+            (&SliceLengthGreaterOrEqual(a1, a2, _),
+             &SliceLengthGreaterOrEqual(b1, b2, _)) => {
                 a1 == b1 && a2 == b2
             }
             _ => false
@@ -273,29 +277,39 @@ impl<'a, 'tcx> Opt<'a, 'tcx> {
         let _icx = push_ctxt("match::trans_opt");
         let ccx = bcx.ccx();
         match *self {
-            ConstantValue(ConstantExpr(lit_expr)) => {
+            ConstantValue(ConstantExpr(lit_expr), _) => {
                 let lit_ty = ty::node_id_to_type(bcx.tcx(), lit_expr.id);
                 let (llval, _) = consts::const_expr(ccx, &*lit_expr);
                 let lit_datum = immediate_rvalue(llval, lit_ty);
                 let lit_datum = unpack_datum!(bcx, lit_datum.to_appropriate_datum(bcx));
                 SingleResult(Result::new(bcx, lit_datum.val))
             }
-            ConstantRange(ConstantExpr(ref l1), ConstantExpr(ref l2)) => {
+            ConstantRange(ConstantExpr(ref l1), ConstantExpr(ref l2), _) => {
                 let (l1, _) = consts::const_expr(ccx, &**l1);
                 let (l2, _) = consts::const_expr(ccx, &**l2);
                 RangeResult(Result::new(bcx, l1), Result::new(bcx, l2))
             }
-            Variant(disr_val, ref repr, _) => {
+            Variant(disr_val, ref repr, _, _) => {
                 adt::trans_case(bcx, &**repr, disr_val)
             }
-            SliceLengthEqual(length) => {
+            SliceLengthEqual(length, _) => {
                 SingleResult(Result::new(bcx, C_uint(ccx, length)))
             }
-            SliceLengthGreaterOrEqual(prefix, suffix) => {
+            SliceLengthGreaterOrEqual(prefix, suffix, _) => {
                 LowerBound(Result::new(bcx, C_uint(ccx, prefix + suffix)))
             }
         }
     }
+
+    fn debug_loc(&self) -> DebugLoc {
+        match *self {
+            ConstantValue(_,debug_loc)                 |
+            ConstantRange(_, _, debug_loc)             |
+            Variant(_, _, _, debug_loc)                |
+            SliceLengthEqual(_, debug_loc)             |
+            SliceLengthGreaterOrEqual(_, _, debug_loc) => debug_loc
+        }
+    }
 }
 
 #[derive(Copy, PartialEq)]
@@ -527,18 +541,18 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>(
     let _indenter = indenter();
 
     let ctor = match opt {
-        &ConstantValue(ConstantExpr(expr)) => check_match::ConstantValue(
+        &ConstantValue(ConstantExpr(expr), _) => check_match::ConstantValue(
             const_eval::eval_const_expr(bcx.tcx(), &*expr)
         ),
-        &ConstantRange(ConstantExpr(lo), ConstantExpr(hi)) => check_match::ConstantRange(
+        &ConstantRange(ConstantExpr(lo), ConstantExpr(hi), _) => check_match::ConstantRange(
             const_eval::eval_const_expr(bcx.tcx(), &*lo),
             const_eval::eval_const_expr(bcx.tcx(), &*hi)
         ),
-        &SliceLengthEqual(n) =>
+        &SliceLengthEqual(n, _) =>
             check_match::Slice(n),
-        &SliceLengthGreaterOrEqual(before, after) =>
+        &SliceLengthGreaterOrEqual(before, after, _) =>
             check_match::SliceWithSubslice(before, after),
-        &Variant(_, _, def_id) =>
+        &Variant(_, _, def_id, _) =>
             check_match::Constructor::Variant(def_id)
     };
 
@@ -563,27 +577,34 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let mut found: Vec<Opt> = vec![];
     for br in m {
         let cur = br.pats[col];
+        let debug_loc = DebugLoc::At(cur.id, cur.span);
+
         let opt = match cur.node {
-            ast::PatLit(ref l) => ConstantValue(ConstantExpr(&**l)),
+            ast::PatLit(ref l) => {
+                ConstantValue(ConstantExpr(&**l), debug_loc)
+            }
             ast::PatIdent(..) | ast::PatEnum(..) | ast::PatStruct(..) => {
                 // This is either an enum variant or a variable binding.
                 let opt_def = tcx.def_map.borrow().get(&cur.id).cloned();
                 match opt_def {
                     Some(def::DefVariant(enum_id, var_id, _)) => {
                         let variant = ty::enum_variant_with_id(tcx, enum_id, var_id);
-                        Variant(variant.disr_val, adt::represent_node(bcx, cur.id), var_id)
+                        Variant(variant.disr_val,
+                                adt::represent_node(bcx, cur.id),
+                                var_id,
+                                debug_loc)
                     }
                     _ => continue
                 }
             }
             ast::PatRange(ref l1, ref l2) => {
-                ConstantRange(ConstantExpr(&**l1), ConstantExpr(&**l2))
+                ConstantRange(ConstantExpr(&**l1), ConstantExpr(&**l2), debug_loc)
             }
             ast::PatVec(ref before, None, ref after) => {
-                SliceLengthEqual(before.len() + after.len())
+                SliceLengthEqual(before.len() + after.len(), debug_loc)
             }
             ast::PatVec(ref before, Some(_), ref after) => {
-                SliceLengthGreaterOrEqual(before.len(), after.len())
+                SliceLengthGreaterOrEqual(before.len(), after.len(), debug_loc)
             }
             _ => continue
         };
@@ -779,19 +800,21 @@ fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<uint> {
 fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                               lhs: ValueRef,
                               rhs: ValueRef,
-                              rhs_t: Ty<'tcx>)
+                              rhs_t: Ty<'tcx>,
+                              debug_loc: DebugLoc)
                               -> Result<'blk, 'tcx> {
     fn compare_str<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                                lhs: ValueRef,
                                rhs: ValueRef,
-                               rhs_t: Ty<'tcx>)
+                               rhs_t: Ty<'tcx>,
+                               debug_loc: DebugLoc)
                                -> Result<'blk, 'tcx> {
         let did = langcall(cx,
                            None,
                            &format!("comparison of `{}`",
                                    cx.ty_to_string(rhs_t))[],
                            StrEqFnLangItem);
-        callee::trans_lang_call(cx, did, &[lhs, rhs], None)
+        callee::trans_lang_call(cx, did, &[lhs, rhs], None, debug_loc)
     }
 
     let _icx = push_ctxt("compare_values");
@@ -802,7 +825,7 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
 
     match rhs_t.sty {
         ty::ty_rptr(_, mt) => match mt.ty.sty {
-            ty::ty_str => compare_str(cx, lhs, rhs, rhs_t),
+            ty::ty_str => compare_str(cx, lhs, rhs, rhs_t, debug_loc),
             ty::ty_vec(ty, _) => match ty.sty {
                 ty::ty_uint(ast::TyU8) => {
                     // NOTE: cast &[u8] to &str and abuse the str_eq lang item,
@@ -812,7 +835,7 @@ fn compare_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                                              ast::MutImmutable);
                     let lhs = BitCast(cx, lhs, type_of::type_of(cx.ccx(), t).ptr_to());
                     let rhs = BitCast(cx, rhs, type_of::type_of(cx.ccx(), t).ptr_to());
-                    compare_str(cx, lhs, rhs, rhs_t)
+                    compare_str(cx, lhs, rhs, rhs_t, debug_loc)
                 },
                 _ => cx.sess().bug("only byte strings supported in compare_values"),
             },
@@ -1044,7 +1067,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     debug!("test_val={}", bcx.val_to_string(test_val));
     if opts.len() > 0 {
         match opts[0] {
-            ConstantValue(_) | ConstantRange(_, _) => {
+            ConstantValue(..) | ConstantRange(..) => {
                 test_val = load_if_immediate(bcx, val, left_ty);
                 kind = if ty::type_is_integral(left_ty) {
                     Switch
@@ -1052,12 +1075,12 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                     Compare
                 };
             }
-            Variant(_, ref repr, _) => {
+            Variant(_, ref repr, _, _) => {
                 let (the_kind, val_opt) = adt::trans_switch(bcx, &**repr, val);
                 kind = the_kind;
                 if let Some(tval) = val_opt { test_val = tval; }
             }
-            SliceLengthEqual(_) | SliceLengthGreaterOrEqual(_, _) => {
+            SliceLengthEqual(..) | SliceLengthGreaterOrEqual(..) => {
                 let (_, len) = tvec::get_base_and_len(bcx, val, left_ty);
                 test_val = len;
                 kind = Switch;
@@ -1066,8 +1089,8 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     }
     for o in &opts {
         match *o {
-            ConstantRange(_, _) => { kind = Compare; break },
-            SliceLengthGreaterOrEqual(_, _) => { kind = CompareSliceLength; break },
+            ConstantRange(..) => { kind = Compare; break },
+            SliceLengthGreaterOrEqual(..) => { kind = CompareSliceLength; break },
             _ => ()
         }
     }
@@ -1093,10 +1116,12 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         // for the current conditional branch.
         let mut branch_chk = None;
         let mut opt_cx = else_cx;
+        let debug_loc = opt.debug_loc();
+
         if !exhaustive || i + 1 < len {
             opt_cx = bcx.fcx.new_temp_block("match_case");
             match kind {
-                Single => Br(bcx, opt_cx.llbb, DebugLoc::None),
+                Single => Br(bcx, opt_cx.llbb, debug_loc),
                 Switch => {
                     match opt.trans(bcx) {
                         SingleResult(r) => {
@@ -1119,7 +1144,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                     let Result { bcx: after_cx, val: matches } = {
                         match opt.trans(bcx) {
                             SingleResult(Result { bcx, val }) => {
-                                compare_values(bcx, test_val, val, t)
+                                compare_values(bcx, test_val, val, t, debug_loc)
                             }
                             RangeResult(Result { val: vbegin, .. },
                                         Result { bcx, val: vend }) => {
@@ -1131,7 +1156,7 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                                     compare_scalar_types(
                                     bcx, test_val, vend,
                                     t, ast::BiLe);
-                                Result::new(bcx, And(bcx, llge, llle, DebugLoc::None))
+                                Result::new(bcx, And(bcx, llge, llle, debug_loc))
                             }
                             LowerBound(Result { bcx, val }) => {
                                 compare_scalar_types(bcx, test_val, val, t, ast::BiGe)
@@ -1149,37 +1174,37 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
                     if i + 1 < len && (guarded || multi_pats || kind == CompareSliceLength) {
                         branch_chk = Some(JumpToBasicBlock(bcx.llbb));
                     }
-                    CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb, DebugLoc::None);
+                    CondBr(after_cx, matches, opt_cx.llbb, bcx.llbb, debug_loc);
                 }
                 _ => ()
             }
         } else if kind == Compare || kind == CompareSliceLength {
-            Br(bcx, else_cx.llbb, DebugLoc::None);
+            Br(bcx, else_cx.llbb, debug_loc);
         }
 
         let mut size = 0;
         let mut unpacked = Vec::new();
         match *opt {
-            Variant(disr_val, ref repr, _) => {
+            Variant(disr_val, ref repr, _, _) => {
                 let ExtractedBlock {vals: argvals, bcx: new_bcx} =
                     extract_variant_args(opt_cx, &**repr, disr_val, val);
                 size = argvals.len();
                 unpacked = argvals;
                 opt_cx = new_bcx;
             }
-            SliceLengthEqual(len) => {
+            SliceLengthEqual(len, _) => {
                 let args = extract_vec_elems(opt_cx, left_ty, len, 0, val);
                 size = args.vals.len();
                 unpacked = args.vals.clone();
                 opt_cx = args.bcx;
             }
-            SliceLengthGreaterOrEqual(before, after) => {
+            SliceLengthGreaterOrEqual(before, after, _) => {
                 let args = extract_vec_elems(opt_cx, left_ty, before, after, val);
                 size = args.vals.len();
                 unpacked = args.vals.clone();
                 opt_cx = args.bcx;
             }
-            ConstantValue(_) | ConstantRange(_, _) => ()
+            ConstantValue(..) | ConstantRange(..) => ()
         }
         let opt_ms = enter_opt(opt_cx, pat_id, dm, m, opt, col, size, val);
         let mut opt_vals = unpacked;
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 38051a647ca..6f9dc12a26d 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -57,7 +57,7 @@ use trans::closure;
 use trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_integral};
 use trans::common::{C_null, C_struct_in_context, C_u64, C_u8, C_undef};
 use trans::common::{CrateContext, ExternMap, FunctionContext};
-use trans::common::{Result};
+use trans::common::{Result, NodeIdAndSpan};
 use trans::common::{node_id_type, return_type_is_void};
 use trans::common::{tydesc_info, type_is_immediate};
 use trans::common::{type_is_zero_size, val_ty};
@@ -379,7 +379,8 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                   llty_ptr: Type,
                                   info_ty: Ty<'tcx>,
                                   size: ValueRef,
-                                  align: ValueRef)
+                                  align: ValueRef,
+                                  debug_loc: DebugLoc)
                                   -> Result<'blk, 'tcx> {
     let _icx = push_ctxt("malloc_raw_exchange");
 
@@ -387,7 +388,8 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let r = callee::trans_lang_call(bcx,
         require_alloc_fn(bcx, info_ty, ExchangeMallocFnLangItem),
         &[size, align],
-        None);
+        None,
+        debug_loc);
 
     Result::new(r.bcx, PointerCast(r.bcx, r.val, llty_ptr))
 }
@@ -851,7 +853,7 @@ pub fn cast_shift_rhs<F, G>(op: ast::BinOp,
 
 pub fn fail_if_zero_or_overflows<'blk, 'tcx>(
                                 cx: Block<'blk, 'tcx>,
-                                span: Span,
+                                call_info: NodeIdAndSpan,
                                 divrem: ast::BinOp,
                                 lhs: ValueRef,
                                 rhs: ValueRef,
@@ -879,7 +881,7 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>(
         }
     };
     let bcx = with_cond(cx, is_zero, |bcx| {
-        controlflow::trans_fail(bcx, span, InternedString::new(zero_text))
+        controlflow::trans_fail(bcx, call_info, InternedString::new(zero_text))
     });
 
     // To quote LLVM's documentation for the sdiv instruction:
@@ -913,7 +915,8 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>(
             let is_min = ICmp(bcx, llvm::IntEQ, lhs,
                               C_integral(llty, min, true));
             with_cond(bcx, is_min, |bcx| {
-                controlflow::trans_fail(bcx, span,
+                controlflow::trans_fail(bcx,
+                                        call_info,
                                         InternedString::new(overflow_text))
             })
         })
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index 5f383d54a68..4a0c2147ddb 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -36,8 +36,8 @@ use trans::callee;
 use trans::cleanup;
 use trans::cleanup::CleanupMethods;
 use trans::closure;
-use trans::common;
-use trans::common::*;
+use trans::common::{self, Block, Result, NodeIdAndSpan, ExprId, CrateContext,
+                    ExprOrMethodCall, FunctionContext, MethodCallKey};
 use trans::consts;
 use trans::datum::*;
 use trans::debuginfo::{DebugLoc, ToDebugLoc};
@@ -136,7 +136,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
                              ref_expr: &ast::Expr)
                              -> Callee<'blk, 'tcx> {
         debug!("trans_def(def={}, ref_expr={})", def.repr(bcx.tcx()), ref_expr.repr(bcx.tcx()));
-        let expr_ty = node_id_type(bcx, ref_expr.id);
+        let expr_ty = common::node_id_type(bcx, ref_expr.id);
         match def {
             def::DefFn(did, _) if {
                 let maybe_def_id = inline::get_local_instance(bcx.ccx(), did);
@@ -147,8 +147,9 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
                     _ => false
                 }
             } => {
-                let substs = node_id_substs(bcx.ccx(), ExprId(ref_expr.id),
-                                            bcx.fcx.param_substs);
+                let substs = common::node_id_substs(bcx.ccx(),
+                                                    ExprId(ref_expr.id),
+                                                    bcx.fcx.param_substs);
                 Callee {
                     bcx: bcx,
                     data: NamedTupleConstructor(substs, 0)
@@ -158,8 +159,9 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
                 ty::ty_bare_fn(_, ref f) => f.abi == synabi::RustIntrinsic,
                 _ => false
             } => {
-                let substs = node_id_substs(bcx.ccx(), ExprId(ref_expr.id),
-                                            bcx.fcx.param_substs);
+                let substs = common::node_id_substs(bcx.ccx(),
+                                                    ExprId(ref_expr.id),
+                                                    bcx.fcx.param_substs);
                 let def_id = inline::maybe_instantiate_inline(bcx.ccx(), did);
                 Callee { bcx: bcx, data: Intrinsic(def_id.node, substs) }
             }
@@ -178,8 +180,9 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
             }
             def::DefVariant(tid, vid, _) => {
                 let vinfo = ty::enum_variant_with_id(bcx.tcx(), tid, vid);
-                let substs = node_id_substs(bcx.ccx(), ExprId(ref_expr.id),
-                                            bcx.fcx.param_substs);
+                let substs = common::node_id_substs(bcx.ccx(),
+                                                    ExprId(ref_expr.id),
+                                                    bcx.fcx.param_substs);
 
                 // Nullary variants are not callable
                 assert!(vinfo.args.len() > 0);
@@ -190,8 +193,9 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr)
                 }
             }
             def::DefStruct(_) => {
-                let substs = node_id_substs(bcx.ccx(), ExprId(ref_expr.id),
-                                            bcx.fcx.param_substs);
+                let substs = common::node_id_substs(bcx.ccx(),
+                                                    ExprId(ref_expr.id),
+                                                    bcx.fcx.param_substs);
                 Callee {
                     bcx: bcx,
                     data: NamedTupleConstructor(substs, 0)
@@ -226,7 +230,7 @@ pub fn trans_fn_ref<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                               -> Datum<'tcx, Rvalue> {
     let _icx = push_ctxt("trans_fn_ref");
 
-    let substs = node_id_substs(ccx, node, param_substs);
+    let substs = common::node_id_substs(ccx, node, param_substs);
     debug!("trans_fn_ref(def_id={}, node={:?}, substs={})",
            def_id.repr(ccx.tcx()),
            node,
@@ -269,7 +273,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
     let _icx = push_ctxt("trans_fn_pointer_shim");
     let tcx = ccx.tcx();
 
-    let bare_fn_ty = erase_regions(tcx, &bare_fn_ty);
+    let bare_fn_ty = common::erase_regions(tcx, &bare_fn_ty);
     match ccx.fn_pointer_shims().borrow().get(&bare_fn_ty) {
         Some(&llval) => { return llval; }
         None => { }
@@ -352,7 +356,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
     );
 
     bcx = trans_call_inner(bcx,
-                           None,
+                           DebugLoc::None,
                            bare_fn_ty,
                            |bcx, _| Callee { bcx: bcx, data: Fn(llfnpointer) },
                            ArgVals(&llargs[]),
@@ -515,7 +519,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
                                                           param_substs,
                                                           &ref_ty);
             let llptrty = type_of::type_of_fn_from_ty(ccx, ref_ty).ptr_to();
-            if llptrty != val_ty(val) {
+            if llptrty != common::val_ty(val) {
                 let val = consts::ptrcast(val, llptrty);
                 return Datum::new(val, ref_ty, Rvalue::new(ByValue));
             }
@@ -563,7 +567,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
     // other weird situations. Annoying.
     let llty = type_of::type_of_fn_from_ty(ccx, fn_type);
     let llptrty = llty.ptr_to();
-    if val_ty(val) != llptrty {
+    if common::val_ty(val) != llptrty {
         debug!("trans_fn_ref_with_vtables(): casting pointer!");
         val = consts::ptrcast(val, llptrty);
     } else {
@@ -577,34 +581,34 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
 // Translating calls
 
 pub fn trans_call<'a, 'blk, 'tcx>(in_cx: Block<'blk, 'tcx>,
-                                  call_ex: &ast::Expr,
+                                  call_expr: &ast::Expr,
                                   f: &ast::Expr,
                                   args: CallArgs<'a, 'tcx>,
                                   dest: expr::Dest)
                                   -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_call");
     trans_call_inner(in_cx,
-                     Some(common::expr_info(call_ex)),
-                     expr_ty_adjusted(in_cx, f),
+                     call_expr.debug_loc(),
+                     common::expr_ty_adjusted(in_cx, f),
                      |cx, _| trans(cx, f),
                      args,
                      Some(dest)).bcx
 }
 
 pub fn trans_method_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                         call_ex: &ast::Expr,
+                                         call_expr: &ast::Expr,
                                          rcvr: &ast::Expr,
                                          args: CallArgs<'a, 'tcx>,
                                          dest: expr::Dest)
                                          -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_method_call");
-    debug!("trans_method_call(call_ex={})", call_ex.repr(bcx.tcx()));
-    let method_call = MethodCall::expr(call_ex.id);
+    debug!("trans_method_call(call_expr={})", call_expr.repr(bcx.tcx()));
+    let method_call = MethodCall::expr(call_expr.id);
     let method_ty = (*bcx.tcx().method_map.borrow())[method_call].ty;
     trans_call_inner(
         bcx,
-        Some(common::expr_info(call_ex)),
-        monomorphize_type(bcx, method_ty),
+        call_expr.debug_loc(),
+        common::monomorphize_type(bcx, method_ty),
         |cx, arg_cleanup_scope| {
             meth::trans_method_callee(cx, method_call, Some(rcvr), arg_cleanup_scope)
         },
@@ -615,7 +619,8 @@ pub fn trans_method_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                    did: ast::DefId,
                                    args: &[ValueRef],
-                                   dest: Option<expr::Dest>)
+                                   dest: Option<expr::Dest>,
+                                   debug_loc: DebugLoc)
                                    -> Result<'blk, 'tcx> {
     let fty = if did.krate == ast::LOCAL_CRATE {
         ty::node_id_to_type(bcx.tcx(), did.node)
@@ -623,7 +628,7 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         csearch::get_type(bcx.tcx(), did).ty
     };
     callee::trans_call_inner(bcx,
-                             None,
+                             debug_loc,
                              fty,
                              |bcx, _| {
                                 trans_fn_ref_with_substs_to_callee(bcx,
@@ -646,7 +651,7 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 /// For non-lang items, `dest` is always Some, and hence the result is written into memory
 /// somewhere. Nonetheless we return the actual return value of the function.
 pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
-                                           call_info: Option<NodeIdAndSpan>,
+                                           debug_loc: DebugLoc,
                                            callee_ty: Ty<'tcx>,
                                            get_callee: F,
                                            args: CallArgs<'a, 'tcx>,
@@ -687,7 +692,13 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
             assert!(abi == synabi::RustIntrinsic);
             assert!(dest.is_some());
 
-            let call_info = call_info.expect("no call info for intrinsic call?");
+            let call_info = match debug_loc {
+                DebugLoc::At(id, span) => NodeIdAndSpan { id: id, span: span },
+                DebugLoc::None => {
+                    bcx.sess().bug("No call info for intrinsic call?")
+                }
+            };
+
             return intrinsic::trans_intrinsic_call(bcx, node, callee_ty,
                                                    arg_cleanup_scope, args,
                                                    dest.unwrap(), substs,
@@ -703,7 +714,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
                                                        disr,
                                                        args,
                                                        dest.unwrap(),
-                                                       call_info.debug_loc());
+                                                       debug_loc);
         }
     };
 
@@ -724,12 +735,12 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
             };
             if !is_rust_fn ||
               type_of::return_uses_outptr(ccx, ret_ty) ||
-              type_needs_drop(bcx.tcx(), ret_ty) {
+              common::type_needs_drop(bcx.tcx(), ret_ty) {
                 // Push the out-pointer if we use an out-pointer for this
                 // return type, otherwise push "undef".
-                if type_is_zero_size(ccx, ret_ty) {
+                if common::type_is_zero_size(ccx, ret_ty) {
                     let llty = type_of::type_of(ccx, ret_ty);
-                    Some(C_undef(llty.ptr_to()))
+                    Some(common::C_undef(llty.ptr_to()))
                 } else {
                     Some(alloc_ty(bcx, ret_ty, "__llret"))
                 }
@@ -781,7 +792,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
                                       llfn,
                                       &llargs[],
                                       callee_ty,
-                                      call_info.debug_loc());
+                                      debug_loc);
         bcx = b;
         llresult = llret;
 
@@ -790,7 +801,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
         match (opt_llretslot, ret_ty) {
             (Some(llretslot), ty::FnConverging(ret_ty)) => {
                 if !type_of::return_uses_outptr(bcx.ccx(), ret_ty) &&
-                    !type_is_zero_size(bcx.ccx(), ret_ty)
+                    !common::type_is_zero_size(bcx.ccx(), ret_ty)
                 {
                     store_ty(bcx, llret, llretslot, ret_ty)
                 }
@@ -804,7 +815,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
 
         let mut llargs = Vec::new();
         let arg_tys = match args {
-            ArgExprs(a) => a.iter().map(|x| expr_ty(bcx, &**x)).collect(),
+            ArgExprs(a) => a.iter().map(|x| common::expr_ty(bcx, &**x)).collect(),
             _ => panic!("expected arg exprs.")
         };
         bcx = trans_args(bcx,
@@ -831,7 +842,7 @@ pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
             bcx = glue::drop_ty(bcx,
                                 llretslot,
                                 ret_ty,
-                                call_info.debug_loc());
+                                debug_loc);
             call_lifetime_end(bcx, llretslot);
         }
         _ => {}
@@ -892,7 +903,7 @@ fn trans_args_under_call_abi<'blk, 'tcx>(
 
     // Now untuple the rest of the arguments.
     let tuple_expr = &arg_exprs[1];
-    let tuple_type = node_id_type(bcx, tuple_expr.id);
+    let tuple_type = common::node_id_type(bcx, tuple_expr.id);
 
     match tuple_type.sty {
         ty::ty_tup(ref field_types) => {
@@ -1014,7 +1025,7 @@ pub fn trans_args<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                 }
                 let arg_ty = if i >= num_formal_args {
                     assert!(variadic);
-                    expr_ty_adjusted(cx, &**arg_expr)
+                    common::expr_ty_adjusted(cx, &**arg_expr)
                 } else {
                     arg_tys[i]
                 };
diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs
index ac76b52598d..bebba151a0d 100644
--- a/src/librustc_trans/trans/cleanup.rs
+++ b/src/librustc_trans/trans/cleanup.rs
@@ -940,11 +940,12 @@ impl<'tcx> Cleanup<'tcx> for FreeValue<'tcx> {
                    bcx: Block<'blk, 'tcx>,
                    debug_loc: DebugLoc)
                    -> Block<'blk, 'tcx> {
-        debug_loc.apply(bcx.fcx);
-
         match self.heap {
             HeapExchange => {
-                glue::trans_exchange_free_ty(bcx, self.ptr, self.content_ty)
+                glue::trans_exchange_free_ty(bcx,
+                                             self.ptr,
+                                             self.content_ty,
+                                             debug_loc)
             }
         }
     }
@@ -975,11 +976,13 @@ impl<'tcx> Cleanup<'tcx> for FreeSlice {
                    bcx: Block<'blk, 'tcx>,
                    debug_loc: DebugLoc)
                    -> Block<'blk, 'tcx> {
-        debug_loc.apply(bcx.fcx);
-
         match self.heap {
             HeapExchange => {
-                glue::trans_exchange_free_dyn(bcx, self.ptr, self.size, self.align)
+                glue::trans_exchange_free_dyn(bcx,
+                                              self.ptr,
+                                              self.size,
+                                              self.align,
+                                              debug_loc)
             }
         }
     }
diff --git a/src/librustc_trans/trans/controlflow.rs b/src/librustc_trans/trans/controlflow.rs
index 651058a5674..8004726d25e 100644
--- a/src/librustc_trans/trans/controlflow.rs
+++ b/src/librustc_trans/trans/controlflow.rs
@@ -28,7 +28,6 @@ use util::ppaux::Repr;
 use syntax::ast;
 use syntax::ast::Ident;
 use syntax::ast_util;
-use syntax::codemap::Span;
 use syntax::parse::token::InternedString;
 use syntax::parse::token;
 use syntax::visit::Visitor;
@@ -361,31 +360,32 @@ pub fn trans_ret<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 }
 
 pub fn trans_fail<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                              sp: Span,
+                              call_info: NodeIdAndSpan,
                               fail_str: InternedString)
                               -> Block<'blk, 'tcx> {
     let ccx = bcx.ccx();
     let _icx = push_ctxt("trans_fail_value");
 
     let v_str = C_str_slice(ccx, fail_str);
-    let loc = bcx.sess().codemap().lookup_char_pos(sp.lo);
+    let loc = bcx.sess().codemap().lookup_char_pos(call_info.span.lo);
     let filename = token::intern_and_get_ident(&loc.file.name[]);
     let filename = C_str_slice(ccx, filename);
     let line = C_uint(ccx, loc.line);
     let expr_file_line_const = C_struct(ccx, &[v_str, filename, line], false);
     let expr_file_line = consts::const_addr_of(ccx, expr_file_line_const, ast::MutImmutable);
     let args = vec!(expr_file_line);
-    let did = langcall(bcx, Some(sp), "", PanicFnLangItem);
+    let did = langcall(bcx, Some(call_info.span), "", PanicFnLangItem);
     let bcx = callee::trans_lang_call(bcx,
                                       did,
                                       &args[],
-                                      Some(expr::Ignore)).bcx;
+                                      Some(expr::Ignore),
+                                      call_info.debug_loc()).bcx;
     Unreachable(bcx);
     return bcx;
 }
 
 pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                           sp: Span,
+                                           call_info: NodeIdAndSpan,
                                            index: ValueRef,
                                            len: ValueRef)
                                            -> Block<'blk, 'tcx> {
@@ -393,7 +393,7 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let _icx = push_ctxt("trans_fail_bounds_check");
 
     // Extract the file/line from the span
-    let loc = bcx.sess().codemap().lookup_char_pos(sp.lo);
+    let loc = bcx.sess().codemap().lookup_char_pos(call_info.span.lo);
     let filename = token::intern_and_get_ident(&loc.file.name[]);
 
     // Invoke the lang item
@@ -402,11 +402,12 @@ pub fn trans_fail_bounds_check<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let file_line_const = C_struct(ccx, &[filename, line], false);
     let file_line = consts::const_addr_of(ccx, file_line_const, ast::MutImmutable);
     let args = vec!(file_line, index, len);
-    let did = langcall(bcx, Some(sp), "", PanicBoundsCheckFnLangItem);
+    let did = langcall(bcx, Some(call_info.span), "", PanicBoundsCheckFnLangItem);
     let bcx = callee::trans_lang_call(bcx,
                                       did,
                                       &args[],
-                                      Some(expr::Ignore)).bcx;
+                                      Some(expr::Ignore),
+                                      call_info.debug_loc()).bcx;
     Unreachable(bcx);
     return bcx;
 }
diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs
index 1e788351172..a6a7422778a 100644
--- a/src/librustc_trans/trans/debuginfo.rs
+++ b/src/librustc_trans/trans/debuginfo.rs
@@ -1113,7 +1113,7 @@ pub fn get_cleanup_debug_loc_for_ast_node<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
 pub enum DebugLoc {
     At(ast::NodeId, Span),
     None
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index dea34baad37..154d54c3d73 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -586,7 +586,7 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let contents_ty = expr_ty(bcx, &**contents);
             match box_ty.sty {
                 ty::ty_uniq(..) => {
-                    trans_uniq_expr(bcx, box_ty, &**contents, contents_ty)
+                    trans_uniq_expr(bcx, expr, box_ty, &**contents, contents_ty)
                 }
                 _ => bcx.sess().span_bug(expr.span,
                                          "expected unique box")
@@ -787,7 +787,7 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                 index_expr.debug_loc());
             bcx = with_cond(bcx, expected, |bcx| {
                 controlflow::trans_fail_bounds_check(bcx,
-                                                     index_expr.span,
+                                                     expr_info(index_expr),
                                                      ix_val,
                                                      len)
             });
@@ -1574,7 +1574,7 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             immediate_rvalue_bcx(bcx, llneg, un_ty).to_expr_datumblock()
         }
         ast::UnUniq => {
-            trans_uniq_expr(bcx, un_ty, sub_expr, expr_ty(bcx, sub_expr))
+            trans_uniq_expr(bcx, expr, un_ty, sub_expr, expr_ty(bcx, sub_expr))
         }
         ast::UnDeref => {
             let datum = unpack_datum!(bcx, trans(bcx, sub_expr));
@@ -1584,6 +1584,7 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 }
 
 fn trans_uniq_expr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                               box_expr: &ast::Expr,
                                box_ty: Ty<'tcx>,
                                contents: &ast::Expr,
                                contents_ty: Ty<'tcx>)
@@ -1595,7 +1596,12 @@ fn trans_uniq_expr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let size = llsize_of(bcx.ccx(), llty);
     let align = C_uint(bcx.ccx(), type_of::align_of(bcx.ccx(), contents_ty));
     let llty_ptr = llty.ptr_to();
-    let Result { bcx, val } = malloc_raw_dyn(bcx, llty_ptr, box_ty, size, align);
+    let Result { bcx, val } = malloc_raw_dyn(bcx,
+                                             llty_ptr,
+                                             box_ty,
+                                             size,
+                                             align,
+                                             box_expr.debug_loc());
     // Unique boxes do not allocate for zero-size types. The standard library
     // may assume that `free` is never called on the pointer returned for
     // `Box<ZeroSizeType>`.
@@ -1697,8 +1703,12 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             FDiv(bcx, lhs, rhs, binop_debug_loc)
         } else {
             // Only zero-check integers; fp /0 is NaN
-            bcx = base::fail_if_zero_or_overflows(bcx, binop_expr.span,
-                                                  op, lhs, rhs, rhs_t);
+            bcx = base::fail_if_zero_or_overflows(bcx,
+                                                  expr_info(binop_expr),
+                                                  op,
+                                                  lhs,
+                                                  rhs,
+                                                  rhs_t);
             if is_signed {
                 SDiv(bcx, lhs, rhs, binop_debug_loc)
             } else {
@@ -1711,7 +1721,8 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             FRem(bcx, lhs, rhs, binop_debug_loc)
         } else {
             // Only zero-check integers; fp %0 is NaN
-            bcx = base::fail_if_zero_or_overflows(bcx, binop_expr.span,
+            bcx = base::fail_if_zero_or_overflows(bcx,
+                                                  expr_info(binop_expr),
                                                   op, lhs, rhs, rhs_t);
             if is_signed {
                 SRem(bcx, lhs, rhs, binop_debug_loc)
@@ -1845,7 +1856,7 @@ fn trans_overloaded_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                    -> Result<'blk, 'tcx> {
     let method_ty = (*bcx.tcx().method_map.borrow())[method_call].ty;
     callee::trans_call_inner(bcx,
-                             Some(expr_info(expr)),
+                             expr.debug_loc(),
                              monomorphize_type(bcx, method_ty),
                              |bcx, arg_cleanup_scope| {
                                 meth::trans_method_callee(bcx,
@@ -1872,7 +1883,7 @@ fn trans_overloaded_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
     all_args.extend(args.iter().map(|e| &**e));
     unpack_result!(bcx,
                    callee::trans_call_inner(bcx,
-                                            Some(expr_info(expr)),
+                                            expr.debug_loc(),
                                             monomorphize_type(bcx,
                                                               method_type),
                                             |bcx, arg_cleanup_scope| {
diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs
index 5d26daab5cd..aefa0978dd4 100644
--- a/src/librustc_trans/trans/glue.rs
+++ b/src/librustc_trans/trans/glue.rs
@@ -45,25 +45,39 @@ use std::ffi::CString;
 use syntax::ast;
 use syntax::parse::token;
 
-pub fn trans_exchange_free_dyn<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef,
-                                           size: ValueRef, align: ValueRef)
+pub fn trans_exchange_free_dyn<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
+                                           v: ValueRef,
+                                           size: ValueRef,
+                                           align: ValueRef,
+                                           debug_loc: DebugLoc)
                                            -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("trans_exchange_free");
     let ccx = cx.ccx();
     callee::trans_lang_call(cx,
         langcall(cx, None, "", ExchangeFreeFnLangItem),
         &[PointerCast(cx, v, Type::i8p(ccx)), size, align],
-        Some(expr::Ignore)).bcx
+        Some(expr::Ignore),
+        debug_loc).bcx
 }
 
-pub fn trans_exchange_free<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef,
-                                       size: u64, align: u32) -> Block<'blk, 'tcx> {
-    trans_exchange_free_dyn(cx, v, C_uint(cx.ccx(), size),
-                                   C_uint(cx.ccx(), align))
+pub fn trans_exchange_free<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
+                                       v: ValueRef,
+                                       size: u64,
+                                       align: u32,
+                                       debug_loc: DebugLoc)
+                                       -> Block<'blk, 'tcx> {
+    trans_exchange_free_dyn(cx,
+                            v,
+                            C_uint(cx.ccx(), size),
+                            C_uint(cx.ccx(), align),
+                            debug_loc)
 }
 
-pub fn trans_exchange_free_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ptr: ValueRef,
-                                          content_ty: Ty<'tcx>) -> Block<'blk, 'tcx> {
+pub fn trans_exchange_free_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                                          ptr: ValueRef,
+                                          content_ty: Ty<'tcx>,
+                                          debug_loc: DebugLoc)
+                                          -> Block<'blk, 'tcx> {
     assert!(type_is_sized(bcx.ccx().tcx(), content_ty));
     let sizing_type = sizing_type_of(bcx.ccx(), content_ty);
     let content_size = llsize_of_alloc(bcx.ccx(), sizing_type);
@@ -71,7 +85,7 @@ pub fn trans_exchange_free_ty<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ptr: ValueRef,
     // `Box<ZeroSizeType>` does not allocate.
     if content_size != 0 {
         let content_align = align_of(bcx.ccx(), content_ty);
-        trans_exchange_free(bcx, ptr, content_size, content_align)
+        trans_exchange_free(bcx, ptr, content_size, content_align, debug_loc)
     } else {
         bcx
     }
@@ -394,7 +408,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
                         let info = GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]);
                         let info = Load(bcx, info);
                         let (llsize, llalign) = size_and_align_of_dst(bcx, content_ty, info);
-                        trans_exchange_free_dyn(bcx, llbox, llsize, llalign)
+                        trans_exchange_free_dyn(bcx, llbox, llsize, llalign, DebugLoc::None)
                     })
                 }
                 _ => {
@@ -404,7 +418,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
                     let not_null = IsNotNull(bcx, llbox);
                     with_cond(bcx, not_null, |bcx| {
                         let bcx = drop_ty(bcx, llbox, content_ty, DebugLoc::None);
-                        trans_exchange_free_ty(bcx, llbox, content_ty)
+                        trans_exchange_free_ty(bcx, llbox, content_ty, DebugLoc::None)
                     })
                 }
             }
diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs
index 9c440d4509e..5161382a927 100644
--- a/src/librustc_trans/trans/meth.rs
+++ b/src/librustc_trans/trans/meth.rs
@@ -667,7 +667,7 @@ pub fn trans_object_shim<'a, 'tcx>(
            method_offset_in_vtable);
 
     bcx = trans_call_inner(bcx,
-                           None,
+                           DebugLoc::None,
                            method_bare_fn_ty,
                            |bcx, _| trans_trait_callee_from_llval(bcx,
                                                                   method_bare_fn_ty,
diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs
index 66f603cbe07..5930876d15c 100644
--- a/src/librustc_trans/trans/tvec.rs
+++ b/src/librustc_trans/trans/tvec.rs
@@ -77,7 +77,11 @@ pub fn make_drop_glue_unboxed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 with_cond(bcx, not_empty, |bcx| {
                     let llalign = C_uint(ccx, machine::llalign_of_min(ccx, llty));
                     let size = Mul(bcx, C_uint(ccx, unit_size), len, DebugLoc::None);
-                    glue::trans_exchange_free_dyn(bcx, dataptr, size, llalign)
+                    glue::trans_exchange_free_dyn(bcx,
+                                                  dataptr,
+                                                  size,
+                                                  llalign,
+                                                  DebugLoc::None)
                 })
             } else {
                 bcx