diff options
33 files changed, 370 insertions, 166 deletions
diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs index b0825816626..238207f12b6 100644 --- a/src/libcore/comm.rs +++ b/src/libcore/comm.rs @@ -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. diff --git a/src/libcore/core.rc b/src/libcore/core.rc index 91eb61e342e..3e514ce249f 100644 --- a/src/libcore/core.rc +++ b/src/libcore/core.rc @@ -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"]; diff --git a/src/libcore/num/strconv.rs b/src/libcore/num/strconv.rs index 4322ea40428..50fc1b03ccc 100644 --- a/src/libcore/num/strconv.rs +++ b/src/libcore/num/strconv.rs @@ -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(); } } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 6ee6d282841..7dfc52c458a 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -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. diff --git a/src/libfuzzer/fuzzer.rc b/src/libfuzzer/fuzzer.rc index 97ac8cf2d50..c16a7cf8d3e 100644 --- a/src/libfuzzer/fuzzer.rc +++ b/src/libfuzzer/fuzzer.rc @@ -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]; diff --git a/src/librust/rust.rc b/src/librust/rust.rc index 950623b8760..e60f2bfaa50 100644 --- a/src/librust/rust.rc +++ b/src/librust/rust.rc @@ -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"); diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 222931d1829..d5cb2f8726d 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -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)), + }) + } } } } diff --git a/src/librustc/middle/borrowck/gather_loans.rs b/src/librustc/middle/borrowck/gather_loans.rs index c6f4f04fe71..ab343456ef4 100644 --- a/src/librustc/middle/borrowck/gather_loans.rs +++ b/src/librustc/middle/borrowck/gather_loans.rs @@ -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 { diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 9bdf69f4c88..e0f3aad4bc2 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -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, diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 227d262a79e..7a6a434c41f 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -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; diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index d5adfee65af..b9f35af37e0 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -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) }; diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 3a68e8e94c6..12864f12abd 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -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)); - - fn closure_callee(db: &DatumBlock) -> Callee { - return Callee {bcx: db.bcx, data: Closure(db.datum)}; + return datum_callee(bcx, expr); + + 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, diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 97f8ec84a1d..c2a7abe747b 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -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); diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index c6ed190c7c3..7fe2bd605e9 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -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). diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 7d3aa4c24f4..fdb5e94559f 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -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), diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 90f97a939ad..cabda54eeea 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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. diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 34b650aa180..63d09d88f52 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -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); } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 3bf474b2bed..9ca8268171b 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -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 }) ); } diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index bf6ddc4f542..1f2dfe7192f 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -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); + 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); + 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); + 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); diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index 7fb896a902c..e5aca315dd1 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -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); } diff --git a/src/librustc/middle/typeck/infer/coercion.rs b/src/librustc/middle/typeck/infer/coercion.rs index 6ad58bc5d4f..9ee0b848176 100644 --- a/src/librustc/middle/typeck/infer/coercion.rs +++ b/src/librustc/middle/typeck/infer/coercion.rs @@ -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, diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index 56ad56c3ae6..140b52f03aa 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -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]; diff --git a/src/librustdoc/rustdoc.rc b/src/librustdoc/rustdoc.rc index 7d94352cc82..fc0ea4ce396 100644 --- a/src/librustdoc/rustdoc.rc +++ b/src/librustdoc/rustdoc.rc @@ -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]; diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index 0fe533e3dd9..56375ca5bfb 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -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]; diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rc index c16a56249ff..b58b5977f97 100644 --- a/src/librustpkg/rustpkg.rc +++ b/src/librustpkg/rustpkg.rc @@ -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, diff --git a/src/libstd/std.rc b/src/libstd/std.rc index 854abfdd112..2f6c4e3f190 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -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)]; diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index 8cebe3cd187..0e2f3c2c856 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -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 { diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index 40d0e2c5db2..3b885b7a7b9 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -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())))) } } diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index 052a3e48791..16db384bb06 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -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 } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b0b2107703c..127af5b73ac 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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 { diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index 9eb7507f3d0..f6e358e535f 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -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]; diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index b0e13717b82..9f39e1433fc 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -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(); } diff --git a/src/snapshots.txt b/src/snapshots.txt index fc72551e7dd..31acfa81100 100644 --- a/src/snapshots.txt +++ b/src/snapshots.txt @@ -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 |
