Add heterogeneous arithmetic operators for CppCompat.Long32 (#6644)

Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
This commit is contained in:
Ivana Ivanovska
2026-01-27 17:39:36 +00:00
committed by GitHub
parent 04793ba525
commit 3757a79f4c
2 changed files with 2364 additions and 579 deletions
+69 -7
View File
@@ -66,9 +66,16 @@ impl i32 as ImplicitAs(CppCompat.Long32) {
fn Convert[self: Self]() -> CppCompat.Long32 = "int.convert";
}
// TODO: ImplicitAs from Long32 to Int(N) if N > 32.
final impl CppCompat.Long32 as ImplicitAs(i32) {
fn Convert[self: Self]() -> i32 = "int.convert";
// TODO: Generalize ImplicitAs from Long32 to Int(N) for all N > 32.
// N == 32 is explicitly skipped, as Core.Cpp.Long32 is considered to
// be between i32 and i33 (details:
// https://github.com/carbon-language/carbon-lang/issues/6275#issuecomment-3488010485).
// This follows the rule that implicit conversions exist for all iN -> iM if
// M > N. Otherwise, operations like i32 + Cpp.long result in i32, instead of
// Cpp.long, which differs from the result for Cpp.long + i32 -> Cpp.long, as
// the best match for the left operand is being selected.
final impl CppCompat.Long32 as ImplicitAs(i64) {
fn Convert[self: Self]() -> i64 = "int.convert";
}
impl IntLiteral() as ImplicitAs(CppCompat.ULong32) {
@@ -273,8 +280,63 @@ final impl CppCompat.Long32 as ModWith(Self) where .Result = Self {
fn Op[self: Self](other: Self) -> Self = "int.smod";
}
// TODO: ULong32, LongLong64, ULongLong64: homogeneous arithmetic operators.
// TODO: Long32, ULong32, LongLong64, ULongLong64: heterogeneous arithmetic operators.
// - Heterogeneous.
// - CppCompat.Long32 on left-hand side.
impl forall [T:! ImplicitAs(CppCompat.Long32)]
CppCompat.Long32 as AddWith(T) where .Result = CppCompat.Long32 {
fn Op[self: CppCompat.Long32](other: CppCompat.Long32) -> CppCompat.Long32 = "int.sadd";
}
impl forall [T:! ImplicitAs(CppCompat.Long32)]
CppCompat.Long32 as SubWith(T) where .Result = CppCompat.Long32 {
fn Op[self: CppCompat.Long32](other: CppCompat.Long32) -> CppCompat.Long32 = "int.ssub";
}
impl forall [T:! ImplicitAs(CppCompat.Long32)]
CppCompat.Long32 as MulWith(T) where .Result = CppCompat.Long32 {
fn Op[self: CppCompat.Long32](other: CppCompat.Long32) -> CppCompat.Long32 = "int.smul";
}
impl forall [T:! ImplicitAs(CppCompat.Long32)]
CppCompat.Long32 as DivWith(T) where .Result = CppCompat.Long32 {
fn Op[self: CppCompat.Long32](other: CppCompat.Long32) -> CppCompat.Long32 = "int.sdiv";
}
impl forall [T:! ImplicitAs(CppCompat.Long32)]
CppCompat.Long32 as ModWith(T) where .Result = CppCompat.Long32 {
fn Op[self: CppCompat.Long32](other: CppCompat.Long32) -> CppCompat.Long32 = "int.smod";
}
// - CppCompat.Long32 on right-hand side.
impl forall [T:! ImplicitAs(CppCompat.Long32)]
T as AddWith(CppCompat.Long32) where .Result = CppCompat.Long32 {
fn Op[self: CppCompat.Long32](other: CppCompat.Long32) -> CppCompat.Long32 = "int.sadd";
}
impl forall [T:! ImplicitAs(CppCompat.Long32)]
T as SubWith(CppCompat.Long32) where .Result = CppCompat.Long32 {
fn Op[self: CppCompat.Long32](other: CppCompat.Long32) -> CppCompat.Long32 = "int.ssub";
}
impl forall [T:! ImplicitAs(CppCompat.Long32)]
T as MulWith(CppCompat.Long32) where .Result = CppCompat.Long32 {
fn Op[self: CppCompat.Long32](other: CppCompat.Long32) -> CppCompat.Long32 = "int.smul";
}
impl forall [T:! ImplicitAs(CppCompat.Long32)]
T as DivWith(CppCompat.Long32) where .Result = CppCompat.Long32 {
fn Op[self: CppCompat.Long32](other: CppCompat.Long32) -> CppCompat.Long32 = "int.sdiv";
}
impl forall [T:! ImplicitAs(CppCompat.Long32)]
T as ModWith(CppCompat.Long32) where .Result = CppCompat.Long32 {
fn Op[self: CppCompat.Long32](other: CppCompat.Long32) -> CppCompat.Long32 = "int.smod";
}
// TODO: ULong32, LongLong64, ULongLong64: arithmetic operators.
// Bitwise operators.
@@ -304,8 +366,8 @@ final impl CppCompat.Long32 as RightShiftWith(Self) where .Result = Self {
fn Op[self: Self](other: Self) -> Self = "int.right_shift";
}
// TODO: ULong32, LongLong64, ULongLong64: homogeneous bitwise operators.
// TODO: Long32, ULong32, LongLong64, ULongLong64: heterogeneous bitwise operators.
// TODO: ULong32, LongLong64, ULongLong64: bitwise operators.
// TODO: Long32: heterogeneous bitwise operators.
// Compound assignments.
File diff suppressed because it is too large Load Diff