rustc: print out filename/line-number when a borrow fails

This commit is contained in:
Niko Matsakis 2013-05-01 09:14:47 -04:00
parent d96c65afc8
commit 84861101ec
5 changed files with 36 additions and 14 deletions

View File

@ -53,7 +53,7 @@ pub fn fail_(expr: *c_char, file: *c_char, line: size_t) -> ! {
#[lang="fail_bounds_check"]
pub fn fail_bounds_check(file: *c_char, line: size_t,
index: size_t, len: size_t) {
index: size_t, len: size_t) {
let msg = fmt!("index out of bounds: the len is %d but the index is %d",
len as int, index as int);
do str::as_buf(msg) |p, _len| {
@ -61,12 +61,10 @@ pub fn fail_bounds_check(file: *c_char, line: size_t,
}
}
pub fn fail_borrowed() {
pub fn fail_borrowed(file: *c_char, line: size_t) {
let msg = "borrowed";
do str::as_buf(msg) |msg_p, _| {
do str::as_buf("???") |file_p, _| {
fail_(msg_p as *c_char, file_p as *c_char, 0);
}
fail_(msg_p as *c_char, file, line);
}
}
@ -160,12 +158,27 @@ pub unsafe fn return_to_mut(a: *u8) {
}
}
#[cfg(stage0)]
#[lang="check_not_borrowed"]
#[inline(always)]
pub unsafe fn check_not_borrowed(a: *u8) {
let a: *mut BoxRepr = transmute(a);
if ((*a).header.ref_count & FROZEN_BIT) != 0 {
fail_borrowed();
do str::as_buf("XXX") |file_p, _| {
fail_borrowed(file_p as *c_char, 0);
}
}
}
#[cfg(not(stage0))]
#[lang="check_not_borrowed"]
#[inline(always)]
pub unsafe fn check_not_borrowed(a: *u8,
file: *c_char,
line: size_t) {
let a: *mut BoxRepr = transmute(a);
if ((*a).header.ref_count & FROZEN_BIT) != 0 {
fail_borrowed(file, line);
}
}

View File

@ -26,7 +26,6 @@ use middle::ty;
use util::common::indenter;
use util::ppaux::{Repr};
use core::hashmap::HashSet;
use syntax::ast::{m_const, m_imm, m_mutbl};
use syntax::ast;
use syntax::ast_util::id_range;

View File

@ -105,6 +105,7 @@ use util::ppaux::ty_to_str;
use core::container::Set; // XXX: this should not be necessary
use core::to_bytes;
use syntax::ast;
use syntax::codemap::span;
use syntax::parse::token::special_idents;
#[deriving(Eq)]
@ -556,17 +557,24 @@ pub impl Datum {
}
}
fn perform_write_guard(&self, bcx: block) -> block {
fn perform_write_guard(&self, bcx: block, span: span) -> block {
// Create scratch space, but do not root it.
let llval = match self.mode {
ByValue => self.val,
ByRef => Load(bcx, self.val),
};
let loc = bcx.sess().parse_sess.cm.lookup_char_pos(span.lo);
let line = C_int(bcx.ccx(), loc.line as int);
let filename_cstr = C_cstr(bcx.ccx(), @/*bad*/copy loc.file.name);
let filename = PointerCast(bcx, filename_cstr, T_ptr(T_i8()));
callee::trans_lang_call(
bcx,
bcx.tcx().lang_items.check_not_borrowed_fn(),
~[ PointerCast(bcx, llval, T_ptr(T_i8())) ],
~[PointerCast(bcx, llval, T_ptr(T_i8())),
filename,
line],
expr::Ignore)
}
@ -621,6 +629,7 @@ pub impl Datum {
fn try_deref(&self,
bcx: block, // block wherein to generate insn's
span: span, // location where deref occurs
expr_id: ast::node_id, // id of expr being deref'd
derefs: uint, // number of times deref'd already
is_auto: bool) // if true, only deref if auto-derefable
@ -645,7 +654,7 @@ pub impl Datum {
//
// (Note: write-guarded values are always boxes)
let bcx = if ccx.maps.write_guard_map.contains(&key) {
self.perform_write_guard(bcx)
self.perform_write_guard(bcx, span)
} else { bcx };
match ty::get(self.ty).sty {
@ -759,7 +768,7 @@ pub impl Datum {
expr: @ast::expr, // the expression whose value is being deref'd
derefs: uint)
-> DatumBlock {
match self.try_deref(bcx, expr.id, derefs, false) {
match self.try_deref(bcx, expr.span, expr.id, derefs, false) {
(Some(lvres), bcx) => DatumBlock { bcx: bcx, datum: lvres },
(None, _) => {
bcx.ccx().sess.span_bug(
@ -769,6 +778,7 @@ pub impl Datum {
}
fn autoderef(&self, bcx: block,
span: span,
expr_id: ast::node_id,
max: uint)
-> DatumBlock {
@ -783,7 +793,7 @@ pub impl Datum {
let mut bcx = bcx;
while derefs < max {
derefs += 1u;
match datum.try_deref(bcx, expr_id, derefs, true) {
match datum.try_deref(bcx, span, expr_id, derefs, true) {
(None, new_bcx) => { bcx = new_bcx; break }
(Some(datum_deref), new_bcx) => {
datum = datum_deref;

View File

@ -205,7 +205,7 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock {
if adj.autoderefs > 0 {
let DatumBlock { bcx: new_bcx, datum: new_datum } =
datum.autoderef(bcx, expr.id, adj.autoderefs);
datum.autoderef(bcx, expr.span, expr.id, adj.autoderefs);
datum = new_datum;
bcx = new_bcx;
}

View File

@ -3723,7 +3723,7 @@ pub impl Parser {
first_item_attrs: ~[attribute])
-> foreign_mod {
let ParsedItemsAndViewItems {
attrs_remaining: attrs_remaining,
attrs_remaining: _,
view_items: view_items,
items: _,
foreign_items: foreign_items