From ec0a8a9b52ac1e5555f0e86cb6b2501804c4ec1c Mon Sep 17 00:00:00 2001 From: Ivana Ivanovska Date: Mon, 19 Jan 2026 16:25:48 +0100 Subject: [PATCH] Implement copying for CppCompat.Long32 (#6625) Context: https://github.com/carbon-language/carbon-lang/issues/6275. Part of https://github.com/carbon-language/carbon-lang/issues/5263. --- core/prelude/types/cpp/int.carbon | 9 +- .../interop/cpp/builtins.llp64.carbon | 94 +++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/core/prelude/types/cpp/int.carbon b/core/prelude/types/cpp/int.carbon index f9916984eb30..23eb6e0266ef 100644 --- a/core/prelude/types/cpp/int.carbon +++ b/core/prelude/types/cpp/int.carbon @@ -4,6 +4,7 @@ package Core library "prelude/types/cpp/int"; +import library "prelude/copy"; import library "prelude/operators"; import library "prelude/types/int"; import library "prelude/types/int_literal"; @@ -27,7 +28,13 @@ class CppCompat.ULongLong64 { adapt u64; } -// TODO: Copy. +// Copy + +impl CppCompat.Long32 as Copy { + fn Op[self: Self]() -> Self = "primitive_copy"; +} + +// TODO: Copy for ULong32, LongLong64, ULongLong64. // Conversions. diff --git a/toolchain/check/testdata/interop/cpp/builtins.llp64.carbon b/toolchain/check/testdata/interop/cpp/builtins.llp64.carbon index b7dacabefc8e..8d7509abee9e 100644 --- a/toolchain/check/testdata/interop/cpp/builtins.llp64.carbon +++ b/toolchain/check/testdata/interop/cpp/builtins.llp64.carbon @@ -69,6 +69,19 @@ fn F() { //@dump-sem-ir-end } +// --- copy_long.carbon + +library "[[@TEST_NAME]]"; + +import Cpp; + +fn CopyLong() { + //@dump-sem-ir-begin + var a: Cpp.long = 1; + var b: Cpp.long = a; + //@dump-sem-ir-end +} + // operators // --- arithmetic_homogeneous_long.carbon @@ -913,6 +926,87 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: fn @DestroyOp.loc19(%self.param: %LongResult) = "no_op"; // CHECK:STDOUT: +// CHECK:STDOUT: --- copy_long.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// 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: %Copy.type: type = facet_type <@Copy> [concrete] +// CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [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: %Copy.impl_witness.e75: = impl_witness imports.%Copy.impl_witness_table.572 [concrete] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %Cpp.long, (%Copy.impl_witness.e75) [concrete] +// CHECK:STDOUT: %.03e: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet [concrete] +// CHECK:STDOUT: %Cpp.long.as.Copy.impl.Op.type: type = fn_type @Cpp.long.as.Copy.impl.Op [concrete] +// CHECK:STDOUT: %Cpp.long.as.Copy.impl.Op: %Cpp.long.as.Copy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %DestroyOp.type: type = fn_type @DestroyOp [concrete] +// CHECK:STDOUT: %DestroyOp: %DestroyOp.type = struct_value () [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: %Core.import_ref.915: %Cpp.long.as.Copy.impl.Op.type = import_ref Core//prelude/types/cpp/int, loc{{\d+_\d+}}, loaded [concrete = constants.%Cpp.long.as.Copy.impl.Op] +// CHECK:STDOUT: %Copy.impl_witness_table.572 = impl_witness_table (%Core.import_ref.915), @Cpp.long.as.Copy.impl [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @CopyLong() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %a.patt: %pattern_type.68c = ref_binding_pattern a [concrete] +// CHECK:STDOUT: %a.var_patt: %pattern_type.68c = var_pattern %a.patt [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %a.var: ref %Cpp.long = var %a.var_patt +// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// 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, %impl.elem0.loc8 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %Cpp.long = call %bound_method.loc8(%int_1) [concrete = constants.%int_1.5a4] +// CHECK:STDOUT: %.loc8_3: init %Cpp.long = converted %int_1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_1.5a4] +// CHECK:STDOUT: assign %a.var, %.loc8_3 +// 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: %a: ref %Cpp.long = ref_binding a, %a.var +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %b.patt: %pattern_type.68c = ref_binding_pattern b [concrete] +// CHECK:STDOUT: %b.var_patt: %pattern_type.68c = var_pattern %b.patt [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %b.var: ref %Cpp.long = var %b.var_patt +// CHECK:STDOUT: %a.ref: ref %Cpp.long = name_ref a, %a +// CHECK:STDOUT: %.loc9_21: %Cpp.long = acquire_value %a.ref +// CHECK:STDOUT: %impl.elem0.loc9: %.03e = impl_witness_access constants.%Copy.impl_witness.e75, element0 [concrete = constants.%Cpp.long.as.Copy.impl.Op] +// CHECK:STDOUT: %bound_method.loc9: = bound_method %.loc9_21, %impl.elem0.loc9 +// CHECK:STDOUT: %Cpp.long.as.Copy.impl.Op.call: init %Cpp.long = call %bound_method.loc9(%.loc9_21) +// CHECK:STDOUT: assign %b.var, %Cpp.long.as.Copy.impl.Op.call +// 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: %b: ref %Cpp.long = ref_binding b, %b.var +// CHECK:STDOUT: %DestroyOp.bound.loc9: = bound_method %b.var, constants.%DestroyOp +// CHECK:STDOUT: %DestroyOp.call.loc9: init %empty_tuple.type = call %DestroyOp.bound.loc9(%b.var) +// CHECK:STDOUT: %DestroyOp.bound.loc8: = bound_method %a.var, constants.%DestroyOp +// CHECK:STDOUT: %DestroyOp.call.loc8: init %empty_tuple.type = call %DestroyOp.bound.loc8(%a.var) +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @DestroyOp(%self.param: %Cpp.long) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- arithmetic_homogeneous_long.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants {