Merge remote-tracking branch 'mozilla/incoming' into incoming
This commit is contained in:
commit
4396ad488f
@ -94,27 +94,31 @@ fn listen<T: send, U>(f: fn(chan<T>) -> U) -> U {
|
||||
f(po.chan())
|
||||
}
|
||||
|
||||
resource port_ptr<T: send>(po: *rust_port) unsafe {
|
||||
class port_ptr<T:send> {
|
||||
let po: *rust_port;
|
||||
new(po: *rust_port) { self.po = po; }
|
||||
drop unsafe {
|
||||
task::unkillable {||
|
||||
// Once the port is detached it's guaranteed not to receive further
|
||||
// messages
|
||||
let yield = 0u;
|
||||
let yieldp = ptr::addr_of(yield);
|
||||
rustrt::rust_port_begin_detach(po, yieldp);
|
||||
rustrt::rust_port_begin_detach(self.po, yieldp);
|
||||
if yield != 0u {
|
||||
// Need to wait for the port to be detached
|
||||
// FIXME: If this fails then we're going to leave our port
|
||||
// in a bogus state. (Issue #1988)
|
||||
task::yield();
|
||||
}
|
||||
rustrt::rust_port_end_detach(po);
|
||||
rustrt::rust_port_end_detach(self.po);
|
||||
|
||||
// Drain the port so that all the still-enqueued items get dropped
|
||||
while rustrt::rust_port_size(po) > 0u as size_t {
|
||||
recv_::<T>(po);
|
||||
while rustrt::rust_port_size(self.po) > 0u as size_t {
|
||||
recv_::<T>(self.po);
|
||||
}
|
||||
rustrt::del_port(po);
|
||||
rustrt::del_port(self.po);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
@ -126,21 +130,26 @@ Fails if the port is detached or dead. Fails if the port
|
||||
is owned by a different task.
|
||||
"]
|
||||
fn as_raw_port<T: send, U>(ch: comm::chan<T>, f: fn(*rust_port) -> U) -> U {
|
||||
resource portref(p: *rust_port) {
|
||||
if !ptr::is_null(p) {
|
||||
rustrt::rust_port_drop(p);
|
||||
}
|
||||
|
||||
class portref {
|
||||
let p: *rust_port;
|
||||
new(p: *rust_port) { self.p = p; }
|
||||
drop {
|
||||
if !ptr::is_null(self.p) {
|
||||
rustrt::rust_port_drop(self.p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let p = portref(rustrt::rust_port_take(*ch));
|
||||
|
||||
if ptr::is_null(*p) {
|
||||
if ptr::is_null(p.p) {
|
||||
fail "unable to locate port for channel"
|
||||
} else if rustrt::get_task_id() != rustrt::rust_port_task(*p) {
|
||||
} else if rustrt::get_task_id() != rustrt::rust_port_task(p.p) {
|
||||
fail "unable to access unowned port"
|
||||
}
|
||||
|
||||
f(*p)
|
||||
f(p.p)
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
@ -148,7 +157,7 @@ Constructs a channel. The channel is bound to the port used to
|
||||
construct it.
|
||||
"]
|
||||
fn chan<T: send>(p: port<T>) -> chan<T> {
|
||||
chan_t(rustrt::get_port_id(***p))
|
||||
chan_t(rustrt::get_port_id((**p).po))
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
@ -170,10 +179,10 @@ fn send<T: send>(ch: chan<T>, -data: T) {
|
||||
Receive from a port. If no data is available on the port then the
|
||||
task will block until data becomes available.
|
||||
"]
|
||||
fn recv<T: send>(p: port<T>) -> T { recv_(***p) }
|
||||
fn recv<T: send>(p: port<T>) -> T { recv_((**p).po) }
|
||||
|
||||
#[doc = "Returns true if there are messages available"]
|
||||
fn peek<T: send>(p: port<T>) -> bool { peek_(***p) }
|
||||
fn peek<T: send>(p: port<T>) -> bool { peek_((**p).po) }
|
||||
|
||||
#[doc(hidden)]
|
||||
fn recv_chan<T: send>(ch: comm::chan<T>) -> T {
|
||||
@ -196,7 +205,7 @@ fn recv_<T: send>(p: *rust_port) -> T {
|
||||
// Data isn't available yet, so res has not been initialized.
|
||||
task::yield();
|
||||
} else {
|
||||
// In the absense of compiler-generated preemption points
|
||||
// In the absence of compiler-generated preemption points
|
||||
// this is a good place to yield
|
||||
task::yield();
|
||||
}
|
||||
@ -210,7 +219,7 @@ fn peek_(p: *rust_port) -> bool unsafe {
|
||||
#[doc = "Receive on one of two ports"]
|
||||
fn select2<A: send, B: send>(p_a: port<A>, p_b: port<B>)
|
||||
-> either<A, B> unsafe {
|
||||
let ports = [***p_a, ***p_b];
|
||||
let ports = [(**p_a).po, (**p_b).po];
|
||||
let n_ports = 2 as libc::size_t;
|
||||
let yield = 0u, yieldp = ptr::addr_of(yield);
|
||||
|
||||
@ -233,9 +242,9 @@ fn select2<A: send, B: send>(p_a: port<A>, p_b: port<B>)
|
||||
// Now we know the port we're supposed to receive from
|
||||
assert resport != ptr::null();
|
||||
|
||||
if resport == ***p_a {
|
||||
if resport == (**p_a).po {
|
||||
either::left(recv(p_a))
|
||||
} else if resport == ***p_b {
|
||||
} else if resport == (**p_b).po {
|
||||
either::right(recv(p_b))
|
||||
} else {
|
||||
fail "unexpected result from rust_port_select";
|
||||
@ -482,4 +491,4 @@ fn test_port_detach_fail() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,10 +23,10 @@ fn walk_stack(visit: fn(frame) -> bool) {
|
||||
reinterpret_cast(frame_pointer)
|
||||
};
|
||||
loop {
|
||||
let frame = frame(frame_address);
|
||||
let fr = frame(frame_address);
|
||||
|
||||
#debug("frame: %x", unsafe { reinterpret_cast(frame.fp) });
|
||||
visit(frame);
|
||||
#debug("frame: %x", unsafe { reinterpret_cast(fr.fp) });
|
||||
visit(fr);
|
||||
|
||||
unsafe {
|
||||
let next_fp: **word = reinterpret_cast(frame_address);
|
||||
@ -44,7 +44,7 @@ fn walk_stack(visit: fn(frame) -> bool) {
|
||||
|
||||
#[test]
|
||||
fn test_simple() {
|
||||
for walk_stack { |frame|
|
||||
for walk_stack { |_frame|
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ fn test_simple_deep() {
|
||||
fn run(i: int) {
|
||||
if i == 0 { ret }
|
||||
|
||||
for walk_stack { |frame|
|
||||
for walk_stack { |_frame|
|
||||
unsafe {
|
||||
breakpoint();
|
||||
}
|
||||
|
@ -566,7 +566,7 @@ pure fn to_upper(s: str/&) -> str {
|
||||
}
|
||||
|
||||
#[doc = "
|
||||
Replace all occurances of one string with another
|
||||
Replace all occurrences of one string with another
|
||||
|
||||
# Arguments
|
||||
|
||||
|
@ -7,7 +7,7 @@ import future::future;
|
||||
export map, mapi, alli, any, mapi_factory;
|
||||
|
||||
#[doc="The maximum number of tasks this module will spawn for a single
|
||||
operationg."]
|
||||
operation."]
|
||||
const max_tasks : uint = 32u;
|
||||
|
||||
#[doc="The minimum number of elements each task will process."]
|
||||
|
@ -47,6 +47,7 @@ fn check_loans(bccx: borrowck_ctxt,
|
||||
mut declared_purity: ast::impure_fn,
|
||||
mut fn_args: @[]});
|
||||
let vt = visit::mk_vt(@{visit_expr: check_loans_in_expr,
|
||||
visit_local: check_loans_in_local,
|
||||
visit_block: check_loans_in_block,
|
||||
visit_fn: check_loans_in_fn
|
||||
with *visit::default_visitor()});
|
||||
@ -419,6 +420,9 @@ impl methods for check_loan_ctxt {
|
||||
// rvalues, I guess.
|
||||
cat_special(sk_static_item) { }
|
||||
|
||||
cat_deref(_, _, unsafe_ptr) {
|
||||
}
|
||||
|
||||
// Nothing else.
|
||||
_ {
|
||||
self.bccx.span_err(
|
||||
@ -542,6 +546,18 @@ fn check_loans_in_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk,
|
||||
#debug["purity on exit=%?", copy self.declared_purity];
|
||||
}
|
||||
|
||||
fn check_loans_in_local(local: @ast::local,
|
||||
&&self: check_loan_ctxt,
|
||||
vt: visit::vt<check_loan_ctxt>) {
|
||||
alt local.node.init {
|
||||
some({op: ast::init_move, expr: expr}) {
|
||||
self.check_move_out(expr);
|
||||
}
|
||||
some({op: ast::init_assign, _}) | none {}
|
||||
}
|
||||
visit::visit_local(local, self, vt);
|
||||
}
|
||||
|
||||
fn check_loans_in_expr(expr: @ast::expr,
|
||||
&&self: check_loan_ctxt,
|
||||
vt: visit::vt<check_loan_ctxt>) {
|
||||
|
@ -573,7 +573,6 @@ fn visit_item_with_scope(e: @env, i: @ast::item,
|
||||
}
|
||||
ast::item_class(tps, ifaces, members, ctor, m_dtor, _) {
|
||||
v.visit_ty_params(tps, sc, v);
|
||||
// Can maybe skip this now that we require self on class fields
|
||||
let class_scope = @cons(scope_item(i), sc);
|
||||
/* visit the constructor... */
|
||||
let ctor_scope = @cons(scope_method(ctor.node.self_id, tps),
|
||||
@ -1061,7 +1060,7 @@ fn lookup_in_scope(e: env, &&sc: scopes, sp: span, name: ident, ns: namespace,
|
||||
}
|
||||
ast::item_class(tps, _, members, ctor, _, _) {
|
||||
if ns == ns_type {
|
||||
ret lookup_in_ty_params(e, name, tps);
|
||||
ret lookup_in_ty_params(e, name, tps);
|
||||
}
|
||||
if ns == ns_val && name == it.ident {
|
||||
ret some(ast::def_fn(local_def(ctor.node.id),
|
||||
@ -1317,13 +1316,14 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option<def> {
|
||||
alt i.node {
|
||||
ast::item_const(*) {
|
||||
if ns == ns_val {
|
||||
ret some(ast::def_const(local_def(i.id))); }
|
||||
}
|
||||
ast::item_fn(decl, _, _) {
|
||||
if ns == ns_val {
|
||||
ret some(ast::def_fn(local_def(i.id), decl.purity));
|
||||
ret some(ast::def_const(local_def(i.id)));
|
||||
}
|
||||
}
|
||||
ast::item_fn(decl, _, _) {
|
||||
if ns == ns_val {
|
||||
ret some(ast::def_fn(local_def(i.id), decl.purity));
|
||||
}
|
||||
}
|
||||
ast::item_mod(_) {
|
||||
if ns == ns_module { ret some(ast::def_mod(local_def(i.id))); }
|
||||
}
|
||||
@ -1342,9 +1342,16 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option<def> {
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
ast::item_class(*) {
|
||||
if ns == ns_type {
|
||||
ret some(ast::def_class(local_def(i.id)));
|
||||
ast::item_class(_, _, _members, ct, _, _) {
|
||||
alt ns {
|
||||
ns_type {
|
||||
ret some(ast::def_class(local_def(i.id)));
|
||||
}
|
||||
ns_val {
|
||||
ret some(ast::def_fn(local_def(ct.node.id),
|
||||
ast::impure_fn));
|
||||
}
|
||||
ns_module { }
|
||||
}
|
||||
}
|
||||
ast::item_impl(*) { /* ??? */ }
|
||||
@ -1653,14 +1660,6 @@ fn index_mod(md: ast::_mod) -> mod_index {
|
||||
ast::item_class(tps, _, items, ctor, _, _) {
|
||||
// add the class name itself
|
||||
add_to_index(index, it.ident, mie_item(it));
|
||||
// add the constructor decl
|
||||
add_to_index(index, it.ident,
|
||||
mie_item(@{ident: it.ident, attrs: [],
|
||||
id: ctor.node.id,
|
||||
node:
|
||||
item_fn(ctor.node.dec, tps, ctor.node.body),
|
||||
vis: ast::public,
|
||||
span: ctor.node.body.span}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -754,7 +754,8 @@ fn trans_class_drop(bcx: block, v0: ValueRef, dtor_did: ast::def_id,
|
||||
// We have to cast v0
|
||||
let classptr = GEPi(bcx, v0, [0u, 1u]);
|
||||
// Find and call the actual destructor
|
||||
let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did, substs.tps);
|
||||
let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did, some(class_did),
|
||||
substs.tps);
|
||||
// The second argument is the "self" argument for drop
|
||||
let params = lib::llvm::fn_ty_param_tys
|
||||
(llvm::LLVMGetElementType
|
||||
@ -829,7 +830,11 @@ fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
|
||||
build_return(bcx);
|
||||
}
|
||||
|
||||
fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, substs: [ty::t])
|
||||
fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id,
|
||||
// Parent ID is an option because resources don't
|
||||
// have one. We can make this a def_id when
|
||||
// resources get removed.
|
||||
opt_id: option<ast::def_id>, substs: [ty::t])
|
||||
-> ValueRef {
|
||||
let _icx = ccx.insn_ctxt("trans_res_dtor");
|
||||
if (substs.len() > 0u) {
|
||||
@ -841,14 +846,27 @@ fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, substs: [ty::t])
|
||||
} else if did.crate == ast::local_crate {
|
||||
get_item_val(ccx, did.node)
|
||||
} else {
|
||||
let fty = ty::mk_fn(ccx.tcx, {purity: ast::impure_fn,
|
||||
proto: ast::proto_bare,
|
||||
inputs: [{mode: ast::expl(ast::by_ref),
|
||||
alt opt_id {
|
||||
some(parent_id) {
|
||||
let tcx = ccx.tcx;
|
||||
let name = csearch::get_symbol(ccx.sess.cstore, did);
|
||||
let class_ty = ty::subst_tps(tcx, substs,
|
||||
ty::lookup_item_type(tcx, parent_id).ty);
|
||||
let llty = type_of_dtor(ccx, class_ty);
|
||||
get_extern_fn(ccx.externs, ccx.llmod, name, lib::llvm::CCallConv,
|
||||
llty)
|
||||
}
|
||||
none {
|
||||
let fty = ty::mk_fn(ccx.tcx, {purity: ast::impure_fn,
|
||||
proto: ast::proto_bare,
|
||||
inputs: [{mode: ast::expl(ast::by_ref),
|
||||
ty: ty::mk_nil_ptr(ccx.tcx)}],
|
||||
output: ty::mk_nil(ccx.tcx),
|
||||
ret_style: ast::return_val,
|
||||
constraints: []});
|
||||
trans_external_path(ccx, did, fty)
|
||||
trans_external_path(ccx, did, fty)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -862,7 +880,7 @@ fn trans_res_drop(bcx: block, rs: ValueRef, did: ast::def_id,
|
||||
with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag))) {|bcx|
|
||||
let valptr = GEPi(bcx, rs, [0u, 1u]);
|
||||
// Find and call the actual destructor.
|
||||
let dtor_addr = get_res_dtor(ccx, did, tps);
|
||||
let dtor_addr = get_res_dtor(ccx, did, none, tps);
|
||||
let args = [bcx.fcx.llretptr, null_env_ptr(bcx)];
|
||||
// Kludge to work around the fact that we know the precise type of the
|
||||
// value here, but the dtor expects a type that might have opaque
|
||||
@ -2304,14 +2322,14 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id, real_substs: [ty::t],
|
||||
}
|
||||
}
|
||||
ast_map::node_dtor(_, dtor, _, pt) {
|
||||
let parent_id = alt ty::ty_to_def_id(ty::node_id_to_type(ccx.tcx,
|
||||
dtor.node.self_id)) {
|
||||
some(did) { did }
|
||||
none { ccx.sess.span_bug(dtor.span, "Bad self ty in \
|
||||
let parent_id = alt ty::ty_to_def_id(ty::node_id_to_type(ccx.tcx,
|
||||
dtor.node.self_id)) {
|
||||
some(did) { did }
|
||||
none { ccx.sess.span_bug(dtor.span, "Bad self ty in \
|
||||
dtor"); }
|
||||
};
|
||||
trans_class_dtor(ccx, *pt, dtor.node.body,
|
||||
dtor.node.id, psubsts, some(hash_id), parent_id)
|
||||
};
|
||||
trans_class_dtor(ccx, *pt, dtor.node.body,
|
||||
dtor.node.id, psubsts, some(hash_id), parent_id)
|
||||
}
|
||||
// Ugh -- but this ensures any new variants won't be forgotten
|
||||
ast_map::node_expr(*) { ccx.tcx.sess.bug("Can't monomorphize an expr") }
|
||||
@ -4930,15 +4948,15 @@ fn trans_class_ctor(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
|
||||
}
|
||||
|
||||
fn trans_class_dtor(ccx: @crate_ctxt, path: path,
|
||||
body: ast::blk,
|
||||
dtor_id: ast::node_id, substs: option<param_substs>,
|
||||
hash_id: option<mono_id>, parent_id: ast::def_id)
|
||||
body: ast::blk, dtor_id: ast::node_id,
|
||||
psubsts: option<param_substs>,
|
||||
hash_id: option<mono_id>, parent_id: ast::def_id)
|
||||
-> ValueRef {
|
||||
let tcx = ccx.tcx;
|
||||
/* Look up the parent class's def_id */
|
||||
let mut class_ty = ty::lookup_item_type(tcx, parent_id).ty;
|
||||
/* Substitute in the class type if necessary */
|
||||
option::iter(substs) {|ss|
|
||||
option::iter(psubsts) {|ss|
|
||||
class_ty = ty::subst_tps(tcx, ss.tys, class_ty);
|
||||
}
|
||||
|
||||
@ -4947,7 +4965,9 @@ fn trans_class_dtor(ccx: @crate_ctxt, path: path,
|
||||
let lldty = T_fn([T_ptr(type_of(ccx, ty::mk_nil(tcx))),
|
||||
T_ptr(type_of(ccx, class_ty))],
|
||||
llvm::LLVMVoidType());
|
||||
let s = get_dtor_symbol(ccx, path, dtor_id);
|
||||
|
||||
let s = get_dtor_symbol(ccx, path, dtor_id, psubsts);
|
||||
|
||||
/* Register the dtor as a function. It has external linkage */
|
||||
let lldecl = decl_internal_cdecl_fn(ccx.llmod, s, lldty);
|
||||
lib::llvm::SetLinkage(lldecl, lib::llvm::ExternalLinkage);
|
||||
@ -4959,7 +4979,7 @@ fn trans_class_dtor(ccx: @crate_ctxt, path: path,
|
||||
}
|
||||
/* Translate the dtor body */
|
||||
trans_fn(ccx, path, ast_util::dtor_dec(),
|
||||
body, lldecl, impl_self(class_ty), substs, dtor_id);
|
||||
body, lldecl, impl_self(class_ty), psubsts, dtor_id);
|
||||
lldecl
|
||||
}
|
||||
|
||||
@ -5196,16 +5216,34 @@ fn item_path(ccx: @crate_ctxt, i: @ast::item) -> path {
|
||||
} + [path_name(i.ident)]
|
||||
}
|
||||
|
||||
/* If there's already a symbol for the dtor with <id>, return it;
|
||||
otherwise, create one and register it, returning it as well */
|
||||
fn get_dtor_symbol(ccx: @crate_ctxt, path: path, id: ast::node_id) -> str {
|
||||
/* If there's already a symbol for the dtor with <id> and substs <substs>,
|
||||
return it; otherwise, create one and register it, returning it as well */
|
||||
fn get_dtor_symbol(ccx: @crate_ctxt, path: path, id: ast::node_id,
|
||||
substs: option<param_substs>) -> str {
|
||||
let t = ty::node_id_to_type(ccx.tcx, id);
|
||||
alt ccx.item_symbols.find(id) {
|
||||
some(s) { s }
|
||||
none if is_none(substs) {
|
||||
let s = mangle_exported_name(ccx,
|
||||
path + [path_name(@ccx.names("dtor"))],
|
||||
t);
|
||||
ccx.item_symbols.insert(id, s);
|
||||
s
|
||||
}
|
||||
none {
|
||||
let s = mangle_exported_name(ccx, path +
|
||||
[path_name(@ccx.names("dtor"))], ty::node_id_to_type(ccx.tcx, id));
|
||||
ccx.item_symbols.insert(id, s);
|
||||
s
|
||||
// Monomorphizing, so just make a symbol, don't add
|
||||
// this to item_symbols
|
||||
alt substs {
|
||||
some(ss) {
|
||||
let mono_ty = ty::subst_tps(ccx.tcx, ss.tys, t);
|
||||
mangle_exported_name(ccx, path +
|
||||
[path_name(@ccx.names("dtor"))], mono_ty)
|
||||
}
|
||||
none {
|
||||
ccx.sess.bug(#fmt("get_dtor_symbol: not monomorphizing and \
|
||||
couldn't find a symbol for dtor %?", path));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5289,7 +5327,7 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
|
||||
let lldty = T_fn([T_ptr(type_of(ccx, ty::mk_nil(tcx))),
|
||||
T_ptr(type_of(ccx, class_ty))],
|
||||
llvm::LLVMVoidType());
|
||||
let s = get_dtor_symbol(ccx, *pt, dt.node.id);
|
||||
let s = get_dtor_symbol(ccx, *pt, dt.node.id, none);
|
||||
|
||||
/* Make the declaration for the dtor */
|
||||
let llfn = decl_internal_cdecl_fn(ccx.llmod, s, lldty);
|
||||
|
@ -21,12 +21,14 @@ import std::map::hashmap;
|
||||
|
||||
import ty_ctxt = middle::ty::ctxt;
|
||||
|
||||
type nominal_id = @{did: ast::def_id, tps: [ty::t]};
|
||||
type nominal_id = @{did: ast::def_id, parent_id: option<ast::def_id>,
|
||||
tps: [ty::t]};
|
||||
|
||||
fn mk_nominal_id(tcx: ty::ctxt, did: ast::def_id,
|
||||
parent_id: option<ast::def_id>,
|
||||
tps: [ty::t]) -> nominal_id {
|
||||
let tps_norm = tps.map { |t| ty::normalize_ty(tcx, t) };
|
||||
@{did: did, tps: tps_norm}
|
||||
@{did: did, parent_id: parent_id, tps: tps_norm}
|
||||
}
|
||||
|
||||
fn hash_nominal_id(&&ri: nominal_id) -> uint {
|
||||
@ -233,7 +235,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
|
||||
tk_enum { [s_variant_enum_t(ccx.tcx)] }
|
||||
tk_newtype | tk_complex {
|
||||
let mut s = [shape_enum], id;
|
||||
let nom_id = mk_nominal_id(ccx.tcx, did, substs.tps);
|
||||
let nom_id = mk_nominal_id(ccx.tcx, did, none, substs.tps);
|
||||
alt ccx.shape_cx.tag_id_to_index.find(nom_id) {
|
||||
none {
|
||||
id = ccx.shape_cx.next_tag_id;
|
||||
@ -335,7 +337,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
|
||||
else { [shape_struct] };
|
||||
let mut sub = [];
|
||||
option::iter(m_dtor_did) {|dtor_did|
|
||||
let ri = @{did: dtor_did, tps: tps};
|
||||
let ri = @{did: dtor_did, parent_id: some(did), tps: tps};
|
||||
let id = interner::intern(ccx.shape_cx.resources, ri);
|
||||
add_u16(s, id as u16);
|
||||
|
||||
@ -362,7 +364,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
|
||||
for substs.tps.each() {|t| assert !ty::type_has_params(t); }
|
||||
let subt = ty::subst(ccx.tcx, substs, raw_subt);
|
||||
let tps = substs.tps;
|
||||
let ri = @{did: did, tps: tps};
|
||||
let ri = @{did: did, parent_id: none, tps: tps};
|
||||
let id = interner::intern(ccx.shape_cx.resources, ri);
|
||||
|
||||
let mut s = [shape_res];
|
||||
@ -597,7 +599,8 @@ fn gen_resource_shapes(ccx: @crate_ctxt) -> ValueRef {
|
||||
for uint::range(0u, len) {|i|
|
||||
let ri = interner::get(ccx.shape_cx.resources, i);
|
||||
for ri.tps.each() {|s| assert !ty::type_has_params(s); }
|
||||
dtors += [trans::base::get_res_dtor(ccx, ri.did, ri.tps)];
|
||||
dtors += [trans::base::get_res_dtor(ccx, ri.did, ri.parent_id,
|
||||
ri.tps)];
|
||||
}
|
||||
ret mk_global(ccx, "resource_shapes", C_struct(dtors), true);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import std::map::hashmap;
|
||||
import ty::*;
|
||||
|
||||
export type_of;
|
||||
export type_of_dtor;
|
||||
export type_of_explicit_args;
|
||||
export type_of_fn_from_ty;
|
||||
export type_of_fn;
|
||||
@ -251,3 +252,9 @@ fn llvm_type_name(cx: @crate_ctxt, t: ty::t) -> str {
|
||||
);
|
||||
}
|
||||
|
||||
fn type_of_dtor(ccx: @crate_ctxt, self_ty: ty::t) -> TypeRef {
|
||||
T_fn([T_ptr(type_of(ccx, ty::mk_nil(ccx.tcx))),
|
||||
T_ptr(type_of(ccx, self_ty))],
|
||||
llvm::LLVMVoidType())
|
||||
}
|
||||
|
||||
|
@ -28,12 +28,12 @@ fn bound_region_to_str(cx: ctxt, br: bound_region) -> str {
|
||||
}
|
||||
|
||||
fn re_scope_id_to_str(cx: ctxt, node_id: ast::node_id) -> str {
|
||||
alt cx.items.get(node_id) {
|
||||
ast_map::node_block(blk) {
|
||||
alt cx.items.find(node_id) {
|
||||
some(ast_map::node_block(blk)) {
|
||||
#fmt("<block at %s>",
|
||||
codemap::span_to_str(blk.span, cx.sess.codemap))
|
||||
}
|
||||
ast_map::node_expr(expr) {
|
||||
some(ast_map::node_expr(expr)) {
|
||||
alt expr.node {
|
||||
ast::expr_call(*) {
|
||||
#fmt("<call at %s>",
|
||||
|
@ -1,3 +1,11 @@
|
||||
S 2012-06-20 c891dec
|
||||
macos-x86_64 cd7b3213a05e11dbf7440db016c9f7db16598501
|
||||
macos-i386 eba609b4c815c415ca9485cac749c08ede5bf9ff
|
||||
freebsd-x86_64 c93d3297bf68d12a55af04fecab5c1792394fcca
|
||||
linux-x86_64 eb0e614c6f463fdbf3f40953ff122eb7cd829b85
|
||||
linux-i386 6d858ef6915517135e633043115ab51d677010c5
|
||||
winnt-i386 ffc26150a21aac3c5b023070c0e52d3c01b1881c
|
||||
|
||||
S 2012-06-19 de491ea
|
||||
freebsd-x86_64 b5c1080df70136bb316286e1973fa2b5734c9a01
|
||||
winnt-i386 fa1c7b2295dbde00269f859b8cb637a59a8deec4
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
|
||||
An implementation of the Graph500 Bread First Search problem in Rust.
|
||||
An implementation of the Graph500 Breadth First Search problem in Rust.
|
||||
|
||||
*/
|
||||
|
||||
|
9
src/test/compile-fail/borrowck-issue-2657-1.rs
Normal file
9
src/test/compile-fail/borrowck-issue-2657-1.rs
Normal file
@ -0,0 +1,9 @@
|
||||
fn main() {
|
||||
let x = some(~1);
|
||||
alt x { //! NOTE loan of immutable local variable granted here
|
||||
some(y) {
|
||||
let _a <- x; //! ERROR moving out of immutable local variable prohibited due to outstanding loan
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
}
|
14
src/test/compile-fail/borrowck-issue-2657-2.rs
Normal file
14
src/test/compile-fail/borrowck-issue-2657-2.rs
Normal file
@ -0,0 +1,14 @@
|
||||
//xfail-test
|
||||
|
||||
// this should be illegal but borrowck is not handling
|
||||
// pattern bindings correctly right now
|
||||
|
||||
fn main() {
|
||||
let x = some(~1);
|
||||
alt x {
|
||||
some(y) {
|
||||
let b <- y;
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
}
|
7
src/test/compile-fail/borrowck-move-from-unsafe-ptr.rs
Normal file
7
src/test/compile-fail/borrowck-move-from-unsafe-ptr.rs
Normal file
@ -0,0 +1,7 @@
|
||||
fn foo(x: *~int) -> ~int {
|
||||
let y <- *x; //! ERROR dereference of unsafe pointer requires unsafe function or block
|
||||
ret y;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
11
src/test/run-pass/borrowck-move-from-unsafe-ptr-ok.rs
Normal file
11
src/test/run-pass/borrowck-move-from-unsafe-ptr-ok.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// just make sure this compiles:
|
||||
|
||||
fn bar(x: *~int) -> ~int {
|
||||
unsafe {
|
||||
let y <- *x;
|
||||
ret y;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
15
src/test/run-pass/nested-class.rs
Normal file
15
src/test/run-pass/nested-class.rs
Normal file
@ -0,0 +1,15 @@
|
||||
fn main() {
|
||||
|
||||
class b {
|
||||
let i: int;
|
||||
fn do_stuff() -> int { ret 37; }
|
||||
new(i:int) { self.i = i; }
|
||||
}
|
||||
|
||||
// fn b(x:int) -> int { fail; }
|
||||
|
||||
let z = b(42);
|
||||
assert(z.i == 42);
|
||||
assert(z.do_stuff() == 37);
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user