diff --git a/src/libcore/rt.rs b/src/libcore/rt.rs index 9bc83a5f9043d..04a8ee3023536 100644 --- a/src/libcore/rt.rs +++ b/src/libcore/rt.rs @@ -34,9 +34,12 @@ extern mod rustrt { // 'rt_', otherwise the compiler won't find it. To fix this, see // gather_rust_rtcalls. #[rt(fail_)] -pub fn rt_fail_(expr: *c_char, file: *c_char, line: size_t) { - cleanup_stack_for_failure(); - rustrt::rust_upcall_fail(expr, file, line); +pub fn rt_fail_(expr: *c_char, file: *c_char, line: size_t) -> ! { + unsafe { + cleanup_stack_for_failure(); + rustrt::rust_upcall_fail(expr, file, line); + cast::transmute(()) + } } #[rt(fail_bounds_check)] diff --git a/src/libcore/to_bytes.rs b/src/libcore/to_bytes.rs index ef15aa00f1138..e686e89f8635f 100644 --- a/src/libcore/to_bytes.rs +++ b/src/libcore/to_bytes.rs @@ -19,6 +19,7 @@ pub type Cb = fn(buf: &[const u8]) -> bool; * modified when default methods and trait inheritence are * completed. */ +#[cfg(stage0)] pub trait IterBytes { /** * Call the provided callback `f` one or more times with @@ -37,6 +38,13 @@ pub trait IterBytes { pure fn iter_bytes(lsb0: bool, f: Cb); } +#[cfg(stage1)] +#[cfg(stage2)] +pub trait IterBytes { + pure fn iter_bytes(&self, lsb0: bool, f: Cb); +} + +#[cfg(stage0)] impl bool: IterBytes { #[inline(always)] pure fn iter_bytes(_lsb0: bool, f: Cb) { @@ -46,6 +54,18 @@ impl bool: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl bool: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, _lsb0: bool, f: Cb) { + f([ + *self as u8 + ]); + } +} + +#[cfg(stage0)] impl u8: IterBytes { #[inline(always)] pure fn iter_bytes(_lsb0: bool, f: Cb) { @@ -55,6 +75,18 @@ impl u8: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl u8: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, _lsb0: bool, f: Cb) { + f([ + *self + ]); + } +} + +#[cfg(stage0)] impl u16: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -72,6 +104,26 @@ impl u16: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl u16: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + if lsb0 { + f([ + *self as u8, + (*self >> 8) as u8 + ]); + } else { + f([ + (*self >> 8) as u8, + *self as u8 + ]); + } + } +} + +#[cfg(stage0)] impl u32: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -93,6 +145,30 @@ impl u32: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl u32: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + if lsb0 { + f([ + *self as u8, + (*self >> 8) as u8, + (*self >> 16) as u8, + (*self >> 24) as u8, + ]); + } else { + f([ + (*self >> 24) as u8, + (*self >> 16) as u8, + (*self >> 8) as u8, + *self as u8 + ]); + } + } +} + +#[cfg(stage0)] impl u64: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -122,6 +198,38 @@ impl u64: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl u64: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + if lsb0 { + f([ + *self as u8, + (*self >> 8) as u8, + (*self >> 16) as u8, + (*self >> 24) as u8, + (*self >> 32) as u8, + (*self >> 40) as u8, + (*self >> 48) as u8, + (*self >> 56) as u8 + ]); + } else { + f([ + (*self >> 56) as u8, + (*self >> 48) as u8, + (*self >> 40) as u8, + (*self >> 32) as u8, + (*self >> 24) as u8, + (*self >> 16) as u8, + (*self >> 8) as u8, + *self as u8 + ]); + } + } +} + +#[cfg(stage0)] impl i8: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -129,6 +237,16 @@ impl i8: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl i8: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + (*self as u8).iter_bytes(lsb0, f) + } +} + +#[cfg(stage0)] impl i16: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -136,6 +254,16 @@ impl i16: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl i16: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + (*self as u16).iter_bytes(lsb0, f) + } +} + +#[cfg(stage0)] impl i32: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -143,6 +271,16 @@ impl i32: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl i32: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + (*self as u32).iter_bytes(lsb0, f) + } +} + +#[cfg(stage0)] impl i64: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -150,6 +288,16 @@ impl i64: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl i64: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + (*self as u64).iter_bytes(lsb0, f) + } +} + +#[cfg(stage0)] impl char: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -157,22 +305,56 @@ impl char: IterBytes { } } -#[cfg(target_word_size = "32")] -impl uint: IterBytes { +#[cfg(stage1)] +#[cfg(stage2)] +impl char: IterBytes { #[inline(always)] - pure fn iter_bytes(lsb0: bool, f: Cb) { - (self as u32).iter_bytes(lsb0, f) + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + (*self as u32).iter_bytes(lsb0, f) + } +} + +#[cfg(target_word_size = "32")] +pub mod x32 { + #[cfg(stage0)] + pub impl uint: IterBytes { + #[inline(always)] + pure fn iter_bytes(lsb0: bool, f: Cb) { + (self as u32).iter_bytes(lsb0, f) + } + } + + #[cfg(stage1)] + #[cfg(stage2)] + pub impl uint: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + (*self as u32).iter_bytes(lsb0, f) + } } } #[cfg(target_word_size = "64")] -impl uint: IterBytes { - #[inline(always)] - pure fn iter_bytes(lsb0: bool, f: Cb) { - (self as u64).iter_bytes(lsb0, f) +pub mod x64 { + #[cfg(stage0)] + pub impl uint: IterBytes { + #[inline(always)] + pure fn iter_bytes(lsb0: bool, f: Cb) { + (self as u64).iter_bytes(lsb0, f) + } + } + + #[cfg(stage1)] + #[cfg(stage2)] + pub impl uint: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + (*self as u64).iter_bytes(lsb0, f) + } } } +#[cfg(stage0)] impl int: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -180,6 +362,16 @@ impl int: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl int: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + (*self as uint).iter_bytes(lsb0, f) + } +} + +#[cfg(stage0)] impl &[A]: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -191,11 +383,25 @@ impl &[A]: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl &[A]: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + for (*self).each |elt| { + do elt.iter_bytes(lsb0) |bytes| { + f(bytes) + } + } + } +} + // Move this to vec, probably. pure fn borrow(a: &x/[A]) -> &x/[A] { a } +#[cfg(stage0)] impl ~[A]: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -203,7 +409,16 @@ impl ~[A]: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl ~[A]: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + borrow(*self).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl @[A]: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -211,6 +426,15 @@ impl @[A]: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl @[A]: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + borrow(*self).iter_bytes(lsb0, f) + } +} + pub pure fn iter_bytes_2(a: &A, b: &B, lsb0: bool, z: Cb) { let mut flag = true; @@ -314,6 +538,7 @@ pub pure fn iter_bytes_7 Option: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -351,6 +612,19 @@ impl Option: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl Option: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + match *self { + Some(ref a) => iter_bytes_2(&0u8, a, lsb0, f), + None => 1u8.iter_bytes(lsb0, f) + } + } +} + +#[cfg(stage0)] impl &A: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -358,6 +632,16 @@ impl &A: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl &A: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + (**self).iter_bytes(lsb0, f); + } +} + +#[cfg(stage0)] impl @A: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -365,6 +649,16 @@ impl @A: IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl @A: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + (**self).iter_bytes(lsb0, f); + } +} + +#[cfg(stage0)] impl ~A: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -372,8 +666,16 @@ impl ~A: IterBytes { } } -// NB: raw-pointer IterBytes does _not_ dereference -// to the target; it just gives you the pointer-bytes. +#[cfg(stage1)] +#[cfg(stage2)] +impl ~A: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + (**self).iter_bytes(lsb0, f); + } +} + +#[cfg(stage0)] impl *const A: IterBytes { #[inline(always)] pure fn iter_bytes(lsb0: bool, f: Cb) { @@ -381,13 +683,24 @@ impl *const A: IterBytes { } } +// NB: raw-pointer IterBytes does _not_ dereference +// to the target; it just gives you the pointer-bytes. +#[cfg(stage1)] +#[cfg(stage2)] +impl *const A: IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: Cb) { + (*self as uint).iter_bytes(lsb0, f); + } +} + trait ToBytes { - fn to_bytes(lsb0: bool) -> ~[u8]; + fn to_bytes(&self, lsb0: bool) -> ~[u8]; } impl A: ToBytes { - fn to_bytes(lsb0: bool) -> ~[u8] { + fn to_bytes(&self, lsb0: bool) -> ~[u8] { do io::with_bytes_writer |wr| { for self.iter_bytes(lsb0) |bytes| { wr.write(bytes) diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index da3247de3b118..3e0016ee40170 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -75,6 +75,7 @@ fn fold_foreign_mod(cx: ctxt, nm: ast::foreign_mod, |a| filter_view_item(cx, *a)); return { sort: nm.sort, + abi: nm.abi, view_items: vec::map(filtered_view_items, |x| fld.fold_view_item(*x)), items: filtered_items }; diff --git a/src/librustc/middle/borrowck.rs b/src/librustc/middle/borrowck.rs index 25e184c2c02c3..7e6dcbf824779 100644 --- a/src/librustc/middle/borrowck.rs +++ b/src/librustc/middle/borrowck.rs @@ -483,11 +483,19 @@ impl root_map_key : cmp::Eq { } } +#[cfg(stage0)] impl root_map_key : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.id, &self.derefs, lsb0, f); } } +#[cfg(stage1)] +#[cfg(stage2)] +impl root_map_key : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.id, &self.derefs, lsb0, f); + } +} fn root_map() -> root_map { return HashMap(); @@ -513,6 +521,16 @@ impl borrowck_ctxt { cat_expr(self.tcx, self.method_map, expr) } + fn cat_expr_unadjusted(expr: @ast::expr) -> cmt { + cat_expr_unadjusted(self.tcx, self.method_map, expr) + } + + fn cat_expr_autoderefd(expr: @ast::expr, + adj: @ty::AutoAdjustment) + -> cmt { + cat_expr_autoderefd(self.tcx, self.method_map, expr, adj) + } + fn cat_def(id: ast::node_id, span: span, ty: ty::t, diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 366dd7e7e8504..03bd403bf461d 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -362,7 +362,12 @@ impl check_loan_ctxt { } fn check_assignment(at: assignment_type, ex: @ast::expr) { - let cmt = self.bccx.cat_expr(ex); + // We don't use cat_expr() here because we don't want to treat + // auto-ref'd parameters in overloaded operators as rvalues. + let cmt = match self.bccx.tcx.adjustments.find(ex.id) { + None => self.bccx.cat_expr_unadjusted(ex), + Some(adj) => self.bccx.cat_expr_autoderefd(ex, adj) + }; debug!("check_assignment(cmt=%s)", self.bccx.cmt_to_repr(cmt)); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index ebc06435c64e6..9eafec930f6e4 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -573,6 +573,29 @@ fn cat_expr( return mcx.cat_expr(expr); } +fn cat_expr_unadjusted( + tcx: ty::ctxt, + method_map: typeck::method_map, + expr: @ast::expr) -> cmt { + + let mcx = &mem_categorization_ctxt { + tcx: tcx, method_map: method_map + }; + return mcx.cat_expr_unadjusted(expr); +} + +fn cat_expr_autoderefd( + tcx: ty::ctxt, + method_map: typeck::method_map, + expr: @ast::expr, + adj: @ty::AutoAdjustment) -> cmt { + + let mcx = &mem_categorization_ctxt { + tcx: tcx, method_map: method_map + }; + return mcx.cat_expr_autoderefd(expr, adj); +} + fn cat_def( tcx: ty::ctxt, method_map: typeck::method_map, diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 1000aec9d182c..3c30f07c74864 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -1226,6 +1226,7 @@ impl mono_id_ : cmp::Eq { pure fn ne(&self, other: &mono_id_) -> bool { !(*self).eq(other) } } +#[cfg(stage0)] impl mono_param_id : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { @@ -1239,12 +1240,35 @@ impl mono_param_id : to_bytes::IterBytes { } } } +#[cfg(stage1)] +#[cfg(stage2)] +impl mono_param_id : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + match *self { + mono_precise(t, mids) => + to_bytes::iter_bytes_3(&0u8, &ty::type_id(t), &mids, lsb0, f), + + mono_any => 1u8.iter_bytes(lsb0, f), + mono_repr(ref a, ref b, ref c, ref d) => + to_bytes::iter_bytes_5(&2u8, a, b, c, d, lsb0, f) + } + } +} + +#[cfg(stage0)] impl mono_id_ : core::to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.def, &self.params, lsb0, f); } } +#[cfg(stage1)] +#[cfg(stage2)] +impl mono_id_ : core::to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.def, &self.params, lsb0, f); + } +} fn umax(cx: block, a: ValueRef, b: ValueRef) -> ValueRef { let cond = build::ICmp(cx, lib::llvm::IntULT, a, b); diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index 126ab65053e81..255598a3fb4f6 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -155,11 +155,19 @@ impl DatumMode: cmp::Eq { pure fn ne(&self, other: &DatumMode) -> bool { !(*self).eq(other) } } +#[cfg(stage0)] impl DatumMode: to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as uint).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl DatumMode: to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (*self as uint).iter_bytes(lsb0, f) + } +} /// See `Datum Sources` section at the head of this module. enum DatumSource { diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 2e4d95acdfbd0..4927d2773c190 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1572,7 +1572,7 @@ fn trans_assign_op(bcx: block, debug!("trans_assign_op(expr=%s)", bcx.expr_to_str(expr)); // Evaluate LHS (destination), which should be an lvalue - let dst_datum = unpack_datum!(bcx, trans_lvalue(bcx, dst)); + let dst_datum = unpack_datum!(bcx, trans_lvalue_unadjusted(bcx, dst)); // A user-defined operator method if bcx.ccx().maps.method_map.find(expr.id).is_some() { diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 7d6f937f82d12..3f46189b3dae6 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -269,11 +269,19 @@ impl creader_cache_key : cmp::Eq { } } +#[cfg(stage0)] impl creader_cache_key : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_3(&self.cnum, &self.pos, &self.len, lsb0, f); } } +#[cfg(stage1)] +#[cfg(stage2)] +impl creader_cache_key : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_3(&self.cnum, &self.pos, &self.len, lsb0, f); + } +} type intern_key = {sty: sty, o_def_id: Option}; @@ -294,11 +302,19 @@ impl intern_key : cmp::Eq { pure fn ne(&self, other: &intern_key) -> bool { !(*self).eq(other) } } +#[cfg(stage0)] impl intern_key : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.sty, &self.o_def_id, lsb0, f); } } +#[cfg(stage1)] +#[cfg(stage2)] +impl intern_key : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.sty, &self.o_def_id, lsb0, f); + } +} enum ast_ty_to_ty_cache_entry { atttce_unresolved, /* not resolved yet */ @@ -563,11 +579,19 @@ impl param_ty : cmp::Eq { pure fn ne(&self, other: ¶m_ty) -> bool { !(*self).eq(other) } } +#[cfg(stage0)] impl param_ty : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.idx, &self.def_id, lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl param_ty : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.idx, &self.def_id, lsb0, f) + } +} /// Representation of regions: @@ -749,6 +773,7 @@ enum InferTy { FloatVar(FloatVid) } +#[cfg(stage0)] impl InferTy : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { @@ -758,6 +783,17 @@ impl InferTy : to_bytes::IterBytes { } } } +#[cfg(stage1)] +#[cfg(stage2)] +impl InferTy : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + match *self { + TyVar(ref tv) => to_bytes::iter_bytes_2(&0u8, tv, lsb0, f), + IntVar(ref iv) => to_bytes::iter_bytes_2(&1u8, iv, lsb0, f), + FloatVar(ref fv) => to_bytes::iter_bytes_2(&2u8, fv, lsb0, f) + } + } +} #[auto_serialize] #[auto_deserialize] @@ -766,6 +802,7 @@ enum InferRegion { ReSkolemized(uint, bound_region) } +#[cfg(stage0)] impl InferRegion : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { @@ -774,6 +811,16 @@ impl InferRegion : to_bytes::IterBytes { } } } +#[cfg(stage1)] +#[cfg(stage2)] +impl InferRegion : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + match *self { + ReVar(ref rv) => to_bytes::iter_bytes_2(&0u8, rv, lsb0, f), + ReSkolemized(ref v, _) => to_bytes::iter_bytes_2(&1u8, v, lsb0, f) + } + } +} impl InferRegion : cmp::Eq { #[cfg(stage0)] @@ -812,6 +859,7 @@ impl InferRegion : cmp::Eq { } } +#[cfg(stage0)] impl param_bound : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { @@ -824,6 +872,20 @@ impl param_bound : to_bytes::IterBytes { } } } +#[cfg(stage1)] +#[cfg(stage2)] +impl param_bound : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + match *self { + bound_copy => 0u8.iter_bytes(lsb0, f), + bound_owned => 1u8.iter_bytes(lsb0, f), + bound_send => 2u8.iter_bytes(lsb0, f), + bound_const => 3u8.iter_bytes(lsb0, f), + bound_trait(ref t) => + to_bytes::iter_bytes_2(&4u8, t, lsb0, f) + } + } +} trait vid { pure fn to_uint() -> uint; @@ -883,35 +945,75 @@ impl purity: purity_to_str { } } +#[cfg(stage0)] impl RegionVid : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (*self).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl RegionVid : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (**self).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl TyVid : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (*self).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl TyVid : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (**self).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl IntVid : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (*self).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl IntVid : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (**self).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl FloatVid : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (*self).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl FloatVid : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (**self).iter_bytes(lsb0, f) + } +} +#[cfg(stage0)] impl FnVid : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (*self).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl FnVid : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (**self).iter_bytes(lsb0, f) + } +} fn param_bounds_to_kind(bounds: param_bounds) -> Kind { let mut kind = kind_noncopyable(); @@ -2722,6 +2824,7 @@ fn index_sty(cx: ctxt, sty: &sty) -> Option { } } +#[cfg(stage0)] impl bound_region : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { @@ -2738,7 +2841,26 @@ impl bound_region : to_bytes::IterBytes { } } } +#[cfg(stage1)] +#[cfg(stage2)] +impl bound_region : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + match *self { + ty::br_self => 0u8.iter_bytes(lsb0, f), + + ty::br_anon(ref idx) => + to_bytes::iter_bytes_2(&1u8, idx, lsb0, f), + + ty::br_named(ref ident) => + to_bytes::iter_bytes_2(&2u8, ident, lsb0, f), + + ty::br_cap_avoid(ref id, ref br) => + to_bytes::iter_bytes_3(&3u8, id, br, lsb0, f) + } + } +} +#[cfg(stage0)] impl Region : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { @@ -2758,7 +2880,29 @@ impl Region : to_bytes::IterBytes { } } } +#[cfg(stage1)] +#[cfg(stage2)] +impl Region : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + match *self { + re_bound(ref br) => + to_bytes::iter_bytes_2(&0u8, br, lsb0, f), + re_free(ref id, ref br) => + to_bytes::iter_bytes_3(&1u8, id, br, lsb0, f), + + re_scope(ref id) => + to_bytes::iter_bytes_2(&2u8, id, lsb0, f), + + re_infer(ref id) => + to_bytes::iter_bytes_2(&3u8, id, lsb0, f), + + re_static => 4u8.iter_bytes(lsb0, f) + } + } +} + +#[cfg(stage0)] impl vstore : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { @@ -2773,7 +2917,24 @@ impl vstore : to_bytes::IterBytes { } } } +#[cfg(stage1)] +#[cfg(stage2)] +impl vstore : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + match *self { + vstore_fixed(ref u) => + to_bytes::iter_bytes_2(&0u8, u, lsb0, f), + vstore_uniq => 1u8.iter_bytes(lsb0, f), + vstore_box => 2u8.iter_bytes(lsb0, f), + + vstore_slice(ref r) => + to_bytes::iter_bytes_2(&3u8, r, lsb0, f), + } + } +} + +#[cfg(stage0)] impl substs : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_3(&self.self_r, @@ -2781,28 +2942,65 @@ impl substs : to_bytes::IterBytes { &self.tps, lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl substs : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_3(&self.self_r, + &self.self_ty, + &self.tps, lsb0, f) + } +} +#[cfg(stage0)] impl mt : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.ty, &self.mutbl, lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl mt : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.ty, + &self.mutbl, lsb0, f) + } +} +#[cfg(stage0)] impl field : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.ident, &self.mt, lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl field : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.ident, + &self.mt, lsb0, f) + } +} +#[cfg(stage0)] impl arg : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.mode, &self.ty, lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl arg : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.mode, + &self.ty, lsb0, f) + } +} +#[cfg(stage0)] impl FnMeta : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_5(&self.purity, @@ -2813,7 +3011,20 @@ impl FnMeta : to_bytes::IterBytes { lsb0, f); } } +#[cfg(stage1)] +#[cfg(stage2)] +impl FnMeta : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_5(&self.purity, + &self.proto, + &self.region, + &self.bounds, + &self.ret_style, + lsb0, f); + } +} +#[cfg(stage0)] impl FnSig : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.inputs, @@ -2821,7 +3032,17 @@ impl FnSig : to_bytes::IterBytes { lsb0, f); } } +#[cfg(stage1)] +#[cfg(stage2)] +impl FnSig : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.inputs, + &self.output, + lsb0, f); + } +} +#[cfg(stage0)] impl sty : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { @@ -2899,6 +3120,85 @@ impl sty : to_bytes::IterBytes { } } } +#[cfg(stage1)] +#[cfg(stage2)] +impl sty : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + match *self { + ty_nil => 0u8.iter_bytes(lsb0, f), + ty_bool => 1u8.iter_bytes(lsb0, f), + + ty_int(ref t) => + to_bytes::iter_bytes_2(&2u8, t, lsb0, f), + + ty_uint(ref t) => + to_bytes::iter_bytes_2(&3u8, t, lsb0, f), + + ty_float(ref t) => + to_bytes::iter_bytes_2(&4u8, t, lsb0, f), + + ty_estr(ref v) => + to_bytes::iter_bytes_2(&5u8, v, lsb0, f), + + ty_enum(ref did, ref substs) => + to_bytes::iter_bytes_3(&6u8, did, substs, lsb0, f), + + ty_box(ref mt) => + to_bytes::iter_bytes_2(&7u8, mt, lsb0, f), + + ty_evec(ref mt, ref v) => + to_bytes::iter_bytes_3(&8u8, mt, v, lsb0, f), + + ty_unboxed_vec(ref mt) => + to_bytes::iter_bytes_2(&9u8, mt, lsb0, f), + + ty_tup(ref ts) => + to_bytes::iter_bytes_2(&10u8, ts, lsb0, f), + + ty_rec(ref fs) => + to_bytes::iter_bytes_2(&11u8, fs, lsb0, f), + + ty_fn(ref ft) => + to_bytes::iter_bytes_3(&12u8, + &ft.meta, + &ft.sig, + lsb0, f), + + ty_self => 13u8.iter_bytes(lsb0, f), + + ty_infer(ref v) => + to_bytes::iter_bytes_2(&14u8, v, lsb0, f), + + ty_param(ref p) => + to_bytes::iter_bytes_2(&15u8, p, lsb0, f), + + ty_type => 16u8.iter_bytes(lsb0, f), + ty_bot => 17u8.iter_bytes(lsb0, f), + + ty_ptr(ref mt) => + to_bytes::iter_bytes_2(&18u8, mt, lsb0, f), + + ty_uniq(ref mt) => + to_bytes::iter_bytes_2(&19u8, mt, lsb0, f), + + ty_trait(ref did, ref substs, ref v) => + to_bytes::iter_bytes_4(&20u8, did, substs, v, lsb0, f), + + ty_opaque_closure_ptr(ref ck) => + to_bytes::iter_bytes_2(&21u8, ck, lsb0, f), + + ty_opaque_box => 22u8.iter_bytes(lsb0, f), + + ty_class(ref did, ref substs) => + to_bytes::iter_bytes_3(&23u8, did, substs, lsb0, f), + + ty_rptr(ref r, ref mt) => + to_bytes::iter_bytes_3(&24u8, r, mt, lsb0, f), + + ty_err => 25u8.iter_bytes(lsb0, f) + } + } +} fn br_hashmap() -> HashMap { map::HashMap() diff --git a/src/librustc/middle/typeck/infer/assignment.rs b/src/librustc/middle/typeck/infer/assignment.rs index e5be4c7a19df6..fc1db7930e994 100644 --- a/src/librustc/middle/typeck/infer/assignment.rs +++ b/src/librustc/middle/typeck/infer/assignment.rs @@ -136,9 +136,9 @@ priv impl Assign { match (a_bnd, b_bnd) { (Some(a_bnd), Some(b_bnd)) => { - // check for a case where a non-region pointer (@, ~) is - // being assigned to a region pointer: match (ty::get(a_bnd).sty, ty::get(b_bnd).sty) { + // check for a case where a non-region pointer (@, ~) is + // being assigned to a region pointer: (ty::ty_box(_), ty::ty_rptr(r_b, mt_b)) => { let nr_b = ty::mk_box(self.infcx.tcx, {ty: mt_b.ty, mutbl: m_const}); @@ -184,8 +184,16 @@ priv impl Assign { a, nr_b, m_imm, b_f.meta.region) } + // check for &T being assigned to *T: + (ty::ty_rptr(_, ref a_t), ty::ty_ptr(ref b_t)) => { + match Sub(*self).mts(*a_t, *b_t) { + Ok(_) => Ok(None), + Err(e) => Err(e) + } + } + + // otherwise, assignment follows normal subtype rules: _ => { - // otherwise, assignment follows normal subtype rules: to_ares(Sub(*self).tys(a, b)) } } diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index 923e29cf8632a..da0d12cd3b212 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -511,6 +511,7 @@ impl Constraint : cmp::Eq { pure fn ne(&self, other: &Constraint) -> bool { !(*self).eq(other) } } +#[cfg(stage0)] impl Constraint : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { @@ -525,6 +526,22 @@ impl Constraint : to_bytes::IterBytes { } } } +#[cfg(stage1)] +#[cfg(stage2)] +impl Constraint : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + match *self { + ConstrainVarSubVar(ref v0, ref v1) => + to_bytes::iter_bytes_3(&0u8, v0, v1, lsb0, f), + + ConstrainRegSubVar(ref ra, ref va) => + to_bytes::iter_bytes_3(&1u8, ra, va, lsb0, f), + + ConstrainVarSubReg(ref va, ref ra) => + to_bytes::iter_bytes_3(&2u8, va, ra, lsb0, f) + } + } +} struct TwoRegions { a: Region, @@ -548,11 +565,19 @@ impl TwoRegions : cmp::Eq { pure fn ne(&self, other: &TwoRegions) -> bool { !(*self).eq(other) } } +#[cfg(stage0)] impl TwoRegions : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.a, &self.b, lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl TwoRegions : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.a, &self.b, lsb0, f) + } +} enum UndoLogEntry { Snapshot, diff --git a/src/libstd/net_url.rs b/src/libstd/net_url.rs index ec9aa60de54f9..946c49b40f742 100644 --- a/src/libstd/net_url.rs +++ b/src/libstd/net_url.rs @@ -782,12 +782,21 @@ impl Url : Eq { } } +#[cfg(stage0)] impl Url: IterBytes { pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { unsafe { self.to_str() }.iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl Url: IterBytes { + pure fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { + unsafe { self.to_str() }.iter_bytes(lsb0, f) + } +} + #[cfg(test)] mod tests { #[legacy_exports]; diff --git a/src/libstd/workcache.rs b/src/libstd/workcache.rs index 07297b546c05d..5bf90ef29c817 100644 --- a/src/libstd/workcache.rs +++ b/src/libstd/workcache.rs @@ -74,9 +74,22 @@ struct WorkKey { name: ~str } +#[cfg(stage0)] impl WorkKey: to_bytes::IterBytes { #[inline(always)] - pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) { + pure fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { + let mut flag = true; + self.kind.iter_bytes(lsb0, |bytes| {flag = f(bytes); flag}); + if !flag { return; } + self.name.iter_bytes(lsb0, f); + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +impl WorkKey: to_bytes::IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) { let mut flag = true; self.kind.iter_bytes(lsb0, |bytes| {flag = f(bytes); flag}); if !flag { return; } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 353bb26ea9ead..d09dd6f7bd17b 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -62,12 +62,21 @@ impl ident: cmp::Eq { pure fn ne(&self, other: &ident) -> bool { !(*self).eq(other) } } +#[cfg(stage0)] impl ident: to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { self.repr.iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl ident: to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + self.repr.iter_bytes(lsb0, f) + } +} + // Functions may or may not have names. type fn_ident = Option; @@ -462,6 +471,7 @@ enum binding_mode { bind_by_implicit_ref } +#[cfg(stage0)] impl binding_mode : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { @@ -478,6 +488,24 @@ impl binding_mode : to_bytes::IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl binding_mode : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + match *self { + bind_by_value => 0u8.iter_bytes(lsb0, f), + + bind_by_move => 1u8.iter_bytes(lsb0, f), + + bind_by_ref(ref m) => + to_bytes::iter_bytes_2(&2u8, m, lsb0, f), + + bind_by_implicit_ref => + 3u8.iter_bytes(lsb0, f), + } + } +} + impl binding_mode : cmp::Eq { #[cfg(stage0)] pure fn eq(other: &binding_mode) -> bool { @@ -573,12 +601,21 @@ enum pat_ { #[auto_deserialize] enum mutability { m_mutbl, m_imm, m_const, } +#[cfg(stage0)] impl mutability : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl mutability : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (*self as u8).iter_bytes(lsb0, f) + } +} + impl mutability : cmp::Eq { #[cfg(stage0)] pure fn eq(other: &mutability) -> bool { @@ -622,12 +659,21 @@ impl Proto : cmp::Eq { pure fn ne(&self, other: &Proto) -> bool { !(*self).eq(other) } } +#[cfg(stage0)] impl Proto : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as uint).iter_bytes(lsb0, f); } } +#[cfg(stage1)] +#[cfg(stage2)] +impl Proto : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (*self as uint).iter_bytes(lsb0, f); + } +} + #[auto_serialize] #[auto_deserialize] enum vstore { @@ -798,6 +844,7 @@ enum inferable { infer(node_id) } +#[cfg(stage0)] impl inferable : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { match self { @@ -810,6 +857,20 @@ impl inferable : to_bytes::IterBytes { } } +#[cfg(stage1)] +#[cfg(stage2)] +impl inferable : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + match *self { + expl(ref t) => + to_bytes::iter_bytes_2(&0u8, t, lsb0, f), + + infer(ref n) => + to_bytes::iter_bytes_2(&1u8, n, lsb0, f), + } + } +} + impl inferable : cmp::Eq { #[cfg(stage0)] pure fn eq(other: &inferable) -> bool { @@ -858,11 +919,19 @@ impl inferable : cmp::Eq { #[auto_deserialize] enum rmode { by_ref, by_val, by_move, by_copy } +#[cfg(stage0)] impl rmode : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl rmode : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (*self as u8).iter_bytes(lsb0, f) + } +} impl rmode : cmp::Eq { @@ -1262,11 +1331,19 @@ enum trait_method { #[auto_deserialize] enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, } +#[cfg(stage0)] impl int_ty : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl int_ty : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (*self as u8).iter_bytes(lsb0, f) + } +} impl int_ty : cmp::Eq { #[cfg(stage0)] @@ -1315,11 +1392,19 @@ impl int_ty : cmp::Eq { #[auto_deserialize] enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, } +#[cfg(stage0)] impl uint_ty : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl uint_ty : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (*self as u8).iter_bytes(lsb0, f) + } +} impl uint_ty : cmp::Eq { #[cfg(stage0)] @@ -1364,11 +1449,20 @@ impl uint_ty : cmp::Eq { #[auto_deserialize] enum float_ty { ty_f, ty_f32, ty_f64, } +#[cfg(stage0)] impl float_ty : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl float_ty : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (*self as u8).iter_bytes(lsb0, f) + } +} + impl float_ty : cmp::Eq { #[cfg(stage0)] pure fn eq(other: &float_ty) -> bool { @@ -1589,12 +1683,21 @@ impl Ty : cmp::Eq { } } +#[cfg(stage0)] impl Ty : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { to_bytes::iter_bytes_2(&self.span.lo, &self.span.hi, lsb0, f); } } +#[cfg(stage1)] +#[cfg(stage2)] +impl Ty : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + to_bytes::iter_bytes_2(&self.span.lo, &self.span.hi, lsb0, f); + } +} + #[auto_serialize] #[auto_deserialize] @@ -1616,12 +1719,21 @@ enum purity { extern_fn, // declared with "extern fn" } +#[cfg(stage0)] impl purity : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl purity : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (*self as u8).iter_bytes(lsb0, f) + } +} + impl purity : cmp::Eq { #[cfg(stage0)] pure fn eq(other: &purity) -> bool { @@ -1647,11 +1759,19 @@ enum ret_style { return_val, // everything else } +#[cfg(stage0)] impl ret_style : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl ret_style : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (*self as u8).iter_bytes(lsb0, f) + } +} impl ret_style : cmp::Eq { #[cfg(stage0)] @@ -1861,6 +1981,7 @@ impl foreign_abi : cmp::Eq { #[auto_deserialize] type foreign_mod = {sort: foreign_mod_sort, + abi: ident, view_items: ~[@view_item], items: ~[@foreign_item]}; @@ -2151,11 +2272,19 @@ enum item_ { #[auto_deserialize] enum class_mutability { class_mutable, class_immutable } +#[cfg(stage0)] impl class_mutability : to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as u8).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl class_mutability : to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (*self as u8).iter_bytes(lsb0, f) + } +} impl class_mutability : cmp::Eq { #[cfg(stage0)] diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 73a1c4b7530a0..12ebca87a80f8 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -251,12 +251,21 @@ pure fn is_call_expr(e: @expr) -> bool { } // This makes def_id hashable +#[cfg(stage0)] impl def_id : core::to_bytes::IterBytes { #[inline(always)] pure fn iter_bytes(+lsb0: bool, f: core::to_bytes::Cb) { core::to_bytes::iter_bytes_2(&self.crate, &self.node, lsb0, f); } } +#[cfg(stage1)] +#[cfg(stage2)] +impl def_id : core::to_bytes::IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, +lsb0: bool, f: core::to_bytes::Cb) { + core::to_bytes::iter_bytes_2(&self.crate, &self.node, lsb0, f); + } +} fn block_from_expr(e: @expr) -> blk { let blk_ = default_block(~[], option::Some::<@expr>(e), e.id); diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index fafcd09e3dc58..2280986ab94ab 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -90,12 +90,21 @@ impl BytePos: Num { static pure fn from_int(+n: int) -> BytePos { BytePos(n as uint) } } +#[cfg(stage0)] impl BytePos: to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (*self).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl BytePos: to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (**self).iter_bytes(lsb0, f) + } +} + impl CharPos: Pos { static pure fn from_uint(n: uint) -> CharPos { CharPos(n) } pure fn to_uint(&self) -> uint { **self } @@ -154,11 +163,19 @@ impl CharPos: Num { static pure fn from_int(+n: int) -> CharPos { CharPos(n as uint) } } +#[cfg(stage0)] impl CharPos: to_bytes::IterBytes { pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (*self).iter_bytes(lsb0, f) } } +#[cfg(stage1)] +#[cfg(stage2)] +impl CharPos: to_bytes::IterBytes { + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (**self).iter_bytes(lsb0, f) + } +} /** Spans represent a region of code, used for error reporting. Positions in spans diff --git a/src/libsyntax/ext/deriving.rs b/src/libsyntax/ext/deriving.rs index 4a92086963ec6..829b53ae22a94 100644 --- a/src/libsyntax/ext/deriving.rs +++ b/src/libsyntax/ext/deriving.rs @@ -292,7 +292,7 @@ fn create_iter_bytes_method(cx: ext_ctxt, let body_block = build::mk_block_(cx, span, move statements); // Create the method. - let self_ty = { node: sty_by_ref, span: span }; + let self_ty = { node: sty_region(m_imm), span: span }; let method_ident = cx.ident_of(~"iter_bytes"); return @{ ident: method_ident, @@ -806,6 +806,7 @@ fn expand_deriving_iter_bytes_enum_method(cx: ext_ctxt, // Create the method body. let self_ident = cx.ident_of(~"self"); let self_expr = build::mk_path(cx, span, ~[ self_ident ]); + let self_expr = build::mk_unary(cx, span, deref, self_expr); let arms = dvec::unwrap(move arms); let self_match_expr = expr_match(self_expr, move arms); let self_match_expr = build::mk_expr(cx, span, move self_match_expr); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 443a937d4eb7a..c09655d73d369 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -248,6 +248,26 @@ fn core_macros() -> ~str { #macro[[#warn[f, ...], log(core::warn, #fmt[f, ...])]]; #macro[[#info[f, ...], log(core::info, #fmt[f, ...])]]; #macro[[#debug[f, ...], log(core::debug, #fmt[f, ...])]]; + + macro_rules! die( + ($msg: expr) => ( + { + do core::str::as_buf($msg) |msg_buf, _msg_len| { + do core::str::as_buf(file!()) |file_buf, _file_len| { + unsafe { + let msg_buf = core::cast::transmute(msg_buf); + let file_buf = core::cast::transmute(file_buf); + let line = line!() as core::libc::size_t; + core::rt::rt_fail_(msg_buf, file_buf, line) + } + } + } + } + ); + () => ( + die!(\"explicit failure\") + ) + ) }"; } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 9d57b5ae814f6..dc7a7feff14e0 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -546,8 +546,9 @@ fn noop_fold_mod(m: _mod, fld: ast_fold) -> _mod { fn noop_fold_foreign_mod(nm: foreign_mod, fld: ast_fold) -> foreign_mod { return {sort: nm.sort, - view_items: vec::map(nm.view_items, |x| fld.fold_view_item(*x)), - items: vec::map(nm.items, |x| fld.fold_foreign_item(*x))} + abi: nm.abi, + view_items: vec::map(nm.view_items, |x| fld.fold_view_item(*x)), + items: vec::map(nm.items, |x| fld.fold_foreign_item(*x))} } fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ { diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 40df4d5f7d449..a6a7736e3d032 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -49,12 +49,21 @@ impl ObsoleteSyntax : cmp::Eq { } } +#[cfg(stage0)] impl ObsoleteSyntax: to_bytes::IterBytes { #[inline(always)] pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) { (self as uint).iter_bytes(lsb0, f); } } +#[cfg(stage1)] +#[cfg(stage2)] +impl ObsoleteSyntax: to_bytes::IterBytes { + #[inline(always)] + pure fn iter_bytes(&self, +lsb0: bool, f: to_bytes::Cb) { + (*self as uint).iter_bytes(lsb0, f); + } +} pub trait ObsoleteReporter { fn obsolete(sp: span, kind: ObsoleteSyntax); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f340a52a4e7d6..e4d77e7da095f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3043,8 +3043,9 @@ impl Parser { } fn parse_foreign_mod_items(sort: ast::foreign_mod_sort, - +first_item_attrs: ~[attribute]) -> - foreign_mod { + +abi: ast::ident, + +first_item_attrs: ~[attribute]) + -> foreign_mod { // Shouldn't be any view items since we've already parsed an item attr let {attrs_remaining, view_items, items: _, foreign_items} = self.parse_items_and_view_items(first_item_attrs, @@ -3058,8 +3059,12 @@ impl Parser { initial_attrs = ~[]; items.push(self.parse_foreign_item(attrs)); } - return {sort: sort, view_items: view_items, - items: items}; + return { + sort: sort, + abi: move abi, + view_items: view_items, + items: items + }; } fn parse_item_foreign_mod(lo: BytePos, @@ -3068,6 +3073,18 @@ impl Parser { items_allowed: bool) -> item_or_view_item { + // Parse the ABI. + let abi_opt; + match self.token { + token::LIT_STR(copy found_abi) => { + self.bump(); + abi_opt = Some(found_abi); + } + _ => { + abi_opt = None; + } + } + let mut must_be_named_mod = false; if self.is_keyword(~"mod") { must_be_named_mod = true; @@ -3096,9 +3113,18 @@ impl Parser { // extern mod { ... } if items_allowed && self.eat(token::LBRACE) { + let abi; + match move abi_opt { + Some(move found_abi) => abi = move found_abi, + None => abi = special_idents::c_abi, + } + let extra_attrs = self.parse_inner_attrs_and_next(); - let m = self.parse_foreign_mod_items(sort, extra_attrs.next); + let m = self.parse_foreign_mod_items(sort, + move abi, + extra_attrs.next); self.expect(token::RBRACE); + return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_foreign_mod(m), visibility, maybe_append(attrs, @@ -3106,6 +3132,14 @@ impl Parser { inner)))); } + match abi_opt { + None => {} // OK. + Some(_) => { + self.span_err(copy self.span, ~"an ABI may not be specified \ + here"); + } + } + // extern mod foo; let metadata = self.parse_optional_meta(); self.expect(token::SEMI); diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 2e59d2fa45fcc..7b15f00d76197 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -322,6 +322,7 @@ mod special_idents { const intrinsic : ident = ident { repr: 32u }; const clownshoes_foreign_mod: ident = ident { repr: 33 }; const unnamed_field: ident = ident { repr: 34 }; + const c_abi: ident = ident { repr: 35 }; } struct ident_interner { @@ -368,7 +369,8 @@ fn mk_ident_interner() -> @ident_interner { @~"str", @~"TyVisitor", @~"arg", @~"descrim", @~"__rust_abi", @~"__rust_stack_shim", @~"TyDesc", @~"dtor", @~"main", @~"", @~"blk", @~"static", - @~"intrinsic", @~"__foreign_mod__" + @~"intrinsic", @~"__foreign_mod__", @~"__field__", + @~"C" ]; let rv = @ident_interner { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index e0523613ee66f..f525436cc3e0e 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -485,6 +485,7 @@ fn print_item(s: ps, &&item: @ast::item) { } ast::item_foreign_mod(nmod) => { head(s, visibility_qualified(item.vis, ~"extern")); + print_string(s, *s.intr.get(nmod.abi)); match nmod.sort { ast::named => { word_nbsp(s, ~"mod"); diff --git a/src/test/run-pass/extern-mod-abi.rs b/src/test/run-pass/extern-mod-abi.rs new file mode 100644 index 0000000000000..54befe77360ce --- /dev/null +++ b/src/test/run-pass/extern-mod-abi.rs @@ -0,0 +1,6 @@ +extern "C" { + fn pow(x: f64, y: f64) -> f64; +} + +fn main() {} + diff --git a/src/test/run-pass/operator-overloading-explicit-self.rs b/src/test/run-pass/operator-overloading-explicit-self.rs new file mode 100644 index 0000000000000..3b198078cf827 --- /dev/null +++ b/src/test/run-pass/operator-overloading-explicit-self.rs @@ -0,0 +1,16 @@ +struct S { + x: int +} + +impl S { + pure fn add(&self, other: &S) -> S { + S { x: self.x + other.x } + } +} + +fn main() { + let mut s = S { x: 1 }; + s += S { x: 2 }; + assert s.x == 3; +} + diff --git a/src/test/run-pass/unsafe-pointer-assignability.rs b/src/test/run-pass/unsafe-pointer-assignability.rs new file mode 100644 index 0000000000000..f205798c36af6 --- /dev/null +++ b/src/test/run-pass/unsafe-pointer-assignability.rs @@ -0,0 +1,12 @@ +fn f(x: *int) { + unsafe { + assert *x == 3; + } +} + +fn main() { + f(&3); +} + + +