Skip to content

Commit 9e6154d

Browse files
author
Jorge Aparicio
committed
Overloaded augmented assignments
1 parent a951569 commit 9e6154d

13 files changed

+687
-69
lines changed

src/libcore/ops.rs

+248
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,254 @@ macro_rules! shr_impl_all {
870870

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

873+
/// TODO(japaric) docs
874+
#[cfg(not(stage0))]
875+
#[lang = "add_assign"]
876+
pub trait AddAssign<Rhs=Self> {
877+
/// TODO(japaric) docs
878+
fn add_assign(&mut self, Rhs);
879+
}
880+
881+
#[cfg(not(stage0))]
882+
macro_rules! add_assign_impl {
883+
($($t:ty)+) => ($(
884+
impl AddAssign for $t {
885+
#[inline]
886+
fn add_assign(&mut self, other: $t) { *self += other }
887+
}
888+
)+)
889+
}
890+
891+
#[cfg(not(stage0))]
892+
add_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
893+
894+
/// TODO(japaric) docs
895+
#[cfg(not(stage0))]
896+
#[lang = "sub_assign"]
897+
pub trait SubAssign<Rhs=Self> {
898+
/// TODO(japaric) docs
899+
fn sub_assign(&mut self, Rhs);
900+
}
901+
902+
#[cfg(not(stage0))]
903+
macro_rules! sub_assign_impl {
904+
($($t:ty)+) => ($(
905+
impl SubAssign for $t {
906+
#[inline]
907+
fn sub_assign(&mut self, other: $t) { *self -= other }
908+
}
909+
)+)
910+
}
911+
912+
#[cfg(not(stage0))]
913+
sub_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
914+
915+
/// TODO(japaric) docs
916+
#[cfg(not(stage0))]
917+
#[lang = "mul_assign"]
918+
pub trait MulAssign<Rhs=Self> {
919+
/// TODO(japaric) docs
920+
fn mul_assign(&mut self, Rhs);
921+
}
922+
923+
#[cfg(not(stage0))]
924+
macro_rules! mul_assign_impl {
925+
($($t:ty)+) => ($(
926+
impl MulAssign for $t {
927+
#[inline]
928+
fn mul_assign(&mut self, other: $t) { *self *= other }
929+
}
930+
)+)
931+
}
932+
933+
#[cfg(not(stage0))]
934+
mul_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
935+
936+
/// TODO(japaric) docs
937+
#[cfg(not(stage0))]
938+
#[lang = "div_assign"]
939+
pub trait DivAssign<Rhs=Self> {
940+
/// TODO(japaric) docs
941+
fn div_assign(&mut self, Rhs);
942+
}
943+
944+
#[cfg(not(stage0))]
945+
macro_rules! div_assign_impl {
946+
($($t:ty)+) => ($(
947+
impl DivAssign for $t {
948+
#[inline]
949+
fn div_assign(&mut self, other: $t) { *self /= other }
950+
}
951+
)+)
952+
}
953+
954+
#[cfg(not(stage0))]
955+
div_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
956+
957+
/// TODO(japaric) docs
958+
#[cfg(not(stage0))]
959+
#[lang = "rem_assign"]
960+
pub trait RemAssign<Rhs=Self> {
961+
/// TODO(japaric) docs
962+
fn rem_assign(&mut self, Rhs);
963+
}
964+
965+
#[cfg(not(stage0))]
966+
macro_rules! rem_assign_impl {
967+
($($t:ty)+) => ($(
968+
impl RemAssign for $t {
969+
#[inline]
970+
fn rem_assign(&mut self, other: $t) { *self %= other }
971+
}
972+
)+)
973+
}
974+
975+
#[cfg(not(stage0))]
976+
rem_assign_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 }
977+
978+
/// TODO(japaric) docs
979+
#[cfg(not(stage0))]
980+
#[lang = "bitand_assign"]
981+
pub trait BitAndAssign<Rhs=Self> {
982+
/// TODO(japaric) docs
983+
fn bitand_assign(&mut self, Rhs);
984+
}
985+
986+
#[cfg(not(stage0))]
987+
macro_rules! bitand_assign_impl {
988+
($($t:ty)+) => ($(
989+
impl BitAndAssign for $t {
990+
#[inline]
991+
fn bitand_assign(&mut self, other: $t) { *self &= other }
992+
}
993+
)+)
994+
}
995+
996+
#[cfg(not(stage0))]
997+
bitand_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
998+
999+
/// TODO(japaric) docs
1000+
#[cfg(not(stage0))]
1001+
#[lang = "bitor_assign"]
1002+
pub trait BitOrAssign<Rhs=Self> {
1003+
/// TODO(japaric) docs
1004+
fn bitor_assign(&mut self, Rhs);
1005+
}
1006+
1007+
#[cfg(not(stage0))]
1008+
macro_rules! bitor_assign_impl {
1009+
($($t:ty)+) => ($(
1010+
impl BitOrAssign for $t {
1011+
#[inline]
1012+
fn bitor_assign(&mut self, other: $t) { *self |= other }
1013+
}
1014+
)+)
1015+
}
1016+
1017+
#[cfg(not(stage0))]
1018+
bitor_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
1019+
1020+
/// TODO(japaric) docs
1021+
#[cfg(not(stage0))]
1022+
#[lang = "bitxor_assign"]
1023+
pub trait BitXorAssign<Rhs=Self> {
1024+
/// TODO(japaric) docs
1025+
fn bitxor_assign(&mut self, Rhs);
1026+
}
1027+
1028+
#[cfg(not(stage0))]
1029+
macro_rules! bitxor_assign_impl {
1030+
($($t:ty)+) => ($(
1031+
impl BitXorAssign for $t {
1032+
#[inline]
1033+
fn bitxor_assign(&mut self, other: $t) { *self ^= other }
1034+
}
1035+
)+)
1036+
}
1037+
1038+
#[cfg(not(stage0))]
1039+
bitxor_assign_impl! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
1040+
1041+
/// TODO(japaric) docs
1042+
#[cfg(not(stage0))]
1043+
#[lang = "shl_assign"]
1044+
pub trait ShlAssign<Rhs=Self> {
1045+
/// TODO(japaric) docs
1046+
fn shl_assign(&mut self, Rhs);
1047+
}
1048+
1049+
#[cfg(not(stage0))]
1050+
macro_rules! shl_assign_impl {
1051+
($t:ty, $f:ty) => (
1052+
impl ShlAssign<$f> for $t {
1053+
#[inline]
1054+
fn shl_assign(&mut self, other: $f) {
1055+
*self <<= other
1056+
}
1057+
}
1058+
)
1059+
}
1060+
1061+
#[cfg(not(stage0))]
1062+
macro_rules! shl_assign_impl_all {
1063+
($($t:ty)*) => ($(
1064+
shl_assign_impl! { $t, u8 }
1065+
shl_assign_impl! { $t, u16 }
1066+
shl_assign_impl! { $t, u32 }
1067+
shl_assign_impl! { $t, u64 }
1068+
shl_assign_impl! { $t, usize }
1069+
1070+
shl_assign_impl! { $t, i8 }
1071+
shl_assign_impl! { $t, i16 }
1072+
shl_assign_impl! { $t, i32 }
1073+
shl_assign_impl! { $t, i64 }
1074+
shl_assign_impl! { $t, isize }
1075+
)*)
1076+
}
1077+
1078+
#[cfg(not(stage0))]
1079+
shl_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
1080+
1081+
/// TODO(japaric) docs
1082+
#[cfg(not(stage0))]
1083+
#[lang = "shr_assign"]
1084+
pub trait ShrAssign<Rhs=Self> {
1085+
/// TODO(japaric) docs
1086+
fn shr_assign(&mut self, Rhs);
1087+
}
1088+
1089+
#[cfg(not(stage0))]
1090+
macro_rules! shr_assign_impl {
1091+
($t:ty, $f:ty) => (
1092+
impl ShrAssign<$f> for $t {
1093+
#[inline]
1094+
fn shr_assign(&mut self, other: $f) {
1095+
*self >>= other
1096+
}
1097+
}
1098+
)
1099+
}
1100+
1101+
#[cfg(not(stage0))]
1102+
macro_rules! shr_assign_impl_all {
1103+
($($t:ty)*) => ($(
1104+
shr_assign_impl! { $t, u8 }
1105+
shr_assign_impl! { $t, u16 }
1106+
shr_assign_impl! { $t, u32 }
1107+
shr_assign_impl! { $t, u64 }
1108+
shr_assign_impl! { $t, usize }
1109+
1110+
shr_assign_impl! { $t, i8 }
1111+
shr_assign_impl! { $t, i16 }
1112+
shr_assign_impl! { $t, i32 }
1113+
shr_assign_impl! { $t, i64 }
1114+
shr_assign_impl! { $t, isize }
1115+
)*)
1116+
}
1117+
1118+
#[cfg(not(stage0))]
1119+
shr_assign_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
1120+
8731121
/// The `Index` trait is used to specify the functionality of indexing operations
8741122
/// like `arr[idx]` when used in an immutable context.
8751123
///

src/librustc/middle/lang_items.rs

+11
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,17 @@ lets_do_this! {
288288
RangeToStructLangItem, "range_to", range_to_struct;
289289
RangeFullStructLangItem, "range_full", range_full_struct;
290290

291+
AddAssignTraitLangItem, "add_assign", add_assign_trait;
292+
BitAndAssignTraitLangItem, "bitand_assign", bitand_assign_trait;
293+
BitOrAssignTraitLangItem, "bitor_assign", bitor_assign_trait;
294+
BitXorAssignTraitLangItem, "bitxor_assign", bitxor_assign_trait;
295+
DivAssignTraitLangItem, "div_assign", div_assign_trait;
296+
MulAssignTraitLangItem, "mul_assign", mul_assign_trait;
297+
RemAssignTraitLangItem, "rem_assign", rem_assign_trait;
298+
ShlAssignTraitLangItem, "shl_assign", shl_assign_trait;
299+
ShrAssignTraitLangItem, "shr_assign", shr_assign_trait;
300+
SubAssignTraitLangItem, "sub_assign", sub_assign_trait;
301+
291302
UnsafeCellTypeLangItem, "unsafe_cell", unsafe_cell_type;
292303

293304
DerefTraitLangItem, "deref", deref_trait;

src/librustc_trans/trans/expr.rs

+17-3
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,17 @@ fn trans_rvalue_stmt_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
10121012
}
10131013
}
10141014
ast::ExprAssignOp(op, ref dst, ref src) => {
1015-
trans_assign_op(bcx, expr, op, &**dst, &**src)
1015+
let has_method_map =
1016+
bcx.tcx().method_map.borrow().contains_key(&MethodCall::expr(expr.id));
1017+
1018+
if has_method_map {
1019+
let dst = unpack_datum!(bcx, trans(bcx, &**dst));
1020+
let src_datum = unpack_datum!(bcx, trans(bcx, &**src));
1021+
trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), dst,
1022+
vec![(src_datum, src.id)], None, false).bcx
1023+
} else {
1024+
trans_assign_op(bcx, expr, op, &**dst, &**src)
1025+
}
10161026
}
10171027
ast::ExprInlineAsm(ref a) => {
10181028
asm::trans_inline_asm(bcx, a)
@@ -1197,8 +1207,12 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
11971207
// Trait casts used to come this way, now they should be coercions.
11981208
bcx.tcx().sess.span_bug(expr.span, "DPS expr_cast (residual trait cast?)")
11991209
}
1200-
ast::ExprAssignOp(op, ref dst, ref src) => {
1201-
trans_assign_op(bcx, expr, op, &**dst, &**src)
1210+
ast::ExprAssignOp(op, _, _) => {
1211+
bcx.tcx().sess.span_bug(
1212+
expr.span,
1213+
&format!(
1214+
"augmented assignment ({}=) should always be a rvalue_stmt",
1215+
ast_util::binop_to_string(op.node)));
12021216
}
12031217
_ => {
12041218
bcx.tcx().sess.span_bug(

0 commit comments

Comments
 (0)