From d1b13194d5603e8a34a6bf06fef68bd0d2c4ceaa Mon Sep 17 00:00:00 2001 From: Ivana Ivanovska Date: Mon, 12 Jan 2026 12:58:14 +0100 Subject: [PATCH] Add arithmetic operators for `CppCompat.Long32` (#6573) `CppCompat.Long32` is a distinct type, mapped to C++ `long` on `LLP64` (64-bit Windows). Context: #6275. Part of #5263. --- core/prelude/types/cpp/int.carbon | 31 +- .../interop/cpp/builtins.llp64.carbon | 308 ++++++++++++++++++ 2 files changed, 338 insertions(+), 1 deletion(-) diff --git a/core/prelude/types/cpp/int.carbon b/core/prelude/types/cpp/int.carbon index dec73e61b3e2..175848d5d006 100644 --- a/core/prelude/types/cpp/int.carbon +++ b/core/prelude/types/cpp/int.carbon @@ -132,4 +132,33 @@ final impl CppCompat.ULongLong64 as ImplicitAs(u64) { // TODO: As from Int(N) to LongLong64 if N > 64. // TODO: As from UInt(N) to ULongLong64 if N > 64. -// TODO: Operations on Long32, ULong32, LongLong64, ULongLong64. +// TODO: Operations on ULong32, LongLong64, ULongLong64. +// TODO: Long32: heterogeneous arithmetic operators, bitwise operators, compound assignments. + +// Arithmetic. + +// - Homogeneous. + +final impl CppCompat.Long32 as Negate where .Result = Self { + fn Op[self: Self]() -> Self = "int.snegate"; +} + +final impl CppCompat.Long32 as AddWith(Self) where .Result = Self { + fn Op[self: Self](other: Self) -> Self = "int.sadd"; +} + +final impl CppCompat.Long32 as SubWith(Self) where .Result = Self { + fn Op[self: Self](other: Self) -> Self = "int.ssub"; +} + +final impl CppCompat.Long32 as MulWith(Self) where .Result = Self { + fn Op[self: Self](other: Self) -> Self = "int.smul"; +} + +final impl CppCompat.Long32 as DivWith(Self) where .Result = Self { + fn Op[self: Self](other: Self) -> Self = "int.sdiv"; +} + +final impl CppCompat.Long32 as ModWith(Self) where .Result = Self { + fn Op[self: Self](other: Self) -> Self = "int.smod"; +} diff --git a/toolchain/check/testdata/interop/cpp/builtins.llp64.carbon b/toolchain/check/testdata/interop/cpp/builtins.llp64.carbon index 727be38d07f4..b3c795e990b9 100644 --- a/toolchain/check/testdata/interop/cpp/builtins.llp64.carbon +++ b/toolchain/check/testdata/interop/cpp/builtins.llp64.carbon @@ -69,6 +69,41 @@ fn F() { //@dump-sem-ir-end } +// operators + +fn ArithmeticOperatorsLong() { + //@dump-sem-ir-begin + let x: Cpp.long = 1; + let y: Cpp.long = 1; + + let a: Cpp.long = -x; + let b: Cpp.long = x + y; + let c: Cpp.long = x - y; + let d: Cpp.long = x * y; + let e: Cpp.long = x / y; + let f: Cpp.long = x % y; + //@dump-sem-ir-end +} + +// --- fail_todo_bitwise_long.carbon + +library "[[@TEST_NAME]]"; + +import Cpp; + +fn BitWiseOperatorsLong() { + //@dump-sem-ir-begin + let a: Cpp.long = 1; + let b: Cpp.long = 1; + + // CHECK:STDERR: fail_todo_bitwise_long.carbon:[[@LINE+4]]:21: error: cannot access member of interface `Core.BitAndWith(Cpp.long)` in type `Cpp.long` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: let c: Cpp.long = a & b; + // CHECK:STDERR: ^~~~~ + // CHECK:STDERR: + let c: Cpp.long = a & b; + //@dump-sem-ir-end +} + // --- unsigned_long.carbon library "[[@TEST_NAME]]"; @@ -520,6 +555,58 @@ fn F() { // CHECK:STDOUT: %IntResult.cpp_destructor: %IntResult.cpp_destructor.type = struct_value () [concrete] // CHECK:STDOUT: %LongResult.cpp_destructor.type: type = fn_type @LongResult.cpp_destructor [concrete] // CHECK:STDOUT: %LongResult.cpp_destructor: %LongResult.cpp_destructor.type = struct_value () [concrete] +// CHECK:STDOUT: %Negate.type: type = facet_type <@Negate> [concrete] +// CHECK:STDOUT: %Negate.Op.type: type = fn_type @Negate.Op [concrete] +// CHECK:STDOUT: %Negate.impl_witness: = impl_witness imports.%Negate.impl_witness_table [concrete] +// CHECK:STDOUT: %Negate.facet: %Negate.type = facet_value %Cpp.long, (%Negate.impl_witness) [concrete] +// CHECK:STDOUT: %.494: type = fn_type_with_self_type %Negate.Op.type, %Negate.facet [concrete] +// CHECK:STDOUT: %Cpp.long.as.Negate.impl.Op.type: type = fn_type @Cpp.long.as.Negate.impl.Op [concrete] +// CHECK:STDOUT: %Cpp.long.as.Negate.impl.Op: %Cpp.long.as.Negate.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %AddWith.type.e05: type = generic_interface_type @AddWith [concrete] +// CHECK:STDOUT: %AddWith.generic: %AddWith.type.e05 = struct_value () [concrete] +// CHECK:STDOUT: %AddWith.type.9c2: type = facet_type <@AddWith, @AddWith(%Cpp.long)> [concrete] +// CHECK:STDOUT: %AddWith.Op.type.9a6: type = fn_type @AddWith.Op, @AddWith(%Cpp.long) [concrete] +// CHECK:STDOUT: %AddWith.impl_witness: = impl_witness imports.%AddWith.impl_witness_table [concrete] +// CHECK:STDOUT: %AddWith.facet: %AddWith.type.9c2 = facet_value %Cpp.long, (%AddWith.impl_witness) [concrete] +// CHECK:STDOUT: %.a81: type = fn_type_with_self_type %AddWith.Op.type.9a6, %AddWith.facet [concrete] +// CHECK:STDOUT: %Cpp.long.as.AddWith.impl.Op.type: type = fn_type @Cpp.long.as.AddWith.impl.Op [concrete] +// CHECK:STDOUT: %Cpp.long.as.AddWith.impl.Op: %Cpp.long.as.AddWith.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %SubWith.type.378: type = generic_interface_type @SubWith [concrete] +// CHECK:STDOUT: %SubWith.generic: %SubWith.type.378 = struct_value () [concrete] +// CHECK:STDOUT: %SubWith.type.e8e: type = facet_type <@SubWith, @SubWith(%Cpp.long)> [concrete] +// CHECK:STDOUT: %SubWith.Op.type.533: type = fn_type @SubWith.Op, @SubWith(%Cpp.long) [concrete] +// CHECK:STDOUT: %SubWith.impl_witness: = impl_witness imports.%SubWith.impl_witness_table [concrete] +// CHECK:STDOUT: %SubWith.facet: %SubWith.type.e8e = facet_value %Cpp.long, (%SubWith.impl_witness) [concrete] +// CHECK:STDOUT: %.70d: type = fn_type_with_self_type %SubWith.Op.type.533, %SubWith.facet [concrete] +// CHECK:STDOUT: %Cpp.long.as.SubWith.impl.Op.type: type = fn_type @Cpp.long.as.SubWith.impl.Op [concrete] +// CHECK:STDOUT: %Cpp.long.as.SubWith.impl.Op: %Cpp.long.as.SubWith.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %MulWith.type.8b4: type = generic_interface_type @MulWith [concrete] +// CHECK:STDOUT: %MulWith.generic: %MulWith.type.8b4 = struct_value () [concrete] +// CHECK:STDOUT: %MulWith.type.a32: type = facet_type <@MulWith, @MulWith(%Cpp.long)> [concrete] +// CHECK:STDOUT: %MulWith.Op.type.44b: type = fn_type @MulWith.Op, @MulWith(%Cpp.long) [concrete] +// CHECK:STDOUT: %MulWith.impl_witness: = impl_witness imports.%MulWith.impl_witness_table [concrete] +// CHECK:STDOUT: %MulWith.facet: %MulWith.type.a32 = facet_value %Cpp.long, (%MulWith.impl_witness) [concrete] +// CHECK:STDOUT: %.0a7: type = fn_type_with_self_type %MulWith.Op.type.44b, %MulWith.facet [concrete] +// CHECK:STDOUT: %Cpp.long.as.MulWith.impl.Op.type: type = fn_type @Cpp.long.as.MulWith.impl.Op [concrete] +// CHECK:STDOUT: %Cpp.long.as.MulWith.impl.Op: %Cpp.long.as.MulWith.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %DivWith.type.fc9: type = generic_interface_type @DivWith [concrete] +// CHECK:STDOUT: %DivWith.generic: %DivWith.type.fc9 = struct_value () [concrete] +// CHECK:STDOUT: %DivWith.type.0c0: type = facet_type <@DivWith, @DivWith(%Cpp.long)> [concrete] +// CHECK:STDOUT: %DivWith.Op.type.494: type = fn_type @DivWith.Op, @DivWith(%Cpp.long) [concrete] +// CHECK:STDOUT: %DivWith.impl_witness: = impl_witness imports.%DivWith.impl_witness_table [concrete] +// CHECK:STDOUT: %DivWith.facet: %DivWith.type.0c0 = facet_value %Cpp.long, (%DivWith.impl_witness) [concrete] +// CHECK:STDOUT: %.22b: type = fn_type_with_self_type %DivWith.Op.type.494, %DivWith.facet [concrete] +// CHECK:STDOUT: %Cpp.long.as.DivWith.impl.Op.type: type = fn_type @Cpp.long.as.DivWith.impl.Op [concrete] +// CHECK:STDOUT: %Cpp.long.as.DivWith.impl.Op: %Cpp.long.as.DivWith.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %ModWith.type.ff8: type = generic_interface_type @ModWith [concrete] +// CHECK:STDOUT: %ModWith.generic: %ModWith.type.ff8 = struct_value () [concrete] +// CHECK:STDOUT: %ModWith.type.2fc: type = facet_type <@ModWith, @ModWith(%Cpp.long)> [concrete] +// CHECK:STDOUT: %ModWith.Op.type.c13: type = fn_type @ModWith.Op, @ModWith(%Cpp.long) [concrete] +// CHECK:STDOUT: %ModWith.impl_witness: = impl_witness imports.%ModWith.impl_witness_table [concrete] +// CHECK:STDOUT: %ModWith.facet: %ModWith.type.2fc = facet_value %Cpp.long, (%ModWith.impl_witness) [concrete] +// CHECK:STDOUT: %.300: type = fn_type_with_self_type %ModWith.Op.type.c13, %ModWith.facet [concrete] +// CHECK:STDOUT: %Cpp.long.as.ModWith.impl.Op.type: type = fn_type @Cpp.long.as.ModWith.impl.Op [concrete] +// CHECK:STDOUT: %Cpp.long.as.ModWith.impl.Op: %Cpp.long.as.ModWith.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -530,6 +617,12 @@ fn F() { // CHECK:STDOUT: .Float = %Core.Float // CHECK:STDOUT: .As = %Core.As // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .Negate = %Core.Negate +// CHECK:STDOUT: .AddWith = %Core.AddWith +// CHECK:STDOUT: .SubWith = %Core.SubWith +// CHECK:STDOUT: .MulWith = %Core.MulWith +// CHECK:STDOUT: .DivWith = %Core.DivWith +// CHECK:STDOUT: .ModWith = %Core.ModWith // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -575,6 +668,30 @@ fn F() { // CHECK:STDOUT: %Core.import_ref.38a: @Core.FloatLiteral.as.ImplicitAs.impl.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.type (%Core.FloatLiteral.as.ImplicitAs.impl.Convert.type.02f) = import_ref Core//prelude/types/float, loc{{\d+_\d+}}, loaded [symbolic = @Core.FloatLiteral.as.ImplicitAs.impl.%Core.FloatLiteral.as.ImplicitAs.impl.Convert (constants.%Core.FloatLiteral.as.ImplicitAs.impl.Convert.1f0)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.31a = impl_witness_table (%Core.import_ref.38a), @Core.FloatLiteral.as.ImplicitAs.impl [concrete] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Core.Negate: type = import_ref Core//prelude/operators/arithmetic, Negate, loaded [concrete = constants.%Negate.type] +// CHECK:STDOUT: %Core.import_ref.cb912f.1 = import_ref Core//prelude/types/cpp/int, loc{{\d+_\d+}}, unloaded +// CHECK:STDOUT: %Core.import_ref.412: %Cpp.long.as.Negate.impl.Op.type = import_ref Core//prelude/types/cpp/int, loc{{\d+_\d+}}, loaded [concrete = constants.%Cpp.long.as.Negate.impl.Op] +// CHECK:STDOUT: %Negate.impl_witness_table = impl_witness_table (%Core.import_ref.cb912f.1, %Core.import_ref.412), @Cpp.long.as.Negate.impl [concrete] +// CHECK:STDOUT: %Core.AddWith: %AddWith.type.e05 = import_ref Core//prelude/operators/arithmetic, AddWith, loaded [concrete = constants.%AddWith.generic] +// CHECK:STDOUT: %Core.import_ref.cb912f.2 = import_ref Core//prelude/types/cpp/int, loc{{\d+_\d+}}, unloaded +// CHECK:STDOUT: %Core.import_ref.437: %Cpp.long.as.AddWith.impl.Op.type = import_ref Core//prelude/types/cpp/int, loc{{\d+_\d+}}, loaded [concrete = constants.%Cpp.long.as.AddWith.impl.Op] +// CHECK:STDOUT: %AddWith.impl_witness_table = impl_witness_table (%Core.import_ref.cb912f.2, %Core.import_ref.437), @Cpp.long.as.AddWith.impl [concrete] +// CHECK:STDOUT: %Core.SubWith: %SubWith.type.378 = import_ref Core//prelude/operators/arithmetic, SubWith, loaded [concrete = constants.%SubWith.generic] +// CHECK:STDOUT: %Core.import_ref.cb912f.3 = import_ref Core//prelude/types/cpp/int, loc{{\d+_\d+}}, unloaded +// CHECK:STDOUT: %Core.import_ref.51f: %Cpp.long.as.SubWith.impl.Op.type = import_ref Core//prelude/types/cpp/int, loc{{\d+_\d+}}, loaded [concrete = constants.%Cpp.long.as.SubWith.impl.Op] +// CHECK:STDOUT: %SubWith.impl_witness_table = impl_witness_table (%Core.import_ref.cb912f.3, %Core.import_ref.51f), @Cpp.long.as.SubWith.impl [concrete] +// CHECK:STDOUT: %Core.MulWith: %MulWith.type.8b4 = import_ref Core//prelude/operators/arithmetic, MulWith, loaded [concrete = constants.%MulWith.generic] +// CHECK:STDOUT: %Core.import_ref.cb912f.4 = import_ref Core//prelude/types/cpp/int, loc{{\d+_\d+}}, unloaded +// CHECK:STDOUT: %Core.import_ref.ec4: %Cpp.long.as.MulWith.impl.Op.type = import_ref Core//prelude/types/cpp/int, loc{{\d+_\d+}}, loaded [concrete = constants.%Cpp.long.as.MulWith.impl.Op] +// CHECK:STDOUT: %MulWith.impl_witness_table = impl_witness_table (%Core.import_ref.cb912f.4, %Core.import_ref.ec4), @Cpp.long.as.MulWith.impl [concrete] +// CHECK:STDOUT: %Core.DivWith: %DivWith.type.fc9 = import_ref Core//prelude/operators/arithmetic, DivWith, loaded [concrete = constants.%DivWith.generic] +// CHECK:STDOUT: %Core.import_ref.cb912f.5 = import_ref Core//prelude/types/cpp/int, loc{{\d+_\d+}}, unloaded +// CHECK:STDOUT: %Core.import_ref.d85: %Cpp.long.as.DivWith.impl.Op.type = import_ref Core//prelude/types/cpp/int, loc{{\d+_\d+}}, loaded [concrete = constants.%Cpp.long.as.DivWith.impl.Op] +// CHECK:STDOUT: %DivWith.impl_witness_table = impl_witness_table (%Core.import_ref.cb912f.5, %Core.import_ref.d85), @Cpp.long.as.DivWith.impl [concrete] +// CHECK:STDOUT: %Core.ModWith: %ModWith.type.ff8 = import_ref Core//prelude/operators/arithmetic, ModWith, loaded [concrete = constants.%ModWith.generic] +// CHECK:STDOUT: %Core.import_ref.cb912f.6 = import_ref Core//prelude/types/cpp/int, loc{{\d+_\d+}}, unloaded +// CHECK:STDOUT: %Core.import_ref.394: %Cpp.long.as.ModWith.impl.Op.type = import_ref Core//prelude/types/cpp/int, loc{{\d+_\d+}}, loaded [concrete = constants.%Cpp.long.as.ModWith.impl.Op] +// CHECK:STDOUT: %ModWith.impl_witness_table = impl_witness_table (%Core.import_ref.cb912f.6, %Core.import_ref.394), @Cpp.long.as.ModWith.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @F() { @@ -723,6 +840,197 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: fn @DestroyOp.loc19(%self.param: %LongResult) = "no_op"; // CHECK:STDOUT: +// CHECK:STDOUT: fn @ArithmeticOperatorsLong() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %x.patt: %pattern_type.68c = value_binding_pattern x [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_1.loc32: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc32_13: type = splice_block %long.ref.loc32 [concrete = constants.%Cpp.long] { +// CHECK:STDOUT: %Cpp.ref.loc32: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %long.ref.loc32: type = name_ref long, constants.%Cpp.long [concrete = constants.%Cpp.long] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl.elem0.loc32: %.dad = impl_witness_access constants.%ImplicitAs.impl_witness.2ce, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f2a] +// CHECK:STDOUT: %bound_method.loc32: = bound_method %int_1.loc32, %impl.elem0.loc32 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc32: init %Cpp.long = call %bound_method.loc32(%int_1.loc32) [concrete = constants.%int_1.5a4] +// CHECK:STDOUT: %.loc32_21.1: %Cpp.long = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc32 [concrete = constants.%int_1.5a4] +// CHECK:STDOUT: %.loc32_21.2: %Cpp.long = converted %int_1.loc32, %.loc32_21.1 [concrete = constants.%int_1.5a4] +// CHECK:STDOUT: %x: %Cpp.long = value_binding x, %.loc32_21.2 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %y.patt: %pattern_type.68c = value_binding_pattern y [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_1.loc33: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc33_13: type = splice_block %long.ref.loc33 [concrete = constants.%Cpp.long] { +// CHECK:STDOUT: %Cpp.ref.loc33: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %long.ref.loc33: type = name_ref long, constants.%Cpp.long [concrete = constants.%Cpp.long] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl.elem0.loc33: %.dad = impl_witness_access constants.%ImplicitAs.impl_witness.2ce, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f2a] +// CHECK:STDOUT: %bound_method.loc33: = bound_method %int_1.loc33, %impl.elem0.loc33 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc33: init %Cpp.long = call %bound_method.loc33(%int_1.loc33) [concrete = constants.%int_1.5a4] +// CHECK:STDOUT: %.loc33_21.1: %Cpp.long = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc33 [concrete = constants.%int_1.5a4] +// CHECK:STDOUT: %.loc33_21.2: %Cpp.long = converted %int_1.loc33, %.loc33_21.1 [concrete = constants.%int_1.5a4] +// CHECK:STDOUT: %y: %Cpp.long = value_binding y, %.loc33_21.2 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %a.patt: %pattern_type.68c = value_binding_pattern a [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x.ref.loc35: %Cpp.long = name_ref x, %x +// CHECK:STDOUT: %impl.elem1.loc35: %.494 = impl_witness_access constants.%Negate.impl_witness, element1 [concrete = constants.%Cpp.long.as.Negate.impl.Op] +// CHECK:STDOUT: %bound_method.loc35: = bound_method %x.ref.loc35, %impl.elem1.loc35 +// CHECK:STDOUT: %Cpp.long.as.Negate.impl.Op.call: init %Cpp.long = call %bound_method.loc35(%x.ref.loc35) +// CHECK:STDOUT: %.loc35_13: type = splice_block %long.ref.loc35 [concrete = constants.%Cpp.long] { +// CHECK:STDOUT: %Cpp.ref.loc35: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %long.ref.loc35: type = name_ref long, constants.%Cpp.long [concrete = constants.%Cpp.long] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc35_21.1: %Cpp.long = value_of_initializer %Cpp.long.as.Negate.impl.Op.call +// CHECK:STDOUT: %.loc35_21.2: %Cpp.long = converted %Cpp.long.as.Negate.impl.Op.call, %.loc35_21.1 +// CHECK:STDOUT: %a: %Cpp.long = value_binding a, %.loc35_21.2 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %b.patt: %pattern_type.68c = value_binding_pattern b [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x.ref.loc36: %Cpp.long = name_ref x, %x +// CHECK:STDOUT: %y.ref.loc36: %Cpp.long = name_ref y, %y +// CHECK:STDOUT: %impl.elem1.loc36: %.a81 = impl_witness_access constants.%AddWith.impl_witness, element1 [concrete = constants.%Cpp.long.as.AddWith.impl.Op] +// CHECK:STDOUT: %bound_method.loc36: = bound_method %x.ref.loc36, %impl.elem1.loc36 +// CHECK:STDOUT: %Cpp.long.as.AddWith.impl.Op.call: init %Cpp.long = call %bound_method.loc36(%x.ref.loc36, %y.ref.loc36) +// CHECK:STDOUT: %.loc36_13: type = splice_block %long.ref.loc36 [concrete = constants.%Cpp.long] { +// CHECK:STDOUT: %Cpp.ref.loc36: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %long.ref.loc36: type = name_ref long, constants.%Cpp.long [concrete = constants.%Cpp.long] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc36_23.1: %Cpp.long = value_of_initializer %Cpp.long.as.AddWith.impl.Op.call +// CHECK:STDOUT: %.loc36_23.2: %Cpp.long = converted %Cpp.long.as.AddWith.impl.Op.call, %.loc36_23.1 +// CHECK:STDOUT: %b: %Cpp.long = value_binding b, %.loc36_23.2 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %c.patt: %pattern_type.68c = value_binding_pattern c [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x.ref.loc37: %Cpp.long = name_ref x, %x +// CHECK:STDOUT: %y.ref.loc37: %Cpp.long = name_ref y, %y +// CHECK:STDOUT: %impl.elem1.loc37: %.70d = impl_witness_access constants.%SubWith.impl_witness, element1 [concrete = constants.%Cpp.long.as.SubWith.impl.Op] +// CHECK:STDOUT: %bound_method.loc37: = bound_method %x.ref.loc37, %impl.elem1.loc37 +// CHECK:STDOUT: %Cpp.long.as.SubWith.impl.Op.call: init %Cpp.long = call %bound_method.loc37(%x.ref.loc37, %y.ref.loc37) +// CHECK:STDOUT: %.loc37_13: type = splice_block %long.ref.loc37 [concrete = constants.%Cpp.long] { +// CHECK:STDOUT: %Cpp.ref.loc37: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %long.ref.loc37: type = name_ref long, constants.%Cpp.long [concrete = constants.%Cpp.long] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc37_23.1: %Cpp.long = value_of_initializer %Cpp.long.as.SubWith.impl.Op.call +// CHECK:STDOUT: %.loc37_23.2: %Cpp.long = converted %Cpp.long.as.SubWith.impl.Op.call, %.loc37_23.1 +// CHECK:STDOUT: %c: %Cpp.long = value_binding c, %.loc37_23.2 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %d.patt: %pattern_type.68c = value_binding_pattern d [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x.ref.loc38: %Cpp.long = name_ref x, %x +// CHECK:STDOUT: %y.ref.loc38: %Cpp.long = name_ref y, %y +// CHECK:STDOUT: %impl.elem1.loc38: %.0a7 = impl_witness_access constants.%MulWith.impl_witness, element1 [concrete = constants.%Cpp.long.as.MulWith.impl.Op] +// CHECK:STDOUT: %bound_method.loc38: = bound_method %x.ref.loc38, %impl.elem1.loc38 +// CHECK:STDOUT: %Cpp.long.as.MulWith.impl.Op.call: init %Cpp.long = call %bound_method.loc38(%x.ref.loc38, %y.ref.loc38) +// CHECK:STDOUT: %.loc38_13: type = splice_block %long.ref.loc38 [concrete = constants.%Cpp.long] { +// CHECK:STDOUT: %Cpp.ref.loc38: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %long.ref.loc38: type = name_ref long, constants.%Cpp.long [concrete = constants.%Cpp.long] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc38_23.1: %Cpp.long = value_of_initializer %Cpp.long.as.MulWith.impl.Op.call +// CHECK:STDOUT: %.loc38_23.2: %Cpp.long = converted %Cpp.long.as.MulWith.impl.Op.call, %.loc38_23.1 +// CHECK:STDOUT: %d: %Cpp.long = value_binding d, %.loc38_23.2 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %e.patt: %pattern_type.68c = value_binding_pattern e [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x.ref.loc39: %Cpp.long = name_ref x, %x +// CHECK:STDOUT: %y.ref.loc39: %Cpp.long = name_ref y, %y +// CHECK:STDOUT: %impl.elem1.loc39: %.22b = impl_witness_access constants.%DivWith.impl_witness, element1 [concrete = constants.%Cpp.long.as.DivWith.impl.Op] +// CHECK:STDOUT: %bound_method.loc39: = bound_method %x.ref.loc39, %impl.elem1.loc39 +// CHECK:STDOUT: %Cpp.long.as.DivWith.impl.Op.call: init %Cpp.long = call %bound_method.loc39(%x.ref.loc39, %y.ref.loc39) +// CHECK:STDOUT: %.loc39_13: type = splice_block %long.ref.loc39 [concrete = constants.%Cpp.long] { +// CHECK:STDOUT: %Cpp.ref.loc39: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %long.ref.loc39: type = name_ref long, constants.%Cpp.long [concrete = constants.%Cpp.long] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc39_23.1: %Cpp.long = value_of_initializer %Cpp.long.as.DivWith.impl.Op.call +// CHECK:STDOUT: %.loc39_23.2: %Cpp.long = converted %Cpp.long.as.DivWith.impl.Op.call, %.loc39_23.1 +// CHECK:STDOUT: %e: %Cpp.long = value_binding e, %.loc39_23.2 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %f.patt: %pattern_type.68c = value_binding_pattern f [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x.ref.loc40: %Cpp.long = name_ref x, %x +// CHECK:STDOUT: %y.ref.loc40: %Cpp.long = name_ref y, %y +// CHECK:STDOUT: %impl.elem1.loc40: %.300 = impl_witness_access constants.%ModWith.impl_witness, element1 [concrete = constants.%Cpp.long.as.ModWith.impl.Op] +// CHECK:STDOUT: %bound_method.loc40: = bound_method %x.ref.loc40, %impl.elem1.loc40 +// CHECK:STDOUT: %Cpp.long.as.ModWith.impl.Op.call: init %Cpp.long = call %bound_method.loc40(%x.ref.loc40, %y.ref.loc40) +// CHECK:STDOUT: %.loc40_13: type = splice_block %long.ref.loc40 [concrete = constants.%Cpp.long] { +// CHECK:STDOUT: %Cpp.ref.loc40: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %long.ref.loc40: type = name_ref long, constants.%Cpp.long [concrete = constants.%Cpp.long] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc40_23.1: %Cpp.long = value_of_initializer %Cpp.long.as.ModWith.impl.Op.call +// CHECK:STDOUT: %.loc40_23.2: %Cpp.long = converted %Cpp.long.as.ModWith.impl.Op.call, %.loc40_23.1 +// CHECK:STDOUT: %f: %Cpp.long = value_binding f, %.loc40_23.2 +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_bitwise_long.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Cpp.long: type = class_type @Long32 [concrete] +// CHECK:STDOUT: %pattern_type.68c: type = pattern_type %Cpp.long [concrete] +// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] +// CHECK:STDOUT: %ImplicitAs.type.819: type = facet_type <@ImplicitAs, @ImplicitAs(%Cpp.long)> [concrete] +// CHECK:STDOUT: %ImplicitAs.Convert.type.4c2: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%Cpp.long) [concrete] +// CHECK:STDOUT: %ImplicitAs.impl_witness.2ce: = impl_witness imports.%ImplicitAs.impl_witness_table.903 [concrete] +// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.819 = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.2ce) [concrete] +// CHECK:STDOUT: %.dad: type = fn_type_with_self_type %ImplicitAs.Convert.type.4c2, %ImplicitAs.facet [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type = struct_value () [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert [concrete] +// CHECK:STDOUT: %int_1.5a4: %Cpp.long = int_value 1 [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Cpp: = namespace file.%Cpp.import_cpp, [concrete] { +// CHECK:STDOUT: .long = constants.%Cpp.long +// CHECK:STDOUT: import Cpp//... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import_ref.b8a: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type = import_ref Core//prelude/types/cpp/int, loc{{\d+_\d+}}, loaded [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table.903 = impl_witness_table (%Core.import_ref.b8a), @Core.IntLiteral.as.ImplicitAs.impl.052 [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @BitWiseOperatorsLong() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %a.patt: %pattern_type.68c = value_binding_pattern a [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_1.loc8: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc8_13: type = splice_block %long.ref.loc8 [concrete = constants.%Cpp.long] { +// CHECK:STDOUT: %Cpp.ref.loc8: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %long.ref.loc8: type = name_ref long, constants.%Cpp.long [concrete = constants.%Cpp.long] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl.elem0.loc8: %.dad = impl_witness_access constants.%ImplicitAs.impl_witness.2ce, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert] +// CHECK:STDOUT: %bound_method.loc8: = bound_method %int_1.loc8, %impl.elem0.loc8 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc8: init %Cpp.long = call %bound_method.loc8(%int_1.loc8) [concrete = constants.%int_1.5a4] +// CHECK:STDOUT: %.loc8_21.1: %Cpp.long = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc8 [concrete = constants.%int_1.5a4] +// CHECK:STDOUT: %.loc8_21.2: %Cpp.long = converted %int_1.loc8, %.loc8_21.1 [concrete = constants.%int_1.5a4] +// CHECK:STDOUT: %a: %Cpp.long = value_binding a, %.loc8_21.2 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %b.patt: %pattern_type.68c = value_binding_pattern b [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_1.loc9: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc9_13: type = splice_block %long.ref.loc9 [concrete = constants.%Cpp.long] { +// CHECK:STDOUT: %Cpp.ref.loc9: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %long.ref.loc9: type = name_ref long, constants.%Cpp.long [concrete = constants.%Cpp.long] +// CHECK:STDOUT: } +// CHECK:STDOUT: %impl.elem0.loc9: %.dad = impl_witness_access constants.%ImplicitAs.impl_witness.2ce, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert] +// CHECK:STDOUT: %bound_method.loc9: = bound_method %int_1.loc9, %impl.elem0.loc9 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc9: init %Cpp.long = call %bound_method.loc9(%int_1.loc9) [concrete = constants.%int_1.5a4] +// CHECK:STDOUT: %.loc9_21.1: %Cpp.long = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc9 [concrete = constants.%int_1.5a4] +// CHECK:STDOUT: %.loc9_21.2: %Cpp.long = converted %int_1.loc9, %.loc9_21.1 [concrete = constants.%int_1.5a4] +// CHECK:STDOUT: %b: %Cpp.long = value_binding b, %.loc9_21.2 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %c.patt: %pattern_type.68c = value_binding_pattern c [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %a.ref: %Cpp.long = name_ref a, %a +// CHECK:STDOUT: %b.ref: %Cpp.long = name_ref b, %b +// CHECK:STDOUT: %.loc15: type = splice_block %long.ref.loc15 [concrete = constants.%Cpp.long] { +// CHECK:STDOUT: %Cpp.ref.loc15: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] +// CHECK:STDOUT: %long.ref.loc15: type = name_ref long, constants.%Cpp.long [concrete = constants.%Cpp.long] +// CHECK:STDOUT: } +// CHECK:STDOUT: %c: %Cpp.long = value_binding c, [concrete = ] +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- unsigned_long.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants {