diff --git a/core/prelude/operators/deref.carbon b/core/prelude/operators/deref.carbon index 369304a4b469..5b99fa33e52d 100644 --- a/core/prelude/operators/deref.carbon +++ b/core/prelude/operators/deref.carbon @@ -7,5 +7,5 @@ package Core library "prelude/operators/deref"; // TODO: Align with https://docs.carbon-lang.dev/docs/design/values.html#dereferencing-customization. interface CppUnsafeDeref { let Result:! type; - fn Op[ref self: Self]() -> ref Result; + fn Op[self: Self]() -> Result; } diff --git a/toolchain/check/cpp/impl_lookup.cpp b/toolchain/check/cpp/impl_lookup.cpp index a75fad0600fe..d5215db3de56 100644 --- a/toolchain/check/cpp/impl_lookup.cpp +++ b/toolchain/check/cpp/impl_lookup.cpp @@ -8,6 +8,8 @@ #include "clang/Sema/Lookup.h" #include "clang/Sema/Sema.h" #include "toolchain/base/kind_switch.h" +#include "toolchain/check/context.h" +#include "toolchain/check/convert.h" #include "toolchain/check/core_identifier.h" #include "toolchain/check/cpp/import.h" #include "toolchain/check/cpp/location.h" @@ -19,6 +21,7 @@ #include "toolchain/check/impl_lookup.h" #include "toolchain/check/import_ref.h" #include "toolchain/check/inst.h" +#include "toolchain/check/name_lookup.h" #include "toolchain/check/type.h" #include "toolchain/check/type_completion.h" #include "toolchain/sem_ir/builtin_function_kind.h" @@ -187,8 +190,8 @@ static auto BuildCppUnsafeDerefWitness( // TODO: Parameterize the interface by the form of the operand and compute the // appropriate passing mode here. - SemIR::ClangDeclSignatureId signature_id = - MakeSignature(context, {}, SemIR::ClangDeclSignature::PassingMode::ByRef); + SemIR::ClangDeclSignatureId signature_id = MakeSignature( + context, {}, SemIR::ClangDeclSignature::PassingMode::ByValue); auto decl_info = DeclInfo{.decl = *candidates.begin(), .signature_id = signature_id}; @@ -197,17 +200,15 @@ static auto BuildCppUnsafeDerefWitness( return fn_id; } - auto result_type_id = + auto result_type_inst_id = context.functions() .Get(context.insts().GetAs(fn_id).function_id) .return_type_inst_id; - if (result_type_id == SemIR::ErrorInst::InstId) { - return SemIR::ErrorInst::InstId; - } - - return BuildCustomWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, - {result_type_id, fn_id}); + return BuildCustomWitness( + context, loc_id, query_self_const_id, query_specific_interface_id, + {context.types().GetTypeInstId(context.types().GetUnqualifiedType( + context.types().GetTypeIdForTypeInstId(result_type_inst_id))), + fn_id}); } static auto BuildDefaultWitness( diff --git a/toolchain/check/testdata/interop/cpp/operators/deref.carbon b/toolchain/check/testdata/interop/cpp/operators/deref.carbon index 6a2d917bdf74..974aad32221f 100644 --- a/toolchain/check/testdata/interop/cpp/operators/deref.carbon +++ b/toolchain/check/testdata/interop/cpp/operators/deref.carbon @@ -123,8 +123,8 @@ fn TestDerefFail(not_ptr: Cpp.NotAPtr) { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %CppUnsafeDeref.type: type = facet_type <@CppUnsafeDeref> [concrete] -// CHECK:STDOUT: %Self: %CppUnsafeDeref.type = symbolic_binding Self, 0 [symbolic] -// CHECK:STDOUT: %CppUnsafeDeref.WithSelf.Op.type.393: type = fn_type @CppUnsafeDeref.WithSelf.Op, @CppUnsafeDeref.WithSelf(%Self) [symbolic] +// CHECK:STDOUT: %Self.a61: %CppUnsafeDeref.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %CppUnsafeDeref.WithSelf.Op.type.393: type = fn_type @CppUnsafeDeref.WithSelf.Op, @CppUnsafeDeref.WithSelf(%Self.a61) [symbolic] // CHECK:STDOUT: %CppUnsafeDeref.WithSelf.Op.0fa: %CppUnsafeDeref.WithSelf.Op.type.393 = struct_value () [symbolic] // CHECK:STDOUT: %CppUnsafeDeref.assoc_type: type = assoc_entity_type @CppUnsafeDeref [concrete] // CHECK:STDOUT: %assoc1: %CppUnsafeDeref.assoc_type = assoc_entity element1, imports.%Core.import_ref.a48 [concrete] @@ -134,6 +134,7 @@ fn TestDerefFail(not_ptr: Cpp.NotAPtr) { // CHECK:STDOUT: %operator_Star__carbon_thunk: %operator_Star__carbon_thunk.type = struct_value () [concrete] // CHECK:STDOUT: %ConstDeref.Op.type: type = fn_type @ConstDeref.Op [concrete] // CHECK:STDOUT: %ConstDeref.Op: %ConstDeref.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] // CHECK:STDOUT: %custom_witness.000: = custom_witness (%i32, %ConstDeref.Op), @CppUnsafeDeref [concrete] // CHECK:STDOUT: %CppUnsafeDeref.facet.909: %CppUnsafeDeref.type = facet_value %ConstDeref, (%custom_witness.000) [concrete] // CHECK:STDOUT: %CppUnsafeDeref.WithSelf.Op.type.6a5: type = fn_type @CppUnsafeDeref.WithSelf.Op, @CppUnsafeDeref.WithSelf(%CppUnsafeDeref.facet.909) [concrete] @@ -144,6 +145,7 @@ fn TestDerefFail(not_ptr: Cpp.NotAPtr) { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .CppUnsafeDeref = %Core.CppUnsafeDeref +// CHECK:STDOUT: .Copy = %Core.Copy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -161,6 +163,7 @@ fn TestDerefFail(not_ptr: Cpp.NotAPtr) { // CHECK:STDOUT: } { // CHECK:STDOUT: // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/copy, Copy, loaded [concrete = constants.%Copy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @TestDerefPass(%int_ptr.param: ref %ConstDeref) -> ref %i32 { @@ -169,13 +172,14 @@ fn TestDerefFail(not_ptr: Cpp.NotAPtr) { // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %CppUnsafeDeref.ref: type = name_ref CppUnsafeDeref, imports.%Core.CppUnsafeDeref [concrete = constants.%CppUnsafeDeref.type] // CHECK:STDOUT: %Op.ref.loc13_38: %CppUnsafeDeref.assoc_type = name_ref Op, imports.%Core.import_ref.05c [concrete = constants.%assoc1] -// CHECK:STDOUT: %impl_witness_assoc_constant: type = impl_witness_assoc_constant @ConstDeref.cpp_operator.%i32.2 [concrete = constants.%i32] +// CHECK:STDOUT: %impl_witness_assoc_constant: type = impl_witness_assoc_constant constants.%i32 [concrete = constants.%i32] // CHECK:STDOUT: // CHECK:STDOUT: %impl.elem1: %.b71 = impl_witness_access constants.%custom_witness.000, element1 [concrete = constants.%ConstDeref.Op] // CHECK:STDOUT: %bound_method: = bound_method %int_ptr.ref, %impl.elem1 +// CHECK:STDOUT: %.loc13: %ConstDeref = acquire_value %int_ptr.ref // CHECK:STDOUT: %Op.ref.loc13_43: %ConstDeref.cpp_operator.type = name_ref Op, imports.%ConstDeref.cpp_operator.decl [concrete = constants.%ConstDeref.cpp_operator] -// CHECK:STDOUT: %ConstDeref.cpp_operator.bound: = bound_method %int_ptr.ref, %Op.ref.loc13_43 -// CHECK:STDOUT: %operator_Star__carbon_thunk.call: ref %i32 = call imports.%operator_Star__carbon_thunk.decl(%int_ptr.ref) +// CHECK:STDOUT: %ConstDeref.cpp_operator.bound: = bound_method %.loc13, %Op.ref.loc13_43 +// CHECK:STDOUT: %operator_Star__carbon_thunk.call: ref %i32 = call imports.%operator_Star__carbon_thunk.decl(%.loc13) // CHECK:STDOUT: return %operator_Star__carbon_thunk.call // CHECK:STDOUT: } // CHECK:STDOUT: @@ -220,10 +224,11 @@ fn TestDerefFail(not_ptr: Cpp.NotAPtr) { // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %CppUnsafeDeref.ref: type = name_ref CppUnsafeDeref, imports.%Core.CppUnsafeDeref [concrete = constants.%CppUnsafeDeref.type] // CHECK:STDOUT: %Op.ref: %CppUnsafeDeref.assoc_type = name_ref Op, imports.%Core.import_ref.05c [concrete = constants.%assoc1] -// CHECK:STDOUT: %impl_witness_assoc_constant: type = impl_witness_assoc_constant @MutableDeref.cpp_operator.%i32.2 [concrete = constants.%i32] +// CHECK:STDOUT: %impl_witness_assoc_constant: type = impl_witness_assoc_constant constants.%i32 [concrete = constants.%i32] // CHECK:STDOUT: %impl.elem1: %.a97 = impl_witness_access constants.%custom_witness.91c, element1 [concrete = constants.%MutableDeref.cpp_operator] // CHECK:STDOUT: %bound_method: = bound_method %int_ptr.ref, %impl.elem1 -// CHECK:STDOUT: %MutableDeref.cpp_operator.call: ref %i32 = call %bound_method(%int_ptr.ref) +// CHECK:STDOUT: %.loc13: %MutableDeref = acquire_value %int_ptr.ref +// CHECK:STDOUT: %MutableDeref.cpp_operator.call: ref %i32 = call %bound_method(%.loc13) // CHECK:STDOUT: return %MutableDeref.cpp_operator.call // CHECK:STDOUT: } // CHECK:STDOUT: