From bfebb7cb421486f0d288e9a2aea5202fe8c785d1 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Tue, 15 Sep 2026 21:23:28 +0000 Subject: [PATCH] Pass SpecificInterface through custom and C++ witness generation (#7784) We were passing a SpecificInterfaceId which just makes code have to do a lookup to get the actual SpecificInterface. The caller already has the SpecificInterface, so plumb that around. SpecificInterfaceId really only exists when we need to stick a SpecificInterface into an instruction as an operand. --- toolchain/check/cpp/impl_lookup.cpp | 92 +++++++++---------- toolchain/check/cpp/impl_lookup.h | 2 +- toolchain/check/custom_witness.cpp | 135 ++++++++++++---------------- toolchain/check/custom_witness.h | 8 +- toolchain/check/impl_lookup.cpp | 17 ++-- 5 files changed, 111 insertions(+), 143 deletions(-) diff --git a/toolchain/check/cpp/impl_lookup.cpp b/toolchain/check/cpp/impl_lookup.cpp index 98358f320d13..367af41da719 100644 --- a/toolchain/check/cpp/impl_lookup.cpp +++ b/toolchain/check/cpp/impl_lookup.cpp @@ -127,10 +127,10 @@ static auto MakeSignature( modes, SemIR::ClangDeclSignature::Normal, self_passing_mode)); } -static auto BuildCopyWitness( - Context& context, SemIR::LocId loc_id, - SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId { +static auto BuildCopyWitness(Context& context, SemIR::LocId loc_id, + SemIR::ConstantId query_self_const_id, + SemIR::SpecificInterface query_specific_interface) + -> SemIR::InstId { auto& clang_sema = context.clang_sema(); auto* tag_decl = TypeAsTagDecl(context, query_self_const_id); @@ -160,18 +160,18 @@ static auto BuildCopyWitness( return fn_id; } return BuildCustomWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, {fn_id}); + query_specific_interface, {fn_id}); } // Otherwise it's an enum (or eventually a C struct type). Perform a primitive // copy. return BuildPrimitiveCopyWitness(context, loc_id, query_self_const_id, - query_specific_interface_id); + query_specific_interface); } static auto BuildCppUnsafeDerefWitness( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId { + SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId { auto& clang_sema = context.clang_sema(); auto* class_decl = TypeAsClassDecl(context, query_self_const_id); @@ -206,7 +206,7 @@ static auto BuildCppUnsafeDerefWitness( .Get(context.insts().GetAs(fn_id).function_id) .return_type_inst_id; return BuildCustomWitness( - context, loc_id, query_self_const_id, query_specific_interface_id, + context, loc_id, query_self_const_id, query_specific_interface, {context.types().GetTypeInstId(context.types().GetUnqualifiedType( context.types().GetTypeIdForTypeInstId(result_type_inst_id))), fn_id}); @@ -215,7 +215,7 @@ static auto BuildCppUnsafeDerefWitness( static auto BuildDefaultWitness( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId { + SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId { auto& clang_sema = context.clang_sema(); auto* class_decl = TypeAsClassDecl(context, query_self_const_id); @@ -238,13 +238,13 @@ static auto BuildDefaultWitness( return fn_id; } return BuildCustomWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, {fn_id}); + query_specific_interface, {fn_id}); } static auto BuildDestroyWitness( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId { + SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId { auto& clang_sema = context.clang_sema(); auto* tag_decl = TypeAsTagDecl(context, query_self_const_id); @@ -254,7 +254,7 @@ static auto BuildDestroyWitness( auto* class_decl = dyn_cast(tag_decl); if (!class_decl) { return BuildTrivialDestroyWitness(context, loc_id, query_self_const_id, - query_specific_interface_id); + query_specific_interface); } SemIR::ClangDeclSignatureId signature_id = MakeSignature(context, {}); @@ -265,14 +265,14 @@ static auto BuildDestroyWitness( return fn_id; } return BuildCustomWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, {fn_id}); + query_specific_interface, {fn_id}); } // Attempts to build a witness table entry for a C++ unary operator. static auto BuildCppUnaryOperatorWitness( Context& context, SemIR::LocId loc_id, SemIR::CoreInterface core_interface, bool has_associated_result_type, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId { + SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId { auto self_type_id = context.types().GetTypeIdForTypeConstantId(query_self_const_id); auto fn_id = LookupCppOperator( @@ -292,26 +292,22 @@ static auto BuildCppUnaryOperatorWitness( } return BuildCustomWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, + query_specific_interface, {result_type_id, fn_id}); } return BuildCustomWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, {fn_id}); + query_specific_interface, {fn_id}); } // Attempts to build a witness table entry for a C++ binary operator. static auto BuildCppBinaryOperatorWitness( Context& context, SemIR::LocId loc_id, SemIR::CoreInterface core_interface, bool has_associated_result_type, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId { + SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId { auto self_type_id = context.types().GetTypeIdForTypeConstantId(query_self_const_id); - auto args = - context.inst_blocks().Get(context.specifics() - .Get(context.specific_interfaces() - .Get(query_specific_interface_id) - .specific_id) - .args_id); + auto args = context.inst_blocks().Get( + context.specifics().Get(query_specific_interface.specific_id).args_id); CARBON_CHECK(args.size() == 1, "Binary operator missing an argument"); auto arg_type_id = context.types().GetTypeIdForTypeInstId(args.front()); auto fn_id = LookupCppOperator( @@ -329,26 +325,22 @@ static auto BuildCppBinaryOperatorWitness( return SemIR::ErrorInst::InstId; } return BuildCustomWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, + query_specific_interface, {result_type_id, fn_id}); } return BuildCustomWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, {fn_id}); + query_specific_interface, {fn_id}); } static auto BuildCppComparisonWitness( Context& context, SemIR::LocId loc_id, CoreIdentifier interface, llvm::ArrayRef operator_names, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId { + SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId { auto self_type_id = context.types().GetTypeIdForTypeConstantId(query_self_const_id); - auto args = - context.inst_blocks().Get(context.specifics() - .Get(context.specific_interfaces() - .Get(query_specific_interface_id) - .specific_id) - .args_id); + auto args = context.inst_blocks().Get( + context.specifics().Get(query_specific_interface.specific_id).args_id); CARBON_CHECK(args.size() == 1, "Binary operator missing an argument"); auto arg_type_id = context.types().GetTypeIdForTypeInstId(args[0]); @@ -384,7 +376,7 @@ static auto BuildCppComparisonWitness( } return BuildCustomWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, operators); + query_specific_interface, operators); } static auto LookupCppMethod(Context& context, clang::Sema& clang_sema, @@ -496,7 +488,7 @@ static auto BuildCppRangeForIterateWitnessImpl( Context& context, SemIR::LocId loc_id, LookupBeginEndCallees range_for_lookup, clang::CXXRecordDecl* class_decl, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId { + SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId { auto& clang_sema = context.clang_sema(); auto begin_name_info = clang::DeclarationNameInfo( &clang_sema.PP.getIdentifierTable().get("begin"), @@ -536,31 +528,31 @@ static auto BuildCppRangeForIterateWitnessImpl( end_result_type_id != SemIR::InstId::None); return BuildCustomWitness( - context, loc_id, query_self_const_id, query_specific_interface_id, + context, loc_id, query_self_const_id, query_specific_interface, {begin_result_type_id, end_result_type_id, begin_fn_id, end_fn_id}); } static auto BuildCppRangeForIterateWitness( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId { + SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId { auto* class_decl = TypeAsClassDecl(context, query_self_const_id); if (auto with_members = BuildCppRangeForIterateWitnessImpl( context, loc_id, LookupCppMethod, class_decl, query_self_const_id, - query_specific_interface_id); + query_specific_interface); with_members != SemIR::InstId::None) { return with_members; } return BuildCppRangeForIterateWitnessImpl( context, loc_id, LookupCppUnqualified, class_decl, query_self_const_id, - query_specific_interface_id); + query_specific_interface); } auto LookupCppImpl(Context& context, SemIR::LocId loc_id, SemIR::CoreInterface core_interface, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id, + SemIR::SpecificInterface query_specific_interface, const TypeStructure* best_impl_type_structure, SemIR::LocId best_impl_loc_id) -> SemIR::InstId { // TODO: Infer a C++ type structure and check whether it's less strict than @@ -574,11 +566,11 @@ auto LookupCppImpl(Context& context, SemIR::LocId loc_id, return BuildCppUnaryOperatorWitness(context, loc_id, core_interface, /*has_associated_result_type=*/false, query_self_const_id, - query_specific_interface_id); + query_specific_interface); case SemIR::CoreInterface::Negate: return BuildCppUnaryOperatorWitness( context, loc_id, core_interface, /*has_associated_result_type=*/true, - query_self_const_id, query_specific_interface_id); + query_self_const_id, query_specific_interface); case SemIR::CoreInterface::AddWith: case SemIR::CoreInterface::SubWith: case SemIR::CoreInterface::MulWith: @@ -587,7 +579,7 @@ auto LookupCppImpl(Context& context, SemIR::LocId loc_id, return BuildCppBinaryOperatorWitness(context, loc_id, core_interface, /*has_associated_result_type=*/true, query_self_const_id, - query_specific_interface_id); + query_specific_interface); case SemIR::CoreInterface::AddAssignWith: case SemIR::CoreInterface::SubAssignWith: case SemIR::CoreInterface::MulAssignWith: @@ -596,34 +588,34 @@ auto LookupCppImpl(Context& context, SemIR::LocId loc_id, return BuildCppBinaryOperatorWitness(context, loc_id, core_interface, /*has_associated_result_type=*/false, query_self_const_id, - query_specific_interface_id); + query_specific_interface); case SemIR::CoreInterface::EqWith: return BuildCppComparisonWitness( context, loc_id, CoreIdentifier::EqWith, {CoreIdentifier::Equal, CoreIdentifier::NotEqual}, - query_self_const_id, query_specific_interface_id); + query_self_const_id, query_specific_interface); case SemIR::CoreInterface::OrderedWith: return BuildCppComparisonWitness( context, loc_id, CoreIdentifier::OrderedWith, {CoreIdentifier::Less, CoreIdentifier::LessOrEquivalent, CoreIdentifier::Greater, CoreIdentifier::GreaterOrEquivalent}, - query_self_const_id, query_specific_interface_id); + query_self_const_id, query_specific_interface); case SemIR::CoreInterface::Copy: return BuildCopyWitness(context, loc_id, query_self_const_id, - query_specific_interface_id); + query_specific_interface); case SemIR::CoreInterface::CppUnsafeDeref: return BuildCppUnsafeDerefWitness(context, loc_id, query_self_const_id, - query_specific_interface_id); + query_specific_interface); case SemIR::CoreInterface::Default: return BuildDefaultWitness(context, loc_id, query_self_const_id, - query_specific_interface_id); + query_specific_interface); case SemIR::CoreInterface::Destroy: return BuildDestroyWitness(context, loc_id, query_self_const_id, - query_specific_interface_id); + query_specific_interface); case SemIR::CoreInterface::CppRangeForIterate: return BuildCppRangeForIterateWitness( - context, loc_id, query_self_const_id, query_specific_interface_id); + context, loc_id, query_self_const_id, query_specific_interface); // *FitsIn are implemented only by Carbon primitive types. case SemIR::CoreInterface::IntFitsIn: diff --git a/toolchain/check/cpp/impl_lookup.h b/toolchain/check/cpp/impl_lookup.h index 80bfdab55295..855201fa3b65 100644 --- a/toolchain/check/cpp/impl_lookup.h +++ b/toolchain/check/cpp/impl_lookup.h @@ -40,7 +40,7 @@ namespace Carbon::Check { auto LookupCppImpl(Context& context, SemIR::LocId loc_id, SemIR::CoreInterface core_interface, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id, + SemIR::SpecificInterface query_specific_interface, const TypeStructure* best_impl_type_structure, SemIR::LocId best_impl_loc_id) -> SemIR::InstId; diff --git a/toolchain/check/custom_witness.cpp b/toolchain/check/custom_witness.cpp index c54ff59226b3..9893e7455d0d 100644 --- a/toolchain/check/custom_witness.cpp +++ b/toolchain/check/custom_witness.cpp @@ -146,11 +146,7 @@ auto MakeBuiltinOperatorFunction(Context& context, SemIR::LocId loc_id, // Returns a FacetType that contains only the query interface. static auto GetFacetTypeForQuerySpecificInterface( Context& context, SemIR::LocId loc_id, - SemIR::SpecificInterfaceId query_specific_interface_id) - -> SemIR::ConstantId { - const auto query_specific_interface = - context.specific_interfaces().Get(query_specific_interface_id); - + SemIR::SpecificInterface query_specific_interface) -> SemIR::ConstantId { // The Self facet will have type FacetType, for the query interface. auto const_id = EvalOrAddInst( context, loc_id, @@ -163,13 +159,12 @@ static auto GetFacetTypeForQuerySpecificInterface( // for lookups in `HasWitnessForRepeatedField`. static auto PrepareForHasWitness( Context& context, SemIR::LocId loc_id, - SemIR::SpecificInterfaceId query_specific_interface_id) - -> SemIR::ConstantId { + SemIR::SpecificInterface query_specific_interface) -> SemIR::ConstantId { context.inst_block_stack().Push(); StartGenericDecl(context); return GetFacetTypeForQuerySpecificInterface(context, loc_id, - query_specific_interface_id); + query_specific_interface); } // Cleans up state `PrepareForHasWitness`. @@ -200,9 +195,9 @@ enum class DestroyFormat { // field, this can handle the call to `PrepareForHasWitness`. static auto HasWitnessForOneField( Context& context, SemIR::LocId loc_id, SemIR::InstId field_inst_id, - SemIR::SpecificInterfaceId query_specific_interface_id) -> DestroyFormat { + SemIR::SpecificInterface query_specific_interface) -> DestroyFormat { auto query_facet_type_const_id = - PrepareForHasWitness(context, loc_id, query_specific_interface_id); + PrepareForHasWitness(context, loc_id, query_specific_interface); auto has_witness = HasWitnessForRepeatedField(context, loc_id, field_inst_id, query_facet_type_const_id); CleanupAfterHasWitness(context); @@ -210,11 +205,11 @@ static auto HasWitnessForOneField( } // Returns true if `class_type` should impl `Destroy`. -static auto CanDestroyClass( - Context& context, SemIR::LocId loc_id, SemIR::ClassType class_type, - const SemIR::CompleteTypeInfo& complete_info, - SemIR::SpecificInterfaceId query_specific_interface_id, bool is_partial) - -> DestroyFormat { +static auto CanDestroyClass(Context& context, SemIR::LocId loc_id, + SemIR::ClassType class_type, + const SemIR::CompleteTypeInfo& complete_info, + SemIR::SpecificInterface query_specific_interface, + bool is_partial) -> DestroyFormat { // Abstract classes can't be destroyed. if (!is_partial && complete_info.IsAbstract()) { return DestroyFormat::NoDestroy; @@ -236,16 +231,16 @@ static auto CanDestroyClass( return HasWitnessForOneField(context, loc_id, context.types().GetTypeInstId(object_repr_id), - query_specific_interface_id); + query_specific_interface); } // Returns true if the `Self` should impl `Destroy`. This will recurse into impl // lookup of `Destroy` for members, similar to `where .Self.members each impls // Destroy`. -static auto CanDestroyType( - Context& context, SemIR::LocId loc_id, - SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) -> DestroyFormat { +static auto CanDestroyType(Context& context, SemIR::LocId loc_id, + SemIR::ConstantId query_self_const_id, + SemIR::SpecificInterface query_specific_interface) + -> DestroyFormat { auto inst_id = context.constant_values().GetInstId( GetCanonicalFacetOrTypeValue(context, query_self_const_id)); auto inst = context.insts().Get(inst_id); @@ -283,7 +278,7 @@ static auto CanDestroyType( // Verify the element can be destroyed. return HasWitnessForOneField(context, loc_id, array_type.element_type_inst_id, - query_specific_interface_id); + query_specific_interface); } case SemIR::Call::Kind: @@ -294,19 +289,19 @@ static auto CanDestroyType( case CARBON_KIND(SemIR::ClassType class_type): { return CanDestroyClass(context, loc_id, class_type, context.types().GetCompleteTypeInfo(type_id), - query_specific_interface_id, + query_specific_interface, /*is_partial=*/false); } case CARBON_KIND(SemIR::ConstType const_type): { return HasWitnessForOneField(context, loc_id, const_type.inner_id, - query_specific_interface_id); + query_specific_interface); } case CARBON_KIND(SemIR::MaybeUnformedType maybe_unformed_type): { return HasWitnessForOneField(context, loc_id, maybe_unformed_type.inner_id, - query_specific_interface_id); + query_specific_interface); } case CARBON_KIND(SemIR::PartialType partial_type): { @@ -316,7 +311,7 @@ static auto CanDestroyType( context.insts().GetAs(partial_type.inner_id); return CanDestroyClass(context, loc_id, class_type, context.types().GetCompleteTypeInfo(type_id), - query_specific_interface_id, + query_specific_interface, /*is_partial=*/true); } @@ -326,7 +321,7 @@ static auto CanDestroyType( return DestroyFormat::Trivial; } auto query_facet_type_const_id = - PrepareForHasWitness(context, loc_id, query_specific_interface_id); + PrepareForHasWitness(context, loc_id, query_specific_interface); bool has_witness = true; for (const auto& field : fields) { if (!HasWitnessForRepeatedField(context, loc_id, field.type_inst_id, @@ -345,7 +340,7 @@ static auto CanDestroyType( return DestroyFormat::Trivial; } auto query_facet_type_const_id = - PrepareForHasWitness(context, loc_id, query_specific_interface_id); + PrepareForHasWitness(context, loc_id, query_specific_interface); bool has_witness = true; for (const auto& element_id : block) { if (!HasWitnessForRepeatedField(context, loc_id, element_id, @@ -455,7 +450,7 @@ static auto MakeDestroyOpFunction(Context& context, SemIR::LocId loc_id, static auto MakeCustomWitnessConstantInst( Context& context, SemIR::LocId loc_id, - SemIR::SpecificInterfaceId query_specific_interface_id, + SemIR::SpecificInterface query_specific_interface, SemIR::InstBlockId associated_entities_block_id) -> SemIR::InstId { // The witness is a CustomWitness of the query interface with a table that // contains each associated entity. @@ -463,7 +458,8 @@ static auto MakeCustomWitnessConstantInst( context, loc_id, {.type_id = GetSingletonType(context, SemIR::WitnessType::TypeInstId), .elements_id = associated_entities_block_id, - .query_specific_interface_id = query_specific_interface_id}); + .query_specific_interface_id = + context.specific_interfaces().Add(query_specific_interface)}); return context.constant_values().GetInstId(const_id); } @@ -477,13 +473,12 @@ struct TypesForSelfFacet { static auto GetTypesForSelfFacet( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) - -> TypesForSelfFacet { + SemIR::SpecificInterface query_specific_interface) -> TypesForSelfFacet { // The Self facet will have type FacetType, for the query interface. auto facet_type_for_query_specific_interface = context.types().GetTypeIdForTypeConstantId( GetFacetTypeForQuerySpecificInterface(context, loc_id, - query_specific_interface_id)); + query_specific_interface)); // The Self facet needs to point to a type value. If it's not one already, // convert to type. auto query_self_as_type_id = GetFacetAsType(context, query_self_const_id); @@ -494,14 +489,13 @@ static auto GetTypesForSelfFacet( // interface with an entry for each associated entity so far. static auto MakeSelfFacetWithCustomWitness( Context& context, SemIR::LocId loc_id, TypesForSelfFacet query_types, - SemIR::SpecificInterfaceId query_specific_interface_id, + SemIR::SpecificInterface query_specific_interface, SemIR::InstBlockId associated_entities_block_id) -> SemIR::ConstantId { // We are building a facet value for a single interface, so the witness block // is a single witness for that interface. - auto witnesses_block_id = - context.inst_blocks().Add({MakeCustomWitnessConstantInst( - context, loc_id, query_specific_interface_id, - associated_entities_block_id)}); + auto witnesses_block_id = context.inst_blocks().Add( + {MakeCustomWitnessConstantInst(context, loc_id, query_specific_interface, + associated_entities_block_id)}); return EvalOrAddInst( context, loc_id, @@ -513,10 +507,8 @@ static auto MakeSelfFacetWithCustomWitness( auto BuildCustomWitness(Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id, + SemIR::SpecificInterface query_specific_interface, llvm::ArrayRef values) -> SemIR::InstId { - const auto query_specific_interface = - context.specific_interfaces().Get(query_specific_interface_id); const auto& interface = context.interfaces().Get(query_specific_interface.interface_id); auto assoc_entities = @@ -529,7 +521,7 @@ auto BuildCustomWitness(Context& context, SemIR::LocId loc_id, } auto query_types_for_self_facet = GetTypesForSelfFacet( - context, loc_id, query_self_const_id, query_specific_interface_id); + context, loc_id, query_self_const_id, query_specific_interface); // The values that will go in the witness table. llvm::SmallVector entries; @@ -570,7 +562,7 @@ auto BuildCustomWitness(Context& context, SemIR::LocId loc_id, if (associated_entity_state < new_associated_entity_state) { auto self_facet = MakeSelfFacetWithCustomWitness( context, loc_id, query_types_for_self_facet, - query_specific_interface_id, context.inst_blocks().Add(entries)); + query_specific_interface, context.inst_blocks().Add(entries)); interface_with_self_specific_id = MakeSpecificWithInnerSelf( context, loc_id, interface.generic_id, interface.generic_with_self_id, @@ -639,7 +631,7 @@ auto BuildCustomWitness(Context& context, SemIR::LocId loc_id, } return MakeCustomWitnessConstantInst(context, loc_id, - query_specific_interface_id, + query_specific_interface, context.inst_blocks().Add(entries)); } @@ -670,17 +662,15 @@ auto GetCoreInterface(Context& context, SemIR::InterfaceId interface_id) auto BuildPrimitiveCopyWitness( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId { + SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId { auto self_type_id = GetFacetAsType(context, query_self_const_id); auto op_id = MakeBuiltinOperatorFunction( context, loc_id, {self_type_id}, self_type_id, CoreIdentifier::Op, SemIR::BuiltinFunctionKind::PrimitiveCopy, - context.specific_interfaces() - .Get(query_specific_interface_id) - .interface_id); + query_specific_interface.interface_id); return BuildCustomWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, {op_id}); + query_specific_interface, {op_id}); } // Builds and returns a custom witness that performs the specified kind of @@ -688,18 +678,16 @@ auto BuildPrimitiveCopyWitness( static auto BuildDestroyWitness( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id, - DestroyFormat format) -> SemIR::InstId { + SemIR::SpecificInterface query_specific_interface, DestroyFormat format) + -> SemIR::InstId { CARBON_CHECK(format != DestroyFormat::NoDestroy); auto self_type_id = GetFacetAsType(context, query_self_const_id); - auto op_id = MakeDestroyOpFunction(context, loc_id, self_type_id, - context.specific_interfaces() - .Get(query_specific_interface_id) - .interface_id, - format); + auto op_id = + MakeDestroyOpFunction(context, loc_id, self_type_id, + query_specific_interface.interface_id, format); return BuildCustomWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, {op_id}); + query_specific_interface, {op_id}); } // Returns the custom witness to use for destruction of the given type. See @@ -707,10 +695,10 @@ static auto BuildDestroyWitness( static auto LookupDestroyWitness( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id, bool build_witness) + SemIR::SpecificInterface query_specific_interface, bool build_witness) -> std::optional { auto format = CanDestroyType(context, loc_id, query_self_const_id, - query_specific_interface_id); + query_specific_interface); if (format == DestroyFormat::NoDestroy) { return std::nullopt; } @@ -721,26 +709,22 @@ static auto LookupDestroyWitness( } return BuildDestroyWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, format); + query_specific_interface, format); } auto BuildTrivialDestroyWitness( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId { + SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId { return BuildDestroyWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, - DestroyFormat::Trivial); + query_specific_interface, DestroyFormat::Trivial); } static auto MakeIntFitsInWitness( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id, bool build_witness) + SemIR::SpecificInterface query_specific_interface, bool build_witness) -> std::optional { - auto query_specific_interface = - context.specific_interfaces().Get(query_specific_interface_id); - auto args_id = query_specific_interface.specific_id; if (!args_id.has_value()) { return std::nullopt; @@ -792,7 +776,7 @@ static auto MakeIntFitsInWitness( return SemIR::InstId::None; } return BuildCustomWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, {}); + query_specific_interface, {}); } return std::nullopt; } @@ -829,17 +813,14 @@ static auto MakeIntFitsInWitness( } return BuildCustomWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, {}); + query_specific_interface, {}); } static auto MakeFloatFitsInWitness( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id, bool build_witness) + SemIR::SpecificInterface query_specific_interface, bool build_witness) -> std::optional { - auto query_specific_interface = - context.specific_interfaces().Get(query_specific_interface_id); - auto args_id = query_specific_interface.specific_id; if (!args_id.has_value()) { return std::nullopt; @@ -901,24 +882,24 @@ static auto MakeFloatFitsInWitness( } return BuildCustomWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, {}); + query_specific_interface, {}); } auto LookupCustomWitness(Context& context, SemIR::LocId loc_id, SemIR::CoreInterface core_interface, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id, + SemIR::SpecificInterface query_specific_interface, bool build_witness) -> std::optional { switch (core_interface) { case SemIR::CoreInterface::Destroy: return LookupDestroyWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, build_witness); + query_specific_interface, build_witness); case SemIR::CoreInterface::FloatFitsIn: return MakeFloatFitsInWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, build_witness); + query_specific_interface, build_witness); case SemIR::CoreInterface::IntFitsIn: return MakeIntFitsInWitness(context, loc_id, query_self_const_id, - query_specific_interface_id, build_witness); + query_specific_interface, build_witness); case SemIR::CoreInterface::AddAssignWith: case SemIR::CoreInterface::AddWith: case SemIR::CoreInterface::Copy: diff --git a/toolchain/check/custom_witness.h b/toolchain/check/custom_witness.h index 086049b4e2e3..519598ff45a9 100644 --- a/toolchain/check/custom_witness.h +++ b/toolchain/check/custom_witness.h @@ -17,14 +17,14 @@ namespace Carbon::Check { // values aren't suitable for the interface. auto BuildCustomWitness(Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id, + SemIR::SpecificInterface query_specific_interface, llvm::ArrayRef values) -> SemIR::InstId; // Builds a witness that the given type is copyable via a primitive copy. auto BuildPrimitiveCopyWitness( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId; + SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId; // Returns a manufactured operator function. // `param_types` contains the parameter types. The first element of @@ -44,7 +44,7 @@ auto MakeBuiltinOperatorFunction(Context& context, SemIR::LocId loc_id, auto BuildTrivialDestroyWitness( Context& context, SemIR::LocId loc_id, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id) -> SemIR::InstId; + SemIR::SpecificInterface query_specific_interface) -> SemIR::InstId; // Given an interface, returns the corresponding enum if it's covered by // `CoreInterface`, or `Unknown` if it's some other interface. @@ -64,7 +64,7 @@ auto AsCoreIdentifier(SemIR::CoreInterface core_interface) -> CoreIdentifier; auto LookupCustomWitness(Context& context, SemIR::LocId loc_id, SemIR::CoreInterface core_interface, SemIR::ConstantId query_self_const_id, - SemIR::SpecificInterfaceId query_specific_interface_id, + SemIR::SpecificInterface query_specific_interface, bool build_witness) -> std::optional; } // namespace Carbon::Check diff --git a/toolchain/check/impl_lookup.cpp b/toolchain/check/impl_lookup.cpp index 4f5686fd9a63..4cf856d43117 100644 --- a/toolchain/check/impl_lookup.cpp +++ b/toolchain/check/impl_lookup.cpp @@ -889,19 +889,14 @@ static auto FindNonFinalWitness( } } - // TODO: Remove SpecificInterfaceId from LookupCustomWitness apis, switch to - // just SpecificInterface. - auto query_specific_interface_id = - context.specific_interfaces().Add(req_specific_interface); - // Consider a custom witness for core interfaces. // TODO: This needs to expand to more interfaces, and we might want to have // that dispatch in custom_witness.cpp instead of here. auto core_interface = GetCoreInterface(context, req_specific_interface.interface_id); - if (auto witness_id = LookupCustomWitness( - context, loc_id, core_interface, req_self_const_id, - query_specific_interface_id, false)) { + if (auto witness_id = LookupCustomWitness(context, loc_id, core_interface, + req_self_const_id, + req_specific_interface, false)) { // If there's a final witness, we would have already found it via evaluating // the LookupImplWitness instruction. CARBON_CHECK(!witness_id->has_value()); @@ -1275,7 +1270,7 @@ auto EvalLookupSingleFinalWitness(Context& context, SemIR::LocId loc_id, bool used_custom_witness = false; if (auto witness_inst_id = LookupCustomWitness( context, loc_id, core_interface, query_self_const_id, - eval_query.query_specific_interface_id, true)) { + query_specific_interface, true)) { if (witness_inst_id->has_value()) { lookup_result = {.witness_id = context.constant_values().Get(*witness_inst_id)}; @@ -1316,8 +1311,8 @@ auto EvalLookupSingleFinalWitness(Context& context, SemIR::LocId loc_id, // `impl` we may have found in Carbon. auto cpp_witness_id = LookupCppImpl( context, loc_id, core_interface, query_self_const_id, - eval_query.query_specific_interface_id, - lookup_result.impl_type_structure, lookup_result.impl_loc_id); + query_specific_interface, lookup_result.impl_type_structure, + lookup_result.impl_loc_id); if (cpp_witness_id.has_value()) { lookup_result = {.witness_id = context.constant_values().Get(cpp_witness_id)};