Skip to content

Commit

Permalink
Overloaded augmented assignments
Browse files Browse the repository at this point in the history
  • Loading branch information
Jorge Aparicio committed May 16, 2015
1 parent daaf715 commit 95e1419
Show file tree
Hide file tree
Showing 13 changed files with 692 additions and 70 deletions.
248 changes: 248 additions & 0 deletions src/libcore/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,254 @@ macro_rules! shr_impl_all {

shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }

/// TODO(japaric) docs
#[cfg(not(stage0))]
#[lang = "add_assign"]
pub trait AddAssign<Rhs=Self> {
/// TODO(japaric) docs
fn add_assign(&mut self, Rhs);
}

#[cfg(not(stage0))]
macro_rules! add_assign_impl {
($($t:ty)+) => ($(
impl AddAssign for $t {
#[inline]
fn add_assign(&mut self, other: $t) { *self += other }
}
)+)
}

#[cfg(not(stage0))]
add_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }

/// TODO(japaric) docs
#[cfg(not(stage0))]
#[lang = "sub_assign"]
pub trait SubAssign<Rhs=Self> {
/// TODO(japaric) docs
fn sub_assign(&mut self, Rhs);
}

#[cfg(not(stage0))]
macro_rules! sub_assign_impl {
($($t:ty)+) => ($(
impl SubAssign for $t {
#[inline]
fn sub_assign(&mut self, other: $t) { *self -= other }
}
)+)
}

#[cfg(not(stage0))]
sub_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }

/// TODO(japaric) docs
#[cfg(not(stage0))]
#[lang = "mul_assign"]
pub trait MulAssign<Rhs=Self> {
/// TODO(japaric) docs
fn mul_assign(&mut self, Rhs);
}

#[cfg(not(stage0))]
macro_rules! mul_assign_impl {
($($t:ty)+) => ($(
impl MulAssign for $t {
#[inline]
fn mul_assign(&mut self, other: $t) { *self *= other }
}
)+)
}

#[cfg(not(stage0))]
mul_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }

/// TODO(japaric) docs
#[cfg(not(stage0))]
#[lang = "div_assign"]
pub trait DivAssign<Rhs=Self> {
/// TODO(japaric) docs
fn div_assign(&mut self, Rhs);
}

#[cfg(not(stage0))]
macro_rules! div_assign_impl {
($($t:ty)+) => ($(
impl DivAssign for $t {
#[inline]
fn div_assign(&mut self, other: $t) { *self /= other }
}
)+)
}

#[cfg(not(stage0))]
div_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }

/// TODO(japaric) docs
#[cfg(not(stage0))]
#[lang = "rem_assign"]
pub trait RemAssign<Rhs=Self> {
/// TODO(japaric) docs
fn rem_assign(&mut self, Rhs);
}

#[cfg(not(stage0))]
macro_rules! rem_assign_impl {
($($t:ty)+) => ($(
impl RemAssign for $t {
#[inline]
fn rem_assign(&mut self, other: $t) { *self %= other }
}
)+)
}

#[cfg(not(stage0))]
rem_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }

/// TODO(japaric) docs
#[cfg(not(stage0))]
#[lang = "bitand_assign"]
pub trait BitAndAssign<Rhs=Self> {
/// TODO(japaric) docs
fn bitand_assign(&mut self, Rhs);
}

#[cfg(not(stage0))]
macro_rules! bitand_assign_impl {
($($t:ty)+) => ($(
impl BitAndAssign for $t {
#[inline]
fn bitand_assign(&mut self, other: $t) { *self &= other }
}
)+)
}

#[cfg(not(stage0))]
bitand_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }

/// TODO(japaric) docs
#[cfg(not(stage0))]
#[lang = "bitor_assign"]
pub trait BitOrAssign<Rhs=Self> {
/// TODO(japaric) docs
fn bitor_assign(&mut self, Rhs);
}

#[cfg(not(stage0))]
macro_rules! bitor_assign_impl {
($($t:ty)+) => ($(
impl BitOrAssign for $t {
#[inline]
fn bitor_assign(&mut self, other: $t) { *self |= other }
}
)+)
}

#[cfg(not(stage0))]
bitor_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }

/// TODO(japaric) docs
#[cfg(not(stage0))]
#[lang = "bitxor_assign"]
pub trait BitXorAssign<Rhs=Self> {
/// TODO(japaric) docs
fn bitxor_assign(&mut self, Rhs);
}

#[cfg(not(stage0))]
macro_rules! bitxor_assign_impl {
($($t:ty)+) => ($(
impl BitXorAssign for $t {
#[inline]
fn bitxor_assign(&mut self, other: $t) { *self ^= other }
}
)+)
}

#[cfg(not(stage0))]
bitxor_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }

/// TODO(japaric) docs
#[cfg(not(stage0))]
#[lang = "shl_assign"]
pub trait ShlAssign<Rhs=Self> {
/// TODO(japaric) docs
fn shl_assign(&mut self, Rhs);
}

#[cfg(not(stage0))]
macro_rules! shl_assign_impl {
($t:ty, $f:ty) => (
impl ShlAssign<$f> for $t {
#[inline]
fn shl_assign(&mut self, other: $f) {
*self <<= other
}
}
)
}

#[cfg(not(stage0))]
macro_rules! shl_assign_impl_all {
($($t:ty)*) => ($(
shl_assign_impl! { $t, u8 }
shl_assign_impl! { $t, u16 }
shl_assign_impl! { $t, u32 }
shl_assign_impl! { $t, u64 }
shl_assign_impl! { $t, usize }

shl_assign_impl! { $t, i8 }
shl_assign_impl! { $t, i16 }
shl_assign_impl! { $t, i32 }
shl_assign_impl! { $t, i64 }
shl_assign_impl! { $t, isize }
)*)
}

#[cfg(not(stage0))]
shl_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }

/// TODO(japaric) docs
#[cfg(not(stage0))]
#[lang = "shr_assign"]
pub trait ShrAssign<Rhs=Self> {
/// TODO(japaric) docs
fn shr_assign(&mut self, Rhs);
}

#[cfg(not(stage0))]
macro_rules! shr_assign_impl {
($t:ty, $f:ty) => (
impl ShrAssign<$f> for $t {
#[inline]
fn shr_assign(&mut self, other: $f) {
*self >>= other
}
}
)
}

#[cfg(not(stage0))]
macro_rules! shr_assign_impl_all {
($($t:ty)*) => ($(
shr_assign_impl! { $t, u8 }
shr_assign_impl! { $t, u16 }
shr_assign_impl! { $t, u32 }
shr_assign_impl! { $t, u64 }
shr_assign_impl! { $t, usize }

shr_assign_impl! { $t, i8 }
shr_assign_impl! { $t, i16 }
shr_assign_impl! { $t, i32 }
shr_assign_impl! { $t, i64 }
shr_assign_impl! { $t, isize }
)*)
}

#[cfg(not(stage0))]
shr_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }

/// The `Index` trait is used to specify the functionality of indexing operations
/// like `arr[idx]` when used in an immutable context.
///
Expand Down
11 changes: 11 additions & 0 deletions src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,17 @@ lets_do_this! {
RangeToStructLangItem, "range_to", range_to_struct;
RangeFullStructLangItem, "range_full", range_full_struct;

AddAssignTraitLangItem, "add_assign", add_assign_trait;
BitAndAssignTraitLangItem, "bitand_assign", bitand_assign_trait;
BitOrAssignTraitLangItem, "bitor_assign", bitor_assign_trait;
BitXorAssignTraitLangItem, "bitxor_assign", bitxor_assign_trait;
DivAssignTraitLangItem, "div_assign", div_assign_trait;
MulAssignTraitLangItem, "mul_assign", mul_assign_trait;
RemAssignTraitLangItem, "rem_assign", rem_assign_trait;
ShlAssignTraitLangItem, "shl_assign", shl_assign_trait;
ShrAssignTraitLangItem, "shr_assign", shr_assign_trait;
SubAssignTraitLangItem, "sub_assign", sub_assign_trait;

UnsafeCellTypeLangItem, "unsafe_cell", unsafe_cell_type;

DerefTraitLangItem, "deref", deref_trait;
Expand Down
20 changes: 17 additions & 3 deletions src/librustc_trans/trans/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1009,7 +1009,17 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
}
ast::ExprAssignOp(op, ref dst, ref src) => {
trans_assign_op(bcx, expr, op, &**dst, &**src)
let has_method_map =
bcx.tcx().method_map.borrow().contains_key(&MethodCall::expr(expr.id));

if has_method_map {
let dst = unpack_datum!(bcx, trans(bcx, &**dst));
let src_datum = unpack_datum!(bcx, trans(bcx, &**src));
trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), dst,
vec![(src_datum, src.id)], None, false).bcx
} else {
trans_assign_op(bcx, expr, op, &**dst, &**src)
}
}
ast::ExprInlineAsm(ref a) => {
asm::trans_inline_asm(bcx, a)
Expand Down Expand Up @@ -1194,8 +1204,12 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// Trait casts used to come this way, now they should be coercions.
bcx.tcx().sess.span_bug(expr.span, "DPS expr_cast (residual trait cast?)")
}
ast::ExprAssignOp(op, ref dst, ref src) => {
trans_assign_op(bcx, expr, op, &**dst, &**src)
ast::ExprAssignOp(op, _, _) => {
bcx.tcx().sess.span_bug(
expr.span,
&format!(
"augmented assignment ({}=) should always be a rvalue_stmt",
ast_util::binop_to_string(op.node)));
}
_ => {
bcx.tcx().sess.span_bug(
Expand Down
Loading

0 comments on commit 95e1419

Please sign in to comment.