Merge remote-tracking branch 'remotes/origin/incoming' into incoming

This commit is contained in:
Erick Tryzelaar 2013-03-01 20:35:55 -08:00
commit aa3505d8ff
33 changed files with 371 additions and 167 deletions

View File

@ -17,8 +17,8 @@ use vec;
use pipes::{recv, try_recv, wait_many, peek, PacketHeader};
// NOTE Making this public exposes some plumbing from pipes. Needs
// some refactoring
// FIXME #5160: Making this public exposes some plumbing from
// pipes. Needs some refactoring
pub use pipes::Selectable;
/// A trait for things that can send multiple messages.

View File

@ -1,4 +1,4 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -41,7 +41,7 @@ Implicitly, all crates behave as if they included the following prologue:
url = "https://github.com/mozilla/rust/tree/master/src/libcore")];
#[comment = "The Rust core library"];
#[license = "MIT"];
#[license = "MIT/ASL2"];
#[crate_type = "lib"];

View File

@ -478,17 +478,16 @@ pub pure fn from_str_bytes_common<T:NumCast+Zero+One+Ord+Copy+Div<T,T>+
}
}
// XXX: Bytevector constant from str
if special {
if buf == str::to_bytes("inf") || buf == str::to_bytes("+inf") {
if buf == str::inf_buf || buf == str::positive_inf_buf {
return NumStrConv::inf();
} else if buf == str::to_bytes("-inf") {
} else if buf == str::negative_inf_buf {
if negative {
return NumStrConv::neg_inf();
} else {
return None;
}
} else if buf == str::to_bytes("NaN") {
} else if buf == str::nan_buf {
return NumStrConv::NaN();
}
}

View File

@ -1832,6 +1832,13 @@ const tag_five_b: uint = 248u;
const max_five_b: uint = 67108864u;
const tag_six_b: uint = 252u;
// Constants used for converting strs to floats
pub const inf_buf: [u8*3] = ['i' as u8, 'n' as u8, 'f' as u8];
pub const positive_inf_buf: [u8*4] = ['+' as u8, 'i' as u8,
'n' as u8, 'f' as u8];
pub const negative_inf_buf: [u8*4] = ['-' as u8, 'i' as u8,
'n' as u8, 'f' as u8];
pub const nan_buf: [u8*3] = ['N' as u8, 'a' as u8, 'N' as u8];
/**
* Work with the byte buffer of a string.

View File

@ -1,4 +1,4 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -15,7 +15,7 @@
url = "https://github.com/mozilla/rust/tree/master/src/libfuzzer")];
#[comment = "The Rust fuzzer library"];
#[license = "MIT"];
#[license = "MIT/ASL2"];
#[crate_type = "lib"];
#[no_core];

View File

@ -17,6 +17,7 @@
uuid = "4a24da33-5cc8-4037-9352-2cbe9bd9d27c",
url = "https://github.com/mozilla/rust/tree/master/src/rust")];
#[license = "MIT/ASL2"];
#[crate_type = "lib"];
extern mod core(vers = "0.6");

View File

@ -451,9 +451,17 @@ impl tr for ast::def {
impl tr for ty::AutoAdjustment {
fn tr(&self, xcx: @ExtendedDecodeContext) -> ty::AutoAdjustment {
ty::AutoAdjustment {
autoderefs: self.autoderefs,
autoref: self.autoref.map(|ar| ar.tr(xcx)),
match self {
&ty::AutoAddEnv(r, s) => {
ty::AutoAddEnv(r.tr(xcx), s)
}
&ty::AutoDerefRef(ref adr) => {
ty::AutoDerefRef(ty::AutoDerefRef {
autoderefs: adr.autoderefs,
autoref: adr.autoref.map(|ar| ar.tr(xcx)),
})
}
}
}
}

View File

@ -299,17 +299,27 @@ pub impl GatherLoanCtxt {
expr_repr(self.tcx(), expr), adjustment);
let _i = indenter();
match adjustment.autoref {
None => {
match *adjustment {
ty::AutoAddEnv(*) => {
debug!("autoaddenv -- no autoref");
return;
}
ty::AutoDerefRef(
ty::AutoDerefRef {
autoref: None, _ }) => {
debug!("no autoref");
return;
}
Some(ref autoref) => {
ty::AutoDerefRef(
ty::AutoDerefRef {
autoref: Some(ref autoref),
autoderefs: autoderefs}) => {
let mcx = &mem_categorization_ctxt {
tcx: self.tcx(),
method_map: self.bccx.method_map};
let mut cmt = mcx.cat_expr_autoderefd(expr, adjustment);
let mut cmt = mcx.cat_expr_autoderefd(expr, autoderefs);
debug!("after autoderef, cmt=%s", self.bccx.cmt_to_repr(cmt));
match autoref.kind {

View File

@ -480,9 +480,20 @@ pub impl BorrowckCtxt {
}
fn cat_expr_autoderefd(&self, expr: @ast::expr,
adj: @ty::AutoAdjustment)
-> cmt {
cat_expr_autoderefd(self.tcx, self.method_map, expr, adj)
adj: @ty::AutoAdjustment) -> cmt {
match *adj {
ty::AutoAddEnv(*) => {
// no autoderefs
cat_expr_unadjusted(self.tcx, self.method_map, expr)
}
ty::AutoDerefRef(
ty::AutoDerefRef {
autoderefs: autoderefs, _}) => {
cat_expr_autoderefd(self.tcx, self.method_map, expr,
autoderefs)
}
}
}
fn cat_def(&self,

View File

@ -241,12 +241,12 @@ pub fn cat_expr_autoderefd(
tcx: ty::ctxt,
method_map: typeck::method_map,
expr: @ast::expr,
adj: @ty::AutoAdjustment) -> cmt {
autoderefs: uint) -> cmt
{
let mcx = &mem_categorization_ctxt {
tcx: tcx, method_map: method_map
};
return mcx.cat_expr_autoderefd(expr, adj);
return mcx.cat_expr_autoderefd(expr, autoderefs);
}
pub fn cat_def(
@ -361,28 +361,38 @@ pub impl mem_categorization_ctxt {
self.cat_expr_unadjusted(expr)
}
Some(adjustment) => {
match adjustment.autoref {
Some(_) => {
// Equivalent to &*expr or something similar.
// This is an rvalue, effectively.
let expr_ty = ty::expr_ty(self.tcx, expr);
self.cat_rvalue(expr, expr_ty)
}
None => {
// Equivalent to *expr or something similar.
self.cat_expr_autoderefd(expr, adjustment)
}
}
Some(@ty::AutoAddEnv(*)) => {
// Convert a bare fn to a closure by adding NULL env.
// Result is an rvalue.
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
self.cat_rvalue(expr, expr_ty)
}
Some(
@ty::AutoDerefRef(
ty::AutoDerefRef {
autoref: Some(_), _})) => {
// Equivalent to &*expr or something similar.
// Result is an rvalue.
let expr_ty = ty::expr_ty_adjusted(self.tcx, expr);
self.cat_rvalue(expr, expr_ty)
}
Some(
@ty::AutoDerefRef(
ty::AutoDerefRef {
autoref: None, autoderefs: autoderefs})) => {
// Equivalent to *expr or something similar.
self.cat_expr_autoderefd(expr, autoderefs)
}
}
}
fn cat_expr_autoderefd(&self,
expr: @ast::expr,
adjustment: &ty::AutoAdjustment) -> cmt {
autoderefs: uint) -> cmt {
let mut cmt = self.cat_expr_unadjusted(expr);
for uint::range(1, adjustment.autoderefs+1) |deref| {
for uint::range(1, autoderefs+1) |deref| {
cmt = self.cat_deref(expr, cmt, deref);
}
return cmt;

View File

@ -410,7 +410,9 @@ pub impl VisitContext {
// those adjustments is to take a reference, then it's only
// reading the underlying expression, not moving it.
let comp_mode = match self.tcx.adjustments.find(&expr.id) {
Some(adj) if adj.autoref.is_some() => Read,
Some(@ty::AutoDerefRef(
ty::AutoDerefRef {
autoref: Some(_), _})) => Read,
_ => expr_mode.component_mode(expr)
};

View File

@ -39,6 +39,7 @@ use middle::trans::inline;
use middle::trans::meth;
use middle::trans::monomorphize;
use middle::trans::type_of;
use middle::ty::ty_to_str;
use middle::ty;
use middle::typeck;
use util::common::indenter;
@ -94,10 +95,25 @@ pub fn trans(bcx: block, expr: @ast::expr) -> Callee {
}
// any other expressions are closures:
return closure_callee(&expr::trans_to_datum(bcx, expr));
return datum_callee(bcx, expr);
fn closure_callee(db: &DatumBlock) -> Callee {
return Callee {bcx: db.bcx, data: Closure(db.datum)};
fn datum_callee(bcx: block, expr: @ast::expr) -> Callee {
let DatumBlock {bcx, datum} = expr::trans_to_datum(bcx, expr);
match ty::get(datum.ty).sty {
ty::ty_bare_fn(*) => {
let llval = datum.to_appropriate_llval(bcx);
return Callee {bcx: bcx, data: Fn(FnData {llfn: llval})};
}
ty::ty_closure(*) => {
return Callee {bcx: bcx, data: Closure(datum)};
}
_ => {
bcx.tcx().sess.span_bug(
expr.span,
fmt!("Type of callee is neither bare-fn nor closure: %s",
bcx.ty_to_str(datum.ty)));
}
}
}
fn fn_callee(bcx: block, fd: FnData) -> Callee {
@ -129,7 +145,7 @@ pub fn trans(bcx: block, expr: @ast::expr) -> Callee {
ast::def_binding(*) |
ast::def_upvar(*) |
ast::def_self(*) => {
closure_callee(&expr::trans_to_datum(bcx, ref_expr))
datum_callee(bcx, ref_expr)
}
ast::def_mod(*) | ast::def_foreign_mod(*) |
ast::def_const(*) | ast::def_ty(*) | ast::def_prim_ty(*) |
@ -392,7 +408,6 @@ pub fn trans_lang_call_with_type_params(bcx: block,
fty);
let mut llfnty = type_of::type_of(callee.bcx.ccx(),
substituted);
llfnty = lib::llvm::struct_tys(llfnty)[0];
new_llval = PointerCast(callee.bcx, fn_data.llfn, llfnty);
}
_ => fail!()
@ -715,6 +730,8 @@ pub fn trans_arg_expr(bcx: block,
}
ast::by_copy => {
debug!("by copy arg with type %s, storing to scratch",
bcx.ty_to_str(arg_datum.ty));
let scratch = scratch_datum(bcx, arg_datum.ty, false);
arg_datum.store_to_datum(bcx, arg_expr.id,

View File

@ -1344,6 +1344,12 @@ pub fn expr_ty(bcx: block, ex: @ast::expr) -> ty::t {
node_id_type(bcx, ex.id)
}
pub fn expr_ty_adjusted(bcx: block, ex: @ast::expr) -> ty::t {
let tcx = bcx.tcx();
let t = ty::expr_ty_adjusted(tcx, ex);
monomorphize_type(bcx, t)
}
pub fn node_id_type_params(bcx: block, id: ast::node_id) -> ~[ty::t] {
let tcx = bcx.tcx();
let params = ty::node_id_to_type_params(tcx, id);

View File

@ -144,7 +144,8 @@ use middle::trans::tvec;
use middle::trans::type_of;
use middle::ty;
use middle::ty::struct_mutable_fields;
use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn};
use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn,
AutoDerefRef, AutoAddEnv};
use util::common::indenter;
use util::ppaux::ty_to_str;
@ -197,7 +198,14 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock {
None => {
trans_to_datum_unadjusted(bcx, expr)
}
Some(adj) => {
Some(@AutoAddEnv(*)) => {
let mut bcx = bcx;
let mut datum = unpack_datum!(bcx, {
trans_to_datum_unadjusted(bcx, expr)
});
add_env(bcx, expr, datum)
}
Some(@AutoDerefRef(ref adj)) => {
let mut bcx = bcx;
let mut datum = unpack_datum!(bcx, {
trans_to_datum_unadjusted(bcx, expr)
@ -266,6 +274,25 @@ 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 {
// 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
// code and keep it DRY that accommodates that use case at the
// moment.
let tcx = bcx.tcx();
let closure_ty = expr_ty_adjusted(bcx, expr);
debug!("add_env(closure_ty=%s)", ty_to_str(tcx, closure_ty));
let scratch = scratch_datum(bcx, closure_ty, false);
let llfn = GEPi(bcx, scratch.val, [0u, abi::fn_field_code]);
assert datum.appropriate_mode() == ByValue;
Store(bcx, datum.to_appropriate_llval(bcx), llfn);
let llenv = GEPi(bcx, scratch.val, [0u, abi::fn_field_box]);
Store(bcx, base::null_env_ptr(bcx), llenv);
DatumBlock {bcx: bcx, datum: scratch}
}
fn auto_slice_and_ref(bcx: block, datum: Datum) -> DatumBlock {
let DatumBlock { bcx, datum } = auto_slice(bcx, datum);
auto_ref(bcx, datum)
@ -420,6 +447,9 @@ fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
trace_span!(bcx, expr.span, @shorten(bcx.expr_to_str(expr)));
match expr.node {
ast::expr_path(_) => {
return trans_def_datum_unadjusted(bcx, expr, bcx.def(expr.id));
}
ast::expr_vstore(contents, ast::expr_vstore_box) |
ast::expr_vstore(contents, ast::expr_vstore_mut_box) => {
return tvec::trans_uniq_or_managed_vstore(bcx, heap_managed,
@ -685,22 +715,13 @@ fn trans_def_dps_unadjusted(bcx: block, ref_expr: @ast::expr,
};
match def {
ast::def_fn(did, _) | ast::def_static_method(did, None, _) => {
let fn_data = callee::trans_fn_ref(bcx, did, ref_expr.id);
return fn_data_to_datum(bcx, did, fn_data, lldest);
}
ast::def_static_method(impl_did, Some(trait_did), _) => {
let fn_data = meth::trans_static_method_callee(bcx, impl_did,
trait_did,
ref_expr.id);
return fn_data_to_datum(bcx, impl_did, fn_data, lldest);
}
ast::def_variant(tid, vid) => {
let variant_info = ty::enum_variant_with_id(ccx.tcx, tid, vid);
if variant_info.args.len() > 0u {
// N-ary variant.
let fn_data = callee::trans_fn_ref(bcx, vid, ref_expr.id);
return fn_data_to_datum(bcx, vid, fn_data, lldest);
Store(bcx, fn_data.llfn, lldest);
return bcx;
} else if !ty::enum_is_univariant(ccx.tcx, tid) {
// Nullary variant.
let lldiscrimptr = GEPi(bcx, lldest, [0u, 0u]);
@ -725,6 +746,66 @@ fn trans_def_dps_unadjusted(bcx: block, ref_expr: @ast::expr,
}
}
fn trans_def_datum_unadjusted(bcx: block,
ref_expr: @ast::expr,
def: ast::def) -> DatumBlock
{
let _icx = bcx.insn_ctxt("trans_def_datum_unadjusted");
match def {
ast::def_fn(did, _) | ast::def_static_method(did, None, _) => {
let fn_data = callee::trans_fn_ref(bcx, did, ref_expr.id);
return fn_data_to_datum(bcx, ref_expr, did, fn_data);
}
ast::def_static_method(impl_did, Some(trait_did), _) => {
let fn_data = meth::trans_static_method_callee(bcx, impl_did,
trait_did,
ref_expr.id);
return fn_data_to_datum(bcx, ref_expr, impl_did, fn_data);
}
_ => {
bcx.tcx().sess.span_bug(ref_expr.span, fmt!(
"Non-DPS def %? referened by %s",
def, bcx.node_id_to_str(ref_expr.id)));
}
}
fn fn_data_to_datum(bcx: block,
ref_expr: @ast::expr,
def_id: ast::def_id,
fn_data: callee::FnData) -> DatumBlock {
/*!
*
* Translates a reference to a top-level fn item into a rust
* value. This is just a fn pointer.
*/
let is_extern = {
let fn_tpt = ty::lookup_item_type(bcx.tcx(), def_id);
ty::ty_fn_purity(fn_tpt.ty) == ast::extern_fn
};
let (rust_ty, llval) = if is_extern {
let rust_ty = ty::mk_ptr(
bcx.tcx(),
ty::mt {
ty: ty::mk_mach_uint(bcx.tcx(), ast::ty_u8),
mutbl: ast::m_imm
}); // *u8
(rust_ty, PointerCast(bcx, fn_data.llfn, T_ptr(T_i8())))
} else {
let fn_ty = expr_ty(bcx, ref_expr);
(fn_ty, fn_data.llfn)
};
return DatumBlock {
bcx: bcx,
datum: Datum {val: llval,
ty: rust_ty,
mode: ByValue,
source: RevokeClean}
};
}
}
fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
/*!
*
@ -1012,36 +1093,6 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum {
}
}
fn fn_data_to_datum(bcx: block,
def_id: ast::def_id,
fn_data: callee::FnData,
lldest: ValueRef) -> block {
//!
//
// Translates a reference to a top-level fn item into a rust
// value. This is generally a Rust closure pair: (fn ptr, env)
// where the environment is NULL. However, extern functions for
// interfacing with C are represted as just the fn ptr with type
// *u8.
//
// Strictly speaking, references to extern fns ought to be
// RvalueDatumExprs, but it's not worth the complexity to avoid the
// extra stack slot that LLVM probably optimizes away anyhow.
let fn_tpt = ty::lookup_item_type(bcx.tcx(), def_id);
if ty::ty_fn_purity(fn_tpt.ty) == ast::extern_fn {
let val = PointerCast(bcx, fn_data.llfn, T_ptr(T_i8()));
Store(bcx, val, lldest);
return bcx;
}
let llfn = GEPi(bcx, lldest, [0u, abi::fn_field_code]);
Store(bcx, fn_data.llfn, llfn);
let llenv = GEPi(bcx, lldest, [0u, abi::fn_field_box]);
Store(bcx, base::null_env_ptr(bcx), llenv);
return bcx;
}
// The optional node ID here is the node ID of the path identifying the enum
// variant in use. If none, this cannot possibly an enum variant (so, if it
// is and `node_id_opt` is none, this function fails).

View File

@ -134,8 +134,7 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())])
}
// FIXME(#4804) Bare fn repr
ty::ty_bare_fn(*) => T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())]),
ty::ty_bare_fn(*) => T_ptr(T_i8()),
ty::ty_closure(*) => T_struct(~[T_ptr(T_i8()), T_ptr(T_i8())]),
ty::ty_trait(_, _, vstore) => T_opaque_trait(cx, vstore),
@ -173,7 +172,9 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
ty::ty_enum(def_id, _) => T_struct(enum_body_types(cx, def_id, t)),
ty::ty_self | ty::ty_infer(*) | ty::ty_param(*) | ty::ty_err(*) => {
cx.tcx.sess.bug(~"fictitious type in sizing_type_of()")
cx.tcx.sess.bug(
fmt!("fictitious type %? in sizing_type_of()",
ty::get(t).sty))
}
};
@ -270,9 +271,7 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
T_struct(~[T_struct(tys)])
}
// FIXME(#4804) Bare fn repr
// ty::ty_bare_fn(_) => T_ptr(type_of_fn_from_ty(cx, t)),
ty::ty_bare_fn(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)),
ty::ty_bare_fn(_) => T_ptr(type_of_fn_from_ty(cx, t)),
ty::ty_closure(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)),
ty::ty_trait(_, _, vstore) => T_opaque_trait(cx, vstore),
ty::ty_type => T_ptr(cx.tydesc_type),

View File

@ -172,7 +172,14 @@ impl cmp::Eq for region_variance {
#[auto_encode]
#[auto_decode]
pub struct AutoAdjustment {
pub enum AutoAdjustment {
AutoAddEnv(ty::Region, ast::Sigil),
AutoDerefRef(AutoDerefRef)
}
#[auto_encode]
#[auto_decode]
pub struct AutoDerefRef {
autoderefs: uint,
autoref: Option<AutoRef>
}
@ -198,7 +205,7 @@ pub enum AutoRefKind {
AutoBorrowVecRef,
/// Convert from @fn()/~fn() to &fn()
AutoBorrowFn,
AutoBorrowFn
}
// Stores information about provided methods (a.k.a. default methods) in
@ -1475,7 +1482,6 @@ pub fn type_is_structural(ty: t) -> bool {
match get(ty).sty {
ty_rec(_) | ty_struct(*) | ty_tup(_) | ty_enum(*) |
ty_closure(_) |
ty_bare_fn(_) | // FIXME(#4804) Bare fn repr
ty_trait(*) |
ty_evec(_, vstore_fixed(_)) | ty_estr(vstore_fixed(_)) |
ty_evec(_, vstore_slice(_)) | ty_estr(vstore_slice(_))
@ -1585,7 +1591,7 @@ pub pure fn type_is_scalar(ty: t) -> bool {
match get(ty).sty {
ty_nil | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) |
ty_infer(IntVar(_)) | ty_infer(FloatVar(_)) | ty_type |
ty_ptr(_) => true,
ty_bare_fn(*) | ty_ptr(_) => true,
_ => false
}
}
@ -2882,7 +2888,25 @@ pub fn expr_ty_adjusted(cx: ctxt, expr: @ast::expr) -> t {
return match cx.adjustments.find(&expr.id) {
None => unadjusted_ty,
Some(adj) => {
Some(@AutoAddEnv(r, s)) => {
match ty::get(unadjusted_ty).sty {
ty::ty_bare_fn(ref b) => {
ty::mk_closure(
cx,
ty::ClosureTy {purity: b.purity,
sigil: s,
onceness: ast::Many,
region: r,
sig: copy b.sig})
}
ref b => {
cx.sess.bug(
fmt!("add_env adjustment on non-bare-fn: %?", b));
}
}
}
Some(@AutoDerefRef(ref adj)) => {
let mut adjusted_ty = unadjusted_ty;
for uint::range(0, adj.autoderefs) |i| {
@ -3064,9 +3088,11 @@ pub fn expr_kind(tcx: ctxt,
match expr.node {
ast::expr_path(*) => {
match resolve_expr(tcx, expr) {
ast::def_fn(*) | ast::def_static_method(*) |
ast::def_variant(*) | ast::def_struct(*) => RvalueDpsExpr,
// Fn pointers are just scalar values.
ast::def_fn(*) | ast::def_static_method(*) => RvalueDatumExpr,
// Note: there is actually a good case to be made that
// def_args, particularly those of immediate type, ought to
// considered rvalues.

View File

@ -799,26 +799,28 @@ pub impl LookupContext {
let region = self.infcx().next_region_var(self.expr.span,
self.expr.id);
(ty::mk_rptr(tcx, region, self_mt),
ty::AutoAdjustment {
ty::AutoDerefRef(ty::AutoDerefRef {
autoderefs: autoderefs+1,
autoref: Some(ty::AutoRef {kind: AutoPtr,
region: region,
mutbl: self_mt.mutbl})})
mutbl: self_mt.mutbl})}))
}
ty::ty_evec(self_mt, vstore_slice(_))
if self_mt.mutbl == m_mutbl => {
let region = self.infcx().next_region_var(self.expr.span,
self.expr.id);
(ty::mk_evec(tcx, self_mt, vstore_slice(region)),
ty::AutoAdjustment {
ty::AutoDerefRef(ty::AutoDerefRef {
autoderefs: autoderefs,
autoref: Some(ty::AutoRef {kind: AutoBorrowVec,
region: region,
mutbl: self_mt.mutbl})})
mutbl: self_mt.mutbl})}))
}
_ => {
(self_ty, ty::AutoAdjustment {autoderefs: autoderefs,
autoref: None})
(self_ty,
ty::AutoDerefRef(ty::AutoDerefRef {
autoderefs: autoderefs,
autoref: None}))
}
};
}
@ -947,14 +949,14 @@ pub impl LookupContext {
Some(mme) => {
self.fcx.write_adjustment(
self.self_expr.id,
@ty::AutoAdjustment {
@ty::AutoDerefRef(ty::AutoDerefRef {
autoderefs: autoderefs,
autoref: Some(ty::AutoRef {
kind: kind,
region: region,
mutbl: *mutbl,
}),
});
}));
return Some(mme);
}
}

View File

@ -749,7 +749,9 @@ pub impl FnCtxt {
if derefs == 0 { return; }
self.write_adjustment(
node_id,
@ty::AutoAdjustment { autoderefs: derefs, autoref: None }
@ty::AutoDerefRef(ty::AutoDerefRef {
autoderefs: derefs,
autoref: None })
);
}

View File

@ -184,8 +184,13 @@ pub fn visit_expr(expr: @ast::expr, &&rcx: @mut Rcx, v: rvt) {
debug!("visit_expr(e=%s)", rcx.fcx.expr_to_str(expr));
for rcx.fcx.inh.adjustments.find(&expr.id).each |adjustment| {
for adjustment.autoref.each |autoref| {
guarantor::for_autoref(rcx, expr, *adjustment, autoref);
match *adjustment {
@ty::AutoDerefRef(
ty::AutoDerefRef {
autoderefs: autoderefs, autoref: Some(ref autoref)}) => {
guarantor::for_autoref(rcx, expr, autoderefs, autoref);
}
_ => {}
}
}
@ -329,9 +334,11 @@ pub fn constrain_auto_ref(rcx: @mut Rcx, expr: @ast::expr) {
let adjustment = rcx.fcx.inh.adjustments.find(&expr.id);
let region = match adjustment {
Some(@ty::AutoAdjustment { autoref: Some(ref auto_ref), _ }) => {
Some(@ty::AutoDerefRef(
ty::AutoDerefRef {
autoref: Some(ref auto_ref), _})) => {
auto_ref.region
},
}
_ => { return; }
};
@ -563,7 +570,7 @@ pub mod guarantor {
pub fn for_autoref(rcx: @mut Rcx,
expr: @ast::expr,
adjustment: &ty::AutoAdjustment,
autoderefs: uint,
autoref: &ty::AutoRef) {
/*!
*
@ -578,7 +585,7 @@ pub mod guarantor {
let mut expr_ct = categorize_unadjusted(rcx, expr);
expr_ct = apply_autoderefs(
rcx, expr, adjustment.autoderefs, expr_ct);
rcx, expr, autoderefs, expr_ct);
for expr_ct.cat.guarantor.each |g| {
infallibly_mk_subr(rcx, true, expr.span, autoref.region, *g);
}
@ -723,19 +730,32 @@ pub mod guarantor {
let mut expr_ct = categorize_unadjusted(rcx, expr);
debug!("before adjustments, cat=%?", expr_ct.cat);
for rcx.fcx.inh.adjustments.find(&expr.id).each |adjustment| {
debug!("adjustment=%?", adjustment);
expr_ct = apply_autoderefs(
rcx, expr, adjustment.autoderefs, expr_ct);
for adjustment.autoref.each |autoref| {
// If there is an autoref, then the result of this
// expression will be some sort of borrowed pointer.
expr_ct.cat.guarantor = None;
expr_ct.cat.pointer = BorrowedPointer(autoref.region);
debug!("autoref, cat=%?", expr_ct.cat);
match rcx.fcx.inh.adjustments.find(&expr.id) {
Some(@ty::AutoAddEnv(*)) => {
// This is basically an rvalue, not a pointer, no regions
// involved.
expr_ct.cat = ExprCategorization {
guarantor: None,
pointer: NotPointer
};
}
Some(@ty::AutoDerefRef(ref adjustment)) => {
debug!("adjustment=%?", adjustment);
expr_ct = apply_autoderefs(
rcx, expr, adjustment.autoderefs, expr_ct);
for adjustment.autoref.each |autoref| {
// If there is an autoref, then the result of this
// expression will be some sort of borrowed pointer.
expr_ct.cat.guarantor = None;
expr_ct.cat.pointer = BorrowedPointer(autoref.region);
debug!("autoref, cat=%?", expr_ct.cat);
}
}
None => {}
}
debug!("result=%?", expr_ct.cat);

View File

@ -79,7 +79,24 @@ fn resolve_type_vars_for_node(wbcx: @mut WbCtxt, sp: span, id: ast::node_id)
// Resolve any borrowings for the node with id `id`
match fcx.inh.adjustments.find(&id) {
None => (),
Some(adj) => {
Some(@ty::AutoAddEnv(r, s)) => {
match resolve_region(fcx.infcx(), r, resolve_all | force_all) {
Err(e) => {
// This should not, I think, happen:
fcx.ccx.tcx.sess.span_err(
sp, fmt!("cannot resolve bound for closure: %s",
infer::fixup_err_to_str(e)));
}
Ok(r1) => {
let resolved_adj = @ty::AutoAddEnv(r1, s);
debug!("Adjustments for node %d: %?", id, resolved_adj);
fcx.tcx().adjustments.insert(id, resolved_adj);
}
}
}
Some(@ty::AutoDerefRef(adj)) => {
let resolved_autoref = match adj.autoref {
Some(ref autoref) => {
match resolve_region(fcx.infcx(), autoref.region,
@ -99,9 +116,10 @@ fn resolve_type_vars_for_node(wbcx: @mut WbCtxt, sp: span, id: ast::node_id)
None => None
};
let resolved_adj = @ty::AutoAdjustment {
let resolved_adj = @ty::AutoDerefRef(ty::AutoDerefRef {
autoderefs: adj.autoderefs,
autoref: resolved_autoref,
..*adj};
});
debug!("Adjustments for node %d: %?", id, resolved_adj);
fcx.tcx().adjustments.insert(id, resolved_adj);
}

View File

@ -67,7 +67,7 @@ we may want to adjust precisely when coercions occur.
use core::prelude::*;
use middle::ty::{TyVar, AutoPtr, AutoBorrowVec, AutoBorrowFn};
use middle::ty::{AutoAdjustment, AutoRef};
use middle::ty::{AutoAdjustment, AutoDerefRef, AutoRef};
use middle::ty::{vstore_slice, vstore_box, vstore_uniq, vstore_fixed};
use middle::ty::{mt};
use middle::ty;
@ -206,14 +206,14 @@ pub impl Coerce {
r_borrow,
mt {ty: inner_ty, mutbl: mt_b.mutbl});
if_ok!(sub.tys(a_borrowed, b));
Ok(Some(@AutoAdjustment {
Ok(Some(@AutoDerefRef(AutoDerefRef {
autoderefs: 1,
autoref: Some(AutoRef {
kind: AutoPtr,
region: r_borrow,
mutbl: mt_b.mutbl
})
}))
})))
}
fn coerce_borrowed_string(&self,
@ -236,14 +236,14 @@ pub impl Coerce {
let r_a = self.infcx.next_region_var_nb(self.span);
let a_borrowed = ty::mk_estr(self.infcx.tcx, vstore_slice(r_a));
if_ok!(self.subtype(a_borrowed, b));
Ok(Some(@AutoAdjustment {
Ok(Some(@AutoDerefRef(AutoDerefRef {
autoderefs: 0,
autoref: Some(AutoRef {
kind: AutoBorrowVec,
region: r_a,
mutbl: m_imm
})
}))
})))
}
fn coerce_borrowed_vector(&self,
@ -269,14 +269,14 @@ pub impl Coerce {
mt {ty: ty_inner, mutbl: mt_b.mutbl},
vstore_slice(r_borrow));
if_ok!(sub.tys(a_borrowed, b));
Ok(Some(@AutoAdjustment {
Ok(Some(@AutoDerefRef(AutoDerefRef {
autoderefs: 0,
autoref: Some(AutoRef {
kind: AutoBorrowVec,
region: r_borrow,
mutbl: mt_b.mutbl
})
}))
})))
}
fn coerce_borrowed_fn(&self,
@ -309,14 +309,14 @@ pub impl Coerce {
});
if_ok!(self.subtype(a_borrowed, b));
Ok(Some(@AutoAdjustment {
Ok(Some(@AutoDerefRef(AutoDerefRef {
autoderefs: 0,
autoref: Some(AutoRef {
kind: AutoBorrowFn,
region: r_borrow,
mutbl: m_imm
})
}))
})))
}
fn coerce_from_bare_fn(&self,
@ -347,10 +347,12 @@ pub impl Coerce {
// for now, bare fn and closures have the same
// representation
let adj = @ty::AutoAddEnv(fn_ty_b.region, fn_ty_b.sigil);
let a_closure = ty::mk_closure(
self.infcx.tcx,
ty::ClosureTy {sig: copy fn_ty_a.sig, ..fn_ty_b});
self.subtype(a_closure, b)
if_ok!(self.subtype(a_closure, b));
Ok(Some(adj))
}
fn coerce_unsafe_ptr(&self,

View File

@ -1,4 +1,4 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -15,7 +15,7 @@
url = "https://github.com/mozilla/rust/tree/master/src/rustc")];
#[comment = "The Rust compiler"];
#[license = "MIT"];
#[license = "MIT/ASL2"];
#[crate_type = "lib"];
#[legacy_modes];

View File

@ -1,4 +1,4 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -16,7 +16,7 @@
url = "https://github.com/mozilla/rust/tree/master/src/rustdoc")];
#[comment = "The Rust documentation generator"];
#[license = "MIT"];
#[license = "MIT/ASL2"];
#[crate_type = "lib"];
#[no_core];

View File

@ -1,4 +1,4 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -15,6 +15,7 @@
uuid = "7fb5bf52-7d45-4fee-8325-5ad3311149fc",
url = "https://github.com/mozilla/rust/tree/master/src/rusti")];
#[license = "MIT/ASL2"];
#[crate_type = "lib"];
#[no_core];

View File

@ -1,4 +1,4 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -15,6 +15,7 @@
uuid = "25de5e6e-279e-4a20-845c-4cabae92daaf",
url = "https://github.com/mozilla/rust/tree/master/src/librustpkg")];
#[license = "MIT/ASL2"];
#[crate_type = "lib"];
#[no_core];
#[allow(vecs_implicitly_copyable,

View File

@ -1,4 +1,4 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -23,7 +23,7 @@ not required in or otherwise suitable for the core library.
url = "https://github.com/mozilla/rust/tree/master/src/libstd")];
#[comment = "The Rust standard library"];
#[license = "MIT"];
#[license = "MIT/ASL2"];
#[crate_type = "lib"];
#[allow(vecs_implicitly_copyable)];

View File

@ -469,8 +469,8 @@ fn mk_impl(
let ty = cx.ty_path(
span,
~[ident],
generics.ty_params.map(
|tp| cx.ty_path(span, ~[tp.ident], ~[])).to_vec()
opt_vec::take_vec(generics.ty_params.map(
|tp| cx.ty_path(span, ~[tp.ident], ~[])))
);
let generics = ast::Generics {

View File

@ -434,13 +434,15 @@ impl ext_ctxt_ast_builder for ext_ctxt {
}
fn ty_vars(&self, ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty] {
ty_params.map(|p| self.ty_path_ast_builder(
path(~[p.ident], dummy_sp()))).to_vec()
opt_vec::take_vec(
ty_params.map(|p| self.ty_path_ast_builder(
path(~[p.ident], dummy_sp()))))
}
fn ty_vars_global(&self,
ty_params: &OptVec<ast::TyParam>) -> ~[@ast::Ty] {
ty_params.map(|p| self.ty_path_ast_builder(
path(~[p.ident], dummy_sp()))).to_vec()
opt_vec::take_vec(
ty_params.map(|p| self.ty_path_ast_builder(
path(~[p.ident], dummy_sp()))))
}
}

View File

@ -31,6 +31,14 @@ pub fn with<T>(+t: T) -> OptVec<T> {
Vec(~[t])
}
pub fn from<T>(+t: ~[T]) -> OptVec<T> {
if t.len() == 0 {
Empty
} else {
Vec(t)
}
}
impl<T> OptVec<T> {
fn push(&mut self, +t: T) {
match *self {
@ -70,12 +78,12 @@ impl<T> OptVec<T> {
Vec(ref v) => v.len()
}
}
}
pure fn to_vec(self) -> ~[T] {
match self {
Empty => ~[],
Vec(v) => v
}
pub fn take_vec<T>(+v: OptVec<T>) -> ~[T] {
match v {
Empty => ~[],
Vec(v) => v
}
}

View File

@ -1195,7 +1195,7 @@ pub impl Parser {
&token::RBRACKET,
seq_sep_trailing_allowed(token::COMMA),
|p| p.parse_expr()
).to_vec();
);
ex = expr_vec(~[first_expr] + remaining_exprs, mutbl);
} else {
// Vector with one element.
@ -1478,7 +1478,7 @@ pub impl Parser {
&ket,
seq_sep_none(),
|p| p.parse_token_tree()
).to_vec(),
),
// the close delimiter:
~[parse_any_tt_tok(&self)]
)
@ -2806,7 +2806,7 @@ pub impl Parser {
let result = self.parse_seq_to_gt(
Some(token::COMMA),
|p| p.parse_ty(false));
result.to_vec()
opt_vec::take_vec(result)
}
fn parse_fn_decl(parse_arg_fn: fn(&Parser) -> arg_or_capture_item)
@ -2908,7 +2908,7 @@ pub impl Parser {
&token::RPAREN,
sep,
parse_arg_fn
).to_vec();
);
}
token::RPAREN => {
args_or_capture_items = ~[];
@ -2928,7 +2928,7 @@ pub impl Parser {
&token::RPAREN,
sep,
parse_arg_fn
).to_vec();
);
}
self.expect(&token::RPAREN);
@ -3130,7 +3130,7 @@ pub impl Parser {
ket,
seq_sep_none(),
|p| p.parse_trait_ref()
).to_vec()
)
}
fn parse_item_struct() -> item_info {

View File

@ -1,4 +1,4 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -14,6 +14,7 @@
#[license = "MIT/ASL2"];
#[crate_type = "lib"];
#[legacy_modes];

View File

@ -120,7 +120,7 @@ upcall_fail(char const *expr,
size_t line) {
rust_task *task = rust_try_get_current_task();
if (task == NULL) {
// NOTE: Need to think about what to do here
// FIXME #5161: Need to think about what to do here
printf("failure outside of a task");
abort();
}

View File

@ -1,5 +1,5 @@
S 2013-02-27 a6d9689
freebsd-x86_64 d33b5ebbf3335f6a8a5cc23572f630ad66539830
freebsd-x86_64 683f329fe589af854f9a375405468691d98015ac
linux-i386 22f5c2a91941735007ed804586fc0f0e82fc3601
linux-x86_64 328fb144edbed8cabb8c2c6306304e3d8460ef60
macos-i386 5dda51347f9aba4c70a0890d3ec084d98a49c015