diff --git a/toolchain/check/BUILD b/toolchain/check/BUILD index 200845a08cb1..6232b9865792 100644 --- a/toolchain/check/BUILD +++ b/toolchain/check/BUILD @@ -33,6 +33,7 @@ cc_library( "impl.cpp", "impl_lookup.cpp", "impl_validation.cpp", + "implicit_type_impls.cpp", "import.cpp", "import_cpp.cpp", "import_ref.cpp", @@ -78,6 +79,7 @@ cc_library( "impl.h", "impl_lookup.h", "impl_validation.h", + "implicit_type_impls.h", "import.h", "import_cpp.h", "import_ref.h", diff --git a/toolchain/check/check.cpp b/toolchain/check/check.cpp index 3b0024c0be6e..3bfda9321b09 100644 --- a/toolchain/check/check.cpp +++ b/toolchain/check/check.cpp @@ -448,7 +448,7 @@ auto CheckParseTrees( check_index < static_cast(ready_to_check.size()); ++check_index) { auto* unit_info = ready_to_check[check_index]; CheckUnit(unit_info, &tree_and_subtrees_getters, fs, clang_invocation, - options.vlog_stream) + options.gen_implicit_type_impls, options.vlog_stream) .Run(); for (auto* incoming_import : unit_info->incoming_imports) { --incoming_import->imports_remaining; @@ -497,7 +497,7 @@ auto CheckParseTrees( for (auto& unit_info : unit_infos) { if (unit_info.imports_remaining > 0) { CheckUnit(&unit_info, &tree_and_subtrees_getters, fs, clang_invocation, - options.vlog_stream) + options.gen_implicit_type_impls, options.vlog_stream) .Run(); } } diff --git a/toolchain/check/check.h b/toolchain/check/check.h index a47d06d1a413..674cf5163030 100644 --- a/toolchain/check/check.h +++ b/toolchain/check/check.h @@ -40,6 +40,11 @@ struct CheckParseTreesOptions { // Whether to import the prelude. bool prelude_import = false; + // Whether to generate standard `impl`s for types, such as `Core.Destroy`. + // This only controls generation of the `impl`; code which expects the `impl` + // is expected to fail. + bool gen_implicit_type_impls = true; + // If set, enables verbose output. llvm::raw_ostream* vlog_stream = nullptr; diff --git a/toolchain/check/check_unit.cpp b/toolchain/check/check_unit.cpp index 112d8f8be6d3..b09b72b47be8 100644 --- a/toolchain/check/check_unit.cpp +++ b/toolchain/check/check_unit.cpp @@ -59,7 +59,7 @@ CheckUnit::CheckUnit( const Parse::GetTreeAndSubtreesStore* tree_and_subtrees_getters, llvm::IntrusiveRefCntPtr fs, std::shared_ptr clang_invocation, - llvm::raw_ostream* vlog_stream) + bool gen_implicit_type_impls, llvm::raw_ostream* vlog_stream) : unit_and_imports_(unit_and_imports), tree_and_subtrees_getter_(tree_and_subtrees_getters->Get( unit_and_imports->unit->sem_ir->check_ir_id())), @@ -68,9 +68,10 @@ CheckUnit::CheckUnit( clang_invocation_(std::move(clang_invocation)), emitter_(&unit_and_imports_->err_tracker, tree_and_subtrees_getters, unit_and_imports_->unit->sem_ir), - context_( - &emitter_, tree_and_subtrees_getter_, unit_and_imports_->unit->sem_ir, - GetImportedIRCount(unit_and_imports), total_ir_count_, vlog_stream) {} + context_(&emitter_, tree_and_subtrees_getter_, + unit_and_imports_->unit->sem_ir, + GetImportedIRCount(unit_and_imports), total_ir_count_, + gen_implicit_type_impls, vlog_stream) {} auto CheckUnit::Run() -> void { Timings::ScopedTiming timing(unit_and_imports_->unit->timings, "check"); diff --git a/toolchain/check/check_unit.h b/toolchain/check/check_unit.h index a753d5891cb5..a3622fbfae57 100644 --- a/toolchain/check/check_unit.h +++ b/toolchain/check/check_unit.h @@ -128,7 +128,7 @@ class CheckUnit { const Parse::GetTreeAndSubtreesStore* tree_and_subtrees_getters, llvm::IntrusiveRefCntPtr fs, std::shared_ptr clang_invocation, - llvm::raw_ostream* vlog_stream); + bool gen_implicit_type_impls, llvm::raw_ostream* vlog_stream); // Produces and checks the IR for the provided unit. auto Run() -> void; diff --git a/toolchain/check/class.cpp b/toolchain/check/class.cpp index 508e8d470d8e..2bb932a96cab 100644 --- a/toolchain/check/class.cpp +++ b/toolchain/check/class.cpp @@ -5,12 +5,23 @@ #include "toolchain/check/class.h" #include "toolchain/check/context.h" +#include "toolchain/check/convert.h" #include "toolchain/check/eval.h" #include "toolchain/check/function.h" +#include "toolchain/check/generic.h" +#include "toolchain/check/impl.h" #include "toolchain/check/import_ref.h" #include "toolchain/check/inst.h" +#include "toolchain/check/name_lookup.h" +#include "toolchain/check/name_ref.h" +#include "toolchain/check/pattern.h" +#include "toolchain/check/pattern_match.h" #include "toolchain/check/type.h" #include "toolchain/parse/node_ids.h" +#include "toolchain/sem_ir/builtin_function_kind.h" +#include "toolchain/sem_ir/function.h" +#include "toolchain/sem_ir/ids.h" +#include "toolchain/sem_ir/typed_insts.h" namespace Carbon::Check { diff --git a/toolchain/check/context.cpp b/toolchain/check/context.cpp index e160743c6114..e440e46cbee9 100644 --- a/toolchain/check/context.cpp +++ b/toolchain/check/context.cpp @@ -16,10 +16,11 @@ namespace Carbon::Check { Context::Context(DiagnosticEmitterBase* emitter, Parse::GetTreeAndSubtreesFn tree_and_subtrees_getter, SemIR::File* sem_ir, int imported_ir_count, int total_ir_count, - llvm::raw_ostream* vlog_stream) + bool gen_implicit_type_impls, llvm::raw_ostream* vlog_stream) : emitter_(emitter), tree_and_subtrees_getter_(tree_and_subtrees_getter), sem_ir_(sem_ir), + gen_implicit_type_impls_(gen_implicit_type_impls), vlog_stream_(vlog_stream), node_stack_(sem_ir->parse_tree(), vlog_stream), inst_block_stack_("inst_block_stack_", *sem_ir, vlog_stream), diff --git a/toolchain/check/context.h b/toolchain/check/context.h index b4ea5ce3c270..b44667645734 100644 --- a/toolchain/check/context.h +++ b/toolchain/check/context.h @@ -58,7 +58,8 @@ class Context { explicit Context(DiagnosticEmitterBase* emitter, Parse::GetTreeAndSubtreesFn tree_and_subtrees_getter, SemIR::File* sem_ir, int imported_ir_count, - int total_ir_count, llvm::raw_ostream* vlog_stream); + int total_ir_count, bool gen_implicit_type_impls, + llvm::raw_ostream* vlog_stream); // Marks an implementation TODO. Always returns false. auto TODO(SemIR::LocId loc_id, std::string label) -> bool; @@ -92,6 +93,8 @@ class Context { return parse_tree().tokens(); } + auto gen_implicit_type_impls() -> bool { return gen_implicit_type_impls_; } + auto vlog_stream() -> llvm::raw_ostream* { return vlog_stream_; } auto node_stack() -> NodeStack& { return node_stack_; } @@ -304,6 +307,10 @@ class Context { // The SemIR::File being added to. SemIR::File* sem_ir_; + // Whether to generate standard `impl`s for types, such as `Core.Destroy`; see + // `CheckParseTreesOptions`. + bool gen_implicit_type_impls_; + // Whether to print verbose output. llvm::raw_ostream* vlog_stream_; diff --git a/toolchain/check/handle_class.cpp b/toolchain/check/handle_class.cpp index d0f6f711c439..b5c85cea72b7 100644 --- a/toolchain/check/handle_class.cpp +++ b/toolchain/check/handle_class.cpp @@ -14,6 +14,8 @@ #include "toolchain/check/eval.h" #include "toolchain/check/generic.h" #include "toolchain/check/handle.h" +#include "toolchain/check/impl.h" +#include "toolchain/check/implicit_type_impls.h" #include "toolchain/check/import.h" #include "toolchain/check/import_ref.h" #include "toolchain/check/inst.h" @@ -565,6 +567,8 @@ auto HandleParseNode(Context& context, Parse::ClassDefinitionId node_id) auto class_id = context.node_stack().Pop(); + MakeClassDestroyImpl(context, class_id); + // The class type is now fully defined. Compute its object representation. ComputeClassObjectRepr(context, node_id, class_id, context.field_decls_stack().PeekArray(), diff --git a/toolchain/check/implicit_type_impls.cpp b/toolchain/check/implicit_type_impls.cpp new file mode 100644 index 000000000000..117d9b54c2d7 --- /dev/null +++ b/toolchain/check/implicit_type_impls.cpp @@ -0,0 +1,205 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "toolchain/check/implicit_type_impls.h" + +#include "toolchain/check/convert.h" +#include "toolchain/check/generic.h" +#include "toolchain/check/impl.h" +#include "toolchain/check/inst.h" +#include "toolchain/check/name_lookup.h" +#include "toolchain/check/name_ref.h" +#include "toolchain/check/pattern.h" +#include "toolchain/check/pattern_match.h" +#include "toolchain/check/type.h" +#include "toolchain/sem_ir/ids.h" + +namespace Carbon::Check { + +// Produces an `impl as ` declaration. The caller +// should inspect the resulting `impl` to ensure it's incomplete before +// proceeding to define it. +static auto TryDeclareImpl(Context& context, SemIR::LocId loc_id, + SemIR::NameScopeId parent_scope_id, + SemIR::TypeId self_type_id, + SemIR::InstId interface_id) + -> std::pair { + auto impl_decl_id = AddPlaceholderInst( + context, + SemIR::LocIdAndInst::UncheckedLoc( + loc_id, SemIR::ImplDecl{.impl_id = SemIR::ImplId::None, + .decl_block_id = SemIR::InstBlockId::Empty})); + + auto self_id = context.types().GetInstId(self_type_id); + auto constraint_id = ExprAsType(context, loc_id, interface_id).inst_id; + + SemIR::Impl impl = { + { + .name_id = SemIR::NameId::None, + .parent_scope_id = parent_scope_id, + .generic_id = SemIR::GenericId::None, + .first_param_node_id = Parse::NodeId::None, + .last_param_node_id = Parse::NodeId::None, + .pattern_block_id = SemIR::InstBlockId::None, + .implicit_param_patterns_id = SemIR::InstBlockId::None, + .param_patterns_id = SemIR::InstBlockId::None, + .is_extern = false, + .extern_library_id = SemIR::LibraryNameId::None, + .non_owning_decl_id = SemIR::InstId::None, + .first_owning_decl_id = impl_decl_id, + }, + { + .self_id = self_id, + .constraint_id = constraint_id, + .interface = + CheckConstraintIsInterface(context, impl_decl_id, constraint_id), + .is_final = true, + }}; + + StartGenericDecl(context); + return StartImplDecl(context, loc_id, + /*implicit_params_loc_id=*/SemIR::LocId::None, impl, + /*is_definition=*/true, /*extend_impl=*/std::nullopt); +} + +// Constructs the implicit params for the `Op` function. Returns the block and +// the `self` pattern. +static auto MakeImplicitParams(Context& context, SemIR::LocId loc_id) + -> std::pair { + BeginSubpattern(context); + + auto result = LookupUnqualifiedName(context, loc_id, SemIR::NameId::SelfType); + auto self_id = + BuildNameRef(context, loc_id, SemIR::NameId::SelfType, + result.scope_result.target_inst_id(), result.specific_id); + auto self_type_expr = ExprAsType(context, loc_id, self_id); + + SemIR::ExprRegionId type_expr_region_id = + EndSubpatternAsExpr(context, self_type_expr.inst_id); + + auto self_pattern_id = AddAddrSelfParamPattern( + context, loc_id, type_expr_region_id, self_type_expr.inst_id); + + auto implicit_param_patterns_id = + context.inst_blocks().Add({self_pattern_id}); + return {implicit_param_patterns_id, self_pattern_id}; +} + +// Defines the `Op` function for the `impl`. +static auto DeclareImplOpFunction(Context& context, SemIR::LocId loc_id, + const SemIR::Impl& impl) + -> std::pair { + StartGenericDecl(context); + + auto name_id = SemIR::NameId::ForIdentifier(context.identifiers().Add("Op")); + + context.inst_block_stack().Push(); + + context.pattern_block_stack().Push(); + auto [implicit_param_patterns_id, self_pattern_id] = + MakeImplicitParams(context, loc_id); + constexpr auto NoRegularParams = SemIR::InstBlockId::Empty; + constexpr auto NoReturnSlot = SemIR::InstId::None; + auto pattern_block_id = context.pattern_block_stack().Pop(); + + // Perform callee-side pattern matching to rebuild the parameter list. + auto call_params_id = CalleePatternMatch(context, implicit_param_patterns_id, + NoRegularParams, NoReturnSlot); + auto decl_block_id = context.inst_block_stack().Pop(); + + // Create the `FunctionDecl` instruction. + SemIR::FunctionDecl function_decl = {SemIR::TypeId::None, + SemIR::FunctionId::None, decl_block_id}; + auto decl_id = AddPlaceholderInst( + context, SemIR::LocIdAndInst::UncheckedLoc(loc_id, function_decl)); + auto generic_id = BuildGenericDecl(context, decl_id); + + // Create the `Function` object. + function_decl.function_id = context.functions().Add(SemIR::Function{ + { + .name_id = name_id, + .parent_scope_id = impl.scope_id, + .generic_id = generic_id, + .first_param_node_id = Parse::NodeId::None, + .last_param_node_id = Parse::NodeId::None, + .pattern_block_id = pattern_block_id, + .implicit_param_patterns_id = implicit_param_patterns_id, + .param_patterns_id = NoRegularParams, + .is_extern = false, + .extern_library_id = SemIR::LibraryNameId::None, + .non_owning_decl_id = SemIR::InstId::None, + .first_owning_decl_id = decl_id, + }, + { + .call_params_id = call_params_id, + .return_slot_pattern_id = NoReturnSlot, + .virtual_modifier = SemIR::FunctionFields::VirtualModifier::None, + .virtual_index = -1, + .self_param_id = self_pattern_id, + }}); + function_decl.type_id = + GetFunctionType(context, function_decl.function_id, + context.scope_stack().PeekSpecificId()); + ReplaceInstBeforeConstantUse(context, decl_id, function_decl); + context.name_scopes().AddRequiredName(impl.scope_id, name_id, decl_id); + + return {function_decl.function_id, decl_id}; +} + +auto MakeClassDestroyImpl(Context& context, SemIR::ClassId class_id) -> void { + if (!context.gen_implicit_type_impls()) { + return; + } + + // Identify the type and interface for implementation. + auto& class_info = context.classes().Get(class_id); + auto loc_id = context.insts().GetLocIdForDesugaring( + SemIR::LocId(class_info.latest_decl_id())); + + auto destroy_id = LookupNameInCore(context, loc_id, "Destroy"); + if (destroy_id == SemIR::ErrorInst::InstId) { + return; + } + + // Declare the `impl`. + auto [impl_id, impl_decl_id] = + TryDeclareImpl(context, loc_id, class_info.scope_id, + class_info.self_type_id, destroy_id); + auto& impl = context.impls().Get(impl_id); + if (impl.is_complete()) { + return; + } + + // Define the `impl`. + impl.definition_id = impl_decl_id; + impl.scope_id = context.name_scopes().Add(impl_decl_id, SemIR::NameId::None, + class_info.scope_id); + + context.scope_stack().PushForEntity( + impl_decl_id, impl.scope_id, + context.generics().GetSelfSpecific(impl.generic_id)); + StartGenericDefinition(context, impl.generic_id); + context.inst_block_stack().Push(); + + // Declare the `Op` function. + auto [fn_id, fn_decl_id] = DeclareImplOpFunction(context, loc_id, impl); + + // Define the `Op` function. + // TODO: Add an actual definition. + context.scope_stack().PushForFunctionBody(fn_decl_id); + auto& function = context.functions().Get(fn_id); + function.SetBuiltinFunction(SemIR::BuiltinFunctionKind::NoOp); + StartGenericDefinition(context, function.generic_id); + FinishGenericDefinition(context, function.generic_id); + context.scope_stack().Pop(); + + // Close the `impl` definition. + FinishImplWitness(context, impl_id); + impl.defined = true; + FinishGenericDefinition(context, impl.generic_id); + context.scope_stack().Pop(); + impl.body_block_id = context.inst_block_stack().Pop(); +} + +} // namespace Carbon::Check diff --git a/toolchain/check/implicit_type_impls.h b/toolchain/check/implicit_type_impls.h new file mode 100644 index 000000000000..c144838f103a --- /dev/null +++ b/toolchain/check/implicit_type_impls.h @@ -0,0 +1,18 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef CARBON_TOOLCHAIN_CHECK_IMPLICIT_TYPE_IMPLS_H_ +#define CARBON_TOOLCHAIN_CHECK_IMPLICIT_TYPE_IMPLS_H_ + +#include "toolchain/check/context.h" + +namespace Carbon::Check { + +// Constructs `impl as Destroy { ... }`, with appropriate implementation +// based on the `destroy` function and members. +auto MakeClassDestroyImpl(Context& context, SemIR::ClassId class_id) -> void; + +} // namespace Carbon::Check + +#endif // CARBON_TOOLCHAIN_CHECK_IMPLICIT_TYPE_IMPLS_H_ diff --git a/toolchain/check/import_cpp.cpp b/toolchain/check/import_cpp.cpp index d155fb71780f..d029eecc032b 100644 --- a/toolchain/check/import_cpp.cpp +++ b/toolchain/check/import_cpp.cpp @@ -1101,32 +1101,12 @@ static auto MakeImplicitParamPatternsBlockId( return SemIR::InstBlockId::None; } - if (addr_self) { - type_id = GetPointerType(context, type_inst_id); - } - - SemIR::InstId pattern_id = - // TODO: Fill in a location once available. - AddBindingPattern(context, SemIR::LocId::None, SemIR::NameId::SelfValue, - type_id, type_expr_region_id, /*is_generic*/ false, - /*is_template*/ false) - .pattern_id; - // TODO: Fill in a location once available. - pattern_id = AddPatternInst( - context, SemIR::LocId::None, - {.type_id = context.insts().Get(pattern_id).type_id(), - .subpattern_id = pattern_id, - .index = SemIR::CallParamIndex::None}); - - // If we're building `addr self: Self*`, do that now. - if (addr_self) { - // TODO: Fill in a location once available. - pattern_id = AddPatternInst( - context, SemIR::LocId::None, - {.type_id = GetPatternType(context, SemIR::AutoType::TypeId), - .inner_id = pattern_id}); - } + auto pattern_id = + addr_self ? AddAddrSelfParamPattern(context, SemIR::LocId::None, + type_expr_region_id, type_inst_id) + : AddSelfParamPattern(context, SemIR::LocId::None, + type_expr_region_id, type_id); return context.inst_blocks().Add({pattern_id}); } diff --git a/toolchain/check/pattern.cpp b/toolchain/check/pattern.cpp index c225b2238da3..7f5dbcd5769f 100644 --- a/toolchain/check/pattern.cpp +++ b/toolchain/check/pattern.cpp @@ -133,4 +133,33 @@ auto AddPatternVarStorage(Context& context, SemIR::InstBlockId pattern_block_id, } } +auto AddSelfParamPattern(Context& context, SemIR::LocId loc_id, + SemIR::ExprRegionId type_expr_region_id, + SemIR::TypeId type_id) -> SemIR::InstId { + SemIR::InstId pattern_id = + AddBindingPattern(context, loc_id, SemIR::NameId::SelfValue, type_id, + type_expr_region_id, /*is_generic=*/false, + /*is_template=*/false) + .pattern_id; + + pattern_id = AddPatternInst( + context, loc_id, + {.type_id = context.insts().Get(pattern_id).type_id(), + .subpattern_id = pattern_id, + .index = SemIR::CallParamIndex::None}); + + return pattern_id; +} + +auto AddAddrSelfParamPattern(Context& context, SemIR::LocId loc_id, + SemIR::ExprRegionId type_expr_region_id, + SemIR::TypeInstId type_inst_id) -> SemIR::InstId { + auto pattern_id = AddSelfParamPattern(context, loc_id, type_expr_region_id, + GetPointerType(context, type_inst_id)); + return AddPatternInst( + context, loc_id, + {.type_id = GetPatternType(context, SemIR::AutoType::TypeId), + .inner_id = pattern_id}); +} + } // namespace Carbon::Check diff --git a/toolchain/check/pattern.h b/toolchain/check/pattern.h index 6a0413ca4988..0719be6efff9 100644 --- a/toolchain/check/pattern.h +++ b/toolchain/check/pattern.h @@ -48,6 +48,19 @@ auto AddBindingPattern(Context& context, SemIR::LocId name_loc, auto AddPatternVarStorage(Context& context, SemIR::InstBlockId pattern_block_id, bool is_returned_var) -> void; +// Adds a `self` parameter pattern with the specified type information. This +// only sets up the binding pattern and type; callers are expected to add the +// returned instruction to appropriate blocks. This is used when generating +// functions, rather than processing a user-authored `self: Self`. +auto AddSelfParamPattern(Context& context, SemIR::LocId loc_id, + SemIR::ExprRegionId type_expr_region_id, + SemIR::TypeId type_id) -> SemIR::InstId; + +// As the above, but for `addr self: Self*`. +auto AddAddrSelfParamPattern(Context& context, SemIR::LocId loc_id, + SemIR::ExprRegionId type_expr_region_id, + SemIR::TypeInstId type_inst_id) -> SemIR::InstId; + } // namespace Carbon::Check #endif // CARBON_TOOLCHAIN_CHECK_PATTERN_H_ diff --git a/toolchain/check/testdata/array/basics.carbon b/toolchain/check/testdata/array/basics.carbon index 5a403ece24e8..c15e6d9cdc8d 100644 --- a/toolchain/check/testdata/array/basics.carbon +++ b/toolchain/check/testdata/array/basics.carbon @@ -169,10 +169,10 @@ var a: array(1, 1); // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %tuple.type.ff9: type = tuple_type (type, type, type) [concrete] // CHECK:STDOUT: %tuple.type.734: type = tuple_type (%C, %C, %C) [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: %array_type: type = array_type %int_2, %tuple.type.734 [concrete] diff --git a/toolchain/check/testdata/as/adapter_conversion.carbon b/toolchain/check/testdata/as/adapter_conversion.carbon index 7ebcb6b864f8..6c5b624aabfd 100644 --- a/toolchain/check/testdata/as/adapter_conversion.carbon +++ b/toolchain/check/testdata/as/adapter_conversion.carbon @@ -183,9 +183,9 @@ var b: B = {.x = ()} as B; // CHECK:STDOUT: %A.Make.type: type = fn_type @A.Make [concrete] // CHECK:STDOUT: %A.Make: %A.Make.type = struct_value () [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] -// CHECK:STDOUT: %pattern_type.049: type = pattern_type %B [concrete] // CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] // CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %pattern_type.049: type = pattern_type %B [concrete] // CHECK:STDOUT: %a_ref.var: ref %B = var file.%a_ref.var_patt [concrete] // CHECK:STDOUT: %addr: %ptr.e79 = addr_of %a_ref.var [concrete] // CHECK:STDOUT: } @@ -314,7 +314,7 @@ var b: B = {.x = ()} as B; // CHECK:STDOUT: constants { // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %D [concrete] +// CHECK:STDOUT: %pattern_type.510: type = pattern_type %D [concrete] // CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] // CHECK:STDOUT: %D.val: %D = struct_value () [concrete] // CHECK:STDOUT: } @@ -324,7 +324,7 @@ var b: B = {.x = ()} as B; // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %d.patt: %pattern_type = binding_pattern d [concrete] +// CHECK:STDOUT: %d.patt: %pattern_type.510 = binding_pattern d [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %D.ref: type = name_ref D, %D.decl [concrete = constants.%D] // CHECK:STDOUT: %d: %D = bind_name d, @__global_init.%.loc10_15.2 @@ -425,7 +425,7 @@ var b: B = {.x = ()} as B; // CHECK:STDOUT: %A: type = class_type @A [concrete] // CHECK:STDOUT: %tuple.type.c8c: type = tuple_type (%empty_struct_type, type) [concrete] // CHECK:STDOUT: %tuple.type.a10: type = tuple_type (%empty_struct_type, %Noncopyable) [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %A [concrete] +// CHECK:STDOUT: %pattern_type.c10: type = pattern_type %A [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -434,7 +434,7 @@ var b: B = {.x = ()} as B; // CHECK:STDOUT: fn @F(%a.param: %A) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %a_value.patt: %pattern_type = binding_pattern a_value [concrete] +// CHECK:STDOUT: %a_value.patt: %pattern_type.c10 = binding_pattern a_value [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %a.ref: %A = name_ref a, %a // CHECK:STDOUT: %.loc14_28: %empty_struct_type = struct_literal () diff --git a/toolchain/check/testdata/as/basics.carbon b/toolchain/check/testdata/as/basics.carbon index 04c2b79478fb..e8c49b6ed86a 100644 --- a/toolchain/check/testdata/as/basics.carbon +++ b/toolchain/check/testdata/as/basics.carbon @@ -203,15 +203,15 @@ let n: {.x: ()} = {.x = ()} as {.x = ()}; // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %X: type = class_type @X [concrete] -// CHECK:STDOUT: %Make.type: type = fn_type @Make [concrete] +// CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op.type: type = fn_type @X.as.Destroy.impl.Op [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op: %X.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %Make.type: type = fn_type @Make [concrete] // CHECK:STDOUT: %Make: %Make.type = struct_value () [concrete] // CHECK:STDOUT: %tuple.type.24b: type = tuple_type (type, type) [concrete] // CHECK:STDOUT: %tuple.type.b67: type = tuple_type (%X, %X) [concrete] // CHECK:STDOUT: %pattern_type.bb7: type = pattern_type %tuple.type.b67 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.9e1: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%X) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.33a: %T.as.Destroy.impl.Op.type.9e1 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.df3: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%tuple.type.b67) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.279: %T.as.Destroy.impl.Op.type.df3 = struct_value () [concrete] // CHECK:STDOUT: %ptr.120: type = ptr_type %tuple.type.b67 [concrete] @@ -249,16 +249,12 @@ let n: {.x: ()} = {.x = ()} as {.x = ()}; // CHECK:STDOUT: %tuple: %tuple.type.b67 = tuple_value (%.loc13_25.3, %.loc13_33.3) // CHECK:STDOUT: %.loc13_34.2: %tuple.type.b67 = converted %.loc13_34.1, %tuple // CHECK:STDOUT: %a: %tuple.type.b67 = bind_name a, %.loc13_34.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13_33: = bound_method %.loc13_33.1, constants.%T.as.Destroy.impl.Op.33a -// CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc13_33: = bound_method %.loc13_33.1, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %X.as.Destroy.impl.Op.bound.loc13_33: = bound_method %.loc13_33.1, constants.%X.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc13_33: %ptr.d17 = addr_of %.loc13_33.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc13_33: init %empty_tuple.type = call %bound_method.loc13_33(%addr.loc13_33) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13_25: = bound_method %.loc13_25.1, constants.%T.as.Destroy.impl.Op.33a -// CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc13_25: = bound_method %.loc13_25.1, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %X.as.Destroy.impl.Op.call.loc13_33: init %empty_tuple.type = call %X.as.Destroy.impl.Op.bound.loc13_33(%addr.loc13_33) +// CHECK:STDOUT: %X.as.Destroy.impl.Op.bound.loc13_25: = bound_method %.loc13_25.1, constants.%X.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc13_25: %ptr.d17 = addr_of %.loc13_25.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc13_25: init %empty_tuple.type = call %bound_method.loc13_25(%addr.loc13_25) +// CHECK:STDOUT: %X.as.Destroy.impl.Op.call.loc13_25: init %empty_tuple.type = call %X.as.Destroy.impl.Op.bound.loc13_25(%addr.loc13_25) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: @@ -290,21 +286,17 @@ let n: {.x: ()} = {.x = ()} as {.x = ()}; // CHECK:STDOUT: %.loc20_15.3: type = converted %.loc20_15.2, constants.%tuple.type.b67 [concrete = constants.%tuple.type.b67] // CHECK:STDOUT: } // CHECK:STDOUT: %b: ref %tuple.type.b67 = bind_name b, %b.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc20_34.1: = bound_method %tuple.elem1, constants.%T.as.Destroy.impl.Op.33a -// CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc20_34.1: = bound_method %tuple.elem1, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %X.as.Destroy.impl.Op.bound.loc20_34.1: = bound_method %tuple.elem1, constants.%X.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc20_34.1: %ptr.d17 = addr_of %tuple.elem1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc20_34.1: init %empty_tuple.type = call %bound_method.loc20_34.1(%addr.loc20_34.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc20_34.2: = bound_method %tuple.elem0, constants.%T.as.Destroy.impl.Op.33a -// CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc20_34.2: = bound_method %tuple.elem0, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %X.as.Destroy.impl.Op.call.loc20_34.1: init %empty_tuple.type = call %X.as.Destroy.impl.Op.bound.loc20_34.1(%addr.loc20_34.1) +// CHECK:STDOUT: %X.as.Destroy.impl.Op.bound.loc20_34.2: = bound_method %tuple.elem0, constants.%X.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc20_34.2: %ptr.d17 = addr_of %tuple.elem0 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc20_34.2: init %empty_tuple.type = call %bound_method.loc20_34.2(%addr.loc20_34.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc20_3: = bound_method %b.var, constants.%T.as.Destroy.impl.Op.279 +// CHECK:STDOUT: %X.as.Destroy.impl.Op.call.loc20_34.2: init %empty_tuple.type = call %X.as.Destroy.impl.Op.bound.loc20_34.2(%addr.loc20_34.2) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %b.var, constants.%T.as.Destroy.impl.Op.279 // CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc20_3: = bound_method %b.var, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %bound_method: = bound_method %b.var, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr.loc20_3: %ptr.120 = addr_of %b.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc20_3: init %empty_tuple.type = call %bound_method.loc20_3(%addr.loc20_3) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc20_3) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: @@ -312,14 +304,14 @@ let n: {.x: ()} = {.x = ()} as {.x = ()}; // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %X: type = class_type @X [concrete] -// CHECK:STDOUT: %pattern_type.019: type = pattern_type %X [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete] // CHECK:STDOUT: %pattern_type.1c6: type = pattern_type %ptr.d17 [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op.type: type = fn_type @X.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op: %X.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %pattern_type.019: type = pattern_type %X [concrete] // CHECK:STDOUT: %Make.type: type = fn_type @Make [concrete] // CHECK:STDOUT: %Make: %Make.type = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.9e1: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%X) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.33a: %T.as.Destroy.impl.Op.type.9e1 = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -368,16 +360,12 @@ let n: {.x: ()} = {.x = ()} as {.x = ()}; // CHECK:STDOUT: assign %x.var, %Make.call // CHECK:STDOUT: %X.ref.loc24_10: type = name_ref X, file.%X.decl [concrete = constants.%X] // CHECK:STDOUT: %x: ref %X = bind_name x, %x.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc24_3.1: = bound_method %.loc24, constants.%T.as.Destroy.impl.Op.33a -// CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc24_3.1: = bound_method %.loc24, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %X.as.Destroy.impl.Op.bound.loc24_3.1: = bound_method %.loc24, constants.%X.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc24_3.1: %ptr.d17 = addr_of %.loc24 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc24_3.1: init %empty_tuple.type = call %bound_method.loc24_3.1(%addr.loc24_3.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc24_3.2: = bound_method %x.var, constants.%T.as.Destroy.impl.Op.33a -// CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc24_3.2: = bound_method %x.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %X.as.Destroy.impl.Op.call.loc24_3.1: init %empty_tuple.type = call %X.as.Destroy.impl.Op.bound.loc24_3.1(%addr.loc24_3.1) +// CHECK:STDOUT: %X.as.Destroy.impl.Op.bound.loc24_3.2: = bound_method %x.var, constants.%X.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc24_3.2: %ptr.d17 = addr_of %x.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc24_3.2: init %empty_tuple.type = call %bound_method.loc24_3.2(%addr.loc24_3.2) +// CHECK:STDOUT: %X.as.Destroy.impl.Op.call.loc24_3.2: init %empty_tuple.type = call %X.as.Destroy.impl.Op.bound.loc24_3.2(%addr.loc24_3.2) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/basics/dump_sem_ir_ranges.carbon b/toolchain/check/testdata/basics/dump_sem_ir_ranges.carbon index 6abaaec11444..4d15f39394af 100644 --- a/toolchain/check/testdata/basics/dump_sem_ir_ranges.carbon +++ b/toolchain/check/testdata/basics/dump_sem_ir_ranges.carbon @@ -166,9 +166,17 @@ fn F(); // CHECK:STDOUT: %A: type = class_type @A [concrete] // CHECK:STDOUT: %A.G.type: type = fn_type @A.G [concrete] // CHECK:STDOUT: %A.G: %A.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %C.I.type: type = fn_type @C.I [concrete] // CHECK:STDOUT: %C.I: %C.I.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -178,6 +186,30 @@ fn F(); // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc17: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { // CHECK:STDOUT: // CHECK:STDOUT: %A.G.decl: %A.G.type = fn_decl @A.G [concrete = constants.%A.G] {} {} @@ -193,6 +225,10 @@ fn F(); // CHECK:STDOUT: class @C { // CHECK:STDOUT: %C.I.decl: %C.I.type = fn_decl @C.I [concrete = constants.%C.I] {} {} // CHECK:STDOUT: +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] +// CHECK:STDOUT: // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -203,8 +239,12 @@ fn F(); // CHECK:STDOUT: // CHECK:STDOUT: fn @A.G(); // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.I(); // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- call_params.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/builtins/int/convert_checked.carbon b/toolchain/check/testdata/builtins/int/convert_checked.carbon index 67acb1fc35f3..5f7bf1d9d91b 100644 --- a/toolchain/check/testdata/builtins/int/convert_checked.carbon +++ b/toolchain/check/testdata/builtins/int/convert_checked.carbon @@ -305,8 +305,8 @@ let convert_not_constant_widen: i64 = Int32ToInt64(not_constant); // CHECK:STDOUT: %Main.Int32ToUint32: %Int32ToUint32.type = import_ref Main//int_ops, Int32ToUint32, loaded [concrete = constants.%Int32ToUint32] // CHECK:STDOUT: %Main.Int32ToInt16: %Int32ToInt16.type = import_ref Main//int_ops, Int32ToInt16, loaded [concrete = constants.%Int32ToInt16] // CHECK:STDOUT: %Main.Int32ToInt64: %Int32ToInt64.type = import_ref Main//int_ops, Int32ToInt64, loaded [concrete = constants.%Int32ToInt64] -// CHECK:STDOUT: %Core.import_ref.a86: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.6d7)] -// CHECK:STDOUT: %ImplicitAs.impl_witness_table.e36 = impl_witness_table (%Core.import_ref.a86), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %Core.import_ref.a86c: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.6d7)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table.e36 = impl_witness_table (%Core.import_ref.a86c), @Core.IntLiteral.as.ImplicitAs.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { diff --git a/toolchain/check/testdata/class/access_modifers.carbon b/toolchain/check/testdata/class/access_modifers.carbon index 4a0a9094f0a1..e34a0bc7d746 100644 --- a/toolchain/check/testdata/class/access_modifers.carbon +++ b/toolchain/check/testdata/class/access_modifers.carbon @@ -166,6 +166,8 @@ class A { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -183,6 +185,11 @@ class A { // CHECK:STDOUT: %pattern_type.ce2: type = pattern_type %Circle [concrete] // CHECK:STDOUT: %Circle.Make.type: type = fn_type @Circle.Make [concrete] // CHECK:STDOUT: %Circle.Make: %Circle.Make.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.2a8: = impl_witness @Circle.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.54d: type = ptr_type %Circle [concrete] +// CHECK:STDOUT: %pattern_type.f32: type = pattern_type %ptr.54d [concrete] +// CHECK:STDOUT: %Circle.as.Destroy.impl.Op.type: type = fn_type @Circle.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Circle.as.Destroy.impl.Op: %Circle.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.radius.251: type = struct_type {.radius: %i32} [concrete] // CHECK:STDOUT: %complete_type.5a5: = complete_type_witness %struct_type.radius.251 [concrete] // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] @@ -193,11 +200,6 @@ class A { // CHECK:STDOUT: %Circle.val: %Circle = struct_value (%int_5.0f6) [concrete] // CHECK:STDOUT: %Run.type: type = fn_type @Run [concrete] // CHECK:STDOUT: %Run: %Run.type = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.6cf: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Circle) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.e38: %T.as.Destroy.impl.Op.type.6cf = struct_value () [concrete] -// CHECK:STDOUT: %ptr.54d: type = ptr_type %Circle [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.e38, @T.as.Destroy.impl.Op(%Circle) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -226,6 +228,22 @@ class A { // CHECK:STDOUT: %Run.decl: %Run.type = fn_decl @Run [concrete = constants.%Run] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Circle.as.Destroy.impl: constants.%Circle as constants.%Destroy.type { +// CHECK:STDOUT: %Circle.as.Destroy.impl.Op.decl: %Circle.as.Destroy.impl.Op.type = fn_decl @Circle.as.Destroy.impl.Op [concrete = constants.%Circle.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f32 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f32 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.54d = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Circle [concrete = constants.%Circle] +// CHECK:STDOUT: %self: %ptr.54d = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Circle.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Circle.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Circle { // CHECK:STDOUT: %int_32.loc5: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -263,6 +281,9 @@ class A { // CHECK:STDOUT: %return.param: ref %Circle = out_param call_param0 // CHECK:STDOUT: %return: ref %Circle = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Circle.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Circle.as.Destroy.impl.%Circle.as.Destroy.impl.Op.decl), @Circle.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.2a8] // CHECK:STDOUT: %struct_type.radius: type = struct_type {.radius: %i32} [concrete = constants.%struct_type.radius.251] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.radius [concrete = constants.%complete_type.5a5] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -305,6 +326,8 @@ class A { // CHECK:STDOUT: return %.loc13_25 to %return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Circle.as.Destroy.impl.Op(%self.param: %ptr.54d) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Run() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -336,11 +359,9 @@ class A { // CHECK:STDOUT: %SOME_INTERNAL_CONSTANT.ref: = name_ref SOME_INTERNAL_CONSTANT, [concrete = ] // CHECK:STDOUT: %circle.ref.loc51: %Circle = name_ref circle, %circle // CHECK:STDOUT: %SomeInternalFunction.ref: = name_ref SomeInternalFunction, [concrete = ] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc18_36.1, constants.%T.as.Destroy.impl.Op.e38 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.e38, @T.as.Destroy.impl.Op(constants.%Circle) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc18_36.1, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Circle.as.Destroy.impl.Op.bound: = bound_method %.loc18_36.1, constants.%Circle.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.54d = addr_of %.loc18_36.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %Circle.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Circle.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -353,6 +374,13 @@ class A { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %A.elem: type = unbound_element_type %A, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.x: type = struct_type {.x: %i32} [concrete] // CHECK:STDOUT: %complete_type.1ec: = complete_type_witness %struct_type.x [concrete] // CHECK:STDOUT: %Run.type: type = fn_type @Run [concrete] @@ -363,10 +391,12 @@ class A { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -380,10 +410,29 @@ class A { // CHECK:STDOUT: %Run.decl: %Run.type = fn_decl @Run [concrete = constants.%Run] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc5: %A.elem = field_decl x, element0 [concrete] +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %struct_type.x: type = struct_type {.x: %i32} [concrete = constants.%struct_type.x] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.x [concrete = constants.%complete_type.1ec] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -393,6 +442,8 @@ class A { // CHECK:STDOUT: .x [protected] = %.loc5 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Run() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -425,6 +476,13 @@ class A { // CHECK:STDOUT: %Circle.SomeInternalFunction: %Circle.SomeInternalFunction.type = struct_value () [concrete] // CHECK:STDOUT: %Circle.Compute.type: type = fn_type @Circle.Compute [concrete] // CHECK:STDOUT: %Circle.Compute: %Circle.Compute.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.2a8: = impl_witness @Circle.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.54d: type = ptr_type %Circle [concrete] +// CHECK:STDOUT: %pattern_type.f32: type = pattern_type %ptr.54d [concrete] +// CHECK:STDOUT: %Circle.as.Destroy.impl.Op.type: type = fn_type @Circle.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Circle.as.Destroy.impl.Op: %Circle.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.radius: type = struct_type {.radius: %i32} [concrete] // CHECK:STDOUT: %complete_type.5a5: = complete_type_witness %struct_type.radius [concrete] // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] @@ -449,11 +507,13 @@ class A { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -468,6 +528,22 @@ class A { // CHECK:STDOUT: %Circle.decl: type = class_decl @Circle [concrete = constants.%Circle] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Circle.as.Destroy.impl: constants.%Circle as constants.%Destroy.type { +// CHECK:STDOUT: %Circle.as.Destroy.impl.Op.decl: %Circle.as.Destroy.impl.Op.type = fn_decl @Circle.as.Destroy.impl.Op [concrete = constants.%Circle.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f32 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f32 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.54d = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Circle [concrete = constants.%Circle] +// CHECK:STDOUT: %self: %ptr.54d = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Circle.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Circle.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Circle { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -509,6 +585,9 @@ class A { // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Circle.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Circle.as.Destroy.impl.%Circle.as.Destroy.impl.Op.decl), @Circle.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.2a8] // CHECK:STDOUT: %struct_type.radius: type = struct_type {.radius: %i32} [concrete = constants.%struct_type.radius] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.radius [concrete = constants.%complete_type.5a5] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -553,6 +632,8 @@ class A { // CHECK:STDOUT: return %.loc16_39.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Circle.as.Destroy.impl.Op(%self.param: %ptr.54d) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- public_global_access.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -567,6 +648,8 @@ class A { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -579,6 +662,11 @@ class A { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.956, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] // CHECK:STDOUT: %bound_method: = bound_method %int_5.64b, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_5.0f6: %i32 = int_value 5 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } @@ -587,6 +675,7 @@ class A { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -594,6 +683,7 @@ class A { // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -614,6 +704,22 @@ class A { // CHECK:STDOUT: %x: %i32 = bind_name x, @__global_init.%x.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %x.patt: %pattern_type.7ce = binding_pattern x [concrete] @@ -631,6 +737,9 @@ class A { // CHECK:STDOUT: %.loc5_16.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_5.0f6] // CHECK:STDOUT: %.loc5_16.2: %i32 = converted %int_5, %.loc5_16.1 [concrete = constants.%int_5.0f6] // CHECK:STDOUT: %x: %i32 = bind_name x, %.loc5_16.2 +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -640,6 +749,8 @@ class A { // CHECK:STDOUT: .x = %x // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A] @@ -661,6 +772,8 @@ class A { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -673,6 +786,11 @@ class A { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.956, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] // CHECK:STDOUT: %bound_method: = bound_method %int_5.64b, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_5.0f6: %i32 = int_value 5 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } @@ -681,6 +799,7 @@ class A { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -688,6 +807,7 @@ class A { // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -717,6 +837,22 @@ class A { // CHECK:STDOUT: %y: %i32 = bind_name y, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %x.patt: %pattern_type.7ce = binding_pattern x [concrete] @@ -750,6 +886,9 @@ class A { // CHECK:STDOUT: %.loc6_24.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6 [concrete = constants.%int_5.0f6] // CHECK:STDOUT: %.loc6_24.2: %i32 = converted %int_5.loc6, %.loc6_24.1 [concrete = constants.%int_5.0f6] // CHECK:STDOUT: %y: %i32 = bind_name y, %.loc6_24.2 +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -760,6 +899,8 @@ class A { // CHECK:STDOUT: .y [private] = %y // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %A.ref.loc16: type = name_ref A, file.%A.decl [concrete = constants.%A] @@ -778,15 +919,24 @@ class A { // CHECK:STDOUT: %A.F: %A.F.type = struct_value () [concrete] // CHECK:STDOUT: %A.G.type: type = fn_type @A.G [concrete] // CHECK:STDOUT: %A.G: %A.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -798,9 +948,28 @@ class A { // CHECK:STDOUT: %A.decl: type = class_decl @A [concrete = constants.%A] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { // CHECK:STDOUT: %A.F.decl: %A.F.type = fn_decl @A.F [concrete = constants.%A.F] {} {} // CHECK:STDOUT: %A.G.decl: %A.G.type = fn_decl @A.G [concrete = constants.%A.G] {} {} +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -824,3 +993,5 @@ class A { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/adapter/adapt.carbon b/toolchain/check/testdata/class/adapter/adapt.carbon index 9692edcc0997..24b876d1c676 100644 --- a/toolchain/check/testdata/class/adapter/adapt.carbon +++ b/toolchain/check/testdata/class/adapter/adapt.carbon @@ -77,19 +77,38 @@ interface I { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %SomeClass.elem: type = unbound_element_type %SomeClass, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ab1: = impl_witness @SomeClass.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.c8a: type = ptr_type %SomeClass [concrete] +// CHECK:STDOUT: %pattern_type.a47: type = pattern_type %ptr.c8a [concrete] +// CHECK:STDOUT: %SomeClass.as.Destroy.impl.Op.type: type = fn_type @SomeClass.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %SomeClass.as.Destroy.impl.Op: %SomeClass.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete] // CHECK:STDOUT: %complete_type.705: = complete_type_witness %struct_type.a.b [concrete] // CHECK:STDOUT: %SomeClassAdapter: type = class_type @SomeClassAdapter [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.84c: = impl_witness @SomeClassAdapter.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.b51: type = ptr_type %SomeClassAdapter [concrete] +// CHECK:STDOUT: %pattern_type.76d: type = pattern_type %ptr.b51 [concrete] +// CHECK:STDOUT: %SomeClassAdapter.as.Destroy.impl.Op.type: type = fn_type @SomeClassAdapter.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %SomeClassAdapter.as.Destroy.impl.Op: %SomeClassAdapter.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %StructAdapter: type = class_type @StructAdapter [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.6e0: = impl_witness @StructAdapter.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.670: type = ptr_type %StructAdapter [concrete] +// CHECK:STDOUT: %pattern_type.671: type = pattern_type %ptr.670 [concrete] +// CHECK:STDOUT: %StructAdapter.as.Destroy.impl.Op.type: type = fn_type @StructAdapter.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %StructAdapter.as.Destroy.impl.Op: %StructAdapter.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -105,6 +124,54 @@ interface I { // CHECK:STDOUT: %StructAdapter.decl: type = class_decl @StructAdapter [concrete = constants.%StructAdapter] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @SomeClass.as.Destroy.impl: constants.%SomeClass as constants.%Destroy.type { +// CHECK:STDOUT: %SomeClass.as.Destroy.impl.Op.decl: %SomeClass.as.Destroy.impl.Op.type = fn_decl @SomeClass.as.Destroy.impl.Op [concrete = constants.%SomeClass.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a47 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a47 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.c8a = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SomeClass [concrete = constants.%SomeClass] +// CHECK:STDOUT: %self: %ptr.c8a = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %SomeClass.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @SomeClass.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @SomeClassAdapter.as.Destroy.impl: constants.%SomeClassAdapter as constants.%Destroy.type { +// CHECK:STDOUT: %SomeClassAdapter.as.Destroy.impl.Op.decl: %SomeClassAdapter.as.Destroy.impl.Op.type = fn_decl @SomeClassAdapter.as.Destroy.impl.Op [concrete = constants.%SomeClassAdapter.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.76d = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.76d = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.b51 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SomeClassAdapter [concrete = constants.%SomeClassAdapter] +// CHECK:STDOUT: %self: %ptr.b51 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %SomeClassAdapter.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @SomeClassAdapter.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @StructAdapter.as.Destroy.impl: constants.%StructAdapter as constants.%Destroy.type { +// CHECK:STDOUT: %StructAdapter.as.Destroy.impl.Op.decl: %StructAdapter.as.Destroy.impl.Op.type = fn_decl @StructAdapter.as.Destroy.impl.Op [concrete = constants.%StructAdapter.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.671 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.671 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc13: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.670 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%StructAdapter [concrete = constants.%StructAdapter] +// CHECK:STDOUT: %self: %ptr.670 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %StructAdapter.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @StructAdapter.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @SomeClass { // CHECK:STDOUT: %int_32.loc5: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -112,6 +179,9 @@ interface I { // CHECK:STDOUT: %int_32.loc6: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc6: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc6: %SomeClass.elem = field_decl b, element1 [concrete] +// CHECK:STDOUT: impl_decl @SomeClass.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@SomeClass.as.Destroy.impl.%SomeClass.as.Destroy.impl.Op.decl), @SomeClass.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ab1] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete = constants.%struct_type.a.b] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a.b [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -125,6 +195,9 @@ interface I { // CHECK:STDOUT: class @SomeClassAdapter { // CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [concrete = constants.%SomeClass] // CHECK:STDOUT: adapt_decl %SomeClass.ref [concrete] +// CHECK:STDOUT: impl_decl @SomeClassAdapter.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@SomeClassAdapter.as.Destroy.impl.%SomeClassAdapter.as.Destroy.impl.Op.decl), @SomeClassAdapter.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.84c] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.a.b [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -140,6 +213,9 @@ interface I { // CHECK:STDOUT: %i32.loc14_23: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete = constants.%struct_type.a.b] // CHECK:STDOUT: adapt_decl %struct_type.a.b [concrete] +// CHECK:STDOUT: impl_decl @StructAdapter.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@StructAdapter.as.Destroy.impl.%StructAdapter.as.Destroy.impl.Op.decl), @StructAdapter.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.6e0] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.a.b [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -147,25 +223,45 @@ interface I { // CHECK:STDOUT: .Self = constants.%StructAdapter // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @SomeClass.as.Destroy.impl.Op(%self.param: %ptr.c8a) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @SomeClassAdapter.as.Destroy.impl.Op(%self.param: %ptr.b51) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @StructAdapter.as.Destroy.impl.Op(%self.param: %ptr.670) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_not_extend.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Adapted: type = class_type @Adapted [concrete] // CHECK:STDOUT: %Adapted.F.type: type = fn_type @Adapted.F [concrete] // CHECK:STDOUT: %Adapted.F: %Adapted.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d23: = impl_witness @Adapted.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.08d: type = ptr_type %Adapted [concrete] +// CHECK:STDOUT: %pattern_type.c04: type = pattern_type %ptr.08d [concrete] +// CHECK:STDOUT: %Adapted.as.Destroy.impl.Op.type: type = fn_type @Adapted.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Adapted.as.Destroy.impl.Op: %Adapted.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %AdaptNotExtend: type = class_type @AdaptNotExtend [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %AdaptNotExtend [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.f9b: = impl_witness @AdaptNotExtend.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.ae9: type = ptr_type %AdaptNotExtend [concrete] +// CHECK:STDOUT: %pattern_type.73e: type = pattern_type %ptr.ae9 [concrete] +// CHECK:STDOUT: %AdaptNotExtend.as.Destroy.impl.Op.type: type = fn_type @AdaptNotExtend.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %AdaptNotExtend.as.Destroy.impl.Op: %AdaptNotExtend.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %pattern_type.893: type = pattern_type %AdaptNotExtend [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -179,8 +275,8 @@ interface I { // CHECK:STDOUT: %Adapted.decl: type = class_decl @Adapted [concrete = constants.%Adapted] {} {} // CHECK:STDOUT: %AdaptNotExtend.decl: type = class_decl @AdaptNotExtend [concrete = constants.%AdaptNotExtend] {} {} // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %a.patt: %pattern_type = binding_pattern a [concrete] -// CHECK:STDOUT: %a.param_patt: %pattern_type = value_param_pattern %a.patt, call_param0 [concrete] +// CHECK:STDOUT: %a.patt: %pattern_type.893 = binding_pattern a [concrete] +// CHECK:STDOUT: %a.param_patt: %pattern_type.893 = value_param_pattern %a.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %a.param: %AdaptNotExtend = value_param call_param0 // CHECK:STDOUT: %AdaptNotExtend.ref: type = name_ref AdaptNotExtend, file.%AdaptNotExtend.decl [concrete = constants.%AdaptNotExtend] @@ -188,8 +284,43 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Adapted.as.Destroy.impl: constants.%Adapted as constants.%Destroy.type { +// CHECK:STDOUT: %Adapted.as.Destroy.impl.Op.decl: %Adapted.as.Destroy.impl.Op.type = fn_decl @Adapted.as.Destroy.impl.Op [concrete = constants.%Adapted.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.c04 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.c04 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.08d = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Adapted [concrete = constants.%Adapted] +// CHECK:STDOUT: %self: %ptr.08d = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Adapted.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Adapted.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @AdaptNotExtend.as.Destroy.impl: constants.%AdaptNotExtend as constants.%Destroy.type { +// CHECK:STDOUT: %AdaptNotExtend.as.Destroy.impl.Op.decl: %AdaptNotExtend.as.Destroy.impl.Op.type = fn_decl @AdaptNotExtend.as.Destroy.impl.Op [concrete = constants.%AdaptNotExtend.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.73e = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.73e = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.ae9 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AdaptNotExtend [concrete = constants.%AdaptNotExtend] +// CHECK:STDOUT: %self: %ptr.ae9 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %AdaptNotExtend.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @AdaptNotExtend.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Adapted { // CHECK:STDOUT: %Adapted.F.decl: %Adapted.F.type = fn_decl @Adapted.F [concrete = constants.%Adapted.F] {} {} +// CHECK:STDOUT: impl_decl @Adapted.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Adapted.as.Destroy.impl.%Adapted.as.Destroy.impl.Op.decl), @Adapted.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.d23] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -202,6 +333,9 @@ interface I { // CHECK:STDOUT: class @AdaptNotExtend { // CHECK:STDOUT: %Adapted.ref: type = name_ref Adapted, file.%Adapted.decl [concrete = constants.%Adapted] // CHECK:STDOUT: adapt_decl %Adapted.ref [concrete] +// CHECK:STDOUT: impl_decl @AdaptNotExtend.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@AdaptNotExtend.as.Destroy.impl.%AdaptNotExtend.as.Destroy.impl.Op.decl), @AdaptNotExtend.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.f9b] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -213,6 +347,10 @@ interface I { // CHECK:STDOUT: // CHECK:STDOUT: fn @Adapted.F(); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Adapted.as.Destroy.impl.Op(%self.param: %ptr.08d) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @AdaptNotExtend.as.Destroy.impl.Op(%self.param: %ptr.ae9) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%a.param: %AdaptNotExtend) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %AdaptNotExtend = name_ref a, %a diff --git a/toolchain/check/testdata/class/adapter/adapt_copy.carbon b/toolchain/check/testdata/class/adapter/adapt_copy.carbon index b629ee458cae..ac8d5fd8365f 100644 --- a/toolchain/check/testdata/class/adapter/adapt_copy.carbon +++ b/toolchain/check/testdata/class/adapter/adapt_copy.carbon @@ -135,14 +135,16 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete] // CHECK:STDOUT: %complete_type.f8a: = complete_type_witness %i32.builtin [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9b5: = impl_witness @AdaptCopyable.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.4c1: type = ptr_type %AdaptCopyable [concrete] +// CHECK:STDOUT: %pattern_type.2d8: type = pattern_type %ptr.4c1 [concrete] +// CHECK:STDOUT: %AdaptCopyable.as.Destroy.impl.Op.type: type = fn_type @AdaptCopyable.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %AdaptCopyable.as.Destroy.impl.Op: %AdaptCopyable.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.cdf: type = pattern_type %AdaptCopyable [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.b65: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%AdaptCopyable) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.f60: %T.as.Destroy.impl.Op.type.b65 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.4c1: type = ptr_type %AdaptCopyable [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.e4c: = specific_function %T.as.Destroy.impl.Op.f60, @T.as.Destroy.impl.Op(%AdaptCopyable) [concrete] // CHECK:STDOUT: %UInt.type: type = generic_class_type @UInt [concrete] // CHECK:STDOUT: %UInt.generic: %UInt.type = struct_value () [concrete] // CHECK:STDOUT: %u32: type = class_type @UInt, @UInt(%int_32) [concrete] @@ -154,7 +156,7 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %ptr.c30: type = ptr_type %tuple.type.2a3 [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.f33: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%tuple.type.2a3) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.f7d: %T.as.Destroy.impl.Op.type.f33 = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2af: = specific_function %T.as.Destroy.impl.Op.f7d, @T.as.Destroy.impl.Op(%tuple.type.2a3) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.f7d, @T.as.Destroy.impl.Op(%tuple.type.2a3) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -217,10 +219,29 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @AdaptCopyable.as.Destroy.impl: constants.%AdaptCopyable as constants.%Destroy.type { +// CHECK:STDOUT: %AdaptCopyable.as.Destroy.impl.Op.decl: %AdaptCopyable.as.Destroy.impl.Op.type = fn_decl @AdaptCopyable.as.Destroy.impl.Op [concrete = constants.%AdaptCopyable.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.2d8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.2d8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.4c1 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AdaptCopyable [concrete = constants.%AdaptCopyable] +// CHECK:STDOUT: %self: %ptr.4c1 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %AdaptCopyable.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @AdaptCopyable.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @AdaptCopyable { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: adapt_decl %i32 [concrete] +// CHECK:STDOUT: impl_decl @AdaptCopyable.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@AdaptCopyable.as.Destroy.impl.%AdaptCopyable.as.Destroy.impl.Op.decl), @AdaptCopyable.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.9b5] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%i32.builtin [concrete = constants.%complete_type.f8a] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -228,6 +249,8 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: .Self = constants.%AdaptCopyable // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @AdaptCopyable.as.Destroy.impl.Op(%self.param: %ptr.4c1) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%c.param: %AdaptCopyable) -> %AdaptCopyable { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -241,11 +264,9 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %d: ref %AdaptCopyable = bind_name d, %d.var // CHECK:STDOUT: %d.ref: ref %AdaptCopyable = name_ref d, %d // CHECK:STDOUT: %.loc12: %AdaptCopyable = bind_value %d.ref -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %d.var, constants.%T.as.Destroy.impl.Op.f60 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.f60, @T.as.Destroy.impl.Op(constants.%AdaptCopyable) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.e4c] -// CHECK:STDOUT: %bound_method: = bound_method %d.var, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %AdaptCopyable.as.Destroy.impl.Op.bound: = bound_method %d.var, constants.%AdaptCopyable.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.4c1 = addr_of %d.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %AdaptCopyable.as.Destroy.impl.Op.call: init %empty_tuple.type = call %AdaptCopyable.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %.loc12 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -286,7 +307,7 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %.loc17_10.5: init %tuple.type.2a3 = tuple_init (%.loc17_10.2, %.loc17_10.4) to %return // CHECK:STDOUT: %.loc17_11: init %tuple.type.2a3 = converted %d.ref, %.loc17_10.5 // CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %d.var, constants.%T.as.Destroy.impl.Op.f7d -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.f7d, @T.as.Destroy.impl.Op(constants.%tuple.type.2a3) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.2af] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.f7d, @T.as.Destroy.impl.Op(constants.%tuple.type.2a3) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method: = bound_method %d.var, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr: %ptr.c30 = addr_of %d.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) @@ -304,15 +325,17 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %tuple.type.24b: type = tuple_type (type, type) [concrete] // CHECK:STDOUT: %tuple.type.d07: type = tuple_type (%i32, %i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.116: = impl_witness @AdaptTuple.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.ca3: type = ptr_type %AdaptTuple [concrete] +// CHECK:STDOUT: %pattern_type.0d9: type = pattern_type %ptr.ca3 [concrete] +// CHECK:STDOUT: %AdaptTuple.as.Destroy.impl.Op.type: type = fn_type @AdaptTuple.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %AdaptTuple.as.Destroy.impl.Op: %AdaptTuple.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %complete_type.65d: = complete_type_witness %tuple.type.d07 [concrete] // CHECK:STDOUT: %pattern_type.562: type = pattern_type %AdaptTuple [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.0f1: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%AdaptTuple) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.621: %T.as.Destroy.impl.Op.type.0f1 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.ca3: type = ptr_type %AdaptTuple [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.283: = specific_function %T.as.Destroy.impl.Op.621, @T.as.Destroy.impl.Op(%AdaptTuple) [concrete] // CHECK:STDOUT: %UInt.type: type = generic_class_type @UInt [concrete] // CHECK:STDOUT: %UInt.generic: %UInt.type = struct_value () [concrete] // CHECK:STDOUT: %u32: type = class_type @UInt, @UInt(%int_32) [concrete] @@ -323,7 +346,7 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.390: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%tuple.type.f69) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.d9f: %T.as.Destroy.impl.Op.type.390 = struct_value () [concrete] // CHECK:STDOUT: %ptr.ed5: type = ptr_type %tuple.type.f69 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.20d: = specific_function %T.as.Destroy.impl.Op.d9f, @T.as.Destroy.impl.Op(%tuple.type.f69) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.d9f, @T.as.Destroy.impl.Op(%tuple.type.f69) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -386,6 +409,22 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @AdaptTuple.as.Destroy.impl: constants.%AdaptTuple as constants.%Destroy.type { +// CHECK:STDOUT: %AdaptTuple.as.Destroy.impl.Op.decl: %AdaptTuple.as.Destroy.impl.Op.type = fn_decl @AdaptTuple.as.Destroy.impl.Op [concrete = constants.%AdaptTuple.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.0d9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.0d9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.ca3 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AdaptTuple [concrete = constants.%AdaptTuple] +// CHECK:STDOUT: %self: %ptr.ca3 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %AdaptTuple.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @AdaptTuple.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @AdaptTuple { // CHECK:STDOUT: %int_32.loc5_10: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5_10: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -394,6 +433,9 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %.loc5_18: %tuple.type.24b = tuple_literal (%i32.loc5_10, %i32.loc5_15) // CHECK:STDOUT: %.loc5_19: type = converted %.loc5_18, constants.%tuple.type.d07 [concrete = constants.%tuple.type.d07] // CHECK:STDOUT: adapt_decl %.loc5_19 [concrete] +// CHECK:STDOUT: impl_decl @AdaptTuple.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@AdaptTuple.as.Destroy.impl.%AdaptTuple.as.Destroy.impl.Op.decl), @AdaptTuple.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.116] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%tuple.type.d07 [concrete = constants.%complete_type.65d] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -401,6 +443,8 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: .Self = constants.%AdaptTuple // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @AdaptTuple.as.Destroy.impl.Op(%self.param: %ptr.ca3) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%c.param: %AdaptTuple) -> %return.param: %AdaptTuple { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -437,11 +481,9 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %.loc10_11.7: init %tuple.type.d07 = tuple_init (%.loc10_11.4, %.loc10_11.6) to %.loc10_11.3 // CHECK:STDOUT: %.loc10_11.8: init %AdaptTuple = as_compatible %.loc10_11.7 // CHECK:STDOUT: %.loc10_11.9: init %AdaptTuple = converted %d.ref, %.loc10_11.8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %d.var, constants.%T.as.Destroy.impl.Op.621 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.621, @T.as.Destroy.impl.Op(constants.%AdaptTuple) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.283] -// CHECK:STDOUT: %bound_method: = bound_method %d.var, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %AdaptTuple.as.Destroy.impl.Op.bound: = bound_method %d.var, constants.%AdaptTuple.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.ca3 = addr_of %d.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %AdaptTuple.as.Destroy.impl.Op.call: init %empty_tuple.type = call %AdaptTuple.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %.loc10_11.9 to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -503,7 +545,7 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %.loc15_10.12: init %tuple.type.f69 = tuple_init (%.loc15_10.9, %.loc15_10.11) to %return // CHECK:STDOUT: %.loc15_11: init %tuple.type.f69 = converted %d.ref, %.loc15_10.12 // CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %d.var, constants.%T.as.Destroy.impl.Op.d9f -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d9f, @T.as.Destroy.impl.Op(constants.%tuple.type.f69) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.20d] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d9f, @T.as.Destroy.impl.Op(constants.%tuple.type.f69) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method: = bound_method %d.var, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr: %ptr.ed5 = addr_of %d.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) @@ -514,18 +556,25 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Noncopyable: type = class_type @Noncopyable [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %AdaptNoncopyable: type = class_type @AdaptNoncopyable [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.004: = impl_witness @Noncopyable.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6f4: type = ptr_type %Noncopyable [concrete] +// CHECK:STDOUT: %pattern_type.e38: type = pattern_type %ptr.6f4 [concrete] +// CHECK:STDOUT: %Noncopyable.as.Destroy.impl.Op.type: type = fn_type @Noncopyable.as.Destroy.impl.Op [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Noncopyable.as.Destroy.impl.Op: %Noncopyable.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %AdaptNoncopyable: type = class_type @AdaptNoncopyable [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d88: = impl_witness @AdaptNoncopyable.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.ed9: type = ptr_type %AdaptNoncopyable [concrete] +// CHECK:STDOUT: %pattern_type.ea1: type = pattern_type %ptr.ed9 [concrete] +// CHECK:STDOUT: %AdaptNoncopyable.as.Destroy.impl.Op.type: type = fn_type @AdaptNoncopyable.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %AdaptNoncopyable.as.Destroy.impl.Op: %AdaptNoncopyable.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.8f9: type = pattern_type %AdaptNoncopyable [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.b79: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%AdaptNoncopyable) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.77f: %T.as.Destroy.impl.Op.type.b79 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.ed9: type = ptr_type %AdaptNoncopyable [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.77f, @T.as.Destroy.impl.Op(%AdaptNoncopyable) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -562,9 +611,44 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Noncopyable.as.Destroy.impl: constants.%Noncopyable as constants.%Destroy.type { +// CHECK:STDOUT: %Noncopyable.as.Destroy.impl.Op.decl: %Noncopyable.as.Destroy.impl.Op.type = fn_decl @Noncopyable.as.Destroy.impl.Op [concrete = constants.%Noncopyable.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.e38 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.e38 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6f4 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Noncopyable [concrete = constants.%Noncopyable] +// CHECK:STDOUT: %self: %ptr.6f4 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Noncopyable.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Noncopyable.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @AdaptNoncopyable.as.Destroy.impl: constants.%AdaptNoncopyable as constants.%Destroy.type { +// CHECK:STDOUT: %AdaptNoncopyable.as.Destroy.impl.Op.decl: %AdaptNoncopyable.as.Destroy.impl.Op.type = fn_decl @AdaptNoncopyable.as.Destroy.impl.Op [concrete = constants.%AdaptNoncopyable.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.ea1 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.ea1 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.ed9 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AdaptNoncopyable [concrete = constants.%AdaptNoncopyable] +// CHECK:STDOUT: %self: %ptr.ed9 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %AdaptNoncopyable.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @AdaptNoncopyable.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Noncopyable { +// CHECK:STDOUT: impl_decl @Noncopyable.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Noncopyable.as.Destroy.impl.%Noncopyable.as.Destroy.impl.Op.decl), @Noncopyable.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.004] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -574,7 +658,10 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: class @AdaptNoncopyable { // CHECK:STDOUT: %Noncopyable.ref: type = name_ref Noncopyable, file.%Noncopyable.decl [concrete = constants.%Noncopyable] // CHECK:STDOUT: adapt_decl %Noncopyable.ref [concrete] -// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: impl_decl @AdaptNoncopyable.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@AdaptNoncopyable.as.Destroy.impl.%AdaptNoncopyable.as.Destroy.impl.Op.decl), @AdaptNoncopyable.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.d88] +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -582,6 +669,10 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: .Noncopyable = // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Noncopyable.as.Destroy.impl.Op(%self.param: %ptr.6f4) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @AdaptNoncopyable.as.Destroy.impl.Op(%self.param: %ptr.ed9) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @G(%a.param: %AdaptNoncopyable) -> %return.param: %AdaptNoncopyable { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -595,11 +686,9 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %b: ref %AdaptNoncopyable = bind_name b, %b.var // CHECK:STDOUT: %b.ref: ref %AdaptNoncopyable = name_ref b, %b // CHECK:STDOUT: %.loc22: %AdaptNoncopyable = bind_value %b.ref -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %b.var, constants.%T.as.Destroy.impl.Op.77f -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.77f, @T.as.Destroy.impl.Op(constants.%AdaptNoncopyable) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %b.var, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %AdaptNoncopyable.as.Destroy.impl.Op.bound: = bound_method %b.var, constants.%AdaptNoncopyable.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.ed9 = addr_of %b.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %AdaptNoncopyable.as.Destroy.impl.Op.call: init %empty_tuple.type = call %AdaptNoncopyable.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -607,36 +696,43 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Noncopyable: type = class_type @Noncopyable [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.004: = impl_witness @Noncopyable.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6f4: type = ptr_type %Noncopyable [concrete] +// CHECK:STDOUT: %pattern_type.e38: type = pattern_type %ptr.6f4 [concrete] +// CHECK:STDOUT: %Noncopyable.as.Destroy.impl.Op.type: type = fn_type @Noncopyable.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Noncopyable.as.Destroy.impl.Op: %Noncopyable.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %AdaptNoncopyableIndirect: type = class_type @AdaptNoncopyableIndirect [concrete] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %tuple.type.ff9: type = tuple_type (type, type, type) [concrete] // CHECK:STDOUT: %tuple.type.c9a: type = tuple_type (%i32, %Noncopyable, %i32) [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d3e: = impl_witness @AdaptNoncopyableIndirect.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.921: type = ptr_type %AdaptNoncopyableIndirect [concrete] +// CHECK:STDOUT: %pattern_type.969: type = pattern_type %ptr.921 [concrete] +// CHECK:STDOUT: %AdaptNoncopyableIndirect.as.Destroy.impl.Op.type: type = fn_type @AdaptNoncopyableIndirect.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %AdaptNoncopyableIndirect.as.Destroy.impl.Op: %AdaptNoncopyableIndirect.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %complete_type.201: = complete_type_witness %tuple.type.c9a [concrete] // CHECK:STDOUT: %pattern_type.7e5: type = pattern_type %AdaptNoncopyableIndirect [concrete] // CHECK:STDOUT: %H.type: type = fn_type @H [concrete] // CHECK:STDOUT: %H: %H.type = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.b45: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%AdaptNoncopyableIndirect) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.003: %T.as.Destroy.impl.Op.type.b45 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.921: type = ptr_type %AdaptNoncopyableIndirect [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.003, @T.as.Destroy.impl.Op(%AdaptNoncopyableIndirect) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { -// CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -664,7 +760,42 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Noncopyable.as.Destroy.impl: constants.%Noncopyable as constants.%Destroy.type { +// CHECK:STDOUT: %Noncopyable.as.Destroy.impl.Op.decl: %Noncopyable.as.Destroy.impl.Op.type = fn_decl @Noncopyable.as.Destroy.impl.Op [concrete = constants.%Noncopyable.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.e38 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.e38 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6f4 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Noncopyable [concrete = constants.%Noncopyable] +// CHECK:STDOUT: %self: %ptr.6f4 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Noncopyable.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Noncopyable.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @AdaptNoncopyableIndirect.as.Destroy.impl: constants.%AdaptNoncopyableIndirect as constants.%Destroy.type { +// CHECK:STDOUT: %AdaptNoncopyableIndirect.as.Destroy.impl.Op.decl: %AdaptNoncopyableIndirect.as.Destroy.impl.Op.type = fn_decl @AdaptNoncopyableIndirect.as.Destroy.impl.Op [concrete = constants.%AdaptNoncopyableIndirect.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.969 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.969 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.921 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AdaptNoncopyableIndirect [concrete = constants.%AdaptNoncopyableIndirect] +// CHECK:STDOUT: %self: %ptr.921 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %AdaptNoncopyableIndirect.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @AdaptNoncopyableIndirect.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Noncopyable { +// CHECK:STDOUT: impl_decl @Noncopyable.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Noncopyable.as.Destroy.impl.%Noncopyable.as.Destroy.impl.Op.decl), @Noncopyable.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.004] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -682,6 +813,9 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %.loc9_31: %tuple.type.ff9 = tuple_literal (%i32.loc9_10, %Noncopyable.ref, %i32.loc9_28) // CHECK:STDOUT: %.loc9_32: type = converted %.loc9_31, constants.%tuple.type.c9a [concrete = constants.%tuple.type.c9a] // CHECK:STDOUT: adapt_decl %.loc9_32 [concrete] +// CHECK:STDOUT: impl_decl @AdaptNoncopyableIndirect.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@AdaptNoncopyableIndirect.as.Destroy.impl.%AdaptNoncopyableIndirect.as.Destroy.impl.Op.decl), @AdaptNoncopyableIndirect.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.d3e] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%tuple.type.c9a [concrete = constants.%complete_type.201] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -690,6 +824,10 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: .Noncopyable = // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Noncopyable.as.Destroy.impl.Op(%self.param: %ptr.6f4) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @AdaptNoncopyableIndirect.as.Destroy.impl.Op(%self.param: %ptr.921) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @H(%a.param: %AdaptNoncopyableIndirect) -> %return.param: %AdaptNoncopyableIndirect { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -716,11 +854,9 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %.loc28_11.4: init %i32 = initialize_from %.loc28_11.2 to %tuple.elem0.loc28_11.2 // CHECK:STDOUT: %tuple.elem1.loc28: ref %Noncopyable = tuple_access %.loc28_11.1, element1 // CHECK:STDOUT: %.loc28_11.5: %Noncopyable = bind_value %tuple.elem1.loc28 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %b.var, constants.%T.as.Destroy.impl.Op.003 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.003, @T.as.Destroy.impl.Op(constants.%AdaptNoncopyableIndirect) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %b.var, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %AdaptNoncopyableIndirect.as.Destroy.impl.Op.bound: = bound_method %b.var, constants.%AdaptNoncopyableIndirect.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.921 = addr_of %b.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %AdaptNoncopyableIndirect.as.Destroy.impl.Op.call: init %empty_tuple.type = call %AdaptNoncopyableIndirect.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -734,15 +870,17 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %struct_type.e.f: type = struct_type {.e: %i32, .f: %i32} [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.77a: = impl_witness @AdaptStruct.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e10: type = ptr_type %AdaptStruct [concrete] +// CHECK:STDOUT: %pattern_type.a0a: type = pattern_type %ptr.e10 [concrete] +// CHECK:STDOUT: %AdaptStruct.as.Destroy.impl.Op.type: type = fn_type @AdaptStruct.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %AdaptStruct.as.Destroy.impl.Op: %AdaptStruct.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %complete_type.511: = complete_type_witness %struct_type.e.f [concrete] // CHECK:STDOUT: %pattern_type.f45: type = pattern_type %AdaptStruct [concrete] // CHECK:STDOUT: %I.type: type = fn_type @I [concrete] // CHECK:STDOUT: %I: %I.type = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.38c: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%AdaptStruct) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d16: %T.as.Destroy.impl.Op.type.38c = struct_value () [concrete] -// CHECK:STDOUT: %ptr.e10: type = ptr_type %AdaptStruct [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.ad6: = specific_function %T.as.Destroy.impl.Op.d16, @T.as.Destroy.impl.Op(%AdaptStruct) [concrete] // CHECK:STDOUT: %UInt.type: type = generic_class_type @UInt [concrete] // CHECK:STDOUT: %UInt.generic: %UInt.type = struct_value () [concrete] // CHECK:STDOUT: %u32: type = class_type @UInt, @UInt(%int_32) [concrete] @@ -754,7 +892,7 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.628: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%tuple.type.80b) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.8ff: %T.as.Destroy.impl.Op.type.628 = struct_value () [concrete] // CHECK:STDOUT: %ptr.b09: type = ptr_type %tuple.type.80b [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.301: = specific_function %T.as.Destroy.impl.Op.8ff, @T.as.Destroy.impl.Op(%tuple.type.80b) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.8ff, @T.as.Destroy.impl.Op(%tuple.type.80b) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -817,6 +955,22 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @AdaptStruct.as.Destroy.impl: constants.%AdaptStruct as constants.%Destroy.type { +// CHECK:STDOUT: %AdaptStruct.as.Destroy.impl.Op.decl: %AdaptStruct.as.Destroy.impl.Op.type = fn_decl @AdaptStruct.as.Destroy.impl.Op [concrete = constants.%AdaptStruct.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a0a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a0a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e10 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AdaptStruct [concrete = constants.%AdaptStruct] +// CHECK:STDOUT: %self: %ptr.e10 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %AdaptStruct.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @AdaptStruct.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @AdaptStruct { // CHECK:STDOUT: %int_32.loc5_14: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5_14: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -824,6 +978,9 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %i32.loc5_23: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %struct_type.e.f: type = struct_type {.e: %i32, .f: %i32} [concrete = constants.%struct_type.e.f] // CHECK:STDOUT: adapt_decl %struct_type.e.f [concrete] +// CHECK:STDOUT: impl_decl @AdaptStruct.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@AdaptStruct.as.Destroy.impl.%AdaptStruct.as.Destroy.impl.Op.decl), @AdaptStruct.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.77a] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.e.f [concrete = constants.%complete_type.511] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -831,6 +988,8 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: .Self = constants.%AdaptStruct // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @AdaptStruct.as.Destroy.impl.Op(%self.param: %ptr.e10) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @I(%g.param: %AdaptStruct) -> %return.param: %AdaptStruct { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -867,11 +1026,9 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %.loc10_11.11: init %struct_type.e.f = struct_init (%.loc10_11.6, %.loc10_11.10) to %.loc10_11.4 // CHECK:STDOUT: %.loc10_11.12: init %AdaptStruct = as_compatible %.loc10_11.11 // CHECK:STDOUT: %.loc10_11.13: init %AdaptStruct = converted %h.ref, %.loc10_11.12 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %h.var, constants.%T.as.Destroy.impl.Op.d16 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d16, @T.as.Destroy.impl.Op(constants.%AdaptStruct) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.ad6] -// CHECK:STDOUT: %bound_method: = bound_method %h.var, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %AdaptStruct.as.Destroy.impl.Op.bound: = bound_method %h.var, constants.%AdaptStruct.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.e10 = addr_of %h.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %AdaptStruct.as.Destroy.impl.Op.call: init %empty_tuple.type = call %AdaptStruct.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %.loc10_11.13 to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -933,7 +1090,7 @@ fn InTuple(c: (AdaptStruct, u32)) -> (AdaptStruct, u32) { // CHECK:STDOUT: %.loc15_10.16: init %tuple.type.80b = tuple_init (%.loc15_10.13, %.loc15_10.15) to %return // CHECK:STDOUT: %.loc15_11: init %tuple.type.80b = converted %d.ref, %.loc15_10.16 // CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %d.var, constants.%T.as.Destroy.impl.Op.8ff -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.8ff, @T.as.Destroy.impl.Op(constants.%tuple.type.80b) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.301] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.8ff, @T.as.Destroy.impl.Op(constants.%tuple.type.80b) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method: = bound_method %d.var, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr: %ptr.b09 = addr_of %d.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) diff --git a/toolchain/check/testdata/class/adapter/extend_adapt.carbon b/toolchain/check/testdata/class/adapter/extend_adapt.carbon index 34610bdfcdf9..f1d6fe34b42a 100644 --- a/toolchain/check/testdata/class/adapter/extend_adapt.carbon +++ b/toolchain/check/testdata/class/adapter/extend_adapt.carbon @@ -158,8 +158,20 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %pattern_type.080: type = pattern_type %SomeClassAdapter [concrete] // CHECK:STDOUT: %SomeClass.AdapterMethod.type: type = fn_type @SomeClass.AdapterMethod [concrete] // CHECK:STDOUT: %SomeClass.AdapterMethod: %SomeClass.AdapterMethod.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ab1: = impl_witness @SomeClass.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.c8a: type = ptr_type %SomeClass [concrete] +// CHECK:STDOUT: %pattern_type.a47: type = pattern_type %ptr.c8a [concrete] +// CHECK:STDOUT: %SomeClass.as.Destroy.impl.Op.type: type = fn_type @SomeClass.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %SomeClass.as.Destroy.impl.Op: %SomeClass.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete] // CHECK:STDOUT: %complete_type.705: = complete_type_witness %struct_type.a.b [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.84c: = impl_witness @SomeClassAdapter.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.b51: type = ptr_type %SomeClassAdapter [concrete] +// CHECK:STDOUT: %pattern_type.76d: type = pattern_type %ptr.b51 [concrete] +// CHECK:STDOUT: %SomeClassAdapter.as.Destroy.impl.Op.type: type = fn_type @SomeClassAdapter.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %SomeClassAdapter.as.Destroy.impl.Op: %SomeClassAdapter.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %TestStaticMemberFunction.type: type = fn_type @TestStaticMemberFunction [concrete] // CHECK:STDOUT: %TestStaticMemberFunction: %TestStaticMemberFunction.type = struct_value () [concrete] // CHECK:STDOUT: %TestAdapterMethod.type: type = fn_type @TestAdapterMethod [concrete] @@ -169,10 +181,12 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -205,9 +219,44 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @SomeClass.as.Destroy.impl: constants.%SomeClass as constants.%Destroy.type { +// CHECK:STDOUT: %SomeClass.as.Destroy.impl.Op.decl: %SomeClass.as.Destroy.impl.Op.type = fn_decl @SomeClass.as.Destroy.impl.Op [concrete = constants.%SomeClass.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a47 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a47 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.c8a = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SomeClass [concrete = constants.%SomeClass] +// CHECK:STDOUT: %self: %ptr.c8a = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %SomeClass.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @SomeClass.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @SomeClassAdapter.as.Destroy.impl: constants.%SomeClassAdapter as constants.%Destroy.type { +// CHECK:STDOUT: %SomeClassAdapter.as.Destroy.impl.Op.decl: %SomeClassAdapter.as.Destroy.impl.Op.type = fn_decl @SomeClassAdapter.as.Destroy.impl.Op [concrete = constants.%SomeClassAdapter.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.76d = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.76d = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.b51 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SomeClassAdapter [concrete = constants.%SomeClassAdapter] +// CHECK:STDOUT: %self: %ptr.b51 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %SomeClassAdapter.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @SomeClassAdapter.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @SomeClassAdapter { // CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [concrete = constants.%SomeClass] // CHECK:STDOUT: adapt_decl %SomeClass.ref [concrete] +// CHECK:STDOUT: impl_decl @SomeClassAdapter.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@SomeClassAdapter.as.Destroy.impl.%SomeClassAdapter.as.Destroy.impl.Op.decl), @SomeClassAdapter.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.84c] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.a.b [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -235,6 +284,9 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %SomeClassAdapter.ref: type = name_ref SomeClassAdapter, file.%SomeClassAdapter.decl.loc4 [concrete = constants.%SomeClassAdapter] // CHECK:STDOUT: %self: %SomeClassAdapter = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @SomeClass.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@SomeClass.as.Destroy.impl.%SomeClass.as.Destroy.impl.Op.decl), @SomeClass.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ab1] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete = constants.%struct_type.a.b] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a.b [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -252,6 +304,10 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: fn @SomeClass.AdapterMethod(%self.param: %SomeClassAdapter); // CHECK:STDOUT: +// CHECK:STDOUT: fn @SomeClass.as.Destroy.impl.Op(%self.param: %ptr.c8a) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @SomeClassAdapter.as.Destroy.impl.Op(%self.param: %ptr.b51) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @TestStaticMemberFunction(%a.param: %SomeClassAdapter) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %SomeClassAdapter = name_ref a, %a @@ -277,9 +333,21 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %SomeClass.F.type: type = fn_type @SomeClass.F [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %SomeClass.F: %SomeClass.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ab1: = impl_witness @SomeClass.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.c8a: type = ptr_type %SomeClass [concrete] +// CHECK:STDOUT: %pattern_type.a47: type = pattern_type %ptr.c8a [concrete] +// CHECK:STDOUT: %SomeClass.as.Destroy.impl.Op.type: type = fn_type @SomeClass.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %SomeClass.as.Destroy.impl.Op: %SomeClass.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %SomeClassAdapter: type = class_type @SomeClassAdapter [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.84c: = impl_witness @SomeClassAdapter.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.b51: type = ptr_type %SomeClassAdapter [concrete] +// CHECK:STDOUT: %pattern_type.76d: type = pattern_type %ptr.b51 [concrete] +// CHECK:STDOUT: %SomeClassAdapter.as.Destroy.impl.Op.type: type = fn_type @SomeClassAdapter.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %SomeClassAdapter.as.Destroy.impl.Op: %SomeClassAdapter.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.080: type = pattern_type %SomeClassAdapter [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] @@ -289,10 +357,12 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -316,6 +386,38 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @SomeClass.as.Destroy.impl: constants.%SomeClass as constants.%Destroy.type { +// CHECK:STDOUT: %SomeClass.as.Destroy.impl.Op.decl: %SomeClass.as.Destroy.impl.Op.type = fn_decl @SomeClass.as.Destroy.impl.Op [concrete = constants.%SomeClass.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a47 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a47 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.c8a = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SomeClass [concrete = constants.%SomeClass] +// CHECK:STDOUT: %self: %ptr.c8a = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %SomeClass.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @SomeClass.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @SomeClassAdapter.as.Destroy.impl: constants.%SomeClassAdapter as constants.%Destroy.type { +// CHECK:STDOUT: %SomeClassAdapter.as.Destroy.impl.Op.decl: %SomeClassAdapter.as.Destroy.impl.Op.type = fn_decl @SomeClassAdapter.as.Destroy.impl.Op [concrete = constants.%SomeClassAdapter.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.76d = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.76d = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.b51 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SomeClassAdapter [concrete = constants.%SomeClassAdapter] +// CHECK:STDOUT: %self: %ptr.b51 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %SomeClassAdapter.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @SomeClassAdapter.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @SomeClass { // CHECK:STDOUT: %SomeClass.F.decl: %SomeClass.F.type = fn_decl @SomeClass.F [concrete = constants.%SomeClass.F] { // CHECK:STDOUT: %self.patt: %pattern_type.3eb = binding_pattern self [concrete] @@ -325,6 +427,9 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SomeClass [concrete = constants.%SomeClass] // CHECK:STDOUT: %self: %SomeClass = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @SomeClass.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@SomeClass.as.Destroy.impl.%SomeClass.as.Destroy.impl.Op.decl), @SomeClass.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ab1] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -337,6 +442,9 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: class @SomeClassAdapter { // CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [concrete = constants.%SomeClass] // CHECK:STDOUT: adapt_decl %SomeClass.ref [concrete] +// CHECK:STDOUT: impl_decl @SomeClassAdapter.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@SomeClassAdapter.as.Destroy.impl.%SomeClassAdapter.as.Destroy.impl.Op.decl), @SomeClassAdapter.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.84c] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -349,6 +457,10 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: fn @SomeClass.F(%self.param: %SomeClass); // CHECK:STDOUT: +// CHECK:STDOUT: fn @SomeClass.as.Destroy.impl.Op(%self.param: %ptr.c8a) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @SomeClassAdapter.as.Destroy.impl.Op(%self.param: %ptr.b51) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%a.param: %SomeClassAdapter) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %SomeClassAdapter = name_ref a, %a @@ -368,9 +480,21 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %SomeClass.elem: type = unbound_element_type %SomeClass, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ab1: = impl_witness @SomeClass.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.c8a: type = ptr_type %SomeClass [concrete] +// CHECK:STDOUT: %pattern_type.a47: type = pattern_type %ptr.c8a [concrete] +// CHECK:STDOUT: %SomeClass.as.Destroy.impl.Op.type: type = fn_type @SomeClass.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %SomeClass.as.Destroy.impl.Op: %SomeClass.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete] // CHECK:STDOUT: %complete_type.705: = complete_type_witness %struct_type.a.b [concrete] // CHECK:STDOUT: %SomeClassAdapter: type = class_type @SomeClassAdapter [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.84c: = impl_witness @SomeClassAdapter.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.b51: type = ptr_type %SomeClassAdapter [concrete] +// CHECK:STDOUT: %pattern_type.76d: type = pattern_type %ptr.b51 [concrete] +// CHECK:STDOUT: %SomeClassAdapter.as.Destroy.impl.Op.type: type = fn_type @SomeClassAdapter.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %SomeClassAdapter.as.Destroy.impl.Op: %SomeClassAdapter.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.080: type = pattern_type %SomeClassAdapter [concrete] // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] @@ -382,11 +506,13 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -416,6 +542,38 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @SomeClass.as.Destroy.impl: constants.%SomeClass as constants.%Destroy.type { +// CHECK:STDOUT: %SomeClass.as.Destroy.impl.Op.decl: %SomeClass.as.Destroy.impl.Op.type = fn_decl @SomeClass.as.Destroy.impl.Op [concrete = constants.%SomeClass.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a47 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a47 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.c8a = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SomeClass [concrete = constants.%SomeClass] +// CHECK:STDOUT: %self: %ptr.c8a = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %SomeClass.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @SomeClass.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @SomeClassAdapter.as.Destroy.impl: constants.%SomeClassAdapter as constants.%Destroy.type { +// CHECK:STDOUT: %SomeClassAdapter.as.Destroy.impl.Op.decl: %SomeClassAdapter.as.Destroy.impl.Op.type = fn_decl @SomeClassAdapter.as.Destroy.impl.Op [concrete = constants.%SomeClassAdapter.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.76d = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.76d = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.b51 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SomeClassAdapter [concrete = constants.%SomeClassAdapter] +// CHECK:STDOUT: %self: %ptr.b51 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %SomeClassAdapter.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @SomeClassAdapter.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @SomeClass { // CHECK:STDOUT: %int_32.loc5: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -423,6 +581,9 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %int_32.loc6: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc6: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc6: %SomeClass.elem = field_decl b, element1 [concrete] +// CHECK:STDOUT: impl_decl @SomeClass.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@SomeClass.as.Destroy.impl.%SomeClass.as.Destroy.impl.Op.decl), @SomeClass.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ab1] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete = constants.%struct_type.a.b] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a.b [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -436,6 +597,9 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: class @SomeClassAdapter { // CHECK:STDOUT: %SomeClass.ref: type = name_ref SomeClass, file.%SomeClass.decl [concrete = constants.%SomeClass] // CHECK:STDOUT: adapt_decl %SomeClass.ref [concrete] +// CHECK:STDOUT: impl_decl @SomeClassAdapter.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@SomeClassAdapter.as.Destroy.impl.%SomeClassAdapter.as.Destroy.impl.Op.decl), @SomeClassAdapter.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.84c] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.a.b [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -446,6 +610,10 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: extend %SomeClass.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @SomeClass.as.Destroy.impl.Op(%self.param: %ptr.c8a) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @SomeClassAdapter.as.Destroy.impl.Op(%self.param: %ptr.b51) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%a.param: %SomeClassAdapter) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %SomeClassAdapter = name_ref a, %a @@ -464,6 +632,13 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @StructAdapter.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.670: type = ptr_type %StructAdapter [concrete] +// CHECK:STDOUT: %pattern_type.671: type = pattern_type %ptr.670 [concrete] +// CHECK:STDOUT: %StructAdapter.as.Destroy.impl.Op.type: type = fn_type @StructAdapter.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %StructAdapter.as.Destroy.impl.Op: %StructAdapter.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %complete_type.705: = complete_type_witness %struct_type.a.b [concrete] // CHECK:STDOUT: %pattern_type.016: type = pattern_type %StructAdapter [concrete] // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] @@ -474,10 +649,12 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -504,6 +681,22 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @StructAdapter.as.Destroy.impl: constants.%StructAdapter as constants.%Destroy.type { +// CHECK:STDOUT: %StructAdapter.as.Destroy.impl.Op.decl: %StructAdapter.as.Destroy.impl.Op.type = fn_decl @StructAdapter.as.Destroy.impl.Op [concrete = constants.%StructAdapter.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.671 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.671 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.670 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%StructAdapter [concrete = constants.%StructAdapter] +// CHECK:STDOUT: %self: %ptr.670 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %StructAdapter.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @StructAdapter.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @StructAdapter { // CHECK:STDOUT: %int_32.loc5_21: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5_21: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -511,6 +704,9 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %i32.loc5_30: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete = constants.%struct_type.a.b] // CHECK:STDOUT: adapt_decl %struct_type.a.b [concrete] +// CHECK:STDOUT: impl_decl @StructAdapter.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@StructAdapter.as.Destroy.impl.%StructAdapter.as.Destroy.impl.Op.decl), @StructAdapter.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.a.b [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -520,6 +716,8 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: extend %struct_type.a.b // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @StructAdapter.as.Destroy.impl.Op(%self.param: %ptr.670) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%a.param: %StructAdapter) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %StructAdapter = name_ref a, %a @@ -537,6 +735,13 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %tuple.type.24b: type = tuple_type (type, type) [concrete] // CHECK:STDOUT: %tuple.type.d07: type = tuple_type (%i32, %i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @TupleAdapter.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.58b: type = ptr_type %TupleAdapter [concrete] +// CHECK:STDOUT: %pattern_type.dfa: type = pattern_type %ptr.58b [concrete] +// CHECK:STDOUT: %TupleAdapter.as.Destroy.impl.Op.type: type = fn_type @TupleAdapter.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %TupleAdapter.as.Destroy.impl.Op: %TupleAdapter.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %complete_type.65d: = complete_type_witness %tuple.type.d07 [concrete] // CHECK:STDOUT: %pattern_type.ee1: type = pattern_type %TupleAdapter [concrete] // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] @@ -548,10 +753,12 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -578,6 +785,22 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @TupleAdapter.as.Destroy.impl: constants.%TupleAdapter as constants.%Destroy.type { +// CHECK:STDOUT: %TupleAdapter.as.Destroy.impl.Op.decl: %TupleAdapter.as.Destroy.impl.Op.type = fn_decl @TupleAdapter.as.Destroy.impl.Op [concrete = constants.%TupleAdapter.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.dfa = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.dfa = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.58b = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%TupleAdapter [concrete = constants.%TupleAdapter] +// CHECK:STDOUT: %self: %ptr.58b = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %TupleAdapter.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @TupleAdapter.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @TupleAdapter { // CHECK:STDOUT: %int_32.loc5_17: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5_17: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -586,6 +809,9 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %.loc5_25: %tuple.type.24b = tuple_literal (%i32.loc5_17, %i32.loc5_22) // CHECK:STDOUT: %.loc5_26: type = converted %.loc5_25, constants.%tuple.type.d07 [concrete = constants.%tuple.type.d07] // CHECK:STDOUT: adapt_decl %.loc5_26 [concrete] +// CHECK:STDOUT: impl_decl @TupleAdapter.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@TupleAdapter.as.Destroy.impl.%TupleAdapter.as.Destroy.impl.Op.decl), @TupleAdapter.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%tuple.type.d07 [concrete = constants.%complete_type.65d] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -594,6 +820,8 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: extend %.loc5_26 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @TupleAdapter.as.Destroy.impl.Op(%self.param: %ptr.58b) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%a.param: %TupleAdapter) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %TupleAdapter = name_ref a, %a @@ -613,6 +841,13 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %IntAdapter: type = class_type @IntAdapter [concrete] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @IntAdapter.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.5b3: type = ptr_type %IntAdapter [concrete] +// CHECK:STDOUT: %pattern_type.010: type = pattern_type %ptr.5b3 [concrete] +// CHECK:STDOUT: %IntAdapter.as.Destroy.impl.Op.type: type = fn_type @IntAdapter.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %IntAdapter.as.Destroy.impl.Op: %IntAdapter.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %complete_type.f8a: = complete_type_witness %i32.builtin [concrete] // CHECK:STDOUT: %pattern_type.90a: type = pattern_type %IntAdapter [concrete] // CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] @@ -626,11 +861,13 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .IntLiteral = %Core.IntLiteral +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.IntLiteral: %IntLiteral.type = import_ref Core//prelude/parts/int_literal, IntLiteral, loaded [concrete = constants.%IntLiteral] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -677,6 +914,22 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @IntAdapter.as.Destroy.impl: constants.%IntAdapter as constants.%Destroy.type { +// CHECK:STDOUT: %IntAdapter.as.Destroy.impl.Op.decl: %IntAdapter.as.Destroy.impl.Op.type = fn_decl @IntAdapter.as.Destroy.impl.Op [concrete = constants.%IntAdapter.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.010 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.010 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.5b3 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%IntAdapter [concrete = constants.%IntAdapter] +// CHECK:STDOUT: %self: %ptr.5b3 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %IntAdapter.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @IntAdapter.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @IntAdapter { // CHECK:STDOUT: %MakeInt.ref: %MakeInt.type = name_ref MakeInt, file.%MakeInt.decl [concrete = constants.%MakeInt] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] @@ -684,6 +937,9 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: %.loc7_27.1: type = value_of_initializer %MakeInt.call [concrete = constants.%i32.builtin] // CHECK:STDOUT: %.loc7_27.2: type = converted %MakeInt.call, %.loc7_27.1 [concrete = constants.%i32.builtin] // CHECK:STDOUT: adapt_decl %.loc7_27.2 [concrete] +// CHECK:STDOUT: impl_decl @IntAdapter.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@IntAdapter.as.Destroy.impl.%IntAdapter.as.Destroy.impl.Op.decl), @IntAdapter.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%i32.builtin [concrete = constants.%complete_type.f8a] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -696,6 +952,8 @@ fn F(a: IntAdapter) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: fn @MakeInt(%N.param: Core.IntLiteral) -> type = "int.make_type_signed"; // CHECK:STDOUT: +// CHECK:STDOUT: fn @IntAdapter.as.Destroy.impl.Op(%self.param: %ptr.5b3) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%a.param: %IntAdapter) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %IntAdapter = name_ref a, %a diff --git a/toolchain/check/testdata/class/adapter/fail_adapt_with_subobjects.carbon b/toolchain/check/testdata/class/adapter/fail_adapt_with_subobjects.carbon index 19915c8a5cf8..7c9cf458bb14 100644 --- a/toolchain/check/testdata/class/adapter/fail_adapt_with_subobjects.carbon +++ b/toolchain/check/testdata/class/adapter/fail_adapt_with_subobjects.carbon @@ -83,6 +83,13 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Base: type = class_type @Base [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %AdaptWithBase: type = class_type @AdaptWithBase [concrete] @@ -91,14 +98,21 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %AdaptWithBase.elem: type = unbound_element_type %AdaptWithBase, %Base [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.8b8: = impl_witness @AdaptWithBase.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.52c: type = ptr_type %AdaptWithBase [concrete] +// CHECK:STDOUT: %pattern_type.d4d: type = pattern_type %ptr.52c [concrete] +// CHECK:STDOUT: %AdaptWithBase.as.Destroy.impl.Op.type: type = fn_type @AdaptWithBase.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %AdaptWithBase.as.Destroy.impl.Op: %AdaptWithBase.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -113,7 +127,42 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %AdaptWithBase.decl: type = class_decl @AdaptWithBase [concrete = constants.%AdaptWithBase] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @AdaptWithBase.as.Destroy.impl: constants.%AdaptWithBase as constants.%Destroy.type { +// CHECK:STDOUT: %AdaptWithBase.as.Destroy.impl.Op.decl: %AdaptWithBase.as.Destroy.impl.Op.type = fn_decl @AdaptWithBase.as.Destroy.impl.Op [concrete = constants.%AdaptWithBase.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.d4d = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.d4d = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.52c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AdaptWithBase [concrete = constants.%AdaptWithBase] +// CHECK:STDOUT: %self: %ptr.52c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %AdaptWithBase.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @AdaptWithBase.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Base { +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -128,6 +177,9 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: adapt_decl %i32 [concrete] // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] // CHECK:STDOUT: %.loc15: %AdaptWithBase.elem = base_decl %Base.ref, element [concrete] +// CHECK:STDOUT: impl_decl @AdaptWithBase.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@AdaptWithBase.as.Destroy.impl.%AdaptWithBase.as.Destroy.impl.Op.decl), @AdaptWithBase.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.8b8] // CHECK:STDOUT: complete_type_witness = // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -137,6 +189,10 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: extend %Base.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @AdaptWithBase.as.Destroy.impl.Op(%self.param: %ptr.52c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_adapt_with_fields.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -146,17 +202,31 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %AdaptWithField.elem: type = unbound_element_type %AdaptWithField, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.333: = impl_witness @AdaptWithField.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.849: type = ptr_type %AdaptWithField [concrete] +// CHECK:STDOUT: %pattern_type.55a: type = pattern_type %ptr.849 [concrete] +// CHECK:STDOUT: %AdaptWithField.as.Destroy.impl.Op.type: type = fn_type @AdaptWithField.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %AdaptWithField.as.Destroy.impl.Op: %AdaptWithField.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %AdaptWithFields: type = class_type @AdaptWithFields [concrete] // CHECK:STDOUT: %AdaptWithFields.elem: type = unbound_element_type %AdaptWithFields, %i32 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.8f2: = impl_witness @AdaptWithFields.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.521: type = ptr_type %AdaptWithFields [concrete] +// CHECK:STDOUT: %pattern_type.1a9: type = pattern_type %ptr.521 [concrete] +// CHECK:STDOUT: %AdaptWithFields.as.Destroy.impl.Op.type: type = fn_type @AdaptWithFields.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %AdaptWithFields.as.Destroy.impl.Op: %AdaptWithFields.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -170,6 +240,38 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %AdaptWithFields.decl: type = class_decl @AdaptWithFields [concrete = constants.%AdaptWithFields] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @AdaptWithField.as.Destroy.impl: constants.%AdaptWithField as constants.%Destroy.type { +// CHECK:STDOUT: %AdaptWithField.as.Destroy.impl.Op.decl: %AdaptWithField.as.Destroy.impl.Op.type = fn_decl @AdaptWithField.as.Destroy.impl.Op [concrete = constants.%AdaptWithField.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.55a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.55a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.849 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AdaptWithField [concrete = constants.%AdaptWithField] +// CHECK:STDOUT: %self: %ptr.849 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %AdaptWithField.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @AdaptWithField.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @AdaptWithFields.as.Destroy.impl: constants.%AdaptWithFields as constants.%Destroy.type { +// CHECK:STDOUT: %AdaptWithFields.as.Destroy.impl.Op.decl: %AdaptWithFields.as.Destroy.impl.Op.type = fn_decl @AdaptWithFields.as.Destroy.impl.Op [concrete = constants.%AdaptWithFields.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1a9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1a9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc16: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.521 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AdaptWithFields [concrete = constants.%AdaptWithFields] +// CHECK:STDOUT: %self: %ptr.521 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %AdaptWithFields.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @AdaptWithFields.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @AdaptWithField { // CHECK:STDOUT: %int_32.loc8: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc8: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -177,6 +279,9 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %int_32.loc13: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc13: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc13: %AdaptWithField.elem = field_decl n, element [concrete] +// CHECK:STDOUT: impl_decl @AdaptWithField.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@AdaptWithField.as.Destroy.impl.%AdaptWithField.as.Destroy.impl.Op.decl), @AdaptWithField.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.333] // CHECK:STDOUT: complete_type_witness = // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -197,6 +302,9 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %int_32.loc27: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc27: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc27: %AdaptWithFields.elem = field_decl c, element [concrete] +// CHECK:STDOUT: impl_decl @AdaptWithFields.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@AdaptWithFields.as.Destroy.impl.%AdaptWithFields.as.Destroy.impl.Op.decl), @AdaptWithFields.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.8f2] // CHECK:STDOUT: complete_type_witness = // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -206,10 +314,21 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: .c = %.loc27 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @AdaptWithField.as.Destroy.impl.Op(%self.param: %ptr.849) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @AdaptWithFields.as.Destroy.impl.Op(%self.param: %ptr.521) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_adapt_with_base_and_fields.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Base: type = class_type @Base [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %AdaptWithBaseAndFields: type = class_type @AdaptWithBaseAndFields [concrete] @@ -219,14 +338,21 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %AdaptWithBaseAndFields.elem.ddf: type = unbound_element_type %AdaptWithBaseAndFields, %i32 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.034: = impl_witness @AdaptWithBaseAndFields.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.cbb: type = ptr_type %AdaptWithBaseAndFields [concrete] +// CHECK:STDOUT: %pattern_type.926: type = pattern_type %ptr.cbb [concrete] +// CHECK:STDOUT: %AdaptWithBaseAndFields.as.Destroy.impl.Op.type: type = fn_type @AdaptWithBaseAndFields.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %AdaptWithBaseAndFields.as.Destroy.impl.Op: %AdaptWithBaseAndFields.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -241,7 +367,42 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %AdaptWithBaseAndFields.decl: type = class_decl @AdaptWithBaseAndFields [concrete = constants.%AdaptWithBaseAndFields] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @AdaptWithBaseAndFields.as.Destroy.impl: constants.%AdaptWithBaseAndFields as constants.%Destroy.type { +// CHECK:STDOUT: %AdaptWithBaseAndFields.as.Destroy.impl.Op.decl: %AdaptWithBaseAndFields.as.Destroy.impl.Op.type = fn_decl @AdaptWithBaseAndFields.as.Destroy.impl.Op [concrete = constants.%AdaptWithBaseAndFields.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.926 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.926 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.cbb = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AdaptWithBaseAndFields [concrete = constants.%AdaptWithBaseAndFields] +// CHECK:STDOUT: %self: %ptr.cbb = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %AdaptWithBaseAndFields.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @AdaptWithBaseAndFields.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Base { +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -259,6 +420,9 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: %.loc16_10: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc16_11: type = converted %.loc16_10, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: adapt_decl %.loc16_11 [concrete] +// CHECK:STDOUT: impl_decl @AdaptWithBaseAndFields.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@AdaptWithBaseAndFields.as.Destroy.impl.%AdaptWithBaseAndFields.as.Destroy.impl.Op.decl), @AdaptWithBaseAndFields.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.034] // CHECK:STDOUT: complete_type_witness = // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -269,3 +433,7 @@ class AdaptWithBaseAndFields { // CHECK:STDOUT: extend %Base.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @AdaptWithBaseAndFields.as.Destroy.impl.Op(%self.param: %ptr.cbb) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/adapter/init_adapt.carbon b/toolchain/check/testdata/class/adapter/init_adapt.carbon index 162599fe9a96..00e9b2b5f735 100644 --- a/toolchain/check/testdata/class/adapter/init_adapt.carbon +++ b/toolchain/check/testdata/class/adapter/init_adapt.carbon @@ -105,9 +105,21 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a.b.501: type = struct_type {.a: %i32, .b: %i32} [concrete] // CHECK:STDOUT: %complete_type.705: = complete_type_witness %struct_type.a.b.501 [concrete] // CHECK:STDOUT: %AdaptC: type = class_type @AdaptC [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d92: = impl_witness @AdaptC.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.b20: type = ptr_type %AdaptC [concrete] +// CHECK:STDOUT: %pattern_type.d7e: type = pattern_type %ptr.b20 [concrete] +// CHECK:STDOUT: %AdaptC.as.Destroy.impl.Op.type: type = fn_type @AdaptC.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %AdaptC.as.Destroy.impl.Op: %AdaptC.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] @@ -142,11 +154,13 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -236,6 +250,38 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: %e: ref %C = bind_name e, %e.var [concrete = %e.var] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @AdaptC.as.Destroy.impl: constants.%AdaptC as constants.%Destroy.type { +// CHECK:STDOUT: %AdaptC.as.Destroy.impl.Op.decl: %AdaptC.as.Destroy.impl.Op.type = fn_decl @AdaptC.as.Destroy.impl.Op [concrete = constants.%AdaptC.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.d7e = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.d7e = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.b20 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AdaptC [concrete = constants.%AdaptC] +// CHECK:STDOUT: %self: %ptr.b20 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %AdaptC.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @AdaptC.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %int_32.loc5: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -243,6 +289,9 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: %int_32.loc6: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc6: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc6: %C.elem = field_decl b, element1 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete = constants.%struct_type.a.b.501] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a.b [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -256,6 +305,9 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: class @AdaptC { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: adapt_decl %C.ref [concrete] +// CHECK:STDOUT: impl_decl @AdaptC.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@AdaptC.as.Destroy.impl.%AdaptC.as.Destroy.impl.Op.decl), @AdaptC.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.d92] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.a.b.501 [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -264,6 +316,10 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: .C = // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @AdaptC.as.Destroy.impl.Op(%self.param: %ptr.b20) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @MakeC() -> %return.param: %C; // CHECK:STDOUT: // CHECK:STDOUT: fn @MakeAdaptC() -> %return.param: %AdaptC; @@ -307,9 +363,21 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a.b.501: type = struct_type {.a: %i32, .b: %i32} [concrete] // CHECK:STDOUT: %complete_type.705: = complete_type_witness %struct_type.a.b.501 [concrete] // CHECK:STDOUT: %AdaptC: type = class_type @AdaptC [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d92: = impl_witness @AdaptC.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.b20: type = ptr_type %AdaptC [concrete] +// CHECK:STDOUT: %pattern_type.d7e: type = pattern_type %ptr.b20 [concrete] +// CHECK:STDOUT: %AdaptC.as.Destroy.impl.Op.type: type = fn_type @AdaptC.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %AdaptC.as.Destroy.impl.Op: %AdaptC.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] @@ -344,11 +412,13 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -440,6 +510,38 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: %e: ref %C = bind_name e, %e.var [concrete = %e.var] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @AdaptC.as.Destroy.impl: constants.%AdaptC as constants.%Destroy.type { +// CHECK:STDOUT: %AdaptC.as.Destroy.impl.Op.decl: %AdaptC.as.Destroy.impl.Op.type = fn_decl @AdaptC.as.Destroy.impl.Op [concrete = constants.%AdaptC.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.d7e = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.d7e = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.b20 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AdaptC [concrete = constants.%AdaptC] +// CHECK:STDOUT: %self: %ptr.b20 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %AdaptC.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @AdaptC.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %int_32.loc5: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -447,6 +549,9 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: %int_32.loc6: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc6: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc6: %C.elem = field_decl b, element1 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete = constants.%struct_type.a.b.501] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a.b [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -460,6 +565,9 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: class @AdaptC { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: adapt_decl %C.ref [concrete] +// CHECK:STDOUT: impl_decl @AdaptC.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@AdaptC.as.Destroy.impl.%AdaptC.as.Destroy.impl.Op.decl), @AdaptC.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.d92] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.a.b.501 [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -468,6 +576,10 @@ var e: C = MakeAdaptC(); // CHECK:STDOUT: .C = // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @AdaptC.as.Destroy.impl.Op(%self.param: %ptr.b20) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @MakeC() -> %return.param: %C; // CHECK:STDOUT: // CHECK:STDOUT: fn @MakeAdaptC() -> %return.param: %AdaptC; diff --git a/toolchain/check/testdata/class/base.carbon b/toolchain/check/testdata/class/base.carbon index 0c6bbf375625..afc8ae1b0c26 100644 --- a/toolchain/check/testdata/class/base.carbon +++ b/toolchain/check/testdata/class/base.carbon @@ -58,11 +58,23 @@ class Derived { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Base.elem: type = unbound_element_type %Base, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.b.0a3: type = struct_type {.b: %i32} [concrete] // CHECK:STDOUT: %complete_type.ba8: = complete_type_witness %struct_type.b.0a3 [concrete] // CHECK:STDOUT: %Derived: type = class_type @Derived [concrete] // CHECK:STDOUT: %Derived.elem.69e: type = unbound_element_type %Derived, %Base [concrete] // CHECK:STDOUT: %Derived.elem.344: type = unbound_element_type %Derived, %i32 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.d.f8f: type = struct_type {.base: %Base, .d: %i32} [concrete] // CHECK:STDOUT: %complete_type.da6: = complete_type_witness %struct_type.base.d.f8f [concrete] // CHECK:STDOUT: %pattern_type.fb9: type = pattern_type %Derived [concrete] @@ -103,11 +115,13 @@ class Derived { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -152,10 +166,45 @@ class Derived { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc3: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Base { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc4: %Base.elem = field_decl b, element0 [concrete] +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] // CHECK:STDOUT: %struct_type.b: type = struct_type {.b: %i32} [concrete = constants.%struct_type.b.0a3] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.b [concrete = constants.%complete_type.ba8] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -171,6 +220,9 @@ class Derived { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc10: %Derived.elem.344 = field_decl d, element1 [concrete] +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %struct_type.base.d: type = struct_type {.base: %Base, .d: %i32} [concrete = constants.%struct_type.base.d.f8f] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base.d [concrete = constants.%complete_type.da6] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -183,6 +235,10 @@ class Derived { // CHECK:STDOUT: extend %Base.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Make() -> %return.param: %Derived { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %int_4: Core.IntLiteral = int_value 4 [concrete = constants.%int_4.0c1] @@ -240,6 +296,13 @@ class Derived { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Base: type = class_type @Base [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Derived: type = class_type @Derived [concrete] @@ -248,16 +311,23 @@ class Derived { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Derived.elem: type = unbound_element_type %Derived, %i32 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.d: type = struct_type {.d: %i32} [concrete] // CHECK:STDOUT: %complete_type.860: = complete_type_witness %struct_type.d [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -272,7 +342,42 @@ class Derived { // CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [concrete = constants.%Derived] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc3: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Base { +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -286,6 +391,9 @@ class Derived { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc7: %Derived.elem = field_decl d, element0 [concrete] // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %struct_type.d: type = struct_type {.d: %i32} [concrete = constants.%struct_type.d] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.d [concrete = constants.%complete_type.860] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -296,3 +404,7 @@ class Derived { // CHECK:STDOUT: .Base = // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/base_field.carbon b/toolchain/check/testdata/class/base_field.carbon index 234f72023900..ea2fc4ceafae 100644 --- a/toolchain/check/testdata/class/base_field.carbon +++ b/toolchain/check/testdata/class/base_field.carbon @@ -38,15 +38,25 @@ fn Access(p: Derived*) -> i32* { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Base.elem: type = unbound_element_type %Base, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a.b.c: type = struct_type {.a: %i32, .b: %i32, .c: %i32} [concrete] // CHECK:STDOUT: %complete_type.ebc: = complete_type_witness %struct_type.a.b.c [concrete] // CHECK:STDOUT: %Derived: type = class_type @Derived [concrete] // CHECK:STDOUT: %Derived.elem.69e: type = unbound_element_type %Derived, %Base [concrete] // CHECK:STDOUT: %Derived.elem.344: type = unbound_element_type %Derived, %i32 [concrete] -// CHECK:STDOUT: %struct_type.base.d.e.6a7: type = struct_type {.base: %Base, .d: %i32, .e: %i32} [concrete] -// CHECK:STDOUT: %complete_type.401: = complete_type_witness %struct_type.base.d.e.6a7 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] // CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] // CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %struct_type.base.d.e.6a7: type = struct_type {.base: %Base, .d: %i32, .e: %i32} [concrete] +// CHECK:STDOUT: %complete_type.401: = complete_type_witness %struct_type.base.d.e.6a7 [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] // CHECK:STDOUT: %pattern_type.fe8: type = pattern_type %ptr.235 [concrete] // CHECK:STDOUT: %Access.type: type = fn_type @Access [concrete] @@ -56,10 +66,12 @@ fn Access(p: Derived*) -> i32* { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -92,6 +104,38 @@ fn Access(p: Derived*) -> i32* { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc21: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Base { // CHECK:STDOUT: %int_32.loc16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -102,6 +146,9 @@ fn Access(p: Derived*) -> i32* { // CHECK:STDOUT: %int_32.loc18: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc18: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc18: %Base.elem = field_decl c, element2 [concrete] +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] // CHECK:STDOUT: %struct_type.a.b.c: type = struct_type {.a: %i32, .b: %i32, .c: %i32} [concrete = constants.%struct_type.a.b.c] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a.b.c [concrete = constants.%complete_type.ebc] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -122,6 +169,9 @@ fn Access(p: Derived*) -> i32* { // CHECK:STDOUT: %int_32.loc25: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc25: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc25: %Derived.elem.344 = field_decl e, element2 [concrete] +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %struct_type.base.d.e: type = struct_type {.base: %Base, .d: %i32, .e: %i32} [concrete = constants.%struct_type.base.d.e.6a7] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base.d.e [concrete = constants.%complete_type.401] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -136,6 +186,10 @@ fn Access(p: Derived*) -> i32* { // CHECK:STDOUT: extend %Base.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Access(%p.param: %ptr.404) -> %ptr.235 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %p.ref: %ptr.404 = name_ref p, %p diff --git a/toolchain/check/testdata/class/base_function_unqualified.carbon b/toolchain/check/testdata/class/base_function_unqualified.carbon index 1ff4009a38c1..92095371431a 100644 --- a/toolchain/check/testdata/class/base_function_unqualified.carbon +++ b/toolchain/check/testdata/class/base_function_unqualified.carbon @@ -34,6 +34,13 @@ fn Derived.H() { // CHECK:STDOUT: %Base.F.type: type = fn_type @Base.F [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Base.F: %Base.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Derived: type = class_type @Derived [concrete] @@ -42,15 +49,22 @@ fn Derived.H() { // CHECK:STDOUT: %Derived.G: %Derived.G.type = struct_value () [concrete] // CHECK:STDOUT: %Derived.H.type: type = fn_type @Derived.H [concrete] // CHECK:STDOUT: %Derived.H: %Derived.H.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base} [concrete] // CHECK:STDOUT: %complete_type.15c: = complete_type_witness %struct_type.base [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -65,8 +79,43 @@ fn Derived.H() { // CHECK:STDOUT: %Derived.H.decl: %Derived.H.type = fn_decl @Derived.H [concrete = constants.%Derived.H] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc19: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Base { // CHECK:STDOUT: %Base.F.decl: %Base.F.type = fn_decl @Base.F [concrete = constants.%Base.F] {} {} +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -81,6 +130,9 @@ fn Derived.H() { // CHECK:STDOUT: %.loc20: %Derived.elem = base_decl %Base.ref, element0 [concrete] // CHECK:STDOUT: %Derived.G.decl: %Derived.G.type = fn_decl @Derived.G [concrete = constants.%Derived.G] {} {} // CHECK:STDOUT: %Derived.H.decl: %Derived.H.type = fn_decl @Derived.H [concrete = constants.%Derived.H] {} {} +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base} [concrete = constants.%struct_type.base] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.15c] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -97,6 +149,8 @@ fn Derived.H() { // CHECK:STDOUT: // CHECK:STDOUT: fn @Base.F(); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Derived.G() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %F.ref: %Base.F.type = name_ref F, @Base.%Base.F.decl [concrete = constants.%Base.F] @@ -111,3 +165,5 @@ fn Derived.H() { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/base_method.carbon b/toolchain/check/testdata/class/base_method.carbon index fa6b30061691..2f8c475ed8a5 100644 --- a/toolchain/check/testdata/class/base_method.carbon +++ b/toolchain/check/testdata/class/base_method.carbon @@ -45,6 +45,10 @@ fn Call(p: Derived*) { // CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %Base.F.type: type = fn_type @Base.F [concrete] // CHECK:STDOUT: %Base.F: %Base.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %i32} [concrete] // CHECK:STDOUT: %complete_type.fd7: = complete_type_witness %struct_type.a [concrete] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] @@ -66,10 +70,13 @@ fn Call(p: Derived*) { // CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] // CHECK:STDOUT: %Derived: type = class_type @Derived [concrete] // CHECK:STDOUT: %Derived.elem: type = unbound_element_type %Derived, %Base [concrete] -// CHECK:STDOUT: %struct_type.base.b1e: type = struct_type {.base: %Base} [concrete] -// CHECK:STDOUT: %complete_type.15c: = complete_type_witness %struct_type.base.b1e [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] // CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] // CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %struct_type.base.b1e: type = struct_type {.base: %Base} [concrete] +// CHECK:STDOUT: %complete_type.15c: = complete_type_witness %struct_type.base.b1e [concrete] // CHECK:STDOUT: %Call.type: type = fn_type @Call [concrete] // CHECK:STDOUT: %Call: %Call.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -77,11 +84,13 @@ fn Call(p: Derived*) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -122,6 +131,38 @@ fn Call(p: Derived*) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc25: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Base { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -138,6 +179,9 @@ fn Call(p: Derived*) { // CHECK:STDOUT: } // CHECK:STDOUT: %self.loc18: %ptr.11f = bind_name self, %self.param.loc18 // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %i32} [concrete = constants.%struct_type.a] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a [concrete = constants.%complete_type.fd7] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -151,6 +195,9 @@ fn Call(p: Derived*) { // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] // CHECK:STDOUT: %.loc26: %Derived.elem = base_decl %Base.ref, element0 [concrete] +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base} [concrete = constants.%struct_type.base.b1e] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.15c] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -180,6 +227,10 @@ fn Call(p: Derived*) { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Call(%p.param: %ptr.404) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %p.ref: %ptr.404 = name_ref p, %p diff --git a/toolchain/check/testdata/class/base_method_qualified.carbon b/toolchain/check/testdata/class/base_method_qualified.carbon index e888027ca784..ee9a7e1b13ba 100644 --- a/toolchain/check/testdata/class/base_method_qualified.carbon +++ b/toolchain/check/testdata/class/base_method_qualified.carbon @@ -58,6 +58,13 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 { // CHECK:STDOUT: %pattern_type.fb9: type = pattern_type %Derived [concrete] // CHECK:STDOUT: %Base.G.type: type = fn_type @Base.G [concrete] // CHECK:STDOUT: %Base.G: %Base.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Derived.elem: type = unbound_element_type %Derived, %Base [concrete] @@ -65,12 +72,15 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 { // CHECK:STDOUT: %Derived.F: %Derived.F.type = struct_value () [concrete] // CHECK:STDOUT: %Derived.G.type: type = fn_type @Derived.G [concrete] // CHECK:STDOUT: %Derived.G: %Derived.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.b1e: type = struct_type {.base: %Base} [concrete] // CHECK:STDOUT: %complete_type.15c: = complete_type_witness %struct_type.base.b1e [concrete] // CHECK:STDOUT: %Call.type: type = fn_type @Call [concrete] // CHECK:STDOUT: %Call: %Call.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] -// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] // CHECK:STDOUT: %CallIndirect.type: type = fn_type @CallIndirect [concrete] // CHECK:STDOUT: %CallIndirect: %CallIndirect.type = struct_value () [concrete] // CHECK:STDOUT: %PassDerivedToBase.type: type = fn_type @PassDerivedToBase [concrete] @@ -82,10 +92,12 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -166,6 +178,38 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc17: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc22: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] // CHECK:STDOUT: %.loc23: %Derived.elem = base_decl %Base.ref, element0 [concrete] @@ -185,6 +229,9 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] // CHECK:STDOUT: %self: %Derived = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base} [concrete = constants.%struct_type.base.b1e] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.15c] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -227,6 +274,9 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 { // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -242,10 +292,14 @@ fn PassDerivedToBaseIndirect(p: Derived*) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: fn @Base.G(%self.param: %Derived) -> %i32; // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Derived.F(%self.param: %Derived); // CHECK:STDOUT: // CHECK:STDOUT: fn @Derived.G(%self.param: %Derived); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Call(%a.param: %Derived) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %Derived = name_ref a, %a diff --git a/toolchain/check/testdata/class/base_method_shadow.carbon b/toolchain/check/testdata/class/base_method_shadow.carbon index 5b9242e451ca..e0970e32022a 100644 --- a/toolchain/check/testdata/class/base_method_shadow.carbon +++ b/toolchain/check/testdata/class/base_method_shadow.carbon @@ -47,6 +47,10 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: %A.F.type: type = fn_type @A.F [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %A.F: %A.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] @@ -55,6 +59,9 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] // CHECK:STDOUT: %B.F.type: type = fn_type @B.F [concrete] // CHECK:STDOUT: %B.F: %B.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.953: type = struct_type {.base: %A} [concrete] // CHECK:STDOUT: %complete_type.020: = complete_type_witness %struct_type.base.953 [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] @@ -63,21 +70,29 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] // CHECK:STDOUT: %C.F.type: type = fn_type @C.F [concrete] // CHECK:STDOUT: %C.F: %C.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.0ff: type = struct_type {.base: %B} [concrete] // CHECK:STDOUT: %complete_type.98e: = complete_type_witness %struct_type.base.0ff [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] // CHECK:STDOUT: %D.elem: type = unbound_element_type %D, %B [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] // CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] // CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Call.type: type = fn_type @Call [concrete] // CHECK:STDOUT: %Call: %Call.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -131,6 +146,70 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc19: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc24: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc29: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { // CHECK:STDOUT: %A.F.decl: %A.F.type = fn_decl @A.F [concrete = constants.%A.F] { // CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] @@ -144,6 +223,9 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: } // CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -168,6 +250,9 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: } // CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %A} [concrete = constants.%struct_type.base.953] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.020] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -195,6 +280,9 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: } // CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %B} [concrete = constants.%struct_type.base.0ff] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.98e] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -210,6 +298,9 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: class @D { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [concrete = constants.%B] // CHECK:STDOUT: %.loc30: %D.elem = base_decl %B.ref, element0 [concrete] +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %B} [concrete = constants.%struct_type.base.0ff] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.98e] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -224,10 +315,18 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: // CHECK:STDOUT: fn @A.F(%self.param: %ptr.6db); // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @B.F(%self.param: %ptr.e79); // CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.F(%self.param: %ptr.019); // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Call(%a.param: %ptr.6db, %b.param: %ptr.e79, %c.param: %ptr.019, %d.param: %ptr.19c) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %ptr.6db = name_ref a, %a diff --git a/toolchain/check/testdata/class/basic.carbon b/toolchain/check/testdata/class/basic.carbon index 5034ec9c1cf2..918abd63ce73 100644 --- a/toolchain/check/testdata/class/basic.carbon +++ b/toolchain/check/testdata/class/basic.carbon @@ -44,6 +44,13 @@ fn Run() -> i32 { // CHECK:STDOUT: %Class.G.type: type = fn_type @Class.G [concrete] // CHECK:STDOUT: %Class.G: %Class.G.type = struct_value () [concrete] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b40: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.k: type = struct_type {.k: %i32} [concrete] // CHECK:STDOUT: %complete_type.954: = complete_type_witness %struct_type.k [concrete] // CHECK:STDOUT: %Run.type: type = fn_type @Run [concrete] @@ -70,11 +77,13 @@ fn Run() -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -118,6 +127,22 @@ fn Run() -> i32 { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { // CHECK:STDOUT: %n.patt: %pattern_type.7ce = binding_pattern n [concrete] @@ -156,6 +181,9 @@ fn Run() -> i32 { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc22: %Class.elem = field_decl k, element0 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b40] // CHECK:STDOUT: %struct_type.k: type = struct_type {.k: %i32} [concrete = constants.%struct_type.k] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.k [concrete = constants.%complete_type.954] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -179,6 +207,8 @@ fn Run() -> i32 { // CHECK:STDOUT: return %n.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Run() -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Class.ref: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] diff --git a/toolchain/check/testdata/class/complete_in_member_fn.carbon b/toolchain/check/testdata/class/complete_in_member_fn.carbon index e3506ab4d932..8cb405877879 100644 --- a/toolchain/check/testdata/class/complete_in_member_fn.carbon +++ b/toolchain/check/testdata/class/complete_in_member_fn.carbon @@ -31,6 +31,13 @@ class C { // CHECK:STDOUT: %C.F.type: type = fn_type @C.F [concrete] // CHECK:STDOUT: %C.F: %C.F.type = struct_value () [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %i32} [concrete] // CHECK:STDOUT: %complete_type.fd7: = complete_type_witness %struct_type.a [concrete] // CHECK:STDOUT: } @@ -38,10 +45,12 @@ class C { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -53,6 +62,22 @@ class C { // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %C.F.decl: %C.F.type = fn_decl @C.F [concrete = constants.%C.F] { // CHECK:STDOUT: %c.patt: %pattern_type.c48 = binding_pattern c [concrete] @@ -71,6 +96,9 @@ class C { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc18: %C.elem = field_decl a, element0 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %i32} [concrete = constants.%struct_type.a] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a [concrete = constants.%complete_type.fd7] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -91,3 +119,5 @@ class C { // CHECK:STDOUT: return %.loc16_31.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/compound_field.carbon b/toolchain/check/testdata/class/compound_field.carbon index fab2dda4d941..709f64022d63 100644 --- a/toolchain/check/testdata/class/compound_field.carbon +++ b/toolchain/check/testdata/class/compound_field.carbon @@ -50,11 +50,23 @@ fn AccessBaseIndirect(p: Derived*) -> i32* { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Base.elem: type = unbound_element_type %Base, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a.b.c: type = struct_type {.a: %i32, .b: %i32, .c: %i32} [concrete] // CHECK:STDOUT: %complete_type.ebc: = complete_type_witness %struct_type.a.b.c [concrete] // CHECK:STDOUT: %Derived: type = class_type @Derived [concrete] // CHECK:STDOUT: %Derived.elem.69e: type = unbound_element_type %Derived, %Base [concrete] // CHECK:STDOUT: %Derived.elem.344: type = unbound_element_type %Derived, %i32 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.d.e.6a7: type = struct_type {.base: %Base, .d: %i32, .e: %i32} [concrete] // CHECK:STDOUT: %complete_type.401: = complete_type_witness %struct_type.base.d.e.6a7 [concrete] // CHECK:STDOUT: %pattern_type.fb9: type = pattern_type %Derived [concrete] @@ -63,8 +75,6 @@ fn AccessBaseIndirect(p: Derived*) -> i32* { // CHECK:STDOUT: %AccessDerived: %AccessDerived.type = struct_value () [concrete] // CHECK:STDOUT: %AccessBase.type: type = fn_type @AccessBase [concrete] // CHECK:STDOUT: %AccessBase: %AccessBase.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] -// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] // CHECK:STDOUT: %pattern_type.fe8: type = pattern_type %ptr.235 [concrete] // CHECK:STDOUT: %AccessDerivedIndirect.type: type = fn_type @AccessDerivedIndirect [concrete] @@ -76,10 +86,12 @@ fn AccessBaseIndirect(p: Derived*) -> i32* { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -161,6 +173,38 @@ fn AccessBaseIndirect(p: Derived*) -> i32* { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc21: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Base { // CHECK:STDOUT: %int_32.loc16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -171,6 +215,9 @@ fn AccessBaseIndirect(p: Derived*) -> i32* { // CHECK:STDOUT: %int_32.loc18: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc18: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc18: %Base.elem = field_decl c, element2 [concrete] +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] // CHECK:STDOUT: %struct_type.a.b.c: type = struct_type {.a: %i32, .b: %i32, .c: %i32} [concrete = constants.%struct_type.a.b.c] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a.b.c [concrete = constants.%complete_type.ebc] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -191,6 +238,9 @@ fn AccessBaseIndirect(p: Derived*) -> i32* { // CHECK:STDOUT: %int_32.loc25: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc25: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc25: %Derived.elem.344 = field_decl e, element2 [concrete] +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %struct_type.base.d.e: type = struct_type {.base: %Base, .d: %i32, .e: %i32} [concrete = constants.%struct_type.base.d.e.6a7] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base.d.e [concrete = constants.%complete_type.401] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -204,6 +254,10 @@ fn AccessBaseIndirect(p: Derived*) -> i32* { // CHECK:STDOUT: extend %Base.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @AccessDerived(%d.param: %Derived) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %d.ref.loc29_10: %Derived = name_ref d, %d diff --git a/toolchain/check/testdata/class/cross_package_import.carbon b/toolchain/check/testdata/class/cross_package_import.carbon index f019b968de5b..d13ea6ad7e42 100644 --- a/toolchain/check/testdata/class/cross_package_import.carbon +++ b/toolchain/check/testdata/class/cross_package_import.carbon @@ -108,15 +108,24 @@ var c: Other.C = {}; // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -128,7 +137,26 @@ var c: Other.C = {}; // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -137,6 +165,8 @@ var c: Other.C = {}; // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- other_extern.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/class/derived_to_base.carbon b/toolchain/check/testdata/class/derived_to_base.carbon index 7a19dc25dd12..499cab77768f 100644 --- a/toolchain/check/testdata/class/derived_to_base.carbon +++ b/toolchain/check/testdata/class/derived_to_base.carbon @@ -52,26 +52,37 @@ fn ConvertInit() { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %A.elem: type = unbound_element_type %A, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a.ba9: type = struct_type {.a: %i32} [concrete] // CHECK:STDOUT: %complete_type.fd7: = complete_type_witness %struct_type.a.ba9 [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %B.elem.e38: type = unbound_element_type %B, %A [concrete] // CHECK:STDOUT: %B.elem.5c3: type = unbound_element_type %B, %i32 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.b.b44: type = struct_type {.base: %A, .b: %i32} [concrete] // CHECK:STDOUT: %complete_type.725: = complete_type_witness %struct_type.base.b.b44 [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %C.elem.f0c: type = unbound_element_type %C, %B [concrete] // CHECK:STDOUT: %C.elem.646: type = unbound_element_type %C, %i32 [concrete] -// CHECK:STDOUT: %struct_type.base.c.8e2: type = struct_type {.base: %B, .c: %i32} [concrete] -// CHECK:STDOUT: %complete_type.58a: = complete_type_witness %struct_type.base.c.8e2 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] -// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] -// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %struct_type.base.c.8e2: type = struct_type {.base: %B, .c: %i32} [concrete] +// CHECK:STDOUT: %complete_type.58a: = complete_type_witness %struct_type.base.c.8e2 [concrete] // CHECK:STDOUT: %ConvertCToB.type: type = fn_type @ConvertCToB [concrete] // CHECK:STDOUT: %ConvertCToB: %ConvertCToB.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] -// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] // CHECK:STDOUT: %ConvertBToA.type: type = fn_type @ConvertBToA [concrete] // CHECK:STDOUT: %ConvertBToA: %ConvertBToA.type = struct_value () [concrete] // CHECK:STDOUT: %ConvertCToA.type: type = fn_type @ConvertCToA [concrete] @@ -115,25 +126,21 @@ fn ConvertInit() { // CHECK:STDOUT: %bound_method.047: = bound_method %int_3.1ba, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_3.822: %i32 = int_value 3 [concrete] // CHECK:STDOUT: %C.val: %C = struct_value (%B.val, %int_3.822) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -232,10 +239,61 @@ fn ConvertInit() { // CHECK:STDOUT: %ConvertInit.decl: %ConvertInit.type = fn_decl @ConvertInit [concrete = constants.%ConvertInit] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc19: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc24: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc16: %A.elem = field_decl a, element0 [concrete] +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %i32} [concrete = constants.%struct_type.a.ba9] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a [concrete = constants.%complete_type.fd7] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -251,6 +309,9 @@ fn ConvertInit() { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc21: %B.elem.5c3 = field_decl b, element1 [concrete] +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %struct_type.base.b: type = struct_type {.base: %A, .b: %i32} [concrete = constants.%struct_type.base.b.b44] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base.b [concrete = constants.%complete_type.725] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -269,6 +330,9 @@ fn ConvertInit() { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc26: %C.elem.646 = field_decl c, element1 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %struct_type.base.c: type = struct_type {.base: %B, .c: %i32} [concrete = constants.%struct_type.base.c.8e2] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base.c [concrete = constants.%complete_type.58a] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -281,6 +345,12 @@ fn ConvertInit() { // CHECK:STDOUT: extend %B.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @ConvertCToB(%p.param: %ptr.019) -> %ptr.e79 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %p.ref: %ptr.019 = name_ref p, %p @@ -391,11 +461,9 @@ fn ConvertInit() { // CHECK:STDOUT: %.loc42_59.4: ref %A = converted %.loc42_59.1, %.loc42_59.3 // CHECK:STDOUT: %.loc42_59.5: %A = bind_value %.loc42_59.4 // CHECK:STDOUT: %a: %A = bind_name a, %.loc42_59.5 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc42_57.2, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc42_57.3: = bound_method %.loc42_57.2, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc42_57.2, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.019 = addr_of %.loc42_57.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc42_57.3(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/destroy_calls.carbon b/toolchain/check/testdata/class/destroy_calls.carbon index b75332f74a0e..39dd5723451f 100644 --- a/toolchain/check/testdata/class/destroy_calls.carbon +++ b/toolchain/check/testdata/class/destroy_calls.carbon @@ -115,6 +115,13 @@ fn G() { F({}); } // CHECK:STDOUT: %NoAddr.Make: %NoAddr.Make.type = struct_value () [concrete] // CHECK:STDOUT: %NoAddr.destroy.type: type = fn_type @NoAddr.destroy [concrete] // CHECK:STDOUT: %NoAddr.destroy: %NoAddr.destroy.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.5ce: = impl_witness @NoAddr.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.4b8: type = ptr_type %NoAddr [concrete] +// CHECK:STDOUT: %pattern_type.ba5: type = pattern_type %ptr.4b8 [concrete] +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op.type: type = fn_type @NoAddr.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op: %NoAddr.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %ExplicitReturn: type = class_type @ExplicitReturn [concrete] @@ -124,22 +131,31 @@ fn G() { F({}); } // CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete] // CHECK:STDOUT: %ExplicitReturn.destroy.type: type = fn_type @ExplicitReturn.destroy [concrete] // CHECK:STDOUT: %ExplicitReturn.destroy: %ExplicitReturn.destroy.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.6ac: = impl_witness @ExplicitReturn.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.b0a: type = ptr_type %ExplicitReturn [concrete] +// CHECK:STDOUT: %pattern_type.e7a: type = pattern_type %ptr.b0a [concrete] +// CHECK:STDOUT: %ExplicitReturn.as.Destroy.impl.Op.type: type = fn_type @ExplicitReturn.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %ExplicitReturn.as.Destroy.impl.Op: %ExplicitReturn.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %WithAddr: type = class_type @WithAddr [concrete] // CHECK:STDOUT: %pattern_type.f93: type = pattern_type %WithAddr [concrete] // CHECK:STDOUT: %WithAddr.Make.type: type = fn_type @WithAddr.Make [concrete] // CHECK:STDOUT: %WithAddr.Make: %WithAddr.Make.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %WithAddr [concrete] -// CHECK:STDOUT: %pattern_type.4a0: type = pattern_type %ptr [concrete] -// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %ptr.b4e: type = ptr_type %WithAddr [concrete] +// CHECK:STDOUT: %pattern_type.4a0: type = pattern_type %ptr.b4e [concrete] // CHECK:STDOUT: %WithAddr.destroy.type: type = fn_type @WithAddr.destroy [concrete] // CHECK:STDOUT: %WithAddr.destroy: %WithAddr.destroy.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.934: = impl_witness @WithAddr.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %WithAddr.as.Destroy.impl.Op.type: type = fn_type @WithAddr.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %WithAddr.as.Destroy.impl.Op: %WithAddr.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -155,6 +171,54 @@ fn G() { F({}); } // CHECK:STDOUT: %WithAddr.decl: type = class_decl @WithAddr [concrete = constants.%WithAddr] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @NoAddr.as.Destroy.impl: constants.%NoAddr as constants.%Destroy.type { +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op.decl: %NoAddr.as.Destroy.impl.Op.type = fn_decl @NoAddr.as.Destroy.impl.Op [concrete = constants.%NoAddr.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.ba5 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.ba5 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.4b8 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%NoAddr [concrete = constants.%NoAddr] +// CHECK:STDOUT: %self: %ptr.4b8 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %NoAddr.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @NoAddr.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @ExplicitReturn.as.Destroy.impl: constants.%ExplicitReturn as constants.%Destroy.type { +// CHECK:STDOUT: %ExplicitReturn.as.Destroy.impl.Op.decl: %ExplicitReturn.as.Destroy.impl.Op.type = fn_decl @ExplicitReturn.as.Destroy.impl.Op [concrete = constants.%ExplicitReturn.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.e7a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.e7a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.b0a = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%ExplicitReturn [concrete = constants.%ExplicitReturn] +// CHECK:STDOUT: %self: %ptr.b0a = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %ExplicitReturn.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @ExplicitReturn.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @WithAddr.as.Destroy.impl: constants.%WithAddr as constants.%Destroy.type { +// CHECK:STDOUT: %WithAddr.as.Destroy.impl.Op.decl: %WithAddr.as.Destroy.impl.Op.type = fn_decl @WithAddr.as.Destroy.impl.Op [concrete = constants.%WithAddr.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.4a0 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.4a0 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc14: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.b4e = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%WithAddr [concrete = constants.%WithAddr] +// CHECK:STDOUT: %self: %ptr.b4e = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %WithAddr.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @WithAddr.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @NoAddr { // CHECK:STDOUT: %NoAddr.Make.decl: %NoAddr.Make.type = fn_decl @NoAddr.Make [concrete = constants.%NoAddr.Make] { // CHECK:STDOUT: %return.patt: %pattern_type.88f = return_slot_pattern [concrete] @@ -172,6 +236,9 @@ fn G() { F({}); } // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%NoAddr [concrete = constants.%NoAddr] // CHECK:STDOUT: %self: %NoAddr = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @NoAddr.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@NoAddr.as.Destroy.impl.%NoAddr.as.Destroy.impl.Op.decl), @NoAddr.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.5ce] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -206,6 +273,9 @@ fn G() { F({}); } // CHECK:STDOUT: %return.param: ref %empty_tuple.type = out_param call_param1 // CHECK:STDOUT: %return: ref %empty_tuple.type = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @ExplicitReturn.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@ExplicitReturn.as.Destroy.impl.%ExplicitReturn.as.Destroy.impl.Op.decl), @ExplicitReturn.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.6ac] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -231,13 +301,16 @@ fn G() { F({}); } // CHECK:STDOUT: %self.param_patt: %pattern_type.4a0 = value_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: %.loc16_14: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param: %ptr = value_param call_param0 -// CHECK:STDOUT: %.loc16_29: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %self.param: %ptr.b4e = value_param call_param0 +// CHECK:STDOUT: %.loc16_29: type = splice_block %ptr [concrete = constants.%ptr.b4e] { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%WithAddr [concrete = constants.%WithAddr] -// CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr.b4e] // CHECK:STDOUT: } -// CHECK:STDOUT: %self: %ptr = bind_name self, %self.param +// CHECK:STDOUT: %self: %ptr.b4e = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @WithAddr.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@WithAddr.as.Destroy.impl.%WithAddr.as.Destroy.impl.Op.decl), @WithAddr.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.934] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -253,13 +326,19 @@ fn G() { F({}); } // CHECK:STDOUT: // CHECK:STDOUT: fn @NoAddr.destroy(%self.param: %NoAddr); // CHECK:STDOUT: +// CHECK:STDOUT: fn @NoAddr.as.Destroy.impl.Op(%self.param: %ptr.4b8) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @ExplicitReturn.Make() -> %ExplicitReturn; // CHECK:STDOUT: // CHECK:STDOUT: fn @ExplicitReturn.destroy(%self.param: %ExplicitReturn) -> %empty_tuple.type; // CHECK:STDOUT: +// CHECK:STDOUT: fn @ExplicitReturn.as.Destroy.impl.Op(%self.param: %ptr.b0a) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @WithAddr.Make() -> %WithAddr; // CHECK:STDOUT: -// CHECK:STDOUT: fn @WithAddr.destroy(%self.param: %ptr); +// CHECK:STDOUT: fn @WithAddr.destroy(%self.param: %ptr.b4e); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @WithAddr.as.Destroy.impl.Op(%self.param: %ptr.b4e) = "no_op"; // CHECK:STDOUT: // CHECK:STDOUT: --- implicit_return.carbon // CHECK:STDOUT: @@ -269,25 +348,25 @@ fn G() { F({}); } // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %NoAddr: type = class_type @NoAddr [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.88f: type = pattern_type %NoAddr [concrete] // CHECK:STDOUT: %ExplicitReturn: type = class_type @ExplicitReturn [concrete] // CHECK:STDOUT: %pattern_type.611: type = pattern_type %ExplicitReturn [concrete] // CHECK:STDOUT: %WithAddr: type = class_type @WithAddr [concrete] // CHECK:STDOUT: %pattern_type.f93: type = pattern_type %WithAddr [concrete] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.8f4: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%WithAddr) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bec: %T.as.Destroy.impl.Op.type.8f4 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.91f: = impl_witness imports.%Destroy.impl_witness_table.4f4 [concrete] +// CHECK:STDOUT: %WithAddr.as.Destroy.impl.Op.type: type = fn_type @WithAddr.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %WithAddr.as.Destroy.impl.Op: %WithAddr.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.b4e: type = ptr_type %WithAddr [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.b42: = specific_function %T.as.Destroy.impl.Op.bec, @T.as.Destroy.impl.Op(%WithAddr) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.641: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%ExplicitReturn) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.8e6: %T.as.Destroy.impl.Op.type.641 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.f3a: = impl_witness imports.%Destroy.impl_witness_table.6ea [concrete] +// CHECK:STDOUT: %ExplicitReturn.as.Destroy.impl.Op.type: type = fn_type @ExplicitReturn.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %ExplicitReturn.as.Destroy.impl.Op: %ExplicitReturn.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.b0a: type = ptr_type %ExplicitReturn [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.523: = specific_function %T.as.Destroy.impl.Op.8e6, @T.as.Destroy.impl.Op(%ExplicitReturn) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.73f: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%NoAddr) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d78: %T.as.Destroy.impl.Op.type.73f = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.17d: = impl_witness imports.%Destroy.impl_witness_table.b7c [concrete] +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op.type: type = fn_type @NoAddr.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op: %NoAddr.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.4b8: type = ptr_type %NoAddr [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.8fe: = specific_function %T.as.Destroy.impl.Op.d78, @T.as.Destroy.impl.Op(%NoAddr) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -299,19 +378,34 @@ fn G() { F({}); } // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//types, loc7_1, loaded [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//types, loc7_1, loaded [concrete = constants.%complete_type] // CHECK:STDOUT: %Main.import_ref.f42 = import_ref Main//types, inst18 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.b5b = import_ref Main//types, loc5_22, unloaded // CHECK:STDOUT: %Main.import_ref.1ed = import_ref Main//types, loc6_27, unloaded -// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//types, loc12_1, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Main.import_ref.ee7 = import_ref Main//types, inst42 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//types, loc12_1, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.ee7 = import_ref Main//types, inst80 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.b14 = import_ref Main//types, loc10_30, unloaded // CHECK:STDOUT: %Main.import_ref.f79 = import_ref Main//types, loc11_33, unloaded -// CHECK:STDOUT: %Main.import_ref.8f24d3.3: = import_ref Main//types, loc17_1, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Main.import_ref.95d = import_ref Main//types, inst70 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.3: = import_ref Main//types, loc17_1, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.95d = import_ref Main//types, inst124 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.1cb = import_ref Main//types, loc15_24, unloaded // CHECK:STDOUT: %Main.import_ref.675 = import_ref Main//types, loc16_33, unloaded // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.15b: = import_ref Main//types, loc4_14, loaded [concrete = constants.%Destroy.impl_witness.17d] +// CHECK:STDOUT: %Main.import_ref.09f: type = import_ref Main//types, inst18 [no loc], loaded [concrete = constants.%NoAddr] +// CHECK:STDOUT: %Main.import_ref.cb9298.1: type = import_ref Main//types, inst39 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.022: = import_ref Main//types, loc9_22, loaded [concrete = constants.%Destroy.impl_witness.f3a] +// CHECK:STDOUT: %Main.import_ref.2e8: type = import_ref Main//types, inst80 [no loc], loaded [concrete = constants.%ExplicitReturn] +// CHECK:STDOUT: %Main.import_ref.cb9298.2: type = import_ref Main//types, inst39 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.d7d: = import_ref Main//types, loc14_16, loaded [concrete = constants.%Destroy.impl_witness.91f] +// CHECK:STDOUT: %Main.import_ref.0a2: type = import_ref Main//types, inst124 [no loc], loaded [concrete = constants.%WithAddr] +// CHECK:STDOUT: %Main.import_ref.cb9298.3: type = import_ref Main//types, inst39 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.344: %WithAddr.as.Destroy.impl.Op.type = import_ref Main//types, loc14_16, loaded [concrete = constants.%WithAddr.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.4f4 = impl_witness_table (%Main.import_ref.344), @WithAddr.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.d37: %ExplicitReturn.as.Destroy.impl.Op.type = import_ref Main//types, loc9_22, loaded [concrete = constants.%ExplicitReturn.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.6ea = impl_witness_table (%Main.import_ref.d37), @ExplicitReturn.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.b27: %NoAddr.as.Destroy.impl.Op.type = import_ref Main//types, loc4_14, loaded [concrete = constants.%NoAddr.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.b7c = impl_witness_table (%Main.import_ref.b27), @NoAddr.as.Destroy.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -327,6 +421,21 @@ fn G() { F({}); } // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @NoAddr.as.Destroy.impl: imports.%Main.import_ref.09f as imports.%Main.import_ref.cb9298.1 [from "types.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.15b +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @ExplicitReturn.as.Destroy.impl: imports.%Main.import_ref.2e8 as imports.%Main.import_ref.cb9298.2 [from "types.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.022 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @WithAddr.as.Destroy.impl: imports.%Main.import_ref.0a2 as imports.%Main.import_ref.cb9298.3 [from "types.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.d7d +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @NoAddr [from "types.carbon"] { // CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.1 // CHECK:STDOUT: @@ -377,24 +486,24 @@ fn G() { F({}); } // CHECK:STDOUT: %with_addr.var: ref %WithAddr = var %with_addr.var_patt // CHECK:STDOUT: %WithAddr.ref: type = name_ref WithAddr, imports.%Main.WithAddr [concrete = constants.%WithAddr] // CHECK:STDOUT: %with_addr: ref %WithAddr = bind_name with_addr, %with_addr.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8: = bound_method %with_addr.var, constants.%T.as.Destroy.impl.Op.bec -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.bec, @T.as.Destroy.impl.Op(constants.%WithAddr) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.b42] -// CHECK:STDOUT: %bound_method.loc8: = bound_method %with_addr.var, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %WithAddr.as.Destroy.impl.Op.bound: = bound_method %with_addr.var, constants.%WithAddr.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc8: %ptr.b4e = addr_of %with_addr.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8: init %empty_tuple.type = call %bound_method.loc8(%addr.loc8) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7: = bound_method %explicit_return.var, constants.%T.as.Destroy.impl.Op.8e6 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.8e6, @T.as.Destroy.impl.Op(constants.%ExplicitReturn) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.523] -// CHECK:STDOUT: %bound_method.loc7: = bound_method %explicit_return.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %WithAddr.as.Destroy.impl.Op.call: init %empty_tuple.type = call %WithAddr.as.Destroy.impl.Op.bound(%addr.loc8) +// CHECK:STDOUT: %ExplicitReturn.as.Destroy.impl.Op.bound: = bound_method %explicit_return.var, constants.%ExplicitReturn.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc7: %ptr.b0a = addr_of %explicit_return.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7: init %empty_tuple.type = call %bound_method.loc7(%addr.loc7) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc6: = bound_method %no_addr.var, constants.%T.as.Destroy.impl.Op.d78 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.d78, @T.as.Destroy.impl.Op(constants.%NoAddr) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.8fe] -// CHECK:STDOUT: %bound_method.loc6: = bound_method %no_addr.var, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %ExplicitReturn.as.Destroy.impl.Op.call: init %empty_tuple.type = call %ExplicitReturn.as.Destroy.impl.Op.bound(%addr.loc7) +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op.bound: = bound_method %no_addr.var, constants.%NoAddr.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc6: %ptr.4b8 = addr_of %no_addr.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc6: init %empty_tuple.type = call %bound_method.loc6(%addr.loc6) +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op.call: init %empty_tuple.type = call %NoAddr.as.Destroy.impl.Op.bound(%addr.loc6) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @WithAddr.as.Destroy.impl.Op = "no_op" [from "types.carbon"]; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ExplicitReturn.as.Destroy.impl.Op = "no_op" [from "types.carbon"]; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @NoAddr.as.Destroy.impl.Op = "no_op" [from "types.carbon"]; +// CHECK:STDOUT: // CHECK:STDOUT: --- nested_scope.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -403,7 +512,7 @@ fn G() { F({}); } // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %NoAddr: type = class_type @NoAddr [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.88f: type = pattern_type %NoAddr [concrete] // CHECK:STDOUT: %ExplicitReturn: type = class_type @ExplicitReturn [concrete] // CHECK:STDOUT: %pattern_type.611: type = pattern_type %ExplicitReturn [concrete] @@ -411,18 +520,18 @@ fn G() { F({}); } // CHECK:STDOUT: %pattern_type.f93: type = pattern_type %WithAddr [concrete] // CHECK:STDOUT: %true: bool = bool_literal true [concrete] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.73f: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%NoAddr) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d78: %T.as.Destroy.impl.Op.type.73f = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.17d: = impl_witness imports.%Destroy.impl_witness_table.b7c [concrete] +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op.type: type = fn_type @NoAddr.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op: %NoAddr.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.4b8: type = ptr_type %NoAddr [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.8fe: = specific_function %T.as.Destroy.impl.Op.d78, @T.as.Destroy.impl.Op(%NoAddr) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.8f4: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%WithAddr) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bec: %T.as.Destroy.impl.Op.type.8f4 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.91f: = impl_witness imports.%Destroy.impl_witness_table.4f4 [concrete] +// CHECK:STDOUT: %WithAddr.as.Destroy.impl.Op.type: type = fn_type @WithAddr.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %WithAddr.as.Destroy.impl.Op: %WithAddr.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.b4e: type = ptr_type %WithAddr [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.b42: = specific_function %T.as.Destroy.impl.Op.bec, @T.as.Destroy.impl.Op(%WithAddr) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.641: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%ExplicitReturn) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.8e6: %T.as.Destroy.impl.Op.type.641 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.f3a: = impl_witness imports.%Destroy.impl_witness_table.6ea [concrete] +// CHECK:STDOUT: %ExplicitReturn.as.Destroy.impl.Op.type: type = fn_type @ExplicitReturn.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %ExplicitReturn.as.Destroy.impl.Op: %ExplicitReturn.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.b0a: type = ptr_type %ExplicitReturn [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.523: = specific_function %T.as.Destroy.impl.Op.8e6, @T.as.Destroy.impl.Op(%ExplicitReturn) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -434,19 +543,34 @@ fn G() { F({}); } // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//types, loc7_1, loaded [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//types, loc7_1, loaded [concrete = constants.%complete_type] // CHECK:STDOUT: %Main.import_ref.f42 = import_ref Main//types, inst18 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.b5b = import_ref Main//types, loc5_22, unloaded // CHECK:STDOUT: %Main.import_ref.1ed = import_ref Main//types, loc6_27, unloaded -// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//types, loc12_1, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Main.import_ref.ee7 = import_ref Main//types, inst42 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//types, loc12_1, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.ee7 = import_ref Main//types, inst80 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.b14 = import_ref Main//types, loc10_30, unloaded // CHECK:STDOUT: %Main.import_ref.f79 = import_ref Main//types, loc11_33, unloaded -// CHECK:STDOUT: %Main.import_ref.8f24d3.3: = import_ref Main//types, loc17_1, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Main.import_ref.95d = import_ref Main//types, inst70 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.3: = import_ref Main//types, loc17_1, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.95d = import_ref Main//types, inst124 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.1cb = import_ref Main//types, loc15_24, unloaded // CHECK:STDOUT: %Main.import_ref.675 = import_ref Main//types, loc16_33, unloaded // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.15b: = import_ref Main//types, loc4_14, loaded [concrete = constants.%Destroy.impl_witness.17d] +// CHECK:STDOUT: %Main.import_ref.09f: type = import_ref Main//types, inst18 [no loc], loaded [concrete = constants.%NoAddr] +// CHECK:STDOUT: %Main.import_ref.cb9298.1: type = import_ref Main//types, inst39 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.022: = import_ref Main//types, loc9_22, loaded [concrete = constants.%Destroy.impl_witness.f3a] +// CHECK:STDOUT: %Main.import_ref.2e8: type = import_ref Main//types, inst80 [no loc], loaded [concrete = constants.%ExplicitReturn] +// CHECK:STDOUT: %Main.import_ref.cb9298.2: type = import_ref Main//types, inst39 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.d7d: = import_ref Main//types, loc14_16, loaded [concrete = constants.%Destroy.impl_witness.91f] +// CHECK:STDOUT: %Main.import_ref.0a2: type = import_ref Main//types, inst124 [no loc], loaded [concrete = constants.%WithAddr] +// CHECK:STDOUT: %Main.import_ref.cb9298.3: type = import_ref Main//types, inst39 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.b27: %NoAddr.as.Destroy.impl.Op.type = import_ref Main//types, loc4_14, loaded [concrete = constants.%NoAddr.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.b7c = impl_witness_table (%Main.import_ref.b27), @NoAddr.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.344: %WithAddr.as.Destroy.impl.Op.type = import_ref Main//types, loc14_16, loaded [concrete = constants.%WithAddr.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.4f4 = impl_witness_table (%Main.import_ref.344), @WithAddr.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.d37: %ExplicitReturn.as.Destroy.impl.Op.type = import_ref Main//types, loc9_22, loaded [concrete = constants.%ExplicitReturn.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.6ea = impl_witness_table (%Main.import_ref.d37), @ExplicitReturn.as.Destroy.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -462,6 +586,21 @@ fn G() { F({}); } // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @NoAddr.as.Destroy.impl: imports.%Main.import_ref.09f as imports.%Main.import_ref.cb9298.1 [from "types.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.15b +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @ExplicitReturn.as.Destroy.impl: imports.%Main.import_ref.2e8 as imports.%Main.import_ref.cb9298.2 [from "types.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.022 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @WithAddr.as.Destroy.impl: imports.%Main.import_ref.0a2 as imports.%Main.import_ref.cb9298.3 [from "types.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.d7d +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @NoAddr [from "types.carbon"] { // CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.1 // CHECK:STDOUT: @@ -526,29 +665,27 @@ fn G() { F({}); } // CHECK:STDOUT: br !if.else // CHECK:STDOUT: // CHECK:STDOUT: !if.else: -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10: = bound_method %in_scope.var, constants.%T.as.Destroy.impl.Op.d78 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.d78, @T.as.Destroy.impl.Op(constants.%NoAddr) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.8fe] -// CHECK:STDOUT: %bound_method.loc10: = bound_method %in_scope.var, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op.bound.loc10: = bound_method %in_scope.var, constants.%NoAddr.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc10: %ptr.4b8 = addr_of %in_scope.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10: init %empty_tuple.type = call %bound_method.loc10(%addr.loc10) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8: = bound_method %with_addr.var, constants.%T.as.Destroy.impl.Op.bec -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.bec, @T.as.Destroy.impl.Op(constants.%WithAddr) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.b42] -// CHECK:STDOUT: %bound_method.loc8: = bound_method %with_addr.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op.call.loc10: init %empty_tuple.type = call %NoAddr.as.Destroy.impl.Op.bound.loc10(%addr.loc10) +// CHECK:STDOUT: %WithAddr.as.Destroy.impl.Op.bound: = bound_method %with_addr.var, constants.%WithAddr.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc8: %ptr.b4e = addr_of %with_addr.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8: init %empty_tuple.type = call %bound_method.loc8(%addr.loc8) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7: = bound_method %explicit_return.var, constants.%T.as.Destroy.impl.Op.8e6 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.8e6, @T.as.Destroy.impl.Op(constants.%ExplicitReturn) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.523] -// CHECK:STDOUT: %bound_method.loc7: = bound_method %explicit_return.var, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %WithAddr.as.Destroy.impl.Op.call: init %empty_tuple.type = call %WithAddr.as.Destroy.impl.Op.bound(%addr.loc8) +// CHECK:STDOUT: %ExplicitReturn.as.Destroy.impl.Op.bound: = bound_method %explicit_return.var, constants.%ExplicitReturn.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc7: %ptr.b0a = addr_of %explicit_return.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7: init %empty_tuple.type = call %bound_method.loc7(%addr.loc7) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc6: = bound_method %no_addr.var, constants.%T.as.Destroy.impl.Op.d78 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.4: = specific_function constants.%T.as.Destroy.impl.Op.d78, @T.as.Destroy.impl.Op(constants.%NoAddr) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.8fe] -// CHECK:STDOUT: %bound_method.loc6: = bound_method %no_addr.var, %T.as.Destroy.impl.Op.specific_fn.4 +// CHECK:STDOUT: %ExplicitReturn.as.Destroy.impl.Op.call: init %empty_tuple.type = call %ExplicitReturn.as.Destroy.impl.Op.bound(%addr.loc7) +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op.bound.loc6: = bound_method %no_addr.var, constants.%NoAddr.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc6: %ptr.4b8 = addr_of %no_addr.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc6: init %empty_tuple.type = call %bound_method.loc6(%addr.loc6) +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op.call.loc6: init %empty_tuple.type = call %NoAddr.as.Destroy.impl.Op.bound.loc6(%addr.loc6) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @NoAddr.as.Destroy.impl.Op = "no_op" [from "types.carbon"]; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @WithAddr.as.Destroy.impl.Op = "no_op" [from "types.carbon"]; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ExplicitReturn.as.Destroy.impl.Op = "no_op" [from "types.carbon"]; +// CHECK:STDOUT: // CHECK:STDOUT: --- temp.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -557,7 +694,7 @@ fn G() { F({}); } // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %NoAddr: type = class_type @NoAddr [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %NoAddr.Make.type: type = fn_type @NoAddr.Make [concrete] // CHECK:STDOUT: %NoAddr.Make: %NoAddr.Make.type = struct_value () [concrete] // CHECK:STDOUT: %ExplicitReturn: type = class_type @ExplicitReturn [concrete] @@ -567,18 +704,18 @@ fn G() { F({}); } // CHECK:STDOUT: %WithAddr.Make.type: type = fn_type @WithAddr.Make [concrete] // CHECK:STDOUT: %WithAddr.Make: %WithAddr.Make.type = struct_value () [concrete] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.8f4: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%WithAddr) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bec: %T.as.Destroy.impl.Op.type.8f4 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.91f: = impl_witness imports.%Destroy.impl_witness_table.4f4 [concrete] +// CHECK:STDOUT: %WithAddr.as.Destroy.impl.Op.type: type = fn_type @WithAddr.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %WithAddr.as.Destroy.impl.Op: %WithAddr.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.b4e: type = ptr_type %WithAddr [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.b42: = specific_function %T.as.Destroy.impl.Op.bec, @T.as.Destroy.impl.Op(%WithAddr) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.641: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%ExplicitReturn) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.8e6: %T.as.Destroy.impl.Op.type.641 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.f3a: = impl_witness imports.%Destroy.impl_witness_table.6ea [concrete] +// CHECK:STDOUT: %ExplicitReturn.as.Destroy.impl.Op.type: type = fn_type @ExplicitReturn.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %ExplicitReturn.as.Destroy.impl.Op: %ExplicitReturn.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.b0a: type = ptr_type %ExplicitReturn [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.523: = specific_function %T.as.Destroy.impl.Op.8e6, @T.as.Destroy.impl.Op(%ExplicitReturn) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.73f: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%NoAddr) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d78: %T.as.Destroy.impl.Op.type.73f = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.17d: = impl_witness imports.%Destroy.impl_witness_table.b7c [concrete] +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op.type: type = fn_type @NoAddr.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op: %NoAddr.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.4b8: type = ptr_type %NoAddr [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.8fe: = specific_function %T.as.Destroy.impl.Op.d78, @T.as.Destroy.impl.Op(%NoAddr) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -590,19 +727,34 @@ fn G() { F({}); } // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//types, loc7_1, loaded [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//types, loc7_1, loaded [concrete = constants.%complete_type] // CHECK:STDOUT: %Main.import_ref.f42 = import_ref Main//types, inst18 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.784: %NoAddr.Make.type = import_ref Main//types, loc5_22, loaded [concrete = constants.%NoAddr.Make] // CHECK:STDOUT: %Main.import_ref.1ed = import_ref Main//types, loc6_27, unloaded -// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//types, loc12_1, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Main.import_ref.ee7 = import_ref Main//types, inst42 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//types, loc12_1, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.ee7 = import_ref Main//types, inst80 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.8e0: %ExplicitReturn.Make.type = import_ref Main//types, loc10_30, loaded [concrete = constants.%ExplicitReturn.Make] // CHECK:STDOUT: %Main.import_ref.f79 = import_ref Main//types, loc11_33, unloaded -// CHECK:STDOUT: %Main.import_ref.8f24d3.3: = import_ref Main//types, loc17_1, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Main.import_ref.95d = import_ref Main//types, inst70 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.3: = import_ref Main//types, loc17_1, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.95d = import_ref Main//types, inst124 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.974: %WithAddr.Make.type = import_ref Main//types, loc15_24, loaded [concrete = constants.%WithAddr.Make] // CHECK:STDOUT: %Main.import_ref.675 = import_ref Main//types, loc16_33, unloaded // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.15b: = import_ref Main//types, loc4_14, loaded [concrete = constants.%Destroy.impl_witness.17d] +// CHECK:STDOUT: %Main.import_ref.09f: type = import_ref Main//types, inst18 [no loc], loaded [concrete = constants.%NoAddr] +// CHECK:STDOUT: %Main.import_ref.cb9298.1: type = import_ref Main//types, inst39 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.022: = import_ref Main//types, loc9_22, loaded [concrete = constants.%Destroy.impl_witness.f3a] +// CHECK:STDOUT: %Main.import_ref.2e8: type = import_ref Main//types, inst80 [no loc], loaded [concrete = constants.%ExplicitReturn] +// CHECK:STDOUT: %Main.import_ref.cb9298.2: type = import_ref Main//types, inst39 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.d7d: = import_ref Main//types, loc14_16, loaded [concrete = constants.%Destroy.impl_witness.91f] +// CHECK:STDOUT: %Main.import_ref.0a2: type = import_ref Main//types, inst124 [no loc], loaded [concrete = constants.%WithAddr] +// CHECK:STDOUT: %Main.import_ref.cb9298.3: type = import_ref Main//types, inst39 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.344: %WithAddr.as.Destroy.impl.Op.type = import_ref Main//types, loc14_16, loaded [concrete = constants.%WithAddr.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.4f4 = impl_witness_table (%Main.import_ref.344), @WithAddr.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.d37: %ExplicitReturn.as.Destroy.impl.Op.type = import_ref Main//types, loc9_22, loaded [concrete = constants.%ExplicitReturn.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.6ea = impl_witness_table (%Main.import_ref.d37), @ExplicitReturn.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.b27: %NoAddr.as.Destroy.impl.Op.type = import_ref Main//types, loc4_14, loaded [concrete = constants.%NoAddr.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.b7c = impl_witness_table (%Main.import_ref.b27), @NoAddr.as.Destroy.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -618,6 +770,21 @@ fn G() { F({}); } // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @NoAddr.as.Destroy.impl: imports.%Main.import_ref.09f as imports.%Main.import_ref.cb9298.1 [from "types.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.15b +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @ExplicitReturn.as.Destroy.impl: imports.%Main.import_ref.2e8 as imports.%Main.import_ref.cb9298.2 [from "types.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.022 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @WithAddr.as.Destroy.impl: imports.%Main.import_ref.0a2 as imports.%Main.import_ref.cb9298.3 [from "types.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.d7d +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @NoAddr [from "types.carbon"] { // CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.1 // CHECK:STDOUT: @@ -662,21 +829,15 @@ fn G() { F({}); } // CHECK:STDOUT: %.loc10_17.1: ref %WithAddr = temporary_storage // CHECK:STDOUT: %WithAddr.Make.call: init %WithAddr = call %Make.ref.loc10() to %.loc10_17.1 // CHECK:STDOUT: %.loc10_17.2: ref %WithAddr = temporary %.loc10_17.1, %WithAddr.Make.call -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10: = bound_method %.loc10_17.1, constants.%T.as.Destroy.impl.Op.bec -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.bec, @T.as.Destroy.impl.Op(constants.%WithAddr) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.b42] -// CHECK:STDOUT: %bound_method.loc10: = bound_method %.loc10_17.1, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %WithAddr.as.Destroy.impl.Op.bound: = bound_method %.loc10_17.1, constants.%WithAddr.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc10: %ptr.b4e = addr_of %.loc10_17.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10: init %empty_tuple.type = call %bound_method.loc10(%addr.loc10) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9: = bound_method %.loc9_23.1, constants.%T.as.Destroy.impl.Op.8e6 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.8e6, @T.as.Destroy.impl.Op(constants.%ExplicitReturn) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.523] -// CHECK:STDOUT: %bound_method.loc9: = bound_method %.loc9_23.1, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %WithAddr.as.Destroy.impl.Op.call: init %empty_tuple.type = call %WithAddr.as.Destroy.impl.Op.bound(%addr.loc10) +// CHECK:STDOUT: %ExplicitReturn.as.Destroy.impl.Op.bound: = bound_method %.loc9_23.1, constants.%ExplicitReturn.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc9: %ptr.b0a = addr_of %.loc9_23.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9: init %empty_tuple.type = call %bound_method.loc9(%addr.loc9) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8: = bound_method %.loc8_15.1, constants.%T.as.Destroy.impl.Op.d78 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.d78, @T.as.Destroy.impl.Op(constants.%NoAddr) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.8fe] -// CHECK:STDOUT: %bound_method.loc8: = bound_method %.loc8_15.1, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %ExplicitReturn.as.Destroy.impl.Op.call: init %empty_tuple.type = call %ExplicitReturn.as.Destroy.impl.Op.bound(%addr.loc9) +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op.bound: = bound_method %.loc8_15.1, constants.%NoAddr.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc8: %ptr.4b8 = addr_of %.loc8_15.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8: init %empty_tuple.type = call %bound_method.loc8(%addr.loc8) +// CHECK:STDOUT: %NoAddr.as.Destroy.impl.Op.call: init %empty_tuple.type = call %NoAddr.as.Destroy.impl.Op.bound(%addr.loc8) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -686,6 +847,12 @@ fn G() { F({}); } // CHECK:STDOUT: // CHECK:STDOUT: fn @WithAddr.Make [from "types.carbon"]; // CHECK:STDOUT: +// CHECK:STDOUT: fn @WithAddr.as.Destroy.impl.Op = "no_op" [from "types.carbon"]; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ExplicitReturn.as.Destroy.impl.Op = "no_op" [from "types.carbon"]; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @NoAddr.as.Destroy.impl.Op = "no_op" [from "types.carbon"]; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_recovery.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -693,25 +860,28 @@ fn G() { F({}); } // CHECK:STDOUT: %NoSelf.destroy.type: type = fn_type @NoSelf.destroy [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %NoSelf.destroy: %NoSelf.destroy.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d11: = impl_witness @NoSelf.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.5ab: type = ptr_type %NoSelf [concrete] +// CHECK:STDOUT: %pattern_type.a98: type = pattern_type %ptr.5ab [concrete] +// CHECK:STDOUT: %NoSelf.as.Destroy.impl.Op.type: type = fn_type @NoSelf.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %NoSelf.as.Destroy.impl.Op: %NoSelf.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Args: type = class_type @Args [concrete] // CHECK:STDOUT: %pattern_type.a81: type = pattern_type %Args [concrete] // CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete] // CHECK:STDOUT: %Args.destroy.type: type = fn_type @Args.destroy [concrete] // CHECK:STDOUT: %Args.destroy: %Args.destroy.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.318: = impl_witness @Args.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.7b2: type = ptr_type %Args [concrete] +// CHECK:STDOUT: %pattern_type.8cf: type = pattern_type %ptr.7b2 [concrete] +// CHECK:STDOUT: %Args.as.Destroy.impl.Op.type: type = fn_type @Args.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Args.as.Destroy.impl.Op: %Args.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.9f4: type = pattern_type %NoSelf [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.59d: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Args) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.a71: %T.as.Destroy.impl.Op.type.59d = struct_value () [concrete] -// CHECK:STDOUT: %ptr.7b2: type = ptr_type %Args [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.242: = specific_function %T.as.Destroy.impl.Op.a71, @T.as.Destroy.impl.Op(%Args) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.f20: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%NoSelf) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.2e0: %T.as.Destroy.impl.Op.type.f20 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.5ab: type = ptr_type %NoSelf [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.a58: = specific_function %T.as.Destroy.impl.Op.2e0, @T.as.Destroy.impl.Op(%NoSelf) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -736,10 +906,45 @@ fn G() { F({}); } // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @NoSelf.as.Destroy.impl: constants.%NoSelf as constants.%Destroy.type { +// CHECK:STDOUT: %NoSelf.as.Destroy.impl.Op.decl: %NoSelf.as.Destroy.impl.Op.type = fn_decl @NoSelf.as.Destroy.impl.Op [concrete = constants.%NoSelf.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a98 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a98 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.5ab = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%NoSelf [concrete = constants.%NoSelf] +// CHECK:STDOUT: %self: %ptr.5ab = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %NoSelf.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @NoSelf.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Args.as.Destroy.impl: constants.%Args as constants.%Destroy.type { +// CHECK:STDOUT: %Args.as.Destroy.impl.Op.decl: %Args.as.Destroy.impl.Op.type = fn_decl @Args.as.Destroy.impl.Op [concrete = constants.%Args.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.8cf = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.8cf = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.7b2 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Args [concrete = constants.%Args] +// CHECK:STDOUT: %self: %ptr.7b2 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Args.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Args.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @NoSelf { // CHECK:STDOUT: %NoSelf.destroy.decl: %NoSelf.destroy.type = fn_decl @NoSelf.destroy [concrete = constants.%NoSelf.destroy] {} {} +// CHECK:STDOUT: impl_decl @NoSelf.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@NoSelf.as.Destroy.impl.%NoSelf.as.Destroy.impl.Op.decl), @NoSelf.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.d11] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -764,8 +969,11 @@ fn G() { F({}); } // CHECK:STDOUT: } // CHECK:STDOUT: %x: %empty_tuple.type = bind_name x, %x.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Args.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Args.as.Destroy.impl.%Args.as.Destroy.impl.Op.decl), @Args.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.318] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -775,8 +983,12 @@ fn G() { F({}); } // CHECK:STDOUT: // CHECK:STDOUT: fn @NoSelf.destroy(); // CHECK:STDOUT: +// CHECK:STDOUT: fn @NoSelf.as.Destroy.impl.Op(%self.param: %ptr.5ab) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Args.destroy(%self.param: %Args, %x.param: %empty_tuple.type); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Args.as.Destroy.impl.Op(%self.param: %ptr.7b2) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -793,16 +1005,12 @@ fn G() { F({}); } // CHECK:STDOUT: %b.var: ref %Args = var %b.var_patt // CHECK:STDOUT: %Args.ref: type = name_ref Args, file.%Args.decl [concrete = constants.%Args] // CHECK:STDOUT: %b: ref %Args = bind_name b, %b.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc22: = bound_method %b.var, constants.%T.as.Destroy.impl.Op.a71 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.a71, @T.as.Destroy.impl.Op(constants.%Args) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.242] -// CHECK:STDOUT: %bound_method.loc22: = bound_method %b.var, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %Args.as.Destroy.impl.Op.bound: = bound_method %b.var, constants.%Args.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc22: %ptr.7b2 = addr_of %b.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc22: init %empty_tuple.type = call %bound_method.loc22(%addr.loc22) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc21: = bound_method %a.var, constants.%T.as.Destroy.impl.Op.2e0 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.2e0, @T.as.Destroy.impl.Op(constants.%NoSelf) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.a58] -// CHECK:STDOUT: %bound_method.loc21: = bound_method %a.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %Args.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Args.as.Destroy.impl.Op.bound(%addr.loc22) +// CHECK:STDOUT: %NoSelf.as.Destroy.impl.Op.bound: = bound_method %a.var, constants.%NoSelf.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc21: %ptr.5ab = addr_of %a.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc21: init %empty_tuple.type = call %bound_method.loc21(%addr.loc21) +// CHECK:STDOUT: %NoSelf.as.Destroy.impl.Op.call: init %empty_tuple.type = call %NoSelf.as.Destroy.impl.Op.bound(%addr.loc21) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -815,37 +1023,38 @@ fn G() { F({}); } // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.f2e: type = class_type @C, @C(%T.8b3d5d.1) [template] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.a08: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T.8b3d5d.1) [template] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [template] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [template] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type.7a1: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T.8b3d5d.1) [template] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.d65: %C.as.Destroy.impl.Op.type.7a1 = struct_value () [template] +// CHECK:STDOUT: %Destroy.facet.d7f: %Destroy.type = facet_value %C.f2e, (%Destroy.impl_witness.a08) [template] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.389: = require_complete_type %C.f2e [template] // CHECK:STDOUT: %pattern_type.e5e: type = pattern_type %C.f2e [template] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] -// CHECK:STDOUT: %T.8b3d5d.2: type = bind_symbolic_name T, 0 [symbolic] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.bc9: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%T.8b3d5d.2) [symbolic] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.46f: %T.as.Destroy.impl.Op.type.bc9 = struct_value () [symbolic] -// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [template] +// CHECK:STDOUT: %.a2f: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.d7f [template] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.specific_fn.67e: = specific_function %C.as.Destroy.impl.Op.d65, @C.as.Destroy.impl.Op(%T.8b3d5d.1) [template] // CHECK:STDOUT: %require_complete.448: = require_complete_type %ptr.7d2 [template] -// CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %C.f2e, @Destroy [template] -// CHECK:STDOUT: %Destroy.facet.d66: %Destroy.type = facet_value %C.f2e, (%Destroy.lookup_impl_witness) [template] -// CHECK:STDOUT: %.eb5: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.d66 [template] -// CHECK:STDOUT: %impl.elem0: %.eb5 = impl_witness_access %Destroy.lookup_impl_witness, element0 [template] -// CHECK:STDOUT: %specific_impl_fn: = specific_impl_function %impl.elem0, @Destroy.Op(%Destroy.facet.d66) [template] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%empty_struct_type) [concrete] // CHECK:STDOUT: %C.7a7: type = class_type @C, @C(%empty_struct_type) [concrete] // CHECK:STDOUT: %pattern_type.99a: type = pattern_type %C.7a7 [concrete] -// CHECK:STDOUT: %Destroy.impl_witness.a3f: = impl_witness imports.%Destroy.impl_witness_table, @T.as.Destroy.impl(%C.7a7) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.add: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.7a7) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.b1c: %T.as.Destroy.impl.Op.type.add = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b34: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%empty_struct_type) [concrete] +// CHECK:STDOUT: %Destroy.facet.5e7: %Destroy.type = facet_value %C.7a7, (%Destroy.impl_witness.b34) [concrete] +// CHECK:STDOUT: %.ec8: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.5e7 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type.f57: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%empty_struct_type) [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.a9a: %C.as.Destroy.impl.Op.type.f57 = struct_value () [concrete] // CHECK:STDOUT: %ptr.308: type = ptr_type %C.7a7 [concrete] +// CHECK:STDOUT: %pattern_type.558: type = pattern_type %ptr.308 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.specific_fn.d47: = specific_function %C.as.Destroy.impl.Op.a9a, @C.as.Destroy.impl.Op(%empty_struct_type) [concrete] // CHECK:STDOUT: %complete_type.903: = complete_type_witness %ptr.308 [concrete] -// CHECK:STDOUT: %Destroy.facet.f20: %Destroy.type = facet_value %C.7a7, (%Destroy.impl_witness.a3f) [concrete] -// CHECK:STDOUT: %.2d6: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.f20 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.b1c, @T.as.Destroy.impl.Op(%C.7a7) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -855,8 +1064,6 @@ fn G() { F({}); } // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] -// CHECK:STDOUT: %Core.import_ref.0b9: @T.as.Destroy.impl.%T.as.Destroy.impl.Op.type (%T.as.Destroy.impl.Op.type.bc9) = import_ref Core//prelude/parts/destroy, loc8_29, loaded [symbolic = @T.as.Destroy.impl.%T.as.Destroy.impl.Op (constants.%T.as.Destroy.impl.Op.46f)] -// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (%Core.import_ref.0b9), @T.as.Destroy.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -880,12 +1087,43 @@ fn G() { F({}); } // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc3_18.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0, template [template = %T (constants.%T.8b3d5d.1)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [template = %Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [template = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type.7a1)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type.7a1) = struct_value () [template = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op.d65)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f2e as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type.7a1) = fn_decl @C.as.Destroy.impl.Op [template = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op.d65)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc3_28.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc3_28.2: type = splice_block %Self.ref [template = %C (constants.%C.f2e)] { +// CHECK:STDOUT: %.loc3_28.3: type = specific_constant constants.%C.f2e, @C(constants.%T.8b3d5d.1) [template = %C (constants.%C.f2e)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc3_28.3 [template = %C (constants.%C.f2e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%T.loc3_18.2: type) { // CHECK:STDOUT: %T.loc3_18.1: type = bind_symbolic_name T, 0, template [template = %T.loc3_18.1 (constants.%T.8b3d5d.1)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T.8b3d5d.1) [template = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -895,6 +1133,17 @@ fn G() { F({}); } // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc3_18.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0, template [template = %T (constants.%T.8b3d5d.1)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [template = %C (constants.%C.f2e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [template = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [template = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc5_15.2: type) { // CHECK:STDOUT: %T.loc5_15.1: type = bind_symbolic_name T, 0, template [template = %T.loc5_15.1 (constants.%T.8b3d5d.1)] // CHECK:STDOUT: @@ -902,11 +1151,12 @@ fn G() { F({}); } // CHECK:STDOUT: %C.loc6_13.2: type = class_type @C, @C(%T.loc5_15.1) [template = %C.loc6_13.2 (constants.%C.f2e)] // CHECK:STDOUT: %require_complete.loc6_13: = require_complete_type %C.loc6_13.2 [template = %require_complete.loc6_13 (constants.%require_complete.389)] // CHECK:STDOUT: %pattern_type: type = pattern_type %C.loc6_13.2 [template = %pattern_type (constants.%pattern_type.e5e)] -// CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %C.loc6_13.2, @Destroy [template = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)] -// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %C.loc6_13.2, (%Destroy.lookup_impl_witness) [template = %Destroy.facet (constants.%Destroy.facet.d66)] -// CHECK:STDOUT: %.loc6_3.2: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [template = %.loc6_3.2 (constants.%.eb5)] -// CHECK:STDOUT: %impl.elem0.loc6_3.2: @F.%.loc6_3.2 (%.eb5) = impl_witness_access %Destroy.lookup_impl_witness, element0 [template = %impl.elem0.loc6_3.2 (constants.%impl.elem0)] -// CHECK:STDOUT: %specific_impl_fn.loc6_3.2: = specific_impl_function %impl.elem0.loc6_3.2, @Destroy.Op(%Destroy.facet) [template = %specific_impl_fn.loc6_3.2 (constants.%specific_impl_fn)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T.loc5_15.1) [template = %Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] +// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %C.loc6_13.2, (%Destroy.impl_witness) [template = %Destroy.facet (constants.%Destroy.facet.d7f)] +// CHECK:STDOUT: %.loc6_3: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [template = %.loc6_3 (constants.%.a2f)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T.loc5_15.1) [template = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type.7a1)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @F.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type.7a1) = struct_value () [template = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op.d65)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.specific_fn: = specific_function %C.as.Destroy.impl.Op, @C.as.Destroy.impl.Op(%T.loc5_15.1) [template = %C.as.Destroy.impl.Op.specific_fn (constants.%C.as.Destroy.impl.Op.specific_fn.67e)] // CHECK:STDOUT: %ptr: type = ptr_type %C.loc6_13.2 [template = %ptr (constants.%ptr.7d2)] // CHECK:STDOUT: %require_complete.loc6_3: = require_complete_type %ptr [template = %require_complete.loc6_3 (constants.%require_complete.448)] // CHECK:STDOUT: @@ -923,12 +1173,12 @@ fn G() { F({}); } // CHECK:STDOUT: %C.loc6_13.1: type = class_type @C, @C(constants.%T.8b3d5d.1) [template = %C.loc6_13.2 (constants.%C.f2e)] // CHECK:STDOUT: } // CHECK:STDOUT: %v: ref @F.%C.loc6_13.2 (%C.f2e) = bind_name v, %v.var -// CHECK:STDOUT: %impl.elem0.loc6_3.1: @F.%.loc6_3.2 (%.eb5) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [template = %impl.elem0.loc6_3.2 (constants.%impl.elem0)] -// CHECK:STDOUT: %bound_method.loc6_3.1: = bound_method %v.var, %impl.elem0.loc6_3.1 -// CHECK:STDOUT: %specific_impl_fn.loc6_3.1: = specific_impl_function %impl.elem0.loc6_3.1, @Destroy.Op(constants.%Destroy.facet.d66) [template = %specific_impl_fn.loc6_3.2 (constants.%specific_impl_fn)] -// CHECK:STDOUT: %bound_method.loc6_3.2: = bound_method %v.var, %specific_impl_fn.loc6_3.1 +// CHECK:STDOUT: %impl.elem0: @F.%.loc6_3 (%.a2f) = impl_witness_access constants.%Destroy.impl_witness.a08, element0 [template = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op.d65)] +// CHECK:STDOUT: %bound_method.loc6_3.1: = bound_method %v.var, %impl.elem0 +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @C.as.Destroy.impl.Op(constants.%T.8b3d5d.1) [template = %C.as.Destroy.impl.Op.specific_fn (constants.%C.as.Destroy.impl.Op.specific_fn.67e)] +// CHECK:STDOUT: %bound_method.loc6_3.2: = bound_method %v.var, %specific_fn // CHECK:STDOUT: %addr: @F.%ptr (%ptr.7d2) = addr_of %v.var -// CHECK:STDOUT: %.loc6_3.1: init %empty_tuple.type = call %bound_method.loc6_3.2(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc6_3.2(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -949,6 +1199,22 @@ fn G() { F({}); } // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T.8b3d5d.1) { +// CHECK:STDOUT: %T => constants.%T.8b3d5d.1 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a08 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type => constants.%C.as.Destroy.impl.Op.type.7a1 +// CHECK:STDOUT: %C.as.Destroy.impl.Op => constants.%C.as.Destroy.impl.Op.d65 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T.8b3d5d.1) { +// CHECK:STDOUT: %T => constants.%T.8b3d5d.1 +// CHECK:STDOUT: %C => constants.%C.f2e +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%T.8b3d5d.1) { // CHECK:STDOUT: %T.loc5_15.1 => constants.%T.8b3d5d.1 // CHECK:STDOUT: } @@ -960,11 +1226,12 @@ fn G() { F({}); } // CHECK:STDOUT: %C.loc6_13.2 => constants.%C.7a7 // CHECK:STDOUT: %require_complete.loc6_13 => constants.%complete_type.357 // CHECK:STDOUT: %pattern_type => constants.%pattern_type.99a -// CHECK:STDOUT: %Destroy.lookup_impl_witness => constants.%Destroy.impl_witness.a3f -// CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.f20 -// CHECK:STDOUT: %.loc6_3.2 => constants.%.2d6 -// CHECK:STDOUT: %impl.elem0.loc6_3.2 => constants.%T.as.Destroy.impl.Op.b1c -// CHECK:STDOUT: %specific_impl_fn.loc6_3.2 => constants.%T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.b34 +// CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.5e7 +// CHECK:STDOUT: %.loc6_3 => constants.%.ec8 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type => constants.%C.as.Destroy.impl.Op.type.f57 +// CHECK:STDOUT: %C.as.Destroy.impl.Op => constants.%C.as.Destroy.impl.Op.a9a +// CHECK:STDOUT: %C.as.Destroy.impl.Op.specific_fn => constants.%C.as.Destroy.impl.Op.specific_fn.d47 // CHECK:STDOUT: %ptr => constants.%ptr.308 // CHECK:STDOUT: %require_complete.loc6_3 => constants.%complete_type.903 // CHECK:STDOUT: } @@ -975,3 +1242,15 @@ fn G() { F({}); } // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%empty_struct_type) { +// CHECK:STDOUT: %T => constants.%empty_struct_type +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.b34 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%empty_struct_type) { +// CHECK:STDOUT: %T => constants.%empty_struct_type +// CHECK:STDOUT: %C => constants.%C.7a7 +// CHECK:STDOUT: %ptr => constants.%ptr.308 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.558 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/destroy_decl.carbon b/toolchain/check/testdata/class/destroy_decl.carbon index 1e0d34df6ed7..0cb8065d78bf 100644 --- a/toolchain/check/testdata/class/destroy_decl.carbon +++ b/toolchain/check/testdata/class/destroy_decl.carbon @@ -18,6 +18,31 @@ class C { fn destroy[self: Self](); } +// --- declare_impl.carbon + +library "[[@TEST_NAME]]"; + +class C { + impl as Core.Destroy; +} + +// --- fail_define_impl.carbon + +library "[[@TEST_NAME]]"; + +// CHECK:STDERR: fail_define_impl.carbon:[[@LINE+3]]:1: error: redefinition of `impl C as Core.Destroy` [ImplRedefinition] +// CHECK:STDERR: class C { +// CHECK:STDERR: ^~~~~~~~~ +class C { + // CHECK:STDERR: fail_define_impl.carbon:[[@LINE+4]]:3: note: previous definition was here [ImplPreviousDefinition] + // CHECK:STDERR: impl as Core.Destroy { + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + impl as Core.Destroy { + fn Op[addr self: Self*]() {} + } +} + // --- addr_self.carbon library "[[@TEST_NAME]]"; diff --git a/toolchain/check/testdata/class/fail_abstract.carbon b/toolchain/check/testdata/class/fail_abstract.carbon index 4cac41021b7d..e5bd1eb04aa5 100644 --- a/toolchain/check/testdata/class/fail_abstract.carbon +++ b/toolchain/check/testdata/class/fail_abstract.carbon @@ -197,16 +197,30 @@ fn CallReturnAbstract() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract: type = class_type @Abstract [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9d1: = impl_witness @Abstract.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.f31: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.type: type = fn_type @Abstract.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op: %Abstract.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Contains: type = class_type @Contains [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.6a6: = impl_witness @Contains.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.216: type = ptr_type %Contains [concrete] +// CHECK:STDOUT: %pattern_type.cce: type = pattern_type %ptr.216 [concrete] +// CHECK:STDOUT: %Contains.as.Destroy.impl.Op.type: type = fn_type @Contains.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Contains.as.Destroy.impl.Op: %Contains.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -220,7 +234,42 @@ fn CallReturnAbstract() { // CHECK:STDOUT: %Contains.decl: type = class_decl @Contains [concrete = constants.%Contains] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract.as.Destroy.impl: constants.%Abstract as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.decl: %Abstract.as.Destroy.impl.Op.type = fn_decl @Abstract.as.Destroy.impl.Op [concrete = constants.%Abstract.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f31 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f31 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract [concrete = constants.%Abstract] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Contains.as.Destroy.impl: constants.%Contains as constants.%Destroy.type { +// CHECK:STDOUT: %Contains.as.Destroy.impl.Op.decl: %Contains.as.Destroy.impl.Op.type = fn_decl @Contains.as.Destroy.impl.Op [concrete = constants.%Contains.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.cce = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.cce = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.216 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Contains [concrete = constants.%Contains] +// CHECK:STDOUT: %self: %ptr.216 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Contains.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Contains.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract { +// CHECK:STDOUT: impl_decl @Abstract.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract.as.Destroy.impl.%Abstract.as.Destroy.impl.Op.decl), @Abstract.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.9d1] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -232,6 +281,9 @@ fn CallReturnAbstract() { // CHECK:STDOUT: class @Contains { // CHECK:STDOUT: %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract] // CHECK:STDOUT: %.loc15: = field_decl a, element0 [concrete] +// CHECK:STDOUT: impl_decl @Contains.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Contains.as.Destroy.impl.%Contains.as.Destroy.impl.Op.decl), @Contains.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.6a6] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: } [concrete = ] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a [concrete = ] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -242,15 +294,25 @@ fn CallReturnAbstract() { // CHECK:STDOUT: .a = %.loc15 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Contains.as.Destroy.impl.Op(%self.param: %ptr.216) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_abstract_var.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract: type = class_type @Abstract [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Abstract.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.f31: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.type: type = fn_type @Abstract.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op: %Abstract.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Var.type: type = fn_type @Var [concrete] // CHECK:STDOUT: %Var: %Var.type = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -273,7 +335,26 @@ fn CallReturnAbstract() { // CHECK:STDOUT: %Var.decl: %Var.type = fn_decl @Var [concrete = constants.%Var] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract.as.Destroy.impl: constants.%Abstract as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.decl: %Abstract.as.Destroy.impl.Op.type = fn_decl @Abstract.as.Destroy.impl.Op [concrete = constants.%Abstract.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f31 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f31 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract [concrete = constants.%Abstract] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract { +// CHECK:STDOUT: impl_decl @Abstract.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract.as.Destroy.impl.%Abstract.as.Destroy.impl.Op.decl), @Abstract.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -282,6 +363,8 @@ fn CallReturnAbstract() { // CHECK:STDOUT: .Self = constants.%Abstract // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Var() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -298,18 +381,27 @@ fn CallReturnAbstract() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract: type = class_type @Abstract [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Abstract.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.f31: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.type: type = fn_type @Abstract.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op: %Abstract.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.41e: type = pattern_type %Abstract [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -321,8 +413,8 @@ fn CallReturnAbstract() { // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %Abstract.decl: type = class_decl @Abstract [concrete = constants.%Abstract] {} {} // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %a.patt: %pattern_type = binding_pattern a [concrete] -// CHECK:STDOUT: %a.param_patt: %pattern_type = value_param_pattern %a.patt, call_param0 [concrete] +// CHECK:STDOUT: %a.patt: %pattern_type.41e = binding_pattern a [concrete] +// CHECK:STDOUT: %a.param_patt: %pattern_type.41e = value_param_pattern %a.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %a.param: %Abstract = value_param call_param0 // CHECK:STDOUT: %Abstract.ref.loc7: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract] @@ -330,7 +422,26 @@ fn CallReturnAbstract() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract.as.Destroy.impl: constants.%Abstract as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.decl: %Abstract.as.Destroy.impl.Op.type = fn_decl @Abstract.as.Destroy.impl.Op [concrete = constants.%Abstract.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f31 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f31 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract [concrete = constants.%Abstract] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract { +// CHECK:STDOUT: impl_decl @Abstract.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract.as.Destroy.impl.%Abstract.as.Destroy.impl.Op.decl), @Abstract.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -339,10 +450,12 @@ fn CallReturnAbstract() { // CHECK:STDOUT: .Self = constants.%Abstract // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%a.param: %Abstract) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %l.patt: %pattern_type = binding_pattern l [concrete] +// CHECK:STDOUT: %l.patt: %pattern_type.41e = binding_pattern l [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %a.ref: %Abstract = name_ref a, %a // CHECK:STDOUT: %Abstract.ref.loc8: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract] @@ -354,16 +467,30 @@ fn CallReturnAbstract() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract: type = class_type @Abstract [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9d1: = impl_witness @Abstract.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.f31: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.type: type = fn_type @Abstract.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op: %Abstract.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Adapter: type = class_type @Adapter [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.223: = impl_witness @Adapter.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.0f9: type = ptr_type %Adapter [concrete] +// CHECK:STDOUT: %pattern_type.20f: type = pattern_type %ptr.0f9 [concrete] +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op.type: type = fn_type @Adapter.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op: %Adapter.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -377,7 +504,42 @@ fn CallReturnAbstract() { // CHECK:STDOUT: %Adapter.decl: type = class_decl @Adapter [concrete = constants.%Adapter] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract.as.Destroy.impl: constants.%Abstract as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.decl: %Abstract.as.Destroy.impl.Op.type = fn_decl @Abstract.as.Destroy.impl.Op [concrete = constants.%Abstract.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f31 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f31 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract [concrete = constants.%Abstract] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Adapter.as.Destroy.impl: constants.%Adapter as constants.%Destroy.type { +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op.decl: %Adapter.as.Destroy.impl.Op.type = fn_decl @Adapter.as.Destroy.impl.Op [concrete = constants.%Adapter.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.20f = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.20f = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.0f9 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Adapter [concrete = constants.%Adapter] +// CHECK:STDOUT: %self: %ptr.0f9 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Adapter.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Adapter.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract { +// CHECK:STDOUT: impl_decl @Abstract.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract.as.Destroy.impl.%Abstract.as.Destroy.impl.Op.decl), @Abstract.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.9d1] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -389,6 +551,9 @@ fn CallReturnAbstract() { // CHECK:STDOUT: class @Adapter { // CHECK:STDOUT: %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract] // CHECK:STDOUT: adapt_decl [concrete] +// CHECK:STDOUT: impl_decl @Adapter.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Adapter.as.Destroy.impl.%Adapter.as.Destroy.impl.Op.decl), @Adapter.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.223] // CHECK:STDOUT: %complete_type: = complete_type_witness [concrete = ] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -397,15 +562,26 @@ fn CallReturnAbstract() { // CHECK:STDOUT: .Abstract = // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Adapter.as.Destroy.impl.Op(%self.param: %ptr.0f9) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- define_and_call_abstract_param.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract: type = class_type @Abstract [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Abstract.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.f31: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.type: type = fn_type @Abstract.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op: %Abstract.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.41e: type = pattern_type %Abstract [concrete] // CHECK:STDOUT: %Param.type: type = fn_type @Param [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Param: %Param.type = struct_value () [concrete] // CHECK:STDOUT: %Call.type: type = fn_type @Call [concrete] // CHECK:STDOUT: %Call: %Call.type = struct_value () [concrete] @@ -413,9 +589,11 @@ fn CallReturnAbstract() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -428,16 +606,16 @@ fn CallReturnAbstract() { // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %Abstract.decl: type = class_decl @Abstract [concrete = constants.%Abstract] {} {} // CHECK:STDOUT: %Param.decl: %Param.type = fn_decl @Param [concrete = constants.%Param] { -// CHECK:STDOUT: %a.patt: %pattern_type = binding_pattern a [concrete] -// CHECK:STDOUT: %a.param_patt: %pattern_type = value_param_pattern %a.patt, call_param0 [concrete] +// CHECK:STDOUT: %a.patt: %pattern_type.41e = binding_pattern a [concrete] +// CHECK:STDOUT: %a.param_patt: %pattern_type.41e = value_param_pattern %a.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %a.param: %Abstract = value_param call_param0 // CHECK:STDOUT: %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract] // CHECK:STDOUT: %a: %Abstract = bind_name a, %a.param // CHECK:STDOUT: } // CHECK:STDOUT: %Call.decl: %Call.type = fn_decl @Call [concrete = constants.%Call] { -// CHECK:STDOUT: %p.patt: %pattern_type = binding_pattern p [concrete] -// CHECK:STDOUT: %p.param_patt: %pattern_type = value_param_pattern %p.patt, call_param0 [concrete] +// CHECK:STDOUT: %p.patt: %pattern_type.41e = binding_pattern p [concrete] +// CHECK:STDOUT: %p.param_patt: %pattern_type.41e = value_param_pattern %p.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %p.param: %Abstract = value_param call_param0 // CHECK:STDOUT: %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract] @@ -445,7 +623,26 @@ fn CallReturnAbstract() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract.as.Destroy.impl: constants.%Abstract as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.decl: %Abstract.as.Destroy.impl.Op.type = fn_decl @Abstract.as.Destroy.impl.Op [concrete = constants.%Abstract.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f31 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f31 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract [concrete = constants.%Abstract] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract { +// CHECK:STDOUT: impl_decl @Abstract.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract.as.Destroy.impl.%Abstract.as.Destroy.impl.Op.decl), @Abstract.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -454,6 +651,8 @@ fn CallReturnAbstract() { // CHECK:STDOUT: .Self = constants.%Abstract // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Param(%a.param: %Abstract); // CHECK:STDOUT: // CHECK:STDOUT: fn @Call(%p.param: %Abstract) { @@ -468,14 +667,26 @@ fn CallReturnAbstract() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract: type = class_type @Abstract [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9d1: = impl_witness @Abstract.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.4042: type = ptr_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.f31: type = pattern_type %ptr.4042 [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.type: type = fn_type @Abstract.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op: %Abstract.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Derived: type = class_type @Derived [concrete] // CHECK:STDOUT: %Derived.elem.513: type = unbound_element_type %Derived, %Abstract [concrete] // CHECK:STDOUT: %Derived.elem.ad9: type = unbound_element_type %Derived, %empty_struct_type [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404f: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404f [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.d.c06: type = struct_type {.base: %Abstract, .d: %empty_struct_type} [concrete] // CHECK:STDOUT: %complete_type.b4a: = complete_type_witness %struct_type.base.d.c06 [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.fb9: type = pattern_type %Derived [concrete] // CHECK:STDOUT: %Make.type: type = fn_type @Make [concrete] // CHECK:STDOUT: %Make: %Make.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.d.e0f: type = struct_type {.base: %empty_struct_type, .d: %empty_struct_type} [concrete] @@ -483,9 +694,11 @@ fn CallReturnAbstract() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -499,8 +712,8 @@ fn CallReturnAbstract() { // CHECK:STDOUT: %Abstract.decl: type = class_decl @Abstract [concrete = constants.%Abstract] {} {} // CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [concrete = constants.%Derived] {} {} // CHECK:STDOUT: %Make.decl: %Make.type = fn_decl @Make [concrete = constants.%Make] { -// CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern [concrete] -// CHECK:STDOUT: %return.param_patt: %pattern_type = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.fb9 = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.fb9 = out_param_pattern %return.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %Derived.ref: type = name_ref Derived, file.%Derived.decl [concrete = constants.%Derived] // CHECK:STDOUT: %return.param: ref %Derived = out_param call_param0 @@ -508,7 +721,42 @@ fn CallReturnAbstract() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract.as.Destroy.impl: constants.%Abstract as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.decl: %Abstract.as.Destroy.impl.Op.type = fn_decl @Abstract.as.Destroy.impl.Op [concrete = constants.%Abstract.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f31 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f31 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.4042 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract [concrete = constants.%Abstract] +// CHECK:STDOUT: %self: %ptr.4042 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract { +// CHECK:STDOUT: impl_decl @Abstract.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract.as.Destroy.impl.%Abstract.as.Destroy.impl.Op.decl), @Abstract.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.9d1] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -523,6 +771,9 @@ fn CallReturnAbstract() { // CHECK:STDOUT: %.loc10_11.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc10_11.2: type = converted %.loc10_11.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %.loc10_8: %Derived.elem.ad9 = field_decl d, element1 [concrete] +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %struct_type.base.d: type = struct_type {.base: %Abstract, .d: %empty_struct_type} [concrete = constants.%struct_type.base.d.c06] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base.d [concrete = constants.%complete_type.b4a] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -535,6 +786,10 @@ fn CallReturnAbstract() { // CHECK:STDOUT: extend %Abstract.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract.as.Destroy.impl.Op(%self.param: %ptr.4042) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404f) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Make() -> %return.param: %Derived { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc22_20: %empty_struct_type = struct_literal () @@ -547,23 +802,37 @@ fn CallReturnAbstract() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract: type = class_type @Abstract [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9d1: = impl_witness @Abstract.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.4042: type = ptr_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.f31: type = pattern_type %ptr.4042 [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.type: type = fn_type @Abstract.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op: %Abstract.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Derived: type = class_type @Derived [concrete] // CHECK:STDOUT: %Derived.elem.513: type = unbound_element_type %Derived, %Abstract [concrete] // CHECK:STDOUT: %Derived.elem.ad9: type = unbound_element_type %Derived, %empty_struct_type [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404f: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404f [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.d: type = struct_type {.base: %Abstract, .d: %empty_struct_type} [concrete] // CHECK:STDOUT: %complete_type.b4a: = complete_type_witness %struct_type.base.d [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.41e: type = pattern_type %Abstract [concrete] // CHECK:STDOUT: %Return.type: type = fn_type @Return [concrete] // CHECK:STDOUT: %Return: %Return.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -577,10 +846,10 @@ fn CallReturnAbstract() { // CHECK:STDOUT: %Abstract.decl: type = class_decl @Abstract [concrete = constants.%Abstract] {} {} // CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [concrete = constants.%Derived] {} {} // CHECK:STDOUT: %Return.decl: %Return.type = fn_decl @Return [concrete = constants.%Return] { -// CHECK:STDOUT: %a.patt: %pattern_type = binding_pattern a [concrete] -// CHECK:STDOUT: %a.param_patt: %pattern_type = value_param_pattern %a.patt, call_param0 [concrete] -// CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern [concrete] -// CHECK:STDOUT: %return.param_patt: %pattern_type = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: %a.patt: %pattern_type.41e = binding_pattern a [concrete] +// CHECK:STDOUT: %a.param_patt: %pattern_type.41e = value_param_pattern %a.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.41e = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.41e = out_param_pattern %return.patt, call_param1 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %Abstract.ref.loc13_27: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract] // CHECK:STDOUT: %a.param: %Abstract = value_param call_param0 @@ -591,7 +860,42 @@ fn CallReturnAbstract() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract.as.Destroy.impl: constants.%Abstract as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.decl: %Abstract.as.Destroy.impl.Op.type = fn_decl @Abstract.as.Destroy.impl.Op [concrete = constants.%Abstract.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f31 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f31 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.4042 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract [concrete = constants.%Abstract] +// CHECK:STDOUT: %self: %ptr.4042 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract { +// CHECK:STDOUT: impl_decl @Abstract.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract.as.Destroy.impl.%Abstract.as.Destroy.impl.Op.decl), @Abstract.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.9d1] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -606,6 +910,9 @@ fn CallReturnAbstract() { // CHECK:STDOUT: %.loc10_11.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc10_11.2: type = converted %.loc10_11.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %.loc10_8: %Derived.elem.ad9 = field_decl d, element1 [concrete] +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %struct_type.base.d: type = struct_type {.base: %Abstract, .d: %empty_struct_type} [concrete = constants.%struct_type.base.d] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base.d [concrete = constants.%complete_type.b4a] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -618,6 +925,10 @@ fn CallReturnAbstract() { // CHECK:STDOUT: extend %Abstract.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract.as.Destroy.impl.Op(%self.param: %ptr.4042) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404f) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Return(%a.param: %Abstract) -> %return.param: %Abstract { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %Abstract = name_ref a, %a @@ -630,11 +941,23 @@ fn CallReturnAbstract() { // CHECK:STDOUT: %Abstract: type = class_type @Abstract [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %Abstract.elem: type = unbound_element_type %Abstract, %empty_struct_type [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9d1: = impl_witness @Abstract.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.4042: type = ptr_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.f31: type = pattern_type %ptr.4042 [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.type: type = fn_type @Abstract.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op: %Abstract.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a.225: type = struct_type {.a: %empty_struct_type} [concrete] // CHECK:STDOUT: %complete_type.8c6: = complete_type_witness %struct_type.a.225 [concrete] // CHECK:STDOUT: %Derived: type = class_type @Derived [concrete] // CHECK:STDOUT: %Derived.elem.513: type = unbound_element_type %Derived, %Abstract [concrete] // CHECK:STDOUT: %Derived.elem.ad9: type = unbound_element_type %Derived, %empty_struct_type [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404f: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404f [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.d.c06: type = struct_type {.base: %Abstract, .d: %empty_struct_type} [concrete] // CHECK:STDOUT: %complete_type.b4a: = complete_type_witness %struct_type.base.d.c06 [concrete] // CHECK:STDOUT: %pattern_type.fb9: type = pattern_type %Derived [concrete] @@ -645,9 +968,11 @@ fn CallReturnAbstract() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -676,10 +1001,45 @@ fn CallReturnAbstract() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract.as.Destroy.impl: constants.%Abstract as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.decl: %Abstract.as.Destroy.impl.Op.type = fn_decl @Abstract.as.Destroy.impl.Op [concrete = constants.%Abstract.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f31 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f31 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.4042 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract [concrete = constants.%Abstract] +// CHECK:STDOUT: %self: %ptr.4042 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract { // CHECK:STDOUT: %.loc5_11.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc5_11.2: type = converted %.loc5_11.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %.loc5_8: %Abstract.elem = field_decl a, element0 [concrete] +// CHECK:STDOUT: impl_decl @Abstract.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract.as.Destroy.impl.%Abstract.as.Destroy.impl.Op.decl), @Abstract.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.9d1] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %empty_struct_type} [concrete = constants.%struct_type.a.225] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a [concrete = constants.%complete_type.8c6] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -695,6 +1055,9 @@ fn CallReturnAbstract() { // CHECK:STDOUT: %.loc11_11.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc11_11.2: type = converted %.loc11_11.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %.loc11_8: %Derived.elem.ad9 = field_decl d, element1 [concrete] +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %struct_type.base.d: type = struct_type {.base: %Abstract, .d: %empty_struct_type} [concrete = constants.%struct_type.base.d.c06] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base.d [concrete = constants.%complete_type.b4a] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -707,6 +1070,10 @@ fn CallReturnAbstract() { // CHECK:STDOUT: extend %Abstract.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract.as.Destroy.impl.Op(%self.param: %ptr.4042) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404f) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Access(%d.param: %Derived) -> %empty_struct_type { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %d.ref: %Derived = name_ref d, %d @@ -720,18 +1087,27 @@ fn CallReturnAbstract() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract: type = class_type @Abstract [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Abstract.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.f31: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.type: type = fn_type @Abstract.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op: %Abstract.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.41e: type = pattern_type %Abstract [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -745,7 +1121,26 @@ fn CallReturnAbstract() { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract.as.Destroy.impl: constants.%Abstract as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.decl: %Abstract.as.Destroy.impl.Op.type = fn_decl @Abstract.as.Destroy.impl.Op [concrete = constants.%Abstract.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f31 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f31 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract [concrete = constants.%Abstract] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract { +// CHECK:STDOUT: impl_decl @Abstract.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract.as.Destroy.impl.%Abstract.as.Destroy.impl.Op.decl), @Abstract.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -754,10 +1149,12 @@ fn CallReturnAbstract() { // CHECK:STDOUT: .Self = constants.%Abstract // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %l.patt: %pattern_type = binding_pattern l [concrete] +// CHECK:STDOUT: %l.patt: %pattern_type.41e = binding_pattern l [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %.loc8: %empty_struct_type = struct_literal () // CHECK:STDOUT: %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract] @@ -769,9 +1166,16 @@ fn CallReturnAbstract() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract: type = class_type @Abstract [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Abstract.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.f31: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.type: type = fn_type @Abstract.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op: %Abstract.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.41e: type = pattern_type %Abstract [concrete] // CHECK:STDOUT: %ReturnAbstract.type: type = fn_type @ReturnAbstract [concrete] // CHECK:STDOUT: %ReturnAbstract: %ReturnAbstract.type = struct_value () [concrete] // CHECK:STDOUT: %CallReturnAbstract.type: type = fn_type @CallReturnAbstract [concrete] @@ -780,9 +1184,11 @@ fn CallReturnAbstract() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -795,8 +1201,8 @@ fn CallReturnAbstract() { // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %Abstract.decl: type = class_decl @Abstract [concrete = constants.%Abstract] {} {} // CHECK:STDOUT: %ReturnAbstract.decl: %ReturnAbstract.type = fn_decl @ReturnAbstract [concrete = constants.%ReturnAbstract] { -// CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern [concrete] -// CHECK:STDOUT: %return.param_patt: %pattern_type = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.41e = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.41e = out_param_pattern %return.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %Abstract.ref: type = name_ref Abstract, file.%Abstract.decl [concrete = constants.%Abstract] // CHECK:STDOUT: %return.param: ref %Abstract = out_param call_param0 @@ -805,7 +1211,26 @@ fn CallReturnAbstract() { // CHECK:STDOUT: %CallReturnAbstract.decl: %CallReturnAbstract.type = fn_decl @CallReturnAbstract [concrete = constants.%CallReturnAbstract] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract.as.Destroy.impl: constants.%Abstract as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.decl: %Abstract.as.Destroy.impl.Op.type = fn_decl @Abstract.as.Destroy.impl.Op [concrete = constants.%Abstract.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f31 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f31 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract [concrete = constants.%Abstract] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract { +// CHECK:STDOUT: impl_decl @Abstract.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract.as.Destroy.impl.%Abstract.as.Destroy.impl.Op.decl), @Abstract.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -814,6 +1239,8 @@ fn CallReturnAbstract() { // CHECK:STDOUT: .Self = constants.%Abstract // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @ReturnAbstract() -> %return.param: %Abstract; // CHECK:STDOUT: // CHECK:STDOUT: fn @CallReturnAbstract() { diff --git a/toolchain/check/testdata/class/fail_abstract_in_tuple.carbon b/toolchain/check/testdata/class/fail_abstract_in_tuple.carbon index 9635509c247e..2c17d0d63eac 100644 --- a/toolchain/check/testdata/class/fail_abstract_in_tuple.carbon +++ b/toolchain/check/testdata/class/fail_abstract_in_tuple.carbon @@ -129,18 +129,32 @@ fn Var5() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract1: type = class_type @Abstract1 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.188: = impl_witness @Abstract1.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.cfc: type = ptr_type %Abstract1 [concrete] +// CHECK:STDOUT: %pattern_type.15b: type = pattern_type %ptr.cfc [concrete] +// CHECK:STDOUT: %Abstract1.as.Destroy.impl.Op.type: type = fn_type @Abstract1.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract1.as.Destroy.impl.Op: %Abstract1.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Contains: type = class_type @Contains [concrete] // CHECK:STDOUT: %tuple.type.85c: type = tuple_type (type) [concrete] // CHECK:STDOUT: %tuple.type.f19: type = tuple_type (%Abstract1) [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.6a6: = impl_witness @Contains.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.216: type = ptr_type %Contains [concrete] +// CHECK:STDOUT: %pattern_type.cce: type = pattern_type %ptr.216 [concrete] +// CHECK:STDOUT: %Contains.as.Destroy.impl.Op.type: type = fn_type @Contains.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Contains.as.Destroy.impl.Op: %Contains.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -154,7 +168,42 @@ fn Var5() { // CHECK:STDOUT: %Contains.decl: type = class_decl @Contains [concrete = constants.%Contains] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract1.as.Destroy.impl: constants.%Abstract1 as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract1.as.Destroy.impl.Op.decl: %Abstract1.as.Destroy.impl.Op.type = fn_decl @Abstract1.as.Destroy.impl.Op [concrete = constants.%Abstract1.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.15b = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.15b = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc3: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.cfc = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract1 [concrete = constants.%Abstract1] +// CHECK:STDOUT: %self: %ptr.cfc = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Contains.as.Destroy.impl: constants.%Contains as constants.%Destroy.type { +// CHECK:STDOUT: %Contains.as.Destroy.impl.Op.decl: %Contains.as.Destroy.impl.Op.type = fn_decl @Contains.as.Destroy.impl.Op [concrete = constants.%Contains.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.cce = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.cce = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.216 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Contains [concrete = constants.%Contains] +// CHECK:STDOUT: %self: %ptr.216 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Contains.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Contains.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract1 { +// CHECK:STDOUT: impl_decl @Abstract1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract1.as.Destroy.impl.%Abstract1.as.Destroy.impl.Op.decl), @Abstract1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.188] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -168,6 +217,9 @@ fn Var5() { // CHECK:STDOUT: %.loc13_21.1: %tuple.type.85c = tuple_literal (%Abstract1.ref) // CHECK:STDOUT: %.loc13_21.2: type = converted %.loc13_21.1, constants.%tuple.type.f19 [concrete = constants.%tuple.type.f19] // CHECK:STDOUT: %.loc13_8: = field_decl a, element0 [concrete] +// CHECK:STDOUT: impl_decl @Contains.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Contains.as.Destroy.impl.%Contains.as.Destroy.impl.Op.decl), @Contains.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.6a6] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: } [concrete = ] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a [concrete = ] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -178,17 +230,27 @@ fn Var5() { // CHECK:STDOUT: .a = %.loc13_8 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract1.as.Destroy.impl.Op(%self.param: %ptr.cfc) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Contains.as.Destroy.impl.Op(%self.param: %ptr.216) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_abstract_var.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract2: type = class_type @Abstract2 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Abstract2.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6ce: type = ptr_type %Abstract2 [concrete] +// CHECK:STDOUT: %pattern_type.5f0: type = pattern_type %ptr.6ce [concrete] +// CHECK:STDOUT: %Abstract2.as.Destroy.impl.Op.type: type = fn_type @Abstract2.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract2.as.Destroy.impl.Op: %Abstract2.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Var.type: type = fn_type @Var [concrete] // CHECK:STDOUT: %Var: %Var.type = struct_value () [concrete] // CHECK:STDOUT: %tuple.type.85c: type = tuple_type (type) [concrete] // CHECK:STDOUT: %tuple.type.ac6: type = tuple_type (%Abstract2) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -211,7 +273,26 @@ fn Var5() { // CHECK:STDOUT: %Var.decl: %Var.type = fn_decl @Var [concrete = constants.%Var] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract2.as.Destroy.impl: constants.%Abstract2 as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract2.as.Destroy.impl.Op.decl: %Abstract2.as.Destroy.impl.Op.type = fn_decl @Abstract2.as.Destroy.impl.Op [concrete = constants.%Abstract2.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f0 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f0 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc3: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6ce = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract2 [concrete = constants.%Abstract2] +// CHECK:STDOUT: %self: %ptr.6ce = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract2.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract2.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract2 { +// CHECK:STDOUT: impl_decl @Abstract2.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract2.as.Destroy.impl.%Abstract2.as.Destroy.impl.Op.decl), @Abstract2.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -220,6 +301,8 @@ fn Var5() { // CHECK:STDOUT: .Self = constants.%Abstract2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract2.as.Destroy.impl.Op(%self.param: %ptr.6ce) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Var() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -240,6 +323,13 @@ fn Var5() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract3: type = class_type @Abstract3 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Abstract3.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e65: type = ptr_type %Abstract3 [concrete] +// CHECK:STDOUT: %pattern_type.033: type = pattern_type %ptr.e65 [concrete] +// CHECK:STDOUT: %Abstract3.as.Destroy.impl.Op.type: type = fn_type @Abstract3.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract3.as.Destroy.impl.Op: %Abstract3.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.32b: type = pattern_type %Abstract3 [concrete] @@ -252,9 +342,11 @@ fn Var5() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -275,7 +367,26 @@ fn Var5() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract3.as.Destroy.impl: constants.%Abstract3 as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract3.as.Destroy.impl.Op.decl: %Abstract3.as.Destroy.impl.Op.type = fn_decl @Abstract3.as.Destroy.impl.Op [concrete = constants.%Abstract3.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.033 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.033 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc3: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e65 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract3 [concrete = constants.%Abstract3] +// CHECK:STDOUT: %self: %ptr.e65 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract3.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract3.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract3 { +// CHECK:STDOUT: impl_decl @Abstract3.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract3.as.Destroy.impl.%Abstract3.as.Destroy.impl.Op.decl), @Abstract3.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -284,6 +395,8 @@ fn Var5() { // CHECK:STDOUT: .Self = constants.%Abstract3 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract3.as.Destroy.impl.Op(%self.param: %ptr.e65) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%a.param: %Abstract3) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -304,14 +417,25 @@ fn Var5() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract4: type = class_type @Abstract4 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.695: = impl_witness @Abstract4.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.d57: type = ptr_type %Abstract4 [concrete] +// CHECK:STDOUT: %pattern_type.909: type = pattern_type %ptr.d57 [concrete] +// CHECK:STDOUT: %Abstract4.as.Destroy.impl.Op.type: type = fn_type @Abstract4.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract4.as.Destroy.impl.Op: %Abstract4.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Abstract5: type = class_type @Abstract5 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.5a2: = impl_witness @Abstract5.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.194: type = ptr_type %Abstract5 [concrete] +// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %ptr.194 [concrete] +// CHECK:STDOUT: %Abstract5.as.Destroy.impl.Op.type: type = fn_type @Abstract5.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract5.as.Destroy.impl.Op: %Abstract5.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Var2.type: type = fn_type @Var2 [concrete] // CHECK:STDOUT: %Var2: %Var2.type = struct_value () [concrete] // CHECK:STDOUT: %tuple.type.24b: type = tuple_type (type, type) [concrete] // CHECK:STDOUT: %tuple.type.e3e: type = tuple_type (%Abstract4, %Abstract5) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -336,7 +460,42 @@ fn Var5() { // CHECK:STDOUT: %Var2.decl: %Var2.type = fn_decl @Var2 [concrete = constants.%Var2] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract4.as.Destroy.impl: constants.%Abstract4 as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract4.as.Destroy.impl.Op.decl: %Abstract4.as.Destroy.impl.Op.type = fn_decl @Abstract4.as.Destroy.impl.Op [concrete = constants.%Abstract4.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.909 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.909 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc3: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.d57 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract4 [concrete = constants.%Abstract4] +// CHECK:STDOUT: %self: %ptr.d57 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract4.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract4.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract5.as.Destroy.impl: constants.%Abstract5 as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract5.as.Destroy.impl.Op.decl: %Abstract5.as.Destroy.impl.Op.type = fn_decl @Abstract5.as.Destroy.impl.Op [concrete = constants.%Abstract5.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.7ce = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.7ce = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.194 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract5 [concrete = constants.%Abstract5] +// CHECK:STDOUT: %self: %ptr.194 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract5.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract5.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract4 { +// CHECK:STDOUT: impl_decl @Abstract4.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract4.as.Destroy.impl.%Abstract4.as.Destroy.impl.Op.decl), @Abstract4.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.695] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -346,6 +505,9 @@ fn Var5() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Abstract5 { +// CHECK:STDOUT: impl_decl @Abstract5.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract5.as.Destroy.impl.%Abstract5.as.Destroy.impl.Op.decl), @Abstract5.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.5a2] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -354,6 +516,10 @@ fn Var5() { // CHECK:STDOUT: .Self = constants.%Abstract5 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract4.as.Destroy.impl.Op(%self.param: %ptr.d57) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract5.as.Destroy.impl.Op(%self.param: %ptr.194) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Var2() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -375,13 +541,19 @@ fn Var5() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract6: type = class_type @Abstract6 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Abstract6.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.166: type = ptr_type %Abstract6 [concrete] +// CHECK:STDOUT: %pattern_type.621: type = pattern_type %ptr.166 [concrete] +// CHECK:STDOUT: %Abstract6.as.Destroy.impl.Op.type: type = fn_type @Abstract6.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract6.as.Destroy.impl.Op: %Abstract6.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Var3.type: type = fn_type @Var3 [concrete] // CHECK:STDOUT: %Var3: %Var3.type = struct_value () [concrete] // CHECK:STDOUT: %tuple.type.159: type = tuple_type (type, %empty_struct_type) [concrete] // CHECK:STDOUT: %tuple.type.d93: type = tuple_type (%Abstract6, %empty_struct_type) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -404,7 +576,26 @@ fn Var5() { // CHECK:STDOUT: %Var3.decl: %Var3.type = fn_decl @Var3 [concrete = constants.%Var3] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract6.as.Destroy.impl: constants.%Abstract6 as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract6.as.Destroy.impl.Op.decl: %Abstract6.as.Destroy.impl.Op.type = fn_decl @Abstract6.as.Destroy.impl.Op [concrete = constants.%Abstract6.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.621 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.621 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc3: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.166 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract6 [concrete = constants.%Abstract6] +// CHECK:STDOUT: %self: %ptr.166 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract6.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract6.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract6 { +// CHECK:STDOUT: impl_decl @Abstract6.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract6.as.Destroy.impl.%Abstract6.as.Destroy.impl.Op.decl), @Abstract6.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -413,6 +604,8 @@ fn Var5() { // CHECK:STDOUT: .Self = constants.%Abstract6 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract6.as.Destroy.impl.Op(%self.param: %ptr.166) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Var3() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -435,13 +628,19 @@ fn Var5() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract7: type = class_type @Abstract7 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Abstract7.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.817: type = ptr_type %Abstract7 [concrete] +// CHECK:STDOUT: %pattern_type.bd0: type = pattern_type %ptr.817 [concrete] +// CHECK:STDOUT: %Abstract7.as.Destroy.impl.Op.type: type = fn_type @Abstract7.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract7.as.Destroy.impl.Op: %Abstract7.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Var4.type: type = fn_type @Var4 [concrete] // CHECK:STDOUT: %Var4: %Var4.type = struct_value () [concrete] // CHECK:STDOUT: %tuple.type.c8c: type = tuple_type (%empty_struct_type, type) [concrete] // CHECK:STDOUT: %tuple.type.919: type = tuple_type (%empty_struct_type, %Abstract7) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -464,7 +663,26 @@ fn Var5() { // CHECK:STDOUT: %Var4.decl: %Var4.type = fn_decl @Var4 [concrete = constants.%Var4] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract7.as.Destroy.impl: constants.%Abstract7 as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract7.as.Destroy.impl.Op.decl: %Abstract7.as.Destroy.impl.Op.type = fn_decl @Abstract7.as.Destroy.impl.Op [concrete = constants.%Abstract7.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.bd0 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.bd0 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc3: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.817 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract7 [concrete = constants.%Abstract7] +// CHECK:STDOUT: %self: %ptr.817 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract7.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract7.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract7 { +// CHECK:STDOUT: impl_decl @Abstract7.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract7.as.Destroy.impl.%Abstract7.as.Destroy.impl.Op.decl), @Abstract7.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -473,6 +691,8 @@ fn Var5() { // CHECK:STDOUT: .Self = constants.%Abstract7 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract7.as.Destroy.impl.Op(%self.param: %ptr.817) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Var4() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -495,15 +715,24 @@ fn Var5() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Abstract: type = class_type @Abstract [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Abstract.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.f31: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.type: type = fn_type @Abstract.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op: %Abstract.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -515,7 +744,26 @@ fn Var5() { // CHECK:STDOUT: %Abstract.decl: type = class_decl @Abstract [concrete = constants.%Abstract] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract.as.Destroy.impl: constants.%Abstract as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.decl: %Abstract.as.Destroy.impl.Op.type = fn_decl @Abstract.as.Destroy.impl.Op [concrete = constants.%Abstract.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f31 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f31 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc3: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract [concrete = constants.%Abstract] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Abstract { +// CHECK:STDOUT: impl_decl @Abstract.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract.as.Destroy.impl.%Abstract.as.Destroy.impl.Op.decl), @Abstract.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -524,6 +772,8 @@ fn Var5() { // CHECK:STDOUT: .Self = constants.%Abstract // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_import.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/class/fail_addr_self.carbon b/toolchain/check/testdata/class/fail_addr_self.carbon index 6a3bd853b80d..671289440604 100644 --- a/toolchain/check/testdata/class/fail_addr_self.carbon +++ b/toolchain/check/testdata/class/fail_addr_self.carbon @@ -52,14 +52,14 @@ fn F(c: Class, p: Class*) { // CHECK:STDOUT: %pattern_type.761: type = pattern_type %Class [concrete] // CHECK:STDOUT: %Class.G.type: type = fn_type @Class.G [concrete] // CHECK:STDOUT: %Class.G: %Class.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b40: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.7de: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Class) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d64: %T.as.Destroy.impl.Op.type.7de = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(%Class) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -97,6 +97,22 @@ fn F(c: Class, p: Class*) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { // CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] @@ -118,8 +134,11 @@ fn F(c: Class, p: Class*) { // CHECK:STDOUT: %Class.ref: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] // CHECK:STDOUT: %self: %Class = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b40] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -133,6 +152,8 @@ fn F(c: Class, p: Class*) { // CHECK:STDOUT: // CHECK:STDOUT: fn @Class.G(%self.param: %Class); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%c.param: %Class, %p.param: %ptr.e71) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %c.ref.loc32: %Class = name_ref c, %c @@ -157,11 +178,9 @@ fn F(c: Class, p: Class*) { // CHECK:STDOUT: %Class.G.bound.loc39: = bound_method %.loc39_4.1, %G.ref.loc39 // CHECK:STDOUT: %.loc39_4.2: %Class = bind_value %.loc39_4.1 // CHECK:STDOUT: %Class.G.call.loc39: init %empty_tuple.type = call %Class.G.bound.loc39(%.loc39_4.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc32, constants.%T.as.Destroy.impl.Op.d64 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(constants.%Class) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc32, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.bound: = bound_method %.loc32, constants.%Class.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc32_3.2: %ptr.e71 = addr_of %.loc32 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc32_3.2) +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Class.as.Destroy.impl.Op.bound(%addr.loc32_3.2) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/fail_error_recovery.carbon b/toolchain/check/testdata/class/fail_error_recovery.carbon index 2747ce3d74cc..77d7f5673f4f 100644 --- a/toolchain/check/testdata/class/fail_error_recovery.carbon +++ b/toolchain/check/testdata/class/fail_error_recovery.carbon @@ -21,6 +21,13 @@ fn F(N:! error_not_found) { virtual fn Foo[self: Self]() {} } + // CHECK:STDERR: fail_virtual_fn_in_invalid_context.carbon:[[@LINE+7]]:3: error: redefinition of `impl as Core.Destroy` [ImplRedefinition] + // CHECK:STDERR: base class D { + // CHECK:STDERR: ^~~~~~~~~~~~~~ + // CHECK:STDERR: fail_virtual_fn_in_invalid_context.carbon:[[@LINE-7]]:3: note: previous definition was here [ImplPreviousDefinition] + // CHECK:STDERR: base class C { + // CHECK:STDERR: ^~~~~~~~~~~~~~ + // CHECK:STDERR: base class D { extend base: C; } diff --git a/toolchain/check/testdata/class/field_access.carbon b/toolchain/check/testdata/class/field_access.carbon index c09e471de85b..84fb637ac71b 100644 --- a/toolchain/check/testdata/class/field_access.carbon +++ b/toolchain/check/testdata/class/field_access.carbon @@ -35,6 +35,13 @@ fn Run() { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b40: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.j.k: type = struct_type {.j: %i32, .k: %i32} [concrete] // CHECK:STDOUT: %complete_type.cf7: = complete_type_witness %struct_type.j.k [concrete] // CHECK:STDOUT: %Run.type: type = fn_type @Run [concrete] @@ -62,30 +69,25 @@ fn Run() { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.ef9: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.b92: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_2.ef8: %i32 = int_value 2 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.014: = specific_function %T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(%i32) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.7de: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Class) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d64: %T.as.Destroy.impl.Op.type.7de = struct_value () [concrete] -// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.618: = specific_function %T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(%Class) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(%i32) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -99,6 +101,22 @@ fn Run() { // CHECK:STDOUT: %Run.decl: %Run.type = fn_decl @Run [concrete = constants.%Run] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %int_32.loc16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -106,6 +124,9 @@ fn Run() { // CHECK:STDOUT: %int_32.loc17: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc17: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc17: %Class.elem = field_decl k, element1 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b40] // CHECK:STDOUT: %struct_type.j.k: type = struct_type {.j: %i32, .k: %i32} [concrete = constants.%struct_type.j.k] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.j.k [concrete = constants.%complete_type.cf7] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -116,6 +137,8 @@ fn Run() { // CHECK:STDOUT: .k = %.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Run() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -178,20 +201,18 @@ fn Run() { // CHECK:STDOUT: } // CHECK:STDOUT: %ck: ref %i32 = bind_name ck, %ck.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc25: = bound_method %ck.var, constants.%T.as.Destroy.impl.Op.e6a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.014] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method.loc25: = bound_method %ck.var, %T.as.Destroy.impl.Op.specific_fn.1 // CHECK:STDOUT: %addr.loc25: %ptr.235 = addr_of %ck.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc25: init %empty_tuple.type = call %bound_method.loc25(%addr.loc25) // CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc24: = bound_method %cj.var, constants.%T.as.Destroy.impl.Op.e6a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.014] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method.loc24: = bound_method %cj.var, %T.as.Destroy.impl.Op.specific_fn.2 // CHECK:STDOUT: %addr.loc24: %ptr.235 = addr_of %cj.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc24: init %empty_tuple.type = call %bound_method.loc24(%addr.loc24) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc21: = bound_method %c.var, constants.%T.as.Destroy.impl.Op.d64 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(constants.%Class) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.618] -// CHECK:STDOUT: %bound_method.loc21: = bound_method %c.var, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%Class.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc21: %ptr.e71 = addr_of %c.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc21: init %empty_tuple.type = call %bound_method.loc21(%addr.loc21) +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Class.as.Destroy.impl.Op.bound(%addr.loc21) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/field_access_in_value.carbon b/toolchain/check/testdata/class/field_access_in_value.carbon index 1713fcafe223..9ed0841bce57 100644 --- a/toolchain/check/testdata/class/field_access_in_value.carbon +++ b/toolchain/check/testdata/class/field_access_in_value.carbon @@ -36,6 +36,13 @@ fn Test() { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b40: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.j.k: type = struct_type {.j: %i32, .k: %i32} [concrete] // CHECK:STDOUT: %complete_type.cf7: = complete_type_witness %struct_type.j.k [concrete] // CHECK:STDOUT: %Test.type: type = fn_type @Test [concrete] @@ -63,30 +70,25 @@ fn Test() { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.ef9: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.b92: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_2.ef8: %i32 = int_value 2 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.014: = specific_function %T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(%i32) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.7de: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Class) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d64: %T.as.Destroy.impl.Op.type.7de = struct_value () [concrete] -// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.618: = specific_function %T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(%Class) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(%i32) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -100,6 +102,22 @@ fn Test() { // CHECK:STDOUT: %Test.decl: %Test.type = fn_decl @Test [concrete = constants.%Test] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %int_32.loc16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -107,6 +125,9 @@ fn Test() { // CHECK:STDOUT: %int_32.loc17: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc17: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc17: %Class.elem = field_decl k, element1 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b40] // CHECK:STDOUT: %struct_type.j.k: type = struct_type {.j: %i32, .k: %i32} [concrete = constants.%struct_type.j.k] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.j.k [concrete = constants.%complete_type.cf7] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -117,6 +138,8 @@ fn Test() { // CHECK:STDOUT: .k = %.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Test() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -186,20 +209,18 @@ fn Test() { // CHECK:STDOUT: } // CHECK:STDOUT: %ck: ref %i32 = bind_name ck, %ck.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc26: = bound_method %ck.var, constants.%T.as.Destroy.impl.Op.e6a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.014] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method.loc26: = bound_method %ck.var, %T.as.Destroy.impl.Op.specific_fn.1 // CHECK:STDOUT: %addr.loc26: %ptr.235 = addr_of %ck.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc26: init %empty_tuple.type = call %bound_method.loc26(%addr.loc26) // CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc25: = bound_method %cj.var, constants.%T.as.Destroy.impl.Op.e6a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.014] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method.loc25: = bound_method %cj.var, %T.as.Destroy.impl.Op.specific_fn.2 // CHECK:STDOUT: %addr.loc25: %ptr.235 = addr_of %cj.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc25: init %empty_tuple.type = call %bound_method.loc25(%addr.loc25) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc21: = bound_method %cv.var, constants.%T.as.Destroy.impl.Op.d64 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(constants.%Class) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.618] -// CHECK:STDOUT: %bound_method.loc21: = bound_method %cv.var, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.bound: = bound_method %cv.var, constants.%Class.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc21: %ptr.e71 = addr_of %cv.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc21: init %empty_tuple.type = call %bound_method.loc21(%addr.loc21) +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Class.as.Destroy.impl.Op.bound(%addr.loc21) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/generic/adapt.carbon b/toolchain/check/testdata/class/generic/adapt.carbon index 80a6c64d7b11..41be96862d21 100644 --- a/toolchain/check/testdata/class/generic/adapt.carbon +++ b/toolchain/check/testdata/class/generic/adapt.carbon @@ -135,6 +135,13 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %C.f2e: type = class_type @C, @C(%T) [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %C.elem.66c: type = unbound_element_type %C.f2e, %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.a08: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.x.2ac: type = struct_type {.x: %T} [symbolic] // CHECK:STDOUT: %complete_type.433: = complete_type_witness %struct_type.x.2ac [symbolic] // CHECK:STDOUT: %Adapter: type = class_type @Adapter [concrete] @@ -148,6 +155,11 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %C.elem.476: type = unbound_element_type %C.98a, %i32 [concrete] // CHECK:STDOUT: %struct_type.x.ed6: type = struct_type {.x: %i32} [concrete] // CHECK:STDOUT: %complete_type.1ec: = complete_type_witness %struct_type.x.ed6 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.223: = impl_witness @Adapter.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.0f9: type = ptr_type %Adapter [concrete] +// CHECK:STDOUT: %pattern_type.20f: type = pattern_type %ptr.0f9 [concrete] +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op.type: type = fn_type @Adapter.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op: %Adapter.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.27e: type = pattern_type %Adapter [concrete] // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %Access.type: type = fn_type @Access [concrete] @@ -156,10 +168,12 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -193,6 +207,50 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f2e as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc4_19.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.f2e)] { +// CHECK:STDOUT: %.loc4_19.3: type = specific_constant constants.%C.f2e, @C(constants.%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_19.3 [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Adapter.as.Destroy.impl: constants.%Adapter as constants.%Destroy.type { +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op.decl: %Adapter.as.Destroy.impl.Op.type = fn_decl @Adapter.as.Destroy.impl.Op [concrete = constants.%Adapter.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.20f = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.20f = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.0f9 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Adapter [concrete = constants.%Adapter] +// CHECK:STDOUT: %self: %ptr.0f9 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Adapter.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Adapter.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%T.loc4_9.2: type) { // CHECK:STDOUT: %T.loc4_9.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: @@ -206,6 +264,9 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_9.2 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: %.loc5: @C.%C.elem (%C.elem.66c) = field_decl x, element0 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] // CHECK:STDOUT: %struct_type.x.loc6_1.1: type = struct_type {.x: %T} [symbolic = %struct_type.x.loc6_1.2 (constants.%struct_type.x.2ac)] // CHECK:STDOUT: %complete_type.loc6_1.1: = complete_type_witness %struct_type.x.loc6_1.1 [symbolic = %complete_type.loc6_1.2 (constants.%complete_type.433)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc6_1.1 @@ -223,6 +284,9 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %C: type = class_type @C, @C(constants.%i32) [concrete = constants.%C.98a] // CHECK:STDOUT: adapt_decl %C [concrete] +// CHECK:STDOUT: impl_decl @Adapter.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Adapter.as.Destroy.impl.%Adapter.as.Destroy.impl.Op.decl), @Adapter.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.223] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.x.ed6 [concrete = constants.%complete_type.1ec] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -231,6 +295,19 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: .C = // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Adapter.as.Destroy.impl.Op(%self.param: %ptr.0f9) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Access(%a.param: %Adapter) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %Adapter = name_ref a, %a @@ -250,6 +327,18 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %T.loc4_9.1 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a08 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.f2e +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%i32) { // CHECK:STDOUT: %T.loc4_9.1 => constants.%i32 // CHECK:STDOUT: @@ -303,7 +392,7 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %Main.import_ref.4c0 = import_ref Main//adapt_specific_type, inst26 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.262: @C.%C.elem (%C.elem.66c) = import_ref Main//adapt_specific_type, loc5_8, loaded [concrete = %.22b] // CHECK:STDOUT: %Main.import_ref.709: = import_ref Main//adapt_specific_type, loc10_1, loaded [concrete = constants.%complete_type.c07] -// CHECK:STDOUT: %Main.import_ref.feb = import_ref Main//adapt_specific_type, inst42 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.feb = import_ref Main//adapt_specific_type, inst90 [no loc], unloaded // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %.22b: @C.%C.elem (%C.elem.66c) = field_decl x, element0 [concrete] // CHECK:STDOUT: } @@ -400,6 +489,13 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %C.f2e: type = class_type @C, @C(%T) [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %C.elem.66c: type = unbound_element_type %C.f2e, %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.a08: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.x.2ac: type = struct_type {.x: %T} [symbolic] // CHECK:STDOUT: %complete_type.433: = complete_type_witness %struct_type.x.2ac [symbolic] // CHECK:STDOUT: %Adapter: type = class_type @Adapter [concrete] @@ -413,6 +509,11 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %C.elem.476: type = unbound_element_type %C.98a, %i32 [concrete] // CHECK:STDOUT: %struct_type.x.ed6: type = struct_type {.x: %i32} [concrete] // CHECK:STDOUT: %complete_type.1ec: = complete_type_witness %struct_type.x.ed6 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.223: = impl_witness @Adapter.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.0f9: type = ptr_type %Adapter [concrete] +// CHECK:STDOUT: %pattern_type.20f: type = pattern_type %ptr.0f9 [concrete] +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op.type: type = fn_type @Adapter.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op: %Adapter.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.27e: type = pattern_type %Adapter [concrete] // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %Access.type: type = fn_type @Access [concrete] @@ -423,11 +524,13 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } @@ -462,6 +565,50 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f2e as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc4_19.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.f2e)] { +// CHECK:STDOUT: %.loc4_19.3: type = specific_constant constants.%C.f2e, @C(constants.%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_19.3 [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Adapter.as.Destroy.impl: constants.%Adapter as constants.%Destroy.type { +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op.decl: %Adapter.as.Destroy.impl.Op.type = fn_decl @Adapter.as.Destroy.impl.Op [concrete = constants.%Adapter.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.20f = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.20f = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.0f9 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Adapter [concrete = constants.%Adapter] +// CHECK:STDOUT: %self: %ptr.0f9 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Adapter.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Adapter.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%T.loc4_9.2: type) { // CHECK:STDOUT: %T.loc4_9.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: @@ -475,6 +622,9 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_9.2 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: %.loc5: @C.%C.elem (%C.elem.66c) = field_decl x, element0 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] // CHECK:STDOUT: %struct_type.x.loc6_1.1: type = struct_type {.x: %T} [symbolic = %struct_type.x.loc6_1.2 (constants.%struct_type.x.2ac)] // CHECK:STDOUT: %complete_type.loc6_1.1: = complete_type_witness %struct_type.x.loc6_1.1 [symbolic = %complete_type.loc6_1.2 (constants.%complete_type.433)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc6_1.1 @@ -492,6 +642,9 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %C: type = class_type @C, @C(constants.%i32) [concrete = constants.%C.98a] // CHECK:STDOUT: adapt_decl %C [concrete] +// CHECK:STDOUT: impl_decl @Adapter.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Adapter.as.Destroy.impl.%Adapter.as.Destroy.impl.Op.decl), @Adapter.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.223] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.x.ed6 [concrete = constants.%complete_type.1ec] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -502,6 +655,19 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: extend %C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Adapter.as.Destroy.impl.Op(%self.param: %ptr.0f9) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Access(%a.param: %Adapter) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %Adapter = name_ref a, %a @@ -515,6 +681,18 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %T.loc4_9.1 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a08 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.f2e +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%i32) { // CHECK:STDOUT: %T.loc4_9.1 => constants.%i32 // CHECK:STDOUT: @@ -536,6 +714,13 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %C.f2e: type = class_type @C, @C(%T) [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %C.elem.66c: type = unbound_element_type %C.f2e, %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.a08: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.x.2ac: type = struct_type {.x: %T} [symbolic] // CHECK:STDOUT: %complete_type.433: = complete_type_witness %struct_type.x.2ac [symbolic] // CHECK:STDOUT: %Adapter: type = class_type @Adapter [concrete] @@ -549,14 +734,21 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %C.elem.476: type = unbound_element_type %C.98a, %i32 [concrete] // CHECK:STDOUT: %struct_type.x.ed6: type = struct_type {.x: %i32} [concrete] // CHECK:STDOUT: %complete_type.1ec: = complete_type_witness %struct_type.x.ed6 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.223: = impl_witness @Adapter.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.0f9: type = ptr_type %Adapter [concrete] +// CHECK:STDOUT: %pattern_type.20f: type = pattern_type %ptr.0f9 [concrete] +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op.type: type = fn_type @Adapter.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op: %Adapter.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -575,6 +767,50 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %Adapter.decl: type = class_decl @Adapter [concrete = constants.%Adapter] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc7_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f2e as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc7_19.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.f2e)] { +// CHECK:STDOUT: %.loc7_19.3: type = specific_constant constants.%C.f2e, @C(constants.%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc7_19.3 [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Adapter.as.Destroy.impl: constants.%Adapter as constants.%Destroy.type { +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op.decl: %Adapter.as.Destroy.impl.Op.type = fn_decl @Adapter.as.Destroy.impl.Op [concrete = constants.%Adapter.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.20f = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.20f = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.0f9 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Adapter [concrete = constants.%Adapter] +// CHECK:STDOUT: %self: %ptr.0f9 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Adapter.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Adapter.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%T.loc7_9.2: type) { // CHECK:STDOUT: %T.loc7_9.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc7_9.1 (constants.%T)] // CHECK:STDOUT: @@ -588,6 +824,9 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc7_9.2 [symbolic = %T.loc7_9.1 (constants.%T)] // CHECK:STDOUT: %.loc8: @C.%C.elem (%C.elem.66c) = field_decl x, element0 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] // CHECK:STDOUT: %struct_type.x.loc9_1.1: type = struct_type {.x: %T} [symbolic = %struct_type.x.loc9_1.2 (constants.%struct_type.x.2ac)] // CHECK:STDOUT: %complete_type.loc9_1.1: = complete_type_witness %struct_type.x.loc9_1.1 [symbolic = %complete_type.loc9_1.2 (constants.%complete_type.433)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc9_1.1 @@ -605,6 +844,9 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %C: type = class_type @C, @C(constants.%i32) [concrete = constants.%C.98a] // CHECK:STDOUT: adapt_decl %C [concrete] +// CHECK:STDOUT: impl_decl @Adapter.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Adapter.as.Destroy.impl.%Adapter.as.Destroy.impl.Op.decl), @Adapter.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.223] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.x.ed6 [concrete = constants.%complete_type.1ec] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -614,10 +856,35 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: extend %C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc7_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Adapter.as.Destroy.impl.Op(%self.param: %ptr.0f9) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%T) { // CHECK:STDOUT: %T.loc7_9.1 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a08 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.f2e +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%i32) { // CHECK:STDOUT: %T.loc7_9.1 => constants.%i32 // CHECK:STDOUT: @@ -655,6 +922,12 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %ImportedAccess: %ImportedAccess.type = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.afc: = impl_witness imports.%Destroy.impl_witness_table.00b, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -666,16 +939,26 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Main.import_ref.5ab: type = import_ref Main//extend_adapt_specific_type_library, loc7_9, loaded [symbolic = @C.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.5ab3ec.1: type = import_ref Main//extend_adapt_specific_type_library, loc7_9, loaded [symbolic = @C.%T (constants.%T)] // CHECK:STDOUT: %Main.import_ref.b5f: = import_ref Main//extend_adapt_specific_type_library, loc9_1, loaded [symbolic = @C.%complete_type (constants.%complete_type.433)] // CHECK:STDOUT: %Main.import_ref.4c0 = import_ref Main//extend_adapt_specific_type_library, inst26 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.262: @C.%C.elem (%C.elem.66c) = import_ref Main//extend_adapt_specific_type_library, loc8_8, loaded [concrete = %.22b] // CHECK:STDOUT: %Main.import_ref.709: = import_ref Main//extend_adapt_specific_type_library, loc13_1, loaded [concrete = constants.%complete_type.c07] -// CHECK:STDOUT: %Main.import_ref.feb = import_ref Main//extend_adapt_specific_type_library, inst42 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.feb = import_ref Main//extend_adapt_specific_type_library, inst90 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.19d12e.2: type = import_ref Main//extend_adapt_specific_type_library, loc12_21, loaded [concrete = constants.%C.239] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %.22b: @C.%C.elem (%C.elem.66c) = field_decl x, element0 [concrete] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] +// CHECK:STDOUT: %Main.import_ref.21a = import_ref Main//extend_adapt_specific_type_library, loc7_19, unloaded +// CHECK:STDOUT: %Main.import_ref.5ab3ec.2: type = import_ref Main//extend_adapt_specific_type_library, loc7_9, loaded [symbolic = @C.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.499: type = import_ref Main//extend_adapt_specific_type_library, inst26 [no loc], loaded [symbolic = constants.%C.f2e] +// CHECK:STDOUT: %Main.import_ref.cb9298.1: type = import_ref Main//extend_adapt_specific_type_library, inst37 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.251 = import_ref Main//extend_adapt_specific_type_library, loc7_19, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.00b = impl_witness_table (%Main.import_ref.251), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.5ab3ec.3: type = import_ref Main//extend_adapt_specific_type_library, loc7_9, loaded [symbolic = @C.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.07a = import_ref Main//extend_adapt_specific_type_library, loc11_15, unloaded +// CHECK:STDOUT: %Main.import_ref.b65: type = import_ref Main//extend_adapt_specific_type_library, inst90 [no loc], loaded [concrete = constants.%Adapter] +// CHECK:STDOUT: %Main.import_ref.cb9298.2: type = import_ref Main//extend_adapt_specific_type_library, inst37 [no loc], loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -703,6 +986,25 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(imports.%Main.import_ref.5ab3ec.2: type) [from "extend_adapt_specific_type_library.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.00b, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.afc)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%Main.import_ref.499 as imports.%Main.import_ref.cb9298.1 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.21a +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Adapter.as.Destroy.impl: imports.%Main.import_ref.b65 as imports.%Main.import_ref.cb9298.2 [from "extend_adapt_specific_type_library.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.07a +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Adapter [from "extend_adapt_specific_type_library.carbon"] { // CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.709 // CHECK:STDOUT: @@ -712,7 +1014,7 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: extend imports.%Main.import_ref.19d12e.2 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic class @C(imports.%Main.import_ref.5ab: type) [from "extend_adapt_specific_type_library.carbon"] { +// CHECK:STDOUT: generic class @C(imports.%Main.import_ref.5ab3ec.1: type) [from "extend_adapt_specific_type_library.carbon"] { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: @@ -740,6 +1042,17 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(imports.%Main.import_ref.5ab3ec.3: type) [from "extend_adapt_specific_type_library.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%T) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: } @@ -755,6 +1068,18 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %complete_type => constants.%complete_type.c07 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.afc +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.f2e +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- adapt_generic_type.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -764,6 +1089,13 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %Adapter.generic: %Adapter.type = struct_value () [concrete] // CHECK:STDOUT: %Adapter.0e3: type = class_type @Adapter, @Adapter(%T) [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Adapter.%Destroy.impl_witness_table, @Adapter.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.36c: type = ptr_type %Adapter.0e3 [symbolic] +// CHECK:STDOUT: %pattern_type.aa7: type = pattern_type %ptr.36c [symbolic] +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op.type: type = fn_type @Adapter.as.Destroy.impl.Op, @Adapter.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op: %Adapter.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %complete_type.f87: = complete_type_witness %T [symbolic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] @@ -781,10 +1113,12 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -821,6 +1155,34 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Adapter.as.Destroy.impl(@Adapter.%T.loc4_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Adapter.%Destroy.impl_witness_table, @Adapter.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op.type: type = fn_type @Adapter.as.Destroy.impl.Op, @Adapter.as.Destroy.impl(%T) [symbolic = %Adapter.as.Destroy.impl.Op.type (constants.%Adapter.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op: @Adapter.as.Destroy.impl.%Adapter.as.Destroy.impl.Op.type (%Adapter.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Adapter.as.Destroy.impl.Op (constants.%Adapter.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Adapter.0e3 as constants.%Destroy.type { +// CHECK:STDOUT: %Adapter.as.Destroy.impl.Op.decl: @Adapter.as.Destroy.impl.%Adapter.as.Destroy.impl.Op.type (%Adapter.as.Destroy.impl.Op.type) = fn_decl @Adapter.as.Destroy.impl.Op [symbolic = @Adapter.as.Destroy.impl.%Adapter.as.Destroy.impl.Op (constants.%Adapter.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Adapter.as.Destroy.impl.Op.%pattern_type (%pattern_type.aa7) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Adapter.as.Destroy.impl.Op.%pattern_type (%pattern_type.aa7) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_25.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Adapter.as.Destroy.impl.Op.%ptr (%ptr.36c) = value_param call_param0 +// CHECK:STDOUT: %.loc4_25.2: type = splice_block %Self.ref [symbolic = %Adapter (constants.%Adapter.0e3)] { +// CHECK:STDOUT: %.loc4_25.3: type = specific_constant constants.%Adapter.0e3, @Adapter(constants.%T) [symbolic = %Adapter (constants.%Adapter.0e3)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_25.3 [symbolic = %Adapter (constants.%Adapter.0e3)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Adapter.as.Destroy.impl.Op.%ptr (%ptr.36c) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Adapter.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Adapter.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Adapter(%T.loc4_15.2: type) { // CHECK:STDOUT: %T.loc4_15.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_15.1 (constants.%T)] // CHECK:STDOUT: @@ -831,6 +1193,9 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_15.2 [symbolic = %T.loc4_15.1 (constants.%T)] // CHECK:STDOUT: adapt_decl %T.ref [concrete] +// CHECK:STDOUT: impl_decl @Adapter.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Adapter.as.Destroy.impl.%Adapter.as.Destroy.impl.Op.decl), @Adapter.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Adapter.as.Destroy.impl(constants.%T) [symbolic = @Adapter.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %complete_type.loc6_1.1: = complete_type_witness constants.%T [symbolic = %complete_type.loc6_1.2 (constants.%complete_type.f87)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc6_1.1 // CHECK:STDOUT: @@ -840,6 +1205,17 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Adapter.as.Destroy.impl.Op(@Adapter.%T.loc4_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Adapter: type = class_type @Adapter, @Adapter(%T) [symbolic = %Adapter (constants.%Adapter.0e3)] +// CHECK:STDOUT: %ptr: type = ptr_type %Adapter [symbolic = %ptr (constants.%ptr.36c)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.aa7)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Adapter.as.Destroy.impl.Op.%ptr (%ptr.36c)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @Convert(%a.param: %Adapter.e4c) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %Adapter.e4c = name_ref a, %a @@ -854,6 +1230,18 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %T.loc4_15.1 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Adapter.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Adapter.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Adapter => constants.%Adapter.0e3 +// CHECK:STDOUT: %ptr => constants.%ptr.36c +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.aa7 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Adapter(constants.%i32) { // CHECK:STDOUT: %T.loc4_15.1 => constants.%i32 // CHECK:STDOUT: @@ -884,6 +1272,13 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %complete_type.1eb: = complete_type_witness %i32 [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete] // CHECK:STDOUT: %complete_type.54b: = complete_type_witness %struct_type.n [concrete] // CHECK:STDOUT: %Adapter.58f: type = class_type @Adapter, @Adapter(%C) [concrete] @@ -898,6 +1293,7 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %Main.Convert = import_ref Main//adapt_generic_type, Convert, unloaded // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -905,6 +1301,7 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %Main.import_ref.fb3: = import_ref Main//adapt_generic_type, loc6_1, loaded [symbolic = @Adapter.%complete_type (constants.%complete_type.f87)] // CHECK:STDOUT: %Main.import_ref.9a3 = import_ref Main//adapt_generic_type, inst26 [no loc], unloaded // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -958,6 +1355,22 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc10: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Adapter(imports.%Main.import_ref.5ab: type) [from "adapt_generic_type.carbon"] { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: @@ -977,6 +1390,9 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc11: %C.elem = field_decl n, element0 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete = constants.%struct_type.n] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n [concrete = constants.%complete_type.54b] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -996,6 +1412,8 @@ fn ImportedConvertLocal(a: Adapter(C)) -> i32 { // CHECK:STDOUT: return %.loc7_12.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @ImportedConvertLocal(%a.param: %Adapter.58f) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %Adapter.58f = name_ref a, %a diff --git a/toolchain/check/testdata/class/generic/base_is_generic.carbon b/toolchain/check/testdata/class/generic/base_is_generic.carbon index 3fcead1a4db1..6ffa09471ecf 100644 --- a/toolchain/check/testdata/class/generic/base_is_generic.carbon +++ b/toolchain/check/testdata/class/generic/base_is_generic.carbon @@ -99,6 +99,13 @@ fn H() { // CHECK:STDOUT: %Base.370: type = class_type @Base, @Base(%T) [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %Base.elem.9af: type = unbound_element_type %Base.370, %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9f8: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.b7c: type = ptr_type %Base.370 [symbolic] +// CHECK:STDOUT: %pattern_type.8d4: type = pattern_type %ptr.b7c [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.x.2ac: type = struct_type {.x: %T} [symbolic] // CHECK:STDOUT: %complete_type.433: = complete_type_witness %struct_type.x.2ac [symbolic] // CHECK:STDOUT: %Param: type = class_type @Param [concrete] @@ -107,6 +114,11 @@ fn H() { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Param.elem: type = unbound_element_type %Param, %i32 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.2b9: = impl_witness @Param.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.756: type = ptr_type %Param [concrete] +// CHECK:STDOUT: %pattern_type.fae: type = pattern_type %ptr.756 [concrete] +// CHECK:STDOUT: %Param.as.Destroy.impl.Op.type: type = fn_type @Param.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Param.as.Destroy.impl.Op: %Param.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.y: type = struct_type {.y: %i32} [concrete] // CHECK:STDOUT: %complete_type.0f9: = complete_type_witness %struct_type.y [concrete] // CHECK:STDOUT: %Derived: type = class_type @Derived [concrete] @@ -115,6 +127,11 @@ fn H() { // CHECK:STDOUT: %struct_type.x.975: type = struct_type {.x: %Param} [concrete] // CHECK:STDOUT: %complete_type.db3: = complete_type_witness %struct_type.x.975 [concrete] // CHECK:STDOUT: %Derived.elem: type = unbound_element_type %Derived, %Base.7a8 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.8bc: type = struct_type {.base: %Base.7a8} [concrete] // CHECK:STDOUT: %complete_type.b07: = complete_type_witness %struct_type.base.8bc [concrete] // CHECK:STDOUT: %pattern_type.fb9: type = pattern_type %Derived [concrete] @@ -125,10 +142,12 @@ fn H() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -164,6 +183,66 @@ fn H() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Base.as.Destroy.impl(@Base.%T.loc4_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic = %Base.as.Destroy.impl.Op.type (constants.%Base.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Base.370 as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = fn_decl @Base.as.Destroy.impl.Op [symbolic = @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_27.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = value_param call_param0 +// CHECK:STDOUT: %.loc4_27.2: type = splice_block %Self.ref [symbolic = %Base (constants.%Base.370)] { +// CHECK:STDOUT: %.loc4_27.3: type = specific_constant constants.%Base.370, @Base(constants.%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_27.3 [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Param.as.Destroy.impl: constants.%Param as constants.%Destroy.type { +// CHECK:STDOUT: %Param.as.Destroy.impl.Op.decl: %Param.as.Destroy.impl.Op.type = fn_decl @Param.as.Destroy.impl.Op [concrete = constants.%Param.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.fae = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.fae = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.756 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Param [concrete = constants.%Param] +// CHECK:STDOUT: %self: %ptr.756 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Param.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Param.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Base(%T.loc4_17.2: type) { // CHECK:STDOUT: %T.loc4_17.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_17.1 (constants.%T)] // CHECK:STDOUT: @@ -177,6 +256,9 @@ fn H() { // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_17.2 [symbolic = %T.loc4_17.1 (constants.%T)] // CHECK:STDOUT: %.loc5: @Base.%Base.elem (%Base.elem.9af) = field_decl x, element0 [concrete] +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Base.as.Destroy.impl(constants.%T) [symbolic = @Base.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] // CHECK:STDOUT: %struct_type.x.loc6_1.1: type = struct_type {.x: %T} [symbolic = %struct_type.x.loc6_1.2 (constants.%struct_type.x.2ac)] // CHECK:STDOUT: %complete_type.loc6_1.1: = complete_type_witness %struct_type.x.loc6_1.1 [symbolic = %complete_type.loc6_1.2 (constants.%complete_type.433)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc6_1.1 @@ -192,6 +274,9 @@ fn H() { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc9: %Param.elem = field_decl y, element0 [concrete] +// CHECK:STDOUT: impl_decl @Param.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Param.as.Destroy.impl.%Param.as.Destroy.impl.Op.decl), @Param.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.2b9] // CHECK:STDOUT: %struct_type.y: type = struct_type {.y: %i32} [concrete = constants.%struct_type.y] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.y [concrete = constants.%complete_type.0f9] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -206,6 +291,9 @@ fn H() { // CHECK:STDOUT: %Param.ref: type = name_ref Param, file.%Param.decl [concrete = constants.%Param] // CHECK:STDOUT: %Base: type = class_type @Base, @Base(constants.%Param) [concrete = constants.%Base.7a8] // CHECK:STDOUT: %.loc13: %Derived.elem = base_decl %Base, element0 [concrete] +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base.7a8} [concrete = constants.%struct_type.base.8bc] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.b07] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -219,6 +307,21 @@ fn H() { // CHECK:STDOUT: extend %Base // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Base.as.Destroy.impl.Op(@Base.%T.loc4_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Base: type = class_type @Base, @Base(%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %ptr: type = ptr_type %Base [symbolic = %ptr (constants.%ptr.b7c)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.8d4)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Param.as.Destroy.impl.Op(%self.param: %ptr.756) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @DoubleFieldAccess(%d.param: %Derived) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %d.ref: %Derived = name_ref d, %d @@ -236,6 +339,18 @@ fn H() { // CHECK:STDOUT: %T.loc4_17.1 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.9f8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Base => constants.%Base.370 +// CHECK:STDOUT: %ptr => constants.%ptr.b7c +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.8d4 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Base(constants.%Param) { // CHECK:STDOUT: %T.loc4_17.1 => constants.%Param // CHECK:STDOUT: @@ -288,14 +403,14 @@ fn H() { // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Main.import_ref.e8d: = import_ref Main//extend_generic_base, loc10_1, loaded [concrete = constants.%complete_type.09d] -// CHECK:STDOUT: %Main.import_ref.446 = import_ref Main//extend_generic_base, inst42 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.446 = import_ref Main//extend_generic_base, inst90 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.a92: %Param.elem = import_ref Main//extend_generic_base, loc9_8, loaded [concrete = %.be7] // CHECK:STDOUT: %Main.import_ref.5ab: type = import_ref Main//extend_generic_base, loc4_17, loaded [symbolic = @Base.%T (constants.%T)] // CHECK:STDOUT: %Main.import_ref.b5f: = import_ref Main//extend_generic_base, loc6_1, loaded [symbolic = @Base.%complete_type (constants.%complete_type.433)] // CHECK:STDOUT: %Main.import_ref.8e0 = import_ref Main//extend_generic_base, inst26 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.7f7: @Base.%Base.elem (%Base.elem.9af) = import_ref Main//extend_generic_base, loc5_8, loaded [concrete = %.e66] // CHECK:STDOUT: %Main.import_ref.bd0: = import_ref Main//extend_generic_base, loc14_1, loaded [concrete = constants.%complete_type.b07] -// CHECK:STDOUT: %Main.import_ref.f6c = import_ref Main//extend_generic_base, inst76 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.f6c = import_ref Main//extend_generic_base, inst140 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.d24 = import_ref Main//extend_generic_base, loc13_27, unloaded // CHECK:STDOUT: %Main.import_ref.77a301.2: type = import_ref Main//extend_generic_base, loc13_26, loaded [concrete = constants.%Base.7a8] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] @@ -399,14 +514,26 @@ fn H() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] -// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete] +// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.f2e: type = class_type @C, @C(%T) [symbolic] // CHECK:STDOUT: %require_complete: = require_complete_type %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.a08: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %X: type = class_type @X [concrete] // CHECK:STDOUT: %X.G.type: type = fn_type @X.G [concrete] // CHECK:STDOUT: %X.G: %X.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.807: = impl_witness @X.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete] +// CHECK:STDOUT: %pattern_type.1c6: type = pattern_type %ptr.d17 [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op.type: type = fn_type @X.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op: %X.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] @@ -416,9 +543,11 @@ fn H() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -430,7 +559,7 @@ fn H() { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: %C.type = class_decl @C [concrete = constants.%C.generic] { -// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.loc4_9.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: } @@ -438,6 +567,50 @@ fn H() { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f2e as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc4_19.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.f2e)] { +// CHECK:STDOUT: %.loc4_19.3: type = specific_constant constants.%C.f2e, @C(constants.%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_19.3 [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @X.as.Destroy.impl: constants.%X as constants.%Destroy.type { +// CHECK:STDOUT: %X.as.Destroy.impl.Op.decl: %X.as.Destroy.impl.Op.type = fn_decl @X.as.Destroy.impl.Op [concrete = constants.%X.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1c6 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1c6 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.d17 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%X [concrete = constants.%X] +// CHECK:STDOUT: %self: %ptr.d17 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %X.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @X.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%T.loc4_9.2: type) { // CHECK:STDOUT: %T.loc4_9.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: @@ -447,6 +620,9 @@ fn H() { // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_9.2 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: %.loc9: = base_decl , element0 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: } [concrete = ] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = ] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -462,6 +638,9 @@ fn H() { // CHECK:STDOUT: // CHECK:STDOUT: class @X { // CHECK:STDOUT: %X.G.decl: %X.G.type = fn_decl @X.G [concrete = constants.%X.G] {} {} +// CHECK:STDOUT: impl_decl @X.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@X.as.Destroy.impl.%X.as.Destroy.impl.Op.decl), @X.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.807] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -471,11 +650,24 @@ fn H() { // CHECK:STDOUT: .G = %X.G.decl // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @X.G() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @X.as.Destroy.impl.Op(%self.param: %ptr.d17) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic] @@ -489,6 +681,18 @@ fn H() { // CHECK:STDOUT: %T.loc4_9.1 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a08 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.f2e +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%X) { // CHECK:STDOUT: %T.loc4_9.1 => constants.%X // CHECK:STDOUT: @@ -507,6 +711,13 @@ fn H() { // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %U [symbolic] // CHECK:STDOUT: %X.G.type.56f312.1: type = fn_type @X.G, @X(%U) [symbolic] // CHECK:STDOUT: %X.G.b504c4.1: %X.G.type.56f312.1 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.321: = impl_witness @X.%Destroy.impl_witness_table, @X.as.Destroy.impl(%U) [symbolic] +// CHECK:STDOUT: %ptr.428: type = ptr_type %X.75b6d8.1 [symbolic] +// CHECK:STDOUT: %pattern_type.d72: type = pattern_type %ptr.428 [symbolic] +// CHECK:STDOUT: %X.as.Destroy.impl.Op.type: type = fn_type @X.as.Destroy.impl.Op, @X.as.Destroy.impl(%U) [symbolic] +// CHECK:STDOUT: %X.as.Destroy.impl.Op: %X.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %U [symbolic] @@ -520,6 +731,11 @@ fn H() { // CHECK:STDOUT: %X.G.b504c4.2: %X.G.type.56f312.2 = struct_value () [symbolic] // CHECK:STDOUT: %require_complete.441: = require_complete_type %X.75b6d8.2 [symbolic] // CHECK:STDOUT: %C.elem.3f4: type = unbound_element_type %C.f2e, %X.75b6d8.2 [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.a08: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.base.f5f: type = struct_type {.base: %X.75b6d8.2} [symbolic] // CHECK:STDOUT: %complete_type.768: = complete_type_witness %struct_type.base.f5f [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] @@ -543,10 +759,12 @@ fn H() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -571,6 +789,62 @@ fn H() { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @X.as.Destroy.impl(@X.%U.loc4_14.2: type) { +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @X.%Destroy.impl_witness_table, @X.as.Destroy.impl(%U) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.321)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %X.as.Destroy.impl.Op.type: type = fn_type @X.as.Destroy.impl.Op, @X.as.Destroy.impl(%U) [symbolic = %X.as.Destroy.impl.Op.type (constants.%X.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %X.as.Destroy.impl.Op: @X.as.Destroy.impl.%X.as.Destroy.impl.Op.type (%X.as.Destroy.impl.Op.type) = struct_value () [symbolic = %X.as.Destroy.impl.Op (constants.%X.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%X.75b6d8.1 as constants.%Destroy.type { +// CHECK:STDOUT: %X.as.Destroy.impl.Op.decl: @X.as.Destroy.impl.%X.as.Destroy.impl.Op.type (%X.as.Destroy.impl.Op.type) = fn_decl @X.as.Destroy.impl.Op [symbolic = @X.as.Destroy.impl.%X.as.Destroy.impl.Op (constants.%X.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @X.as.Destroy.impl.Op.%pattern_type (%pattern_type.d72) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @X.as.Destroy.impl.Op.%pattern_type (%pattern_type.d72) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_24.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @X.as.Destroy.impl.Op.%ptr (%ptr.428) = value_param call_param0 +// CHECK:STDOUT: %.loc4_24.2: type = splice_block %Self.ref [symbolic = %X (constants.%X.75b6d8.1)] { +// CHECK:STDOUT: %.loc4_24.3: type = specific_constant constants.%X.75b6d8.1, @X(constants.%U) [symbolic = %X (constants.%X.75b6d8.1)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_24.3 [symbolic = %X (constants.%X.75b6d8.1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @X.as.Destroy.impl.Op.%ptr (%ptr.428) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %X.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @X.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc8_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f2e as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc8_19.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.f2e)] { +// CHECK:STDOUT: %.loc8_19.3: type = specific_constant constants.%C.f2e, @C(constants.%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc8_19.3 [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @X(%U.loc4_14.2: type) { // CHECK:STDOUT: %U.loc4_14.1: type = bind_symbolic_name U, 0 [symbolic = %U.loc4_14.1 (constants.%U)] // CHECK:STDOUT: @@ -587,6 +861,9 @@ fn H() { // CHECK:STDOUT: %return.param: ref @X.G.%U (%U) = out_param call_param0 // CHECK:STDOUT: %return: ref @X.G.%U (%U) = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @X.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@X.as.Destroy.impl.%X.as.Destroy.impl.Op.decl), @X.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @X.as.Destroy.impl(constants.%U) [symbolic = @X.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.321)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -614,6 +891,9 @@ fn H() { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc8_9.2 [symbolic = %T.loc8_9.1 (constants.%T)] // CHECK:STDOUT: %X.loc9_19.1: type = class_type @X, @X(constants.%T) [symbolic = %X.loc9_19.2 (constants.%X.75b6d8.2)] // CHECK:STDOUT: %.loc9: @C.%C.elem (%C.elem.3f4) = base_decl %X.loc9_19.1, element0 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] // CHECK:STDOUT: %struct_type.base.loc10_1.1: type = struct_type {.base: %X.75b6d8.2} [symbolic = %struct_type.base.loc10_1.2 (constants.%struct_type.base.f5f)] // CHECK:STDOUT: %complete_type.loc10_1.1: = complete_type_witness %struct_type.base.loc10_1.1 [symbolic = %complete_type.loc10_1.2 (constants.%complete_type.768)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc10_1.1 @@ -650,6 +930,28 @@ fn H() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @X.as.Destroy.impl.Op(@X.%U.loc4_14.2: type) { +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %X: type = class_type @X, @X(%U) [symbolic = %X (constants.%X.75b6d8.1)] +// CHECK:STDOUT: %ptr: type = ptr_type %X [symbolic = %ptr (constants.%ptr.428)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.d72)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @X.as.Destroy.impl.Op.%ptr (%ptr.428)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc8_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -692,6 +994,18 @@ fn H() { // CHECK:STDOUT: %X.G.specific_fn.loc5_24.2 => constants.%X.G.specific_fn.169 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @X.as.Destroy.impl(constants.%U) { +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.321 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @X.as.Destroy.impl.Op(constants.%U) { +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %X => constants.%X.75b6d8.1 +// CHECK:STDOUT: %ptr => constants.%ptr.428 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d72 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%T) { // CHECK:STDOUT: %T.loc8_9.1 => constants.%T // CHECK:STDOUT: } @@ -704,6 +1018,18 @@ fn H() { // CHECK:STDOUT: %X.G => constants.%X.G.b504c4.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a08 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.f2e +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%i32) { // CHECK:STDOUT: %T.loc8_9.1 => constants.%i32 // CHECK:STDOUT: @@ -792,7 +1118,7 @@ fn H() { // CHECK:STDOUT: %Main.import_ref.b8a: @X.%X.G.type (%X.G.type.56f312.1) = import_ref Main//extend_generic_symbolic_base, loc5_15, loaded [symbolic = @X.%X.G (constants.%X.G.b504c4.1)] // CHECK:STDOUT: %Main.import_ref.5ab3ec.2: type = import_ref Main//extend_generic_symbolic_base, loc8_9, loaded [symbolic = @C.%T (constants.%T)] // CHECK:STDOUT: %Main.import_ref.93f: = import_ref Main//extend_generic_symbolic_base, loc10_1, loaded [symbolic = @C.%complete_type (constants.%complete_type.768)] -// CHECK:STDOUT: %Main.import_ref.4c0 = import_ref Main//extend_generic_symbolic_base, inst66 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.4c0 = import_ref Main//extend_generic_symbolic_base, inst114 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.65d = import_ref Main//extend_generic_symbolic_base, loc9_20, unloaded // CHECK:STDOUT: %Main.import_ref.561eb2.2: type = import_ref Main//extend_generic_symbolic_base, loc9_19, loaded [symbolic = @C.%X (constants.%X.75b6d8.2)] // CHECK:STDOUT: %Main.import_ref.5ab3ec.3: type = import_ref Main//extend_generic_symbolic_base, loc4_14, loaded [symbolic = @X.%U (constants.%U)] diff --git a/toolchain/check/testdata/class/generic/basic.carbon b/toolchain/check/testdata/class/generic/basic.carbon index 7f4fe274cb22..d9786b458bce 100644 --- a/toolchain/check/testdata/class/generic/basic.carbon +++ b/toolchain/check/testdata/class/generic/basic.carbon @@ -48,6 +48,10 @@ class Declaration(T:! type); // CHECK:STDOUT: %Class.GetValue: %Class.GetValue.type = struct_value () [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.k: type = struct_type {.k: %T} [symbolic] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.k [symbolic] // CHECK:STDOUT: %require_complete.6e5: = require_complete_type %ptr.79f [symbolic] @@ -59,9 +63,11 @@ class Declaration(T:! type); // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -83,6 +89,34 @@ class Declaration(T:! type); // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%T.loc15_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = value_param call_param0 +// CHECK:STDOUT: %.loc15_23.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class)] { +// CHECK:STDOUT: %.loc15_23.3: type = specific_constant constants.%Class, @Class(constants.%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc15_23.3 [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Class(%T.loc15_13.2: type) { // CHECK:STDOUT: %T.loc15_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc15_13.1 (constants.%T)] // CHECK:STDOUT: @@ -135,6 +169,9 @@ class Declaration(T:! type); // CHECK:STDOUT: } // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc15_13.2 [symbolic = %T.loc15_13.1 (constants.%T)] // CHECK:STDOUT: %.loc25: @Class.%Class.elem (%Class.elem) = field_decl k, element0 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%T) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %struct_type.k.loc26_1.1: type = struct_type {.k: %T} [symbolic = %struct_type.k.loc26_1.2 (constants.%struct_type.k)] // CHECK:STDOUT: %complete_type.loc26_1.1: = complete_type_witness %struct_type.k.loc26_1.1 [symbolic = %complete_type.loc26_1.2 (constants.%complete_type)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc26_1.1 @@ -200,6 +237,17 @@ class Declaration(T:! type); // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%T.loc15_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.955)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.9e0)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Class(constants.%T) { // CHECK:STDOUT: %T.loc15_13.1 => constants.%T // CHECK:STDOUT: @@ -231,6 +279,18 @@ class Declaration(T:! type); // CHECK:STDOUT: %pattern_type.loc21_29 => constants.%pattern_type.7dc // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Class => constants.%Class +// CHECK:STDOUT: %ptr => constants.%ptr.955 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.9e0 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Declaration(constants.%T) { // CHECK:STDOUT: %T.loc28_19.1 => constants.%T // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/class/generic/call.carbon b/toolchain/check/testdata/class/generic/call.carbon index 499e4d39e2cc..ccf57584deb3 100644 --- a/toolchain/check/testdata/class/generic/call.carbon +++ b/toolchain/check/testdata/class/generic/call.carbon @@ -105,6 +105,13 @@ class Outer(T:! type) { // CHECK:STDOUT: %Class.type: type = generic_class_type @Class [concrete] // CHECK:STDOUT: %Class.generic: %Class.type = struct_value () [concrete] // CHECK:STDOUT: %Class.ab2: type = class_type @Class, @Class(%T, %N.356) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.16f: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T, %N.356) [symbolic] +// CHECK:STDOUT: %ptr.770: type = ptr_type %Class.ab2 [symbolic] +// CHECK:STDOUT: %pattern_type.b96: type = pattern_type %ptr.770 [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T, %N.356) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] @@ -138,11 +145,13 @@ class Outer(T:! type) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -210,6 +219,35 @@ class Outer(T:! type) { // CHECK:STDOUT: %b: ref %Class.dd4 = bind_name b, %b.var [concrete = %b.var] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%T.loc4_13.2: type, @Class.%N.loc4_23.2: %i32) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 1 [symbolic = %N (constants.%N.356)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T, %N) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.16f)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T, %N) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class.ab2 as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.b96) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.b96) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_32.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.770) = value_param call_param0 +// CHECK:STDOUT: %.loc4_32.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class.ab2)] { +// CHECK:STDOUT: %.loc4_32.3: type = specific_constant constants.%Class.ab2, @Class(constants.%T, constants.%N.356) [symbolic = %Class (constants.%Class.ab2)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_32.3 [symbolic = %Class (constants.%Class.ab2)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.770) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Class(%T.loc4_13.2: type, %N.loc4_23.2: %i32) { // CHECK:STDOUT: %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: %N.loc4_23.1: %i32 = bind_symbolic_name N, 1 [symbolic = %N.loc4_23.1 (constants.%N.356)] @@ -217,6 +255,9 @@ class Outer(T:! type) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%T, constants.%N.356) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.16f)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -226,11 +267,37 @@ class Outer(T:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%T.loc4_13.2: type, @Class.%N.loc4_23.2: %i32) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 1 [symbolic = %N (constants.%N.356)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T, %N) [symbolic = %Class (constants.%Class.ab2)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.770)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.b96)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.770)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Class(constants.%T, constants.%N.356) { // CHECK:STDOUT: %T.loc4_13.1 => constants.%T // CHECK:STDOUT: %N.loc4_23.1 => constants.%N.356 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%T, constants.%N.356) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %N => constants.%N.356 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.16f +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%T, constants.%N.356) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %N => constants.%N.356 +// CHECK:STDOUT: %Class => constants.%Class.ab2 +// CHECK:STDOUT: %ptr => constants.%ptr.770 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.b96 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Class(constants.%ptr.235, constants.%int_5.0f6) { // CHECK:STDOUT: %T.loc4_13.1 => constants.%ptr.235 // CHECK:STDOUT: %N.loc4_23.1 => constants.%int_5.0f6 @@ -259,18 +326,27 @@ class Outer(T:! type) { // CHECK:STDOUT: %Class.type: type = generic_class_type @Class [concrete] // CHECK:STDOUT: %Class.generic: %Class.type = struct_value () [concrete] // CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T, %N.356) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T, %N.356) [symbolic] +// CHECK:STDOUT: %ptr.770: type = ptr_type %Class [symbolic] +// CHECK:STDOUT: %pattern_type.b96: type = pattern_type %ptr.770 [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T, %N.356) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete] +// CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -300,11 +376,40 @@ class Outer(T:! type) { // CHECK:STDOUT: %Class.ref: %Class.type = name_ref Class, %Class.decl [concrete = constants.%Class.generic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete = constants.%ptr.235] // CHECK:STDOUT: } // CHECK:STDOUT: %a: = bind_name a, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%T.loc4_13.2: type, @Class.%N.loc4_23.2: %i32) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 1 [symbolic = %N (constants.%N.356)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T, %N) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T, %N) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.b96) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.b96) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_32.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.770) = value_param call_param0 +// CHECK:STDOUT: %.loc4_32.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class)] { +// CHECK:STDOUT: %.loc4_32.3: type = specific_constant constants.%Class, @Class(constants.%T, constants.%N.356) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_32.3 [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.770) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Class(%T.loc4_13.2: type, %N.loc4_23.2: %i32) { // CHECK:STDOUT: %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: %N.loc4_23.1: %i32 = bind_symbolic_name N, 1 [symbolic = %N.loc4_23.1 (constants.%N.356)] @@ -312,6 +417,9 @@ class Outer(T:! type) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%T, constants.%N.356) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -321,11 +429,37 @@ class Outer(T:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%T.loc4_13.2: type, @Class.%N.loc4_23.2: %i32) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 1 [symbolic = %N (constants.%N.356)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T, %N) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.770)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.b96)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.770)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Class(constants.%T, constants.%N.356) { // CHECK:STDOUT: %T.loc4_13.1 => constants.%T // CHECK:STDOUT: %N.loc4_23.1 => constants.%N.356 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%T, constants.%N.356) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %N => constants.%N.356 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%T, constants.%N.356) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %N => constants.%N.356 +// CHECK:STDOUT: %Class => constants.%Class +// CHECK:STDOUT: %ptr => constants.%ptr.770 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.b96 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_too_many.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -340,9 +474,16 @@ class Outer(T:! type) { // CHECK:STDOUT: %Class.type: type = generic_class_type @Class [concrete] // CHECK:STDOUT: %Class.generic: %Class.type = struct_value () [concrete] // CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T, %N.356) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T, %N.356) [symbolic] +// CHECK:STDOUT: %ptr.770: type = ptr_type %Class [symbolic] +// CHECK:STDOUT: %pattern_type.b96: type = pattern_type %ptr.770 [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T, %N.356) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete] +// CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: } @@ -350,10 +491,12 @@ class Outer(T:! type) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -383,13 +526,42 @@ class Outer(T:! type) { // CHECK:STDOUT: %Class.ref: %Class.type = name_ref Class, %Class.decl [concrete = constants.%Class.generic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete = constants.%ptr.235] // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2] // CHECK:STDOUT: } // CHECK:STDOUT: %a: = bind_name a, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%T.loc4_13.2: type, @Class.%N.loc4_23.2: %i32) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 1 [symbolic = %N (constants.%N.356)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T, %N) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T, %N) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.b96) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.b96) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_32.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.770) = value_param call_param0 +// CHECK:STDOUT: %.loc4_32.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class)] { +// CHECK:STDOUT: %.loc4_32.3: type = specific_constant constants.%Class, @Class(constants.%T, constants.%N.356) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_32.3 [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.770) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Class(%T.loc4_13.2: type, %N.loc4_23.2: %i32) { // CHECK:STDOUT: %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: %N.loc4_23.1: %i32 = bind_symbolic_name N, 1 [symbolic = %N.loc4_23.1 (constants.%N.356)] @@ -397,6 +569,9 @@ class Outer(T:! type) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%T, constants.%N.356) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -406,11 +581,37 @@ class Outer(T:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%T.loc4_13.2: type, @Class.%N.loc4_23.2: %i32) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 1 [symbolic = %N (constants.%N.356)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T, %N) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.770)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.b96)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.770)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Class(constants.%T, constants.%N.356) { // CHECK:STDOUT: %T.loc4_13.1 => constants.%T // CHECK:STDOUT: %N.loc4_23.1 => constants.%N.356 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%T, constants.%N.356) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %N => constants.%N.356 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%T, constants.%N.356) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %N => constants.%N.356 +// CHECK:STDOUT: %Class => constants.%Class +// CHECK:STDOUT: %ptr => constants.%ptr.770 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.b96 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_no_conversion.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -425,10 +626,17 @@ class Outer(T:! type) { // CHECK:STDOUT: %Class.type: type = generic_class_type @Class [concrete] // CHECK:STDOUT: %Class.generic: %Class.type = struct_value () [concrete] // CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T, %N.356) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T, %N.356) [symbolic] +// CHECK:STDOUT: %ptr.770: type = ptr_type %Class [symbolic] +// CHECK:STDOUT: %pattern_type.b96: type = pattern_type %ptr.770 [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T, %N.356) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %int_5: Core.IntLiteral = int_value 5 [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete] +// CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: } @@ -436,11 +644,13 @@ class Outer(T:! type) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -472,12 +682,41 @@ class Outer(T:! type) { // CHECK:STDOUT: %int_5: Core.IntLiteral = int_value 5 [concrete = constants.%int_5] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete = constants.%ptr.235] // CHECK:STDOUT: %.loc16: type = converted %int_5, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: %a: = bind_name a, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%T.loc4_13.2: type, @Class.%N.loc4_23.2: %i32) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 1 [symbolic = %N (constants.%N.356)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T, %N) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T, %N) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.b96) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.b96) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_32.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.770) = value_param call_param0 +// CHECK:STDOUT: %.loc4_32.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class)] { +// CHECK:STDOUT: %.loc4_32.3: type = specific_constant constants.%Class, @Class(constants.%T, constants.%N.356) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_32.3 [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.770) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Class(%T.loc4_13.2: type, %N.loc4_23.2: %i32) { // CHECK:STDOUT: %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: %N.loc4_23.1: %i32 = bind_symbolic_name N, 1 [symbolic = %N.loc4_23.1 (constants.%N.356)] @@ -485,6 +724,9 @@ class Outer(T:! type) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%T, constants.%N.356) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -494,11 +736,37 @@ class Outer(T:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%T.loc4_13.2: type, @Class.%N.loc4_23.2: %i32) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 1 [symbolic = %N (constants.%N.356)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T, %N) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.770)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.b96)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.770)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Class(constants.%T, constants.%N.356) { // CHECK:STDOUT: %T.loc4_13.1 => constants.%T // CHECK:STDOUT: %N.loc4_23.1 => constants.%N.356 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%T, constants.%N.356) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %N => constants.%N.356 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%T, constants.%N.356) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %N => constants.%N.356 +// CHECK:STDOUT: %Class => constants.%Class +// CHECK:STDOUT: %ptr => constants.%ptr.770 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.b96 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- call_in_nested_return_type.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -525,8 +793,20 @@ class Outer(T:! type) { // CHECK:STDOUT: %pattern_type.372: type = pattern_type %Inner.c71 [symbolic] // CHECK:STDOUT: %Inner.D.type.102: type = fn_type @Inner.D, @Inner(%T, %U) [symbolic] // CHECK:STDOUT: %Inner.D.d85: %Inner.D.type.102 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.de8: = impl_witness @Inner.%Destroy.impl_witness_table, @Inner.as.Destroy.impl(%T, %U) [symbolic] +// CHECK:STDOUT: %ptr.276: type = ptr_type %Inner.c71 [symbolic] +// CHECK:STDOUT: %pattern_type.01f: type = pattern_type %ptr.276 [symbolic] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.type: type = fn_type @Inner.as.Destroy.impl.Op, @Inner.as.Destroy.impl(%T, %U) [symbolic] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op: %Inner.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.a35: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.6ff: type = ptr_type %Outer.9d6 [symbolic] +// CHECK:STDOUT: %pattern_type.07e: type = pattern_type %ptr.6ff [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: %Outer.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %require_complete.127: = require_complete_type %Outer.9d6 [symbolic] // CHECK:STDOUT: %Outer.val.234: %Outer.9d6 = struct_value () [symbolic] // CHECK:STDOUT: %Inner.type.a71: type = generic_class_type @Inner, @Outer(%U) [symbolic] @@ -549,9 +829,11 @@ class Outer(T:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -567,6 +849,63 @@ class Outer(T:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Inner.as.Destroy.impl(@Outer.%T.loc2_13.2: type, @Inner.%U.loc3_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 1 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Inner.%Destroy.impl_witness_table, @Inner.as.Destroy.impl(%T, %U) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.de8)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.type: type = fn_type @Inner.as.Destroy.impl.Op, @Inner.as.Destroy.impl(%T, %U) [symbolic = %Inner.as.Destroy.impl.Op.type (constants.%Inner.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op: @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.type (%Inner.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Inner.as.Destroy.impl.Op (constants.%Inner.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Inner.c71 as constants.%Destroy.type { +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.decl: @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.type (%Inner.as.Destroy.impl.Op.type) = fn_decl @Inner.as.Destroy.impl.Op [symbolic = @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op (constants.%Inner.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Inner.as.Destroy.impl.Op.%pattern_type (%pattern_type.01f) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Inner.as.Destroy.impl.Op.%pattern_type (%pattern_type.01f) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc3_25.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Inner.as.Destroy.impl.Op.%ptr (%ptr.276) = value_param call_param0 +// CHECK:STDOUT: %.loc3_25.2: type = splice_block %Self.ref [symbolic = %Inner (constants.%Inner.c71)] { +// CHECK:STDOUT: %.loc3_25.3: type = specific_constant constants.%Inner.c71, @Inner(constants.%T, constants.%U) [symbolic = %Inner (constants.%Inner.c71)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc3_25.3 [symbolic = %Inner (constants.%Inner.c71)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Inner.as.Destroy.impl.Op.%ptr (%ptr.276) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Inner.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Inner.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Outer.as.Destroy.impl(@Outer.%T.loc2_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.a35)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%T) [symbolic = %Outer.as.Destroy.impl.Op.type (constants.%Outer.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Outer.9d6 as constants.%Destroy.type { +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.decl: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = fn_decl @Outer.as.Destroy.impl.Op [symbolic = @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.07e) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.07e) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc2_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff) = value_param call_param0 +// CHECK:STDOUT: %.loc2_23.2: type = splice_block %Self.ref [symbolic = %Outer (constants.%Outer.9d6)] { +// CHECK:STDOUT: %.loc2_23.3: type = specific_constant constants.%Outer.9d6, @Outer(constants.%T) [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc2_23.3 [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Outer.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Outer.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Outer(%T.loc2_13.2: type) { // CHECK:STDOUT: %T.loc2_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc2_13.1 (constants.%T)] // CHECK:STDOUT: @@ -580,6 +919,9 @@ class Outer(T:! type) { // CHECK:STDOUT: } { // CHECK:STDOUT: %U.loc3_15.2: type = bind_symbolic_name U, 1 [symbolic = %U.loc3_15.1 (constants.%U)] // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Outer.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.decl), @Outer.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Outer.as.Destroy.impl(constants.%T) [symbolic = @Outer.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a35)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -649,6 +991,9 @@ class Outer(T:! type) { // CHECK:STDOUT: %return.param: ref @Inner.D.%Inner.loc13_22.1 (%Inner.c71) = out_param call_param0 // CHECK:STDOUT: %return: ref @Inner.D.%Inner.loc13_22.1 (%Inner.c71) = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Inner.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.decl), @Inner.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Inner.as.Destroy.impl(constants.%T, constants.%U) [symbolic = @Inner.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.de8)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -743,6 +1088,29 @@ class Outer(T:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Inner.as.Destroy.impl.Op(@Outer.%T.loc2_13.2: type, @Inner.%U.loc3_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 1 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Inner: type = class_type @Inner, @Inner(%T, %U) [symbolic = %Inner (constants.%Inner.c71)] +// CHECK:STDOUT: %ptr: type = ptr_type %Inner [symbolic = %ptr (constants.%ptr.276)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.01f)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Inner.as.Destroy.impl.Op.%ptr (%ptr.276)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Outer.as.Destroy.impl.Op(@Outer.%T.loc2_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Outer: type = class_type @Outer, @Outer(%T) [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: %ptr: type = ptr_type %Outer [symbolic = %ptr (constants.%ptr.6ff)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.07e)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Outer(constants.%T) { // CHECK:STDOUT: %T.loc2_13.1 => constants.%T // CHECK:STDOUT: @@ -818,3 +1186,29 @@ class Outer(T:! type) { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.372 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Inner.as.Destroy.impl(constants.%T, constants.%U) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.de8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Inner.as.Destroy.impl.Op(constants.%T, constants.%U) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Inner => constants.%Inner.c71 +// CHECK:STDOUT: %ptr => constants.%ptr.276 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.01f +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a35 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Outer => constants.%Outer.9d6 +// CHECK:STDOUT: %ptr => constants.%ptr.6ff +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.07e +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/generic/complete_in_conversion.carbon b/toolchain/check/testdata/class/generic/complete_in_conversion.carbon index ffd9dbfa0d67..6e846a2dacb7 100644 --- a/toolchain/check/testdata/class/generic/complete_in_conversion.carbon +++ b/toolchain/check/testdata/class/generic/complete_in_conversion.carbon @@ -45,6 +45,13 @@ fn F(a: A(0)*) { // CHECK:STDOUT: %Int.type.913: type = fn_type @Int.loc2 [concrete] // CHECK:STDOUT: %Int.779: %Int.type.913 = struct_value () [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] @@ -79,6 +86,11 @@ fn F(a: A(0)*) { // CHECK:STDOUT: %iN.builtin.8fe: type = int_type signed, %Int.as.ImplicitAs.impl.Convert.call [symbolic] // CHECK:STDOUT: %require_complete.e34: = require_complete_type %iN.builtin.8fe [symbolic] // CHECK:STDOUT: %A.elem.07f: type = unbound_element_type %A.dd3, %iN.builtin.8fe [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.3b2: = impl_witness @A.%Destroy.impl_witness_table, @A.as.Destroy.impl(%N.51e) [symbolic] +// CHECK:STDOUT: %ptr.72a: type = ptr_type %A.dd3 [symbolic] +// CHECK:STDOUT: %pattern_type.b2f: type = pattern_type %ptr.72a [symbolic] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op, @A.as.Destroy.impl(%N.51e) [symbolic] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.base.n: type = struct_type {.base: %B, .n: %iN.builtin.8fe} [symbolic] // CHECK:STDOUT: %complete_type.beb: = complete_type_witness %struct_type.base.n [symbolic] // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] @@ -98,8 +110,6 @@ fn F(a: A(0)*) { // CHECK:STDOUT: %pattern_type.213: type = pattern_type %ptr.b65 [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] -// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] // CHECK:STDOUT: %A.elem.d81: type = unbound_element_type %A.6fc, %B [concrete] // CHECK:STDOUT: %Int.as.ImplicitAs.impl.Convert.bound.0fd: = bound_method %int_0.6a9, %Int.as.ImplicitAs.impl.Convert.960 [concrete] // CHECK:STDOUT: %bound_method.4b5: = bound_method %int_0.6a9, %Int.as.ImplicitAs.impl.Convert.specific_fn [concrete] @@ -108,12 +118,14 @@ fn F(a: A(0)*) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .IntLiteral = %Core.IntLiteral +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.IntLiteral: %IntLiteral.type = import_ref Core//prelude/parts/int_literal, IntLiteral, loaded [concrete = constants.%IntLiteral] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type.878 = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] @@ -181,7 +193,54 @@ fn F(a: A(0)*) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @A.as.Destroy.impl(@A.%N.loc6_9.2: %i32) { +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.51e)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @A.%Destroy.impl_witness_table, @A.as.Destroy.impl(%N) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.3b2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op, @A.as.Destroy.impl(%N) [symbolic = %A.as.Destroy.impl.Op.type (constants.%A.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: @A.as.Destroy.impl.%A.as.Destroy.impl.Op.type (%A.as.Destroy.impl.Op.type) = struct_value () [symbolic = %A.as.Destroy.impl.Op (constants.%A.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%A.dd3 as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: @A.as.Destroy.impl.%A.as.Destroy.impl.Op.type (%A.as.Destroy.impl.Op.type) = fn_decl @A.as.Destroy.impl.Op [symbolic = @A.as.Destroy.impl.%A.as.Destroy.impl.Op (constants.%A.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @A.as.Destroy.impl.Op.%pattern_type (%pattern_type.b2f) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @A.as.Destroy.impl.Op.%pattern_type (%pattern_type.b2f) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6_18.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @A.as.Destroy.impl.Op.%ptr (%ptr.72a) = value_param call_param0 +// CHECK:STDOUT: %.loc6_18.2: type = splice_block %Self.ref [symbolic = %A (constants.%A.dd3)] { +// CHECK:STDOUT: %.loc6_18.3: type = specific_constant constants.%A.dd3, @A(constants.%N.51e) [symbolic = %A (constants.%A.dd3)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc6_18.3 [symbolic = %A (constants.%A.dd3)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @A.as.Destroy.impl.Op.%ptr (%ptr.72a) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @B { +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -223,6 +282,9 @@ fn F(a: A(0)*) { // CHECK:STDOUT: %.loc12_15.1: type = value_of_initializer %Int.call [symbolic = %iN.builtin (constants.%iN.builtin.8fe)] // CHECK:STDOUT: %.loc12_15.2: type = converted %Int.call, %.loc12_15.1 [symbolic = %iN.builtin (constants.%iN.builtin.8fe)] // CHECK:STDOUT: %.loc12_8: @A.%A.elem.loc12 (%A.elem.07f) = field_decl n, element1 [concrete] +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @A.as.Destroy.impl(constants.%N.51e) [symbolic = @A.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.3b2)] // CHECK:STDOUT: %struct_type.base.n.loc13_1.1: type = struct_type {.base: %B, .n: %iN.builtin.8fe} [symbolic = %struct_type.base.n.loc13_1.2 (constants.%struct_type.base.n)] // CHECK:STDOUT: %complete_type.loc13_1.1: = complete_type_witness %struct_type.base.n.loc13_1.1 [symbolic = %complete_type.loc13_1.2 (constants.%complete_type.beb)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc13_1.1 @@ -240,6 +302,19 @@ fn F(a: A(0)*) { // CHECK:STDOUT: // CHECK:STDOUT: fn @Int.loc2(%N.param: Core.IntLiteral) -> type = "int.make_type_signed"; // CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @A.as.Destroy.impl.Op(@A.%N.loc6_9.2: %i32) { +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.51e)] +// CHECK:STDOUT: %A: type = class_type @A, @A(%N) [symbolic = %A (constants.%A.dd3)] +// CHECK:STDOUT: %ptr: type = ptr_type %A [symbolic = %ptr (constants.%ptr.72a)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.b2f)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @A.as.Destroy.impl.Op.%ptr (%ptr.72a)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%a.param: %ptr.b65) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -262,6 +337,18 @@ fn F(a: A(0)*) { // CHECK:STDOUT: %N.loc6_9.1 => constants.%N.51e // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @A.as.Destroy.impl(constants.%N.51e) { +// CHECK:STDOUT: %N => constants.%N.51e +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.3b2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.as.Destroy.impl.Op(constants.%N.51e) { +// CHECK:STDOUT: %N => constants.%N.51e +// CHECK:STDOUT: %A => constants.%A.dd3 +// CHECK:STDOUT: %ptr => constants.%ptr.72a +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.b2f +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @A(constants.%int_0.6a9) { // CHECK:STDOUT: %N.loc6_9.1 => constants.%int_0.6a9 // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/generic/field.carbon b/toolchain/check/testdata/class/generic/field.carbon index bfe44269b0e5..04b7152ccf35 100644 --- a/toolchain/check/testdata/class/generic/field.carbon +++ b/toolchain/check/testdata/class/generic/field.carbon @@ -38,6 +38,13 @@ fn H(U:! type, c: Class(U)) -> U { // CHECK:STDOUT: %Class.fe1b2d.1: type = class_type @Class, @Class(%T) [symbolic] // CHECK:STDOUT: %require_complete.4aeca8.1: = require_complete_type %T [symbolic] // CHECK:STDOUT: %Class.elem.e262de.1: type = unbound_element_type %Class.fe1b2d.1, %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.955: type = ptr_type %Class.fe1b2d.1 [symbolic] +// CHECK:STDOUT: %pattern_type.9e0: type = pattern_type %ptr.955 [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.x.2ac3f0.1: type = struct_type {.x: %T} [symbolic] // CHECK:STDOUT: %complete_type.4339b3.1: = complete_type_witness %struct_type.x.2ac3f0.1 [symbolic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] @@ -74,10 +81,12 @@ fn H(U:! type, c: Class(U)) -> U { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -154,6 +163,34 @@ fn H(U:! type, c: Class(U)) -> U { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%T.loc15_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class.fe1b2d.1 as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = value_param call_param0 +// CHECK:STDOUT: %.loc15_23.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class.fe1b2d.1)] { +// CHECK:STDOUT: %.loc15_23.3: type = specific_constant constants.%Class.fe1b2d.1, @Class(constants.%T) [symbolic = %Class (constants.%Class.fe1b2d.1)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc15_23.3 [symbolic = %Class (constants.%Class.fe1b2d.1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Class(%T.loc15_13.2: type) { // CHECK:STDOUT: %T.loc15_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc15_13.1 (constants.%T)] // CHECK:STDOUT: @@ -167,6 +204,9 @@ fn H(U:! type, c: Class(U)) -> U { // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc15_13.2 [symbolic = %T.loc15_13.1 (constants.%T)] // CHECK:STDOUT: %.loc16: @Class.%Class.elem (%Class.elem.e262de.1) = field_decl x, element0 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%T) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %struct_type.x.loc17_1.1: type = struct_type {.x: %T} [symbolic = %struct_type.x.loc17_1.2 (constants.%struct_type.x.2ac3f0.1)] // CHECK:STDOUT: %complete_type.loc17_1.1: = complete_type_witness %struct_type.x.loc17_1.1 [symbolic = %complete_type.loc17_1.2 (constants.%complete_type.4339b3.1)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc17_1.1 @@ -178,6 +218,17 @@ fn H(U:! type, c: Class(U)) -> U { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%T.loc15_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.fe1b2d.1)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.955)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.9e0)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%c.param: %Class.247) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %c.ref: %Class.247 = name_ref c, %c @@ -240,6 +291,18 @@ fn H(U:! type, c: Class(U)) -> U { // CHECK:STDOUT: %complete_type.loc17_1.2 => constants.%complete_type.4339b3.1 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Class => constants.%Class.fe1b2d.1 +// CHECK:STDOUT: %ptr => constants.%ptr.955 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.9e0 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Class(constants.%i32) { // CHECK:STDOUT: %T.loc15_13.1 => constants.%i32 // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/generic/import.carbon b/toolchain/check/testdata/class/generic/import.carbon index 7386ddc32059..158a4290f98e 100644 --- a/toolchain/check/testdata/class/generic/import.carbon +++ b/toolchain/check/testdata/class/generic/import.carbon @@ -107,6 +107,13 @@ class Class(U:! type) { // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %CompleteClass.F.type: type = fn_type @CompleteClass.F, @CompleteClass(%T) [symbolic] // CHECK:STDOUT: %CompleteClass.F: %CompleteClass.F.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d3a: = impl_witness @CompleteClass.%Destroy.impl_witness_table, @CompleteClass.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.5b4: type = ptr_type %CompleteClass.f97 [symbolic] +// CHECK:STDOUT: %pattern_type.1fe: type = pattern_type %ptr.5b4 [symbolic] +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op.type: type = fn_type @CompleteClass.as.Destroy.impl.Op, @CompleteClass.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op: %CompleteClass.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete] // CHECK:STDOUT: %complete_type.54b: = complete_type_witness %struct_type.n [concrete] // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] @@ -135,11 +142,13 @@ class Class(U:! type) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -176,6 +185,34 @@ class Class(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @CompleteClass.as.Destroy.impl(@CompleteClass.%T.loc6_21.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @CompleteClass.%Destroy.impl_witness_table, @CompleteClass.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.d3a)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op.type: type = fn_type @CompleteClass.as.Destroy.impl.Op, @CompleteClass.as.Destroy.impl(%T) [symbolic = %CompleteClass.as.Destroy.impl.Op.type (constants.%CompleteClass.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op: @CompleteClass.as.Destroy.impl.%CompleteClass.as.Destroy.impl.Op.type (%CompleteClass.as.Destroy.impl.Op.type) = struct_value () [symbolic = %CompleteClass.as.Destroy.impl.Op (constants.%CompleteClass.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%CompleteClass.f97 as constants.%Destroy.type { +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op.decl: @CompleteClass.as.Destroy.impl.%CompleteClass.as.Destroy.impl.Op.type (%CompleteClass.as.Destroy.impl.Op.type) = fn_decl @CompleteClass.as.Destroy.impl.Op [symbolic = @CompleteClass.as.Destroy.impl.%CompleteClass.as.Destroy.impl.Op (constants.%CompleteClass.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @CompleteClass.as.Destroy.impl.Op.%pattern_type (%pattern_type.1fe) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @CompleteClass.as.Destroy.impl.Op.%pattern_type (%pattern_type.1fe) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6_31.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @CompleteClass.as.Destroy.impl.Op.%ptr (%ptr.5b4) = value_param call_param0 +// CHECK:STDOUT: %.loc6_31.2: type = splice_block %Self.ref [symbolic = %CompleteClass (constants.%CompleteClass.f97)] { +// CHECK:STDOUT: %.loc6_31.3: type = specific_constant constants.%CompleteClass.f97, @CompleteClass(constants.%T) [symbolic = %CompleteClass (constants.%CompleteClass.f97)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc6_31.3 [symbolic = %CompleteClass (constants.%CompleteClass.f97)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @CompleteClass.as.Destroy.impl.Op.%ptr (%ptr.5b4) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %CompleteClass.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @CompleteClass.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Class(%T.loc4_13.2: type) { // CHECK:STDOUT: %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: @@ -204,6 +241,9 @@ class Class(U:! type) { // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @CompleteClass.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@CompleteClass.as.Destroy.impl.%CompleteClass.as.Destroy.impl.Op.decl), @CompleteClass.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @CompleteClass.as.Destroy.impl(constants.%T) [symbolic = @CompleteClass.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.d3a)] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete = constants.%struct_type.n] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n [concrete = constants.%complete_type.54b] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -232,6 +272,17 @@ class Class(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @CompleteClass.as.Destroy.impl.Op(@CompleteClass.%T.loc6_21.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %CompleteClass: type = class_type @CompleteClass, @CompleteClass(%T) [symbolic = %CompleteClass (constants.%CompleteClass.f97)] +// CHECK:STDOUT: %ptr: type = ptr_type %CompleteClass [symbolic = %ptr (constants.%ptr.5b4)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1fe)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @CompleteClass.as.Destroy.impl.Op.%ptr (%ptr.5b4)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() -> %CompleteClass.e9e; // CHECK:STDOUT: // CHECK:STDOUT: specific @Class(constants.%T) { @@ -250,6 +301,18 @@ class Class(U:! type) { // CHECK:STDOUT: // CHECK:STDOUT: specific @CompleteClass.F(constants.%T) {} // CHECK:STDOUT: +// CHECK:STDOUT: specific @CompleteClass.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.d3a +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CompleteClass.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %CompleteClass => constants.%CompleteClass.f97 +// CHECK:STDOUT: %ptr => constants.%ptr.5b4 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1fe +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @CompleteClass(constants.%i32) { // CHECK:STDOUT: %T.loc6_21.1 => constants.%i32 // CHECK:STDOUT: } @@ -257,32 +320,44 @@ class Class(U:! type) { // CHECK:STDOUT: --- foo.impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %CompleteClass.type: type = generic_class_type @CompleteClass [concrete] +// CHECK:STDOUT: %CompleteClass.generic: %CompleteClass.type = struct_value () [concrete] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %struct_type.n.4d6: type = struct_type {.n: %i32} [concrete] +// CHECK:STDOUT: %complete_type.a68: = complete_type_witness %struct_type.n.4d6 [concrete] +// CHECK:STDOUT: %CompleteClass.f97: type = class_type @CompleteClass, @CompleteClass(%T) [symbolic] +// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] +// CHECK:STDOUT: %CompleteClass.elem.9ef: type = unbound_element_type %CompleteClass.f97, %i32 [symbolic] +// CHECK:STDOUT: %CompleteClass.F.type.14f: type = fn_type @CompleteClass.F, @CompleteClass(%T) [symbolic] +// CHECK:STDOUT: %CompleteClass.F.874: %CompleteClass.F.type.14f = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.e38: = impl_witness imports.%Destroy.impl_witness_table.cce, @CompleteClass.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op.type: type = fn_type @CompleteClass.as.Destroy.impl.Op, @CompleteClass.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op: %CompleteClass.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.5b4: type = ptr_type %CompleteClass.f97 [symbolic] +// CHECK:STDOUT: %pattern_type.1fe: type = pattern_type %ptr.5b4 [symbolic] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %ImplicitAs.type.595: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.595 = struct_value () [concrete] -// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9a6: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.458: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9a6 = struct_value () [symbolic] -// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %Class.type: type = generic_class_type @Class [concrete] // CHECK:STDOUT: %Class.generic: %Class.type = struct_value () [concrete] // CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %T [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.6d3: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.955: type = ptr_type %Class [symbolic] +// CHECK:STDOUT: %pattern_type.9e0: type = pattern_type %ptr.955 [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.x: type = struct_type {.x: %T} [symbolic] // CHECK:STDOUT: %complete_type.433: = complete_type_witness %struct_type.x [symbolic] -// CHECK:STDOUT: %CompleteClass.type: type = generic_class_type @CompleteClass [concrete] -// CHECK:STDOUT: %CompleteClass.generic: %CompleteClass.type = struct_value () [concrete] -// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] -// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] -// CHECK:STDOUT: %struct_type.n.4d6: type = struct_type {.n: %i32} [concrete] -// CHECK:STDOUT: %complete_type.a68: = complete_type_witness %struct_type.n.4d6 [concrete] -// CHECK:STDOUT: %CompleteClass.f97: type = class_type @CompleteClass, @CompleteClass(%T) [symbolic] -// CHECK:STDOUT: %CompleteClass.elem.9ef: type = unbound_element_type %CompleteClass.f97, %i32 [symbolic] -// CHECK:STDOUT: %CompleteClass.F.type.14f: type = fn_type @CompleteClass.F, @CompleteClass(%T) [symbolic] -// CHECK:STDOUT: %CompleteClass.F.874: %CompleteClass.F.type.14f = struct_value () [symbolic] // CHECK:STDOUT: %CompleteClass.a06: type = class_type @CompleteClass, @CompleteClass(%i32) [concrete] // CHECK:STDOUT: %pattern_type.84b: type = pattern_type %CompleteClass.a06 [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] @@ -309,20 +384,30 @@ class Class(U:! type) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Main.CompleteClass: %CompleteClass.type = import_ref Main//foo, CompleteClass, loaded [concrete = constants.%CompleteClass.generic] // CHECK:STDOUT: %Core.ece: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Main.import_ref.773: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9a6) = import_ref Main//foo, inst140 [indirect], loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.458)] -// CHECK:STDOUT: %ImplicitAs.impl_witness_table.1ad = impl_witness_table (%Main.import_ref.773), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Main.import_ref.5ab3ec.1: type = import_ref Main//foo, loc4_13, loaded [symbolic = @Class.%T.1 (constants.%T)] -// CHECK:STDOUT: %Main.import_ref.5ab3ec.2: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.b22 = import_ref Main//foo, loc6_31, unloaded +// CHECK:STDOUT: %Main.import_ref.5ab3ec.1: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)] // CHECK:STDOUT: %Main.import_ref.eb1: = import_ref Main//foo, loc9_1, loaded [concrete = constants.%complete_type.a68] // CHECK:STDOUT: %Main.import_ref.3c0 = import_ref Main//foo, inst33 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.051 = import_ref Main//foo, loc7_8, unloaded // CHECK:STDOUT: %Main.import_ref.570 = import_ref Main//foo, loc8_17, unloaded +// CHECK:STDOUT: %Main.import_ref.5ab3ec.2: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.722: type = import_ref Main//foo, inst33 [no loc], loaded [symbolic = constants.%CompleteClass.f97] +// CHECK:STDOUT: %Main.import_ref.cb9: type = import_ref Main//foo, inst78 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.894484.1 = import_ref Main//foo, loc6_31, unloaded // CHECK:STDOUT: %Main.import_ref.5ab3ec.3: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.894484.2 = import_ref Main//foo, loc6_31, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.cce = impl_witness_table (%Main.import_ref.894484.2), @CompleteClass.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.5ab3ec.4: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.773: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9a6) = import_ref Main//foo, inst213 [indirect], loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.458)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table.1ad = impl_witness_table (%Main.import_ref.773), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.5ab3ec.5: type = import_ref Main//foo, loc4_13, loaded [symbolic = @Class.%T.1 (constants.%T)] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.595 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } @@ -355,31 +440,50 @@ class Class(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic class @Class(imports.%Main.import_ref.5ab3ec.1: type) { -// CHECK:STDOUT: %T.1: type = bind_symbolic_name T, 0 [symbolic = %T.1 (constants.%T)] +// CHECK:STDOUT: generic impl @CompleteClass.as.Destroy.impl(imports.%Main.import_ref.5ab3ec.2: type) [from "foo.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.cce, @CompleteClass.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.e38)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete: = require_complete_type %T.1 [symbolic = %require_complete (constants.%require_complete.4ae)] -// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T.1) [symbolic = %Class (constants.%Class)] -// CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %T.1 [symbolic = %Class.elem (constants.%Class.elem)] -// CHECK:STDOUT: %struct_type.x.loc6_1.2: type = struct_type {.x: @Class.%T.1 (%T)} [symbolic = %struct_type.x.loc6_1.2 (constants.%struct_type.x)] -// CHECK:STDOUT: %complete_type.loc6_1.2: = complete_type_witness %struct_type.x.loc6_1.2 [symbolic = %complete_type.loc6_1.2 (constants.%complete_type.433)] -// CHECK:STDOUT: -// CHECK:STDOUT: class { -// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4 [symbolic = %T.1 (constants.%T)] -// CHECK:STDOUT: %.loc5: @Class.%Class.elem (%Class.elem) = field_decl x, element0 [concrete] -// CHECK:STDOUT: %struct_type.x.loc6_1.1: type = struct_type {.x: %T} [symbolic = %struct_type.x.loc6_1.2 (constants.%struct_type.x)] -// CHECK:STDOUT: %complete_type.loc6_1.1: = complete_type_witness %struct_type.x.loc6_1.1 [symbolic = %complete_type.loc6_1.2 (constants.%complete_type.433)] -// CHECK:STDOUT: complete_type_witness = %complete_type.loc6_1.1 +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op.type: type = fn_type @CompleteClass.as.Destroy.impl.Op, @CompleteClass.as.Destroy.impl(%T) [symbolic = %CompleteClass.as.Destroy.impl.Op.type (constants.%CompleteClass.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op: @CompleteClass.as.Destroy.impl.%CompleteClass.as.Destroy.impl.Op.type (%CompleteClass.as.Destroy.impl.Op.type) = struct_value () [symbolic = %CompleteClass.as.Destroy.impl.Op (constants.%CompleteClass.as.Destroy.impl.Op)] // CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%Main.import_ref.722 as imports.%Main.import_ref.cb9 { // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = constants.%Class -// CHECK:STDOUT: .T = -// CHECK:STDOUT: .x = %.loc5 +// CHECK:STDOUT: .Op = imports.%Main.import_ref.894484.1 +// CHECK:STDOUT: witness = imports.%Main.import_ref.b22 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic class @CompleteClass(imports.%Main.import_ref.5ab3ec.2: type) [from "foo.carbon"] { +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%T.loc4: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.6d3)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = value_param call_param0 +// CHECK:STDOUT: %.loc4_23.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class)] { +// CHECK:STDOUT: %.loc4_23.3: type = specific_constant constants.%Class, @Class(constants.%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_23.3 [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @CompleteClass(imports.%Main.import_ref.5ab3ec.1: type) [from "foo.carbon"] { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: @@ -398,12 +502,61 @@ class Class(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic class @Class(imports.%Main.import_ref.5ab3ec.5: type) { +// CHECK:STDOUT: %T.1: type = bind_symbolic_name T, 0 [symbolic = %T.1 (constants.%T)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type %T.1 [symbolic = %require_complete (constants.%require_complete.4ae)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T.1) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %T.1 [symbolic = %Class.elem (constants.%Class.elem)] +// CHECK:STDOUT: %struct_type.x.loc6_1.2: type = struct_type {.x: @Class.%T.1 (%T)} [symbolic = %struct_type.x.loc6_1.2 (constants.%struct_type.x)] +// CHECK:STDOUT: %complete_type.loc6_1.2: = complete_type_witness %struct_type.x.loc6_1.2 [symbolic = %complete_type.loc6_1.2 (constants.%complete_type.433)] +// CHECK:STDOUT: +// CHECK:STDOUT: class { +// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4 [symbolic = %T.1 (constants.%T)] +// CHECK:STDOUT: %.loc5: @Class.%Class.elem (%Class.elem) = field_decl x, element0 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%T) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.6d3)] +// CHECK:STDOUT: %struct_type.x.loc6_1.1: type = struct_type {.x: %T} [symbolic = %struct_type.x.loc6_1.2 (constants.%struct_type.x)] +// CHECK:STDOUT: %complete_type.loc6_1.1: = complete_type_witness %struct_type.x.loc6_1.1 [symbolic = %complete_type.loc6_1.2 (constants.%complete_type.433)] +// CHECK:STDOUT: complete_type_witness = %complete_type.loc6_1.1 +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Class +// CHECK:STDOUT: .T = +// CHECK:STDOUT: .x = %.loc5 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @CompleteClass.F(imports.%Main.import_ref.5ab3ec.3: type) [from "foo.carbon"] { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: fn; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @CompleteClass.as.Destroy.impl.Op(imports.%Main.import_ref.5ab3ec.4: type) [from "foo.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %CompleteClass: type = class_type @CompleteClass, @CompleteClass(%T) [symbolic = %CompleteClass (constants.%CompleteClass.f97)] +// CHECK:STDOUT: %ptr: type = ptr_type %CompleteClass [symbolic = %ptr (constants.%ptr.5b4)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1fe)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%T.loc4: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.955)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.9e0)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() -> %return.param: %CompleteClass.a06 [from "foo.carbon"] { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] @@ -421,10 +574,6 @@ class Class(U:! type) { // CHECK:STDOUT: return %.loc9_18 to %return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @Class(constants.%T) { -// CHECK:STDOUT: %T.1 => constants.%T -// CHECK:STDOUT: } -// CHECK:STDOUT: // CHECK:STDOUT: specific @CompleteClass(constants.%T) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: @@ -435,8 +584,36 @@ class Class(U:! type) { // CHECK:STDOUT: %CompleteClass.F => constants.%CompleteClass.F.874 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @CompleteClass.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.e38 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @CompleteClass.F(constants.%T) {} // CHECK:STDOUT: +// CHECK:STDOUT: specific @CompleteClass.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %CompleteClass => constants.%CompleteClass.f97 +// CHECK:STDOUT: %ptr => constants.%ptr.5b4 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1fe +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class(constants.%T) { +// CHECK:STDOUT: %T.1 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.6d3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Class => constants.%Class +// CHECK:STDOUT: %ptr => constants.%ptr.955 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.9e0 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @CompleteClass(constants.%i32) { // CHECK:STDOUT: %T => constants.%i32 // CHECK:STDOUT: @@ -476,6 +653,12 @@ class Class(U:! type) { // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %CompleteClass.F.specific_fn: = specific_function %CompleteClass.F.f7c, @CompleteClass.F(%i32) [concrete] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.eeb: = impl_witness imports.%Destroy.impl_witness_table.f4c, @CompleteClass.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op.type: type = fn_type @CompleteClass.as.Destroy.impl.Op, @CompleteClass.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op: %CompleteClass.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.5b4: type = ptr_type %CompleteClass.f97 [symbolic] +// CHECK:STDOUT: %pattern_type.1fe: type = pattern_type %ptr.5b4 [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.ae9: = impl_witness imports.%Destroy.impl_witness_table.f4c, @CompleteClass.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.9c5: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%CompleteClass.e9e) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.d10: %T.as.Destroy.impl.Op.type.9c5 = struct_value () [concrete] // CHECK:STDOUT: %ptr.a97: type = ptr_type %CompleteClass.e9e [concrete] @@ -502,6 +685,13 @@ class Class(U:! type) { // CHECK:STDOUT: %Main.import_ref.a52: @CompleteClass.%CompleteClass.F.type (%CompleteClass.F.type.14f) = import_ref Main//foo, loc8_17, loaded [symbolic = @CompleteClass.%CompleteClass.F (constants.%CompleteClass.F.874)] // CHECK:STDOUT: %Main.import_ref.5ab3ec.2: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.b22 = import_ref Main//foo, loc6_31, unloaded +// CHECK:STDOUT: %Main.import_ref.5ab3ec.3: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.722: type = import_ref Main//foo, inst33 [no loc], loaded [symbolic = constants.%CompleteClass.f97] +// CHECK:STDOUT: %Main.import_ref.cb9: type = import_ref Main//foo, inst78 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.894 = import_ref Main//foo, loc6_31, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.f4c = impl_witness_table (%Main.import_ref.894), @CompleteClass.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.5ab3ec.4: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)] // CHECK:STDOUT: %.364: @CompleteClass.%CompleteClass.elem (%CompleteClass.elem.28a) = field_decl n, element0 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -536,6 +726,20 @@ class Class(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @CompleteClass.as.Destroy.impl(imports.%Main.import_ref.5ab3ec.3: type) [from "foo.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.f4c, @CompleteClass.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.eeb)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op.type: type = fn_type @CompleteClass.as.Destroy.impl.Op, @CompleteClass.as.Destroy.impl(%T) [symbolic = %CompleteClass.as.Destroy.impl.Op.type (constants.%CompleteClass.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op: @CompleteClass.as.Destroy.impl.%CompleteClass.as.Destroy.impl.Op.type (%CompleteClass.as.Destroy.impl.Op.type) = struct_value () [symbolic = %CompleteClass.as.Destroy.impl.Op (constants.%CompleteClass.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%Main.import_ref.722 as imports.%Main.import_ref.cb9 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.b22 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @CompleteClass(imports.%Main.import_ref.5ab3ec.1: type) [from "foo.carbon"] { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: @@ -601,6 +805,17 @@ class Class(U:! type) { // CHECK:STDOUT: // CHECK:STDOUT: fn @F [from "foo.carbon"]; // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @CompleteClass.as.Destroy.impl.Op(imports.%Main.import_ref.5ab3ec.4: type) [from "foo.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %CompleteClass: type = class_type @CompleteClass, @CompleteClass(%T) [symbolic = %CompleteClass (constants.%CompleteClass.f97)] +// CHECK:STDOUT: %ptr: type = ptr_type %CompleteClass [symbolic = %ptr (constants.%ptr.5b4)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1fe)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @UseField() -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -662,6 +877,23 @@ class Class(U:! type) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @CompleteClass.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.eeb +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CompleteClass.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %CompleteClass => constants.%CompleteClass.f97 +// CHECK:STDOUT: %ptr => constants.%ptr.5b4 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1fe +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CompleteClass.as.Destroy.impl(constants.%i32) { +// CHECK:STDOUT: %T => constants.%i32 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.ae9 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_generic_arg_mismatch.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -696,14 +928,21 @@ class Class(U:! type) { // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.370: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%CompleteClass.a06) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.867: %T.as.Destroy.impl.Op.type.370 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e38: = impl_witness imports.%Destroy.impl_witness_table.cce, @CompleteClass.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op.type: type = fn_type @CompleteClass.as.Destroy.impl.Op, @CompleteClass.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op: %CompleteClass.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.5b4: type = ptr_type %CompleteClass.f97 [symbolic] +// CHECK:STDOUT: %pattern_type.1fe: type = pattern_type %ptr.5b4 [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.bc4: = impl_witness imports.%Destroy.impl_witness_table.cce, @CompleteClass.as.Destroy.impl(%i32) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.b3f: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%CompleteClass.a06) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.40b: %T.as.Destroy.impl.Op.type.b3f = struct_value () [concrete] // CHECK:STDOUT: %ptr.d29: type = ptr_type %CompleteClass.a06 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.0ab: = specific_function %T.as.Destroy.impl.Op.867, @T.as.Destroy.impl.Op(%CompleteClass.a06) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.310: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%CompleteClass.0fe) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.200: %T.as.Destroy.impl.Op.type.310 = struct_value () [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.61b: = specific_function %T.as.Destroy.impl.Op.40b, @T.as.Destroy.impl.Op(%CompleteClass.a06) [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.c81: = impl_witness imports.%Destroy.impl_witness_table.cce, @CompleteClass.as.Destroy.impl(%ptr.9e1) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.6fa: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%CompleteClass.0fe) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.b9f: %T.as.Destroy.impl.Op.type.6fa = struct_value () [concrete] // CHECK:STDOUT: %ptr.c79: type = ptr_type %CompleteClass.0fe [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.a4e: = specific_function %T.as.Destroy.impl.Op.200, @T.as.Destroy.impl.Op(%CompleteClass.0fe) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.b9f: = specific_function %T.as.Destroy.impl.Op.b9f, @T.as.Destroy.impl.Op(%CompleteClass.0fe) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -725,6 +964,13 @@ class Class(U:! type) { // CHECK:STDOUT: %Main.import_ref.5ab3ec.2: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] +// CHECK:STDOUT: %Main.import_ref.b22 = import_ref Main//foo, loc6_31, unloaded +// CHECK:STDOUT: %Main.import_ref.5ab3ec.3: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.722: type = import_ref Main//foo, inst33 [no loc], loaded [symbolic = constants.%CompleteClass.f97] +// CHECK:STDOUT: %Main.import_ref.cb9: type = import_ref Main//foo, inst78 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.894 = import_ref Main//foo, loc6_31, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.cce = impl_witness_table (%Main.import_ref.894), @CompleteClass.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.5ab3ec.4: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -741,6 +987,20 @@ class Class(U:! type) { // CHECK:STDOUT: %Use.decl: %Use.type = fn_decl @Use [concrete = constants.%Use] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @CompleteClass.as.Destroy.impl(imports.%Main.import_ref.5ab3ec.3: type) [from "foo.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.cce, @CompleteClass.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.e38)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op.type: type = fn_type @CompleteClass.as.Destroy.impl.Op, @CompleteClass.as.Destroy.impl(%T) [symbolic = %CompleteClass.as.Destroy.impl.Op.type (constants.%CompleteClass.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op: @CompleteClass.as.Destroy.impl.%CompleteClass.as.Destroy.impl.Op.type (%CompleteClass.as.Destroy.impl.Op.type) = struct_value () [symbolic = %CompleteClass.as.Destroy.impl.Op (constants.%CompleteClass.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%Main.import_ref.722 as imports.%Main.import_ref.cb9 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.b22 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @CompleteClass(imports.%Main.import_ref.5ab3ec.1: type) [from "foo.carbon"] { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: @@ -780,13 +1040,13 @@ class Class(U:! type) { // CHECK:STDOUT: %CompleteClass: type = class_type @CompleteClass, @CompleteClass(constants.%ptr.9e1) [concrete = constants.%CompleteClass.0fe] // CHECK:STDOUT: } // CHECK:STDOUT: %v: ref %CompleteClass.0fe = bind_name v, %v.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc14_34: = bound_method %.loc14_34, constants.%T.as.Destroy.impl.Op.867 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.867, @T.as.Destroy.impl.Op(constants.%CompleteClass.a06) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.0ab] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc14_34: = bound_method %.loc14_34, constants.%T.as.Destroy.impl.Op.40b +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.40b, @T.as.Destroy.impl.Op(constants.%CompleteClass.a06) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.61b] // CHECK:STDOUT: %bound_method.loc14_34: = bound_method %.loc14_34, %T.as.Destroy.impl.Op.specific_fn.1 // CHECK:STDOUT: %addr.loc14_34: %ptr.d29 = addr_of %.loc14_34 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc14_34: init %empty_tuple.type = call %bound_method.loc14_34(%addr.loc14_34) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc14_3: = bound_method %v.var, constants.%T.as.Destroy.impl.Op.200 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.200, @T.as.Destroy.impl.Op(constants.%CompleteClass.0fe) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.a4e] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc14_3: = bound_method %v.var, constants.%T.as.Destroy.impl.Op.b9f +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.b9f, @T.as.Destroy.impl.Op(constants.%CompleteClass.0fe) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.b9f] // CHECK:STDOUT: %bound_method.loc14_3: = bound_method %v.var, %T.as.Destroy.impl.Op.specific_fn.2 // CHECK:STDOUT: %addr.loc14_3: %ptr.c79 = addr_of %v.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc14_3: init %empty_tuple.type = call %bound_method.loc14_3(%addr.loc14_3) @@ -801,6 +1061,17 @@ class Class(U:! type) { // CHECK:STDOUT: // CHECK:STDOUT: fn @F [from "foo.carbon"]; // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @CompleteClass.as.Destroy.impl.Op(imports.%Main.import_ref.5ab3ec.4: type) [from "foo.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %CompleteClass: type = class_type @CompleteClass, @CompleteClass(%T) [symbolic = %CompleteClass (constants.%CompleteClass.f97)] +// CHECK:STDOUT: %ptr: type = ptr_type %CompleteClass [symbolic = %ptr (constants.%ptr.5b4)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1fe)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @CompleteClass(constants.%T) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: @@ -833,17 +1104,59 @@ class Class(U:! type) { // CHECK:STDOUT: %CompleteClass.F => constants.%CompleteClass.F.971 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @CompleteClass.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.e38 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CompleteClass.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %CompleteClass => constants.%CompleteClass.f97 +// CHECK:STDOUT: %ptr => constants.%ptr.5b4 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1fe +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CompleteClass.as.Destroy.impl(constants.%i32) { +// CHECK:STDOUT: %T => constants.%i32 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.bc4 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CompleteClass.as.Destroy.impl(constants.%ptr.9e1) { +// CHECK:STDOUT: %T => constants.%ptr.9e1 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.c81 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_foo.impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete] +// CHECK:STDOUT: %complete_type.a68: = complete_type_witness %struct_type.n [concrete] +// CHECK:STDOUT: %CompleteClass: type = class_type @CompleteClass, @CompleteClass(%T) [symbolic] // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] +// CHECK:STDOUT: %CompleteClass.elem: type = unbound_element_type %CompleteClass, %i32 [symbolic] +// CHECK:STDOUT: %CompleteClass.F.type: type = fn_type @CompleteClass.F, @CompleteClass(%T) [symbolic] +// CHECK:STDOUT: %CompleteClass.F: %CompleteClass.F.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.e38: = impl_witness imports.%Destroy.impl_witness_table.cce, @CompleteClass.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op.type: type = fn_type @CompleteClass.as.Destroy.impl.Op, @CompleteClass.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op: %CompleteClass.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.5b4: type = ptr_type %CompleteClass [symbolic] +// CHECK:STDOUT: %pattern_type.1fe: type = pattern_type %ptr.5b4 [symbolic] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic] // CHECK:STDOUT: %Class.type.cf06d9.1: type = generic_class_type @Class.1 [concrete] // CHECK:STDOUT: %Class.generic.9545f5.1: %Class.type.cf06d9.1 = struct_value () [concrete] -// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %Class.type.cf06d9.2: type = generic_class_type @Class.loc12 [concrete] // CHECK:STDOUT: %Class.generic.9545f5.2: %Class.type.cf06d9.2 = struct_value () [concrete] // CHECK:STDOUT: %Class.fe1b2d.2: type = class_type @Class.loc12, @Class.loc12(%U) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.6d3: = impl_witness @Class.loc12.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%U) [symbolic] +// CHECK:STDOUT: %ptr.955: type = ptr_type %Class.fe1b2d.2 [symbolic] +// CHECK:STDOUT: %pattern_type.9e0: type = pattern_type %ptr.955 [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%U) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -851,10 +1164,26 @@ class Class(U:! type) { // CHECK:STDOUT: %Main.CompleteClass = import_ref Main//foo, CompleteClass, unloaded // CHECK:STDOUT: %Main.F = import_ref Main//foo, F, unloaded // CHECK:STDOUT: %Core.ece: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Main.import_ref.5ab: type = import_ref Main//foo, loc4_13, loaded [symbolic = @Class.1.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.b22 = import_ref Main//foo, loc6_31, unloaded +// CHECK:STDOUT: %Main.import_ref.5ab3ec.1: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.eb1: = import_ref Main//foo, loc9_1, loaded [concrete = constants.%complete_type.a68] +// CHECK:STDOUT: %Main.import_ref.3c0 = import_ref Main//foo, inst33 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.051 = import_ref Main//foo, loc7_8, unloaded +// CHECK:STDOUT: %Main.import_ref.570 = import_ref Main//foo, loc8_17, unloaded +// CHECK:STDOUT: %Main.import_ref.5ab3ec.2: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.722: type = import_ref Main//foo, inst33 [no loc], loaded [symbolic = constants.%CompleteClass] +// CHECK:STDOUT: %Main.import_ref.cb9: type = import_ref Main//foo, inst78 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.894484.1 = import_ref Main//foo, loc6_31, unloaded +// CHECK:STDOUT: %Main.import_ref.5ab3ec.3: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.894484.2 = import_ref Main//foo, loc6_31, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.cce = impl_witness_table (%Main.import_ref.894484.2), @CompleteClass.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.5ab3ec.4: type = import_ref Main//foo, loc6_21, loaded [symbolic = @CompleteClass.%T (constants.%T)] +// CHECK:STDOUT: %Main.import_ref.5ab3ec.5: type = import_ref Main//foo, loc4_13, loaded [symbolic = @Class.1.%T (constants.%T)] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -875,7 +1204,69 @@ class Class(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic class @Class.1(imports.%Main.import_ref.5ab: type) [from "foo.carbon"] { +// CHECK:STDOUT: generic impl @CompleteClass.as.Destroy.impl(imports.%Main.import_ref.5ab3ec.2: type) [from "foo.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.cce, @CompleteClass.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.e38)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op.type: type = fn_type @CompleteClass.as.Destroy.impl.Op, @CompleteClass.as.Destroy.impl(%T) [symbolic = %CompleteClass.as.Destroy.impl.Op.type (constants.%CompleteClass.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %CompleteClass.as.Destroy.impl.Op: @CompleteClass.as.Destroy.impl.%CompleteClass.as.Destroy.impl.Op.type (%CompleteClass.as.Destroy.impl.Op.type) = struct_value () [symbolic = %CompleteClass.as.Destroy.impl.Op (constants.%CompleteClass.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%Main.import_ref.722 as imports.%Main.import_ref.cb9 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = imports.%Main.import_ref.894484.1 +// CHECK:STDOUT: witness = imports.%Main.import_ref.b22 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.loc12.%U.loc12_13.2: type) { +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.loc12.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%U) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.6d3)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%U) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class.fe1b2d.2 as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = value_param call_param0 +// CHECK:STDOUT: %.loc12_23.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class.fe1b2d.2)] { +// CHECK:STDOUT: %.loc12_23.3: type = specific_constant constants.%Class.fe1b2d.2, @Class.loc12(constants.%U) [symbolic = %Class (constants.%Class.fe1b2d.2)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc12_23.3 [symbolic = %Class (constants.%Class.fe1b2d.2)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.loc12.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @CompleteClass(imports.%Main.import_ref.5ab3ec.1: type) [from "foo.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %CompleteClass: type = class_type @CompleteClass, @CompleteClass(%T) [symbolic = %CompleteClass (constants.%CompleteClass)] +// CHECK:STDOUT: %CompleteClass.elem: type = unbound_element_type %CompleteClass, constants.%i32 [symbolic = %CompleteClass.elem (constants.%CompleteClass.elem)] +// CHECK:STDOUT: %CompleteClass.F.type: type = fn_type @CompleteClass.F, @CompleteClass(%T) [symbolic = %CompleteClass.F.type (constants.%CompleteClass.F.type)] +// CHECK:STDOUT: %CompleteClass.F: @CompleteClass.%CompleteClass.F.type (%CompleteClass.F.type) = struct_value () [symbolic = %CompleteClass.F (constants.%CompleteClass.F)] +// CHECK:STDOUT: +// CHECK:STDOUT: class { +// CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.eb1 +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Main.import_ref.3c0 +// CHECK:STDOUT: .n = imports.%Main.import_ref.051 +// CHECK:STDOUT: .F = imports.%Main.import_ref.570 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @Class.1(imports.%Main.import_ref.5ab3ec.5: type) [from "foo.carbon"] { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: // CHECK:STDOUT: class; @@ -889,6 +1280,9 @@ class Class(U:! type) { // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: = name_ref T, [concrete = ] // CHECK:STDOUT: %.loc17: = field_decl x, element0 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%U) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.6d3)] // CHECK:STDOUT: %struct_type.x: type = struct_type {.x: } [concrete = ] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.x [concrete = ] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -900,6 +1294,58 @@ class Class(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @CompleteClass.F(imports.%Main.import_ref.5ab3ec.3: type) [from "foo.carbon"] { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @CompleteClass.as.Destroy.impl.Op(imports.%Main.import_ref.5ab3ec.4: type) [from "foo.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %CompleteClass: type = class_type @CompleteClass, @CompleteClass(%T) [symbolic = %CompleteClass (constants.%CompleteClass)] +// CHECK:STDOUT: %ptr: type = ptr_type %CompleteClass [symbolic = %ptr (constants.%ptr.5b4)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1fe)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.loc12.%U.loc12_13.2: type) { +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Class: type = class_type @Class.loc12, @Class.loc12(%U) [symbolic = %Class (constants.%Class.fe1b2d.2)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.955)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.9e0)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CompleteClass(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %CompleteClass => constants.%CompleteClass +// CHECK:STDOUT: %CompleteClass.elem => constants.%CompleteClass.elem +// CHECK:STDOUT: %CompleteClass.F.type => constants.%CompleteClass.F.type +// CHECK:STDOUT: %CompleteClass.F => constants.%CompleteClass.F +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CompleteClass.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.e38 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CompleteClass.F(constants.%T) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CompleteClass.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %CompleteClass => constants.%CompleteClass +// CHECK:STDOUT: %ptr => constants.%ptr.5b4 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1fe +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Class.1(constants.%T) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: } @@ -908,3 +1354,15 @@ class Class(U:! type) { // CHECK:STDOUT: %U.loc12_13.1 => constants.%U // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%U) { +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.6d3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%U) { +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Class => constants.%Class.fe1b2d.2 +// CHECK:STDOUT: %ptr => constants.%ptr.955 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.9e0 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/generic/init.carbon b/toolchain/check/testdata/class/generic/init.carbon index 0d132008cd64..45ca0ce33c0f 100644 --- a/toolchain/check/testdata/class/generic/init.carbon +++ b/toolchain/check/testdata/class/generic/init.carbon @@ -57,6 +57,15 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: %Class.fe1: type = class_type @Class, @Class(%T) [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %Class.elem.e26: type = unbound_element_type %Class.fe1, %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.95a: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.955: type = ptr_type %Class.fe1 [symbolic] +// CHECK:STDOUT: %pattern_type.9e0: type = pattern_type %ptr.955 [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.facet.fdf: %Destroy.type = facet_value %Class.fe1, (%Destroy.impl_witness.95a) [symbolic] // CHECK:STDOUT: %struct_type.k.b21: type = struct_type {.k: %T} [symbolic] // CHECK:STDOUT: %complete_type.b9e: = complete_type_witness %struct_type.k.b21 [symbolic] // CHECK:STDOUT: %pattern_type.7dcd0a.1: type = pattern_type %T [symbolic] @@ -64,15 +73,9 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: %InitFromStructGeneric: %InitFromStructGeneric.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.4f8: = require_complete_type %Class.fe1 [symbolic] // CHECK:STDOUT: %pattern_type.3c1: type = pattern_type %Class.fe1 [symbolic] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] -// CHECK:STDOUT: %ptr.955: type = ptr_type %Class.fe1 [symbolic] +// CHECK:STDOUT: %.02c: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.fdf [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.specific_fn: = specific_function %Class.as.Destroy.impl.Op, @Class.as.Destroy.impl.Op(%T) [symbolic] // CHECK:STDOUT: %require_complete.2ae: = require_complete_type %ptr.955 [symbolic] -// CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %Class.fe1, @Destroy [symbolic] -// CHECK:STDOUT: %Destroy.facet.2d8: %Destroy.type = facet_value %Class.fe1, (%Destroy.lookup_impl_witness) [symbolic] -// CHECK:STDOUT: %.d76: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.2d8 [symbolic] -// CHECK:STDOUT: %impl.elem0.5b7: %.d76 = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic] -// CHECK:STDOUT: %specific_impl_fn: = specific_impl_function %impl.elem0.5b7, @Destroy.Op(%Destroy.facet.2d8) [symbolic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] @@ -87,6 +90,7 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: %struct_type.k.0bf: type = struct_type {.k: %i32} [concrete] // CHECK:STDOUT: %complete_type.954: = complete_type_witness %struct_type.k.0bf [concrete] // CHECK:STDOUT: %pattern_type.0fa: type = pattern_type %Class.247 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9fc: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.fdc: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Class.247) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.af5: %T.as.Destroy.impl.Op.type.fdc = struct_value () [concrete] // CHECK:STDOUT: %ptr.f7c: type = ptr_type %Class.247 [concrete] @@ -151,6 +155,34 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.95a)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class.fe1 as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = value_param call_param0 +// CHECK:STDOUT: %.loc4_23.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class.fe1)] { +// CHECK:STDOUT: %.loc4_23.3: type = specific_constant constants.%Class.fe1, @Class(constants.%T) [symbolic = %Class (constants.%Class.fe1)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_23.3 [symbolic = %Class (constants.%Class.fe1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Class(%T.loc4_13.2: type) { // CHECK:STDOUT: %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: @@ -164,6 +196,9 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_13.2 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: %.loc5: @Class.%Class.elem (%Class.elem.e26) = field_decl k, element0 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%T) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.95a)] // CHECK:STDOUT: %struct_type.k.loc6_1.1: type = struct_type {.k: %T} [symbolic = %struct_type.k.loc6_1.2 (constants.%struct_type.k.b21)] // CHECK:STDOUT: %complete_type.loc6_1.1: = complete_type_witness %struct_type.k.loc6_1.1 [symbolic = %complete_type.loc6_1.2 (constants.%complete_type.b9e)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc6_1.1 @@ -175,6 +210,17 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.fe1)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.955)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.9e0)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @InitFromStructGeneric(%T.loc8_26.2: type) { // CHECK:STDOUT: %T.loc8_26.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc8_26.1 (constants.%T)] // CHECK:STDOUT: %pattern_type.loc8: type = pattern_type %T.loc8_26.1 [symbolic = %pattern_type.loc8 (constants.%pattern_type.7dcd0a.1)] @@ -186,11 +232,12 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: %pattern_type.loc9: type = pattern_type %Class.loc9_17.2 [symbolic = %pattern_type.loc9 (constants.%pattern_type.3c1)] // CHECK:STDOUT: %struct_type.k: type = struct_type {.k: @InitFromStructGeneric.%T.loc8_26.1 (%T)} [symbolic = %struct_type.k (constants.%struct_type.k.b21)] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class.loc9_17.2, %T.loc8_26.1 [symbolic = %Class.elem (constants.%Class.elem.e26)] -// CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %Class.loc9_17.2, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)] -// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %Class.loc9_17.2, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet.2d8)] -// CHECK:STDOUT: %.loc9_3.3: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [symbolic = %.loc9_3.3 (constants.%.d76)] -// CHECK:STDOUT: %impl.elem0.loc9_3.2: @InitFromStructGeneric.%.loc9_3.3 (%.d76) = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc9_3.2 (constants.%impl.elem0.5b7)] -// CHECK:STDOUT: %specific_impl_fn.loc9_3.2: = specific_impl_function %impl.elem0.loc9_3.2, @Destroy.Op(%Destroy.facet) [symbolic = %specific_impl_fn.loc9_3.2 (constants.%specific_impl_fn)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T.loc8_26.1) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.95a)] +// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %Class.loc9_17.2, (%Destroy.impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet.fdf)] +// CHECK:STDOUT: %.loc9_3.2: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [symbolic = %.loc9_3.2 (constants.%.02c)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T.loc8_26.1) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @InitFromStructGeneric.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.specific_fn: = specific_function %Class.as.Destroy.impl.Op, @Class.as.Destroy.impl.Op(%T.loc8_26.1) [symbolic = %Class.as.Destroy.impl.Op.specific_fn (constants.%Class.as.Destroy.impl.Op.specific_fn)] // CHECK:STDOUT: %ptr: type = ptr_type %Class.loc9_17.2 [symbolic = %ptr (constants.%ptr.955)] // CHECK:STDOUT: %require_complete.loc9_3: = require_complete_type %ptr [symbolic = %require_complete.loc9_3 (constants.%require_complete.2ae)] // CHECK:STDOUT: @@ -218,12 +265,12 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: %k.ref: @InitFromStructGeneric.%Class.elem (%Class.elem.e26) = name_ref k, @Class.%.loc5 [concrete = @Class.%.loc5] // CHECK:STDOUT: %.loc10_11.1: ref @InitFromStructGeneric.%T.loc8_26.1 (%T) = class_element_access %v.ref, element0 // CHECK:STDOUT: %.loc10_11.2: @InitFromStructGeneric.%T.loc8_26.1 (%T) = bind_value %.loc10_11.1 -// CHECK:STDOUT: %impl.elem0.loc9_3.1: @InitFromStructGeneric.%.loc9_3.3 (%.d76) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc9_3.2 (constants.%impl.elem0.5b7)] -// CHECK:STDOUT: %bound_method.loc9_3.1: = bound_method %v.var, %impl.elem0.loc9_3.1 -// CHECK:STDOUT: %specific_impl_fn.loc9_3.1: = specific_impl_function %impl.elem0.loc9_3.1, @Destroy.Op(constants.%Destroy.facet.2d8) [symbolic = %specific_impl_fn.loc9_3.2 (constants.%specific_impl_fn)] -// CHECK:STDOUT: %bound_method.loc9_3.2: = bound_method %v.var, %specific_impl_fn.loc9_3.1 +// CHECK:STDOUT: %impl.elem0: @InitFromStructGeneric.%.loc9_3.2 (%.02c) = impl_witness_access constants.%Destroy.impl_witness.95a, element0 [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: %bound_method.loc9_3.1: = bound_method %v.var, %impl.elem0 +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Class.as.Destroy.impl.Op(constants.%T) [symbolic = %Class.as.Destroy.impl.Op.specific_fn (constants.%Class.as.Destroy.impl.Op.specific_fn)] +// CHECK:STDOUT: %bound_method.loc9_3.2: = bound_method %v.var, %specific_fn // CHECK:STDOUT: %addr: @InitFromStructGeneric.%ptr (%ptr.955) = addr_of %v.var -// CHECK:STDOUT: %.loc9_3.2: init %empty_tuple.type = call %bound_method.loc9_3.2(%addr) +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc9_3.2(%addr) // CHECK:STDOUT: return %.loc10_11.2 // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -272,6 +319,22 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: %complete_type.loc6_1.2 => constants.%complete_type.b9e // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.95a +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type => constants.%Class.as.Destroy.impl.Op.type +// CHECK:STDOUT: %Class.as.Destroy.impl.Op => constants.%Class.as.Destroy.impl.Op +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Class => constants.%Class.fe1 +// CHECK:STDOUT: %ptr => constants.%ptr.955 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.9e0 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @InitFromStructGeneric(constants.%T) { // CHECK:STDOUT: %T.loc8_26.1 => constants.%T // CHECK:STDOUT: %pattern_type.loc8 => constants.%pattern_type.7dcd0a.1 @@ -288,6 +351,11 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: %complete_type.loc6_1.2 => constants.%complete_type.954 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%i32) { +// CHECK:STDOUT: %T => constants.%i32 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.9fc +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- adapt.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -297,6 +365,13 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: %Adapt.generic: %Adapt.type = struct_value () [concrete] // CHECK:STDOUT: %Adapt.2e4: type = class_type @Adapt, @Adapt(%T) [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Adapt.%Destroy.impl_witness_table, @Adapt.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.42a: type = ptr_type %Adapt.2e4 [symbolic] +// CHECK:STDOUT: %pattern_type.97d: type = pattern_type %ptr.42a [symbolic] +// CHECK:STDOUT: %Adapt.as.Destroy.impl.Op.type: type = fn_type @Adapt.as.Destroy.impl.Op, @Adapt.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Adapt.as.Destroy.impl.Op: %Adapt.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %complete_type.f87: = complete_type_witness %T [symbolic] // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] // CHECK:STDOUT: %InitFromAdaptedGeneric.type: type = fn_type @InitFromAdaptedGeneric [concrete] @@ -317,10 +392,12 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -371,6 +448,34 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Adapt.as.Destroy.impl(@Adapt.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Adapt.%Destroy.impl_witness_table, @Adapt.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Adapt.as.Destroy.impl.Op.type: type = fn_type @Adapt.as.Destroy.impl.Op, @Adapt.as.Destroy.impl(%T) [symbolic = %Adapt.as.Destroy.impl.Op.type (constants.%Adapt.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Adapt.as.Destroy.impl.Op: @Adapt.as.Destroy.impl.%Adapt.as.Destroy.impl.Op.type (%Adapt.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Adapt.as.Destroy.impl.Op (constants.%Adapt.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Adapt.2e4 as constants.%Destroy.type { +// CHECK:STDOUT: %Adapt.as.Destroy.impl.Op.decl: @Adapt.as.Destroy.impl.%Adapt.as.Destroy.impl.Op.type (%Adapt.as.Destroy.impl.Op.type) = fn_decl @Adapt.as.Destroy.impl.Op [symbolic = @Adapt.as.Destroy.impl.%Adapt.as.Destroy.impl.Op (constants.%Adapt.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Adapt.as.Destroy.impl.Op.%pattern_type (%pattern_type.97d) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Adapt.as.Destroy.impl.Op.%pattern_type (%pattern_type.97d) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Adapt.as.Destroy.impl.Op.%ptr (%ptr.42a) = value_param call_param0 +// CHECK:STDOUT: %.loc4_23.2: type = splice_block %Self.ref [symbolic = %Adapt (constants.%Adapt.2e4)] { +// CHECK:STDOUT: %.loc4_23.3: type = specific_constant constants.%Adapt.2e4, @Adapt(constants.%T) [symbolic = %Adapt (constants.%Adapt.2e4)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_23.3 [symbolic = %Adapt (constants.%Adapt.2e4)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Adapt.as.Destroy.impl.Op.%ptr (%ptr.42a) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Adapt.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Adapt.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Adapt(%T.loc4_13.2: type) { // CHECK:STDOUT: %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: @@ -381,6 +486,9 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_13.2 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: adapt_decl %T.ref [concrete] +// CHECK:STDOUT: impl_decl @Adapt.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Adapt.as.Destroy.impl.%Adapt.as.Destroy.impl.Op.decl), @Adapt.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Adapt.as.Destroy.impl(constants.%T) [symbolic = @Adapt.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %complete_type.loc6_1.1: = complete_type_witness constants.%T [symbolic = %complete_type.loc6_1.2 (constants.%complete_type.f87)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc6_1.1 // CHECK:STDOUT: @@ -390,6 +498,17 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Adapt.as.Destroy.impl.Op(@Adapt.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Adapt: type = class_type @Adapt, @Adapt(%T) [symbolic = %Adapt (constants.%Adapt.2e4)] +// CHECK:STDOUT: %ptr: type = ptr_type %Adapt [symbolic = %ptr (constants.%ptr.42a)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.97d)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Adapt.as.Destroy.impl.Op.%ptr (%ptr.42a)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @InitFromAdaptedGeneric(%T.loc8_27.2: type) { // CHECK:STDOUT: %T.loc8_27.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc8_27.1 (constants.%T)] // CHECK:STDOUT: %pattern_type: type = pattern_type %T.loc8_27.1 [symbolic = %pattern_type (constants.%pattern_type.7dc)] @@ -438,6 +557,18 @@ fn InitFromAdaptedSpecific(x: i32) -> i32 { // CHECK:STDOUT: %complete_type.loc6_1.2 => constants.%complete_type.f87 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Adapt.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Adapt.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Adapt => constants.%Adapt.2e4 +// CHECK:STDOUT: %ptr => constants.%ptr.42a +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.97d +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @InitFromAdaptedGeneric(constants.%T) { // CHECK:STDOUT: %T.loc8_27.1 => constants.%T // CHECK:STDOUT: %pattern_type => constants.%pattern_type.7dc diff --git a/toolchain/check/testdata/class/generic/member_access.carbon b/toolchain/check/testdata/class/generic/member_access.carbon index fdb1de9e9e1d..f6ae8e79704a 100644 --- a/toolchain/check/testdata/class/generic/member_access.carbon +++ b/toolchain/check/testdata/class/generic/member_access.carbon @@ -67,6 +67,10 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: %pattern_type.afe: type = pattern_type %ptr.79f [symbolic] // CHECK:STDOUT: %Class.GetAddr.type.402: type = fn_type @Class.GetAddr, @Class(%T) [symbolic] // CHECK:STDOUT: %Class.GetAddr.102: %Class.GetAddr.type.402 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.x.2ac: type = struct_type {.x: %T} [symbolic] // CHECK:STDOUT: %complete_type.433: = complete_type_witness %struct_type.x.2ac [symbolic] // CHECK:STDOUT: %require_complete.4f8: = require_complete_type %Class.fe1 [symbolic] @@ -106,10 +110,12 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -187,6 +193,34 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%T.loc2_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class.fe1 as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc2_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = value_param call_param0 +// CHECK:STDOUT: %.loc2_23.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class.fe1)] { +// CHECK:STDOUT: %.loc2_23.3: type = specific_constant constants.%Class.fe1, @Class(constants.%T) [symbolic = %Class (constants.%Class.fe1)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc2_23.3 [symbolic = %Class (constants.%Class.fe1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Class(%T.loc2_13.2: type) { // CHECK:STDOUT: %T.loc2_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc2_13.1 (constants.%T)] // CHECK:STDOUT: @@ -239,6 +273,9 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: %return.param: ref @Class.GetAddr.%ptr.loc7_38.1 (%ptr.79f) = out_param call_param1 // CHECK:STDOUT: %return: ref @Class.GetAddr.%ptr.loc7_38.1 (%ptr.79f) = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%T) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %struct_type.x.loc8_1.1: type = struct_type {.x: %T} [symbolic = %struct_type.x.loc8_1.2 (constants.%struct_type.x.2ac)] // CHECK:STDOUT: %complete_type.loc8_1.1: = complete_type_witness %struct_type.x.loc8_1.1 [symbolic = %complete_type.loc8_1.2 (constants.%complete_type.433)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc8_1.1 @@ -298,6 +335,17 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%T.loc2_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.fe1)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.955)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.9e0)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @DirectFieldAccess(%x.param: %Class.247) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %x.ref.loc11_10: %Class.247 = name_ref x, %x @@ -370,6 +418,18 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: %pattern_type.loc7_34 => constants.%pattern_type.afe // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Class => constants.%Class.fe1 +// CHECK:STDOUT: %ptr => constants.%ptr.955 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.9e0 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Class(constants.%i32) { // CHECK:STDOUT: %T.loc2_13.1 => constants.%i32 // CHECK:STDOUT: @@ -424,6 +484,15 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: %pattern_type.3c1: type = pattern_type %Class [symbolic] // CHECK:STDOUT: %Class.Make.type: type = fn_type @Class.Make, @Class(%T) [symbolic] // CHECK:STDOUT: %Class.Make: %Class.Make.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.95a: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.955: type = ptr_type %Class [symbolic] +// CHECK:STDOUT: %pattern_type.9e0: type = pattern_type %ptr.955 [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %Class, (%Destroy.impl_witness.95a) [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %require_complete.4f8: = require_complete_type %Class [symbolic] @@ -431,15 +500,9 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: %StaticMemberFunctionCall.type: type = fn_type @StaticMemberFunctionCall [concrete] // CHECK:STDOUT: %StaticMemberFunctionCall: %StaticMemberFunctionCall.type = struct_value () [concrete] // CHECK:STDOUT: %Class.Make.specific_fn: = specific_function %Class.Make, @Class.Make(%T) [symbolic] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] -// CHECK:STDOUT: %ptr.955: type = ptr_type %Class [symbolic] +// CHECK:STDOUT: %.02c: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.specific_fn: = specific_function %Class.as.Destroy.impl.Op, @Class.as.Destroy.impl.Op(%T) [symbolic] // CHECK:STDOUT: %require_complete.2ae: = require_complete_type %ptr.955 [symbolic] -// CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %Class, @Destroy [symbolic] -// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %Class, (%Destroy.lookup_impl_witness) [symbolic] -// CHECK:STDOUT: %.d76: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet [symbolic] -// CHECK:STDOUT: %impl.elem0: %.d76 = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic] -// CHECK:STDOUT: %specific_impl_fn: = specific_impl_function %impl.elem0, @Destroy.Op(%Destroy.facet) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -477,6 +540,34 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.95a)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = value_param call_param0 +// CHECK:STDOUT: %.loc4_23.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class)] { +// CHECK:STDOUT: %.loc4_23.3: type = specific_constant constants.%Class, @Class(constants.%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_23.3 [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Class(%T.loc4_13.2: type) { // CHECK:STDOUT: %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: @@ -495,6 +586,9 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: %return.param: ref @Class.Make.%Class.loc5_23.1 (%Class) = out_param call_param0 // CHECK:STDOUT: %return: ref @Class.Make.%Class.loc5_23.1 (%Class) = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%T) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.95a)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -525,6 +619,17 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.955)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.9e0)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @StaticMemberFunctionCall(%T.loc8_29.2: type) { // CHECK:STDOUT: %T.loc8_29.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc8_29.1 (constants.%T)] // CHECK:STDOUT: %Class.loc8_49.1: type = class_type @Class, @Class(%T.loc8_29.1) [symbolic = %Class.loc8_49.1 (constants.%Class)] @@ -535,11 +640,12 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: %Class.Make.type: type = fn_type @Class.Make, @Class(%T.loc8_29.1) [symbolic = %Class.Make.type (constants.%Class.Make.type)] // CHECK:STDOUT: %Class.Make: @StaticMemberFunctionCall.%Class.Make.type (%Class.Make.type) = struct_value () [symbolic = %Class.Make (constants.%Class.Make)] // CHECK:STDOUT: %Class.Make.specific_fn.loc9_18.2: = specific_function %Class.Make, @Class.Make(%T.loc8_29.1) [symbolic = %Class.Make.specific_fn.loc9_18.2 (constants.%Class.Make.specific_fn)] -// CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %Class.loc8_49.1, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)] -// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %Class.loc8_49.1, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet)] -// CHECK:STDOUT: %.loc8_39.3: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [symbolic = %.loc8_39.3 (constants.%.d76)] -// CHECK:STDOUT: %impl.elem0.loc8_39.2: @StaticMemberFunctionCall.%.loc8_39.3 (%.d76) = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc8_39.2 (constants.%impl.elem0)] -// CHECK:STDOUT: %specific_impl_fn.loc8_39.2: = specific_impl_function %impl.elem0.loc8_39.2, @Destroy.Op(%Destroy.facet) [symbolic = %specific_impl_fn.loc8_39.2 (constants.%specific_impl_fn)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T.loc8_29.1) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.95a)] +// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %Class.loc8_49.1, (%Destroy.impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet)] +// CHECK:STDOUT: %.loc8_39.2: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [symbolic = %.loc8_39.2 (constants.%.02c)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T.loc8_29.1) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @StaticMemberFunctionCall.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.specific_fn: = specific_function %Class.as.Destroy.impl.Op, @Class.as.Destroy.impl.Op(%T.loc8_29.1) [symbolic = %Class.as.Destroy.impl.Op.specific_fn (constants.%Class.as.Destroy.impl.Op.specific_fn)] // CHECK:STDOUT: %ptr: type = ptr_type %Class.loc8_49.1 [symbolic = %ptr (constants.%ptr.955)] // CHECK:STDOUT: %require_complete.loc8: = require_complete_type %ptr [symbolic = %require_complete.loc8 (constants.%require_complete.2ae)] // CHECK:STDOUT: @@ -553,12 +659,12 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: %Class.Make.specific_fn.loc9_18.1: = specific_function %Make.ref, @Class.Make(constants.%T) [symbolic = %Class.Make.specific_fn.loc9_18.2 (constants.%Class.Make.specific_fn)] // CHECK:STDOUT: %.loc8_39.1: ref @StaticMemberFunctionCall.%Class.loc8_49.1 (%Class) = splice_block %return {} // CHECK:STDOUT: %Class.Make.call: init @StaticMemberFunctionCall.%Class.loc8_49.1 (%Class) = call %Class.Make.specific_fn.loc9_18.1() to %.loc8_39.1 -// CHECK:STDOUT: %impl.elem0.loc8_39.1: @StaticMemberFunctionCall.%.loc8_39.3 (%.d76) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc8_39.2 (constants.%impl.elem0)] -// CHECK:STDOUT: %bound_method.loc8_39.1: = bound_method %.loc8_39.1, %impl.elem0.loc8_39.1 -// CHECK:STDOUT: %specific_impl_fn.loc8_39.1: = specific_impl_function %impl.elem0.loc8_39.1, @Destroy.Op(constants.%Destroy.facet) [symbolic = %specific_impl_fn.loc8_39.2 (constants.%specific_impl_fn)] -// CHECK:STDOUT: %bound_method.loc8_39.2: = bound_method %.loc8_39.1, %specific_impl_fn.loc8_39.1 +// CHECK:STDOUT: %impl.elem0: @StaticMemberFunctionCall.%.loc8_39.2 (%.02c) = impl_witness_access constants.%Destroy.impl_witness.95a, element0 [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: %bound_method.loc8_39.1: = bound_method %.loc8_39.1, %impl.elem0 +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Class.as.Destroy.impl.Op(constants.%T) [symbolic = %Class.as.Destroy.impl.Op.specific_fn (constants.%Class.as.Destroy.impl.Op.specific_fn)] +// CHECK:STDOUT: %bound_method.loc8_39.2: = bound_method %.loc8_39.1, %specific_fn // CHECK:STDOUT: %addr: @StaticMemberFunctionCall.%ptr (%ptr.955) = addr_of %.loc8_39.1 -// CHECK:STDOUT: %.loc8_39.2: init %empty_tuple.type = call %bound_method.loc8_39.2(%addr) +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc8_39.2(%addr) // CHECK:STDOUT: return %Class.Make.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -581,6 +687,22 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) { // CHECK:STDOUT: %Class.val => constants.%Class.val // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.95a +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type => constants.%Class.as.Destroy.impl.Op.type +// CHECK:STDOUT: %Class.as.Destroy.impl.Op => constants.%Class.as.Destroy.impl.Op +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Class => constants.%Class +// CHECK:STDOUT: %ptr => constants.%ptr.955 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.9e0 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @StaticMemberFunctionCall(constants.%T) { // CHECK:STDOUT: %T.loc8_29.1 => constants.%T // CHECK:STDOUT: %Class.loc8_49.1 => constants.%Class diff --git a/toolchain/check/testdata/class/generic/member_inline.carbon b/toolchain/check/testdata/class/generic/member_inline.carbon index bddc5b218cae..a1fae0d5f09b 100644 --- a/toolchain/check/testdata/class/generic/member_inline.carbon +++ b/toolchain/check/testdata/class/generic/member_inline.carbon @@ -59,6 +59,13 @@ class C(T:! type) { // CHECK:STDOUT: %Class.G: %Class.G.type = struct_value () [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.955: type = ptr_type %Class [symbolic] +// CHECK:STDOUT: %pattern_type.9e0: type = pattern_type %ptr.955 [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %T} [symbolic] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n [symbolic] // CHECK:STDOUT: %require_complete.4f8: = require_complete_type %Class [symbolic] @@ -66,9 +73,11 @@ class C(T:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -84,6 +93,34 @@ class C(T:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = value_param call_param0 +// CHECK:STDOUT: %.loc4_23.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class)] { +// CHECK:STDOUT: %.loc4_23.3: type = specific_constant constants.%Class, @Class(constants.%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_23.3 [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Class(%T.loc4_13.2: type) { // CHECK:STDOUT: %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: @@ -130,6 +167,9 @@ class C(T:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_13.2 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: %.loc13: @Class.%Class.elem (%Class.elem) = field_decl n, element0 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%T) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %struct_type.n.loc14_1.1: type = struct_type {.n: %T} [symbolic = %struct_type.n.loc14_1.2 (constants.%struct_type.n)] // CHECK:STDOUT: %complete_type.loc14_1.1: = complete_type_witness %struct_type.n.loc14_1.1 [symbolic = %complete_type.loc14_1.2 (constants.%complete_type)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc14_1.1 @@ -178,6 +218,17 @@ class C(T:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.955)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.9e0)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Class(constants.%T) { // CHECK:STDOUT: %T.loc4_13.1 => constants.%T // CHECK:STDOUT: @@ -205,11 +256,23 @@ class C(T:! type) { // CHECK:STDOUT: %pattern_type.loc9_22 => constants.%pattern_type.7dc // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Class => constants.%Class +// CHECK:STDOUT: %ptr => constants.%ptr.955 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.9e0 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_member_inline.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] -// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete] +// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic] @@ -217,15 +280,24 @@ class C(T:! type) { // CHECK:STDOUT: %C.F: %C.F.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %empty_struct_type [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.data: type = struct_type {.data: %empty_struct_type} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.data [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -235,12 +307,40 @@ class C(T:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: %C.type = class_decl @C [concrete = constants.%C.generic] { -// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.loc4_9.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc4_19.2: type = splice_block %Self.ref [symbolic = %C (constants.%C)] { +// CHECK:STDOUT: %.loc4_19.3: type = specific_constant constants.%C, @C(constants.%T) [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_19.3 [symbolic = %C (constants.%C)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%T.loc4_9.2: type) { // CHECK:STDOUT: %T.loc4_9.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: @@ -255,6 +355,9 @@ class C(T:! type) { // CHECK:STDOUT: %.loc12_14.1: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc12_14.2: type = converted %.loc12_14.1, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %.loc12_11: @C.%C.elem (%C.elem) = field_decl data, element0 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %struct_type.data: type = struct_type {.data: %empty_struct_type} [concrete = constants.%struct_type.data] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.data [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -279,6 +382,17 @@ class C(T:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%T) { // CHECK:STDOUT: %T.loc4_9.1 => constants.%T // CHECK:STDOUT: @@ -291,3 +405,15 @@ class C(T:! type) { // CHECK:STDOUT: // CHECK:STDOUT: specific @C.F(constants.%T) {} // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/generic/member_lookup.carbon b/toolchain/check/testdata/class/generic/member_lookup.carbon index 69294a01d75d..86ff86553913 100644 --- a/toolchain/check/testdata/class/generic/member_lookup.carbon +++ b/toolchain/check/testdata/class/generic/member_lookup.carbon @@ -84,6 +84,13 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: %Base.370: type = class_type @Base, @Base(%T) [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %Base.elem.9af: type = unbound_element_type %Base.370, %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9f8: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.b7c: type = ptr_type %Base.370 [symbolic] +// CHECK:STDOUT: %pattern_type.8d4: type = pattern_type %ptr.b7c [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.b.f69: type = struct_type {.b: %T} [symbolic] // CHECK:STDOUT: %complete_type.eaf: = complete_type_witness %struct_type.b.f69 [symbolic] // CHECK:STDOUT: %Derived.type: type = generic_class_type @Derived [concrete] @@ -92,6 +99,11 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: %require_complete.97d: = require_complete_type %Base.370 [symbolic] // CHECK:STDOUT: %Derived.elem.8b3: type = unbound_element_type %Derived.85c, %Base.370 [symbolic] // CHECK:STDOUT: %Derived.elem.6d2: type = unbound_element_type %Derived.85c, %T [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.fa7: = impl_witness @Derived.%Destroy.impl_witness_table, @Derived.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.178: type = ptr_type %Derived.85c [symbolic] +// CHECK:STDOUT: %pattern_type.520: type = pattern_type %ptr.178 [symbolic] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op, @Derived.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.base.d.37c: type = struct_type {.base: %Base.370, .d: %T} [symbolic] // CHECK:STDOUT: %complete_type.8ad: = complete_type_witness %struct_type.base.d.37c [symbolic] // CHECK:STDOUT: %pattern_type.423: type = pattern_type %Derived.85c [symbolic] @@ -124,10 +136,12 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -210,6 +224,62 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Base.as.Destroy.impl(@Base.%T.loc4_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic = %Base.as.Destroy.impl.Op.type (constants.%Base.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Base.370 as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = fn_decl @Base.as.Destroy.impl.Op [symbolic = @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_27.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = value_param call_param0 +// CHECK:STDOUT: %.loc4_27.2: type = splice_block %Self.ref [symbolic = %Base (constants.%Base.370)] { +// CHECK:STDOUT: %.loc4_27.3: type = specific_constant constants.%Base.370, @Base(constants.%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_27.3 [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Derived.as.Destroy.impl(@Derived.%T.loc8_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Derived.%Destroy.impl_witness_table, @Derived.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.fa7)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op, @Derived.as.Destroy.impl(%T) [symbolic = %Derived.as.Destroy.impl.Op.type (constants.%Derived.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: @Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.type (%Derived.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Derived.as.Destroy.impl.Op (constants.%Derived.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Derived.85c as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: @Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.type (%Derived.as.Destroy.impl.Op.type) = fn_decl @Derived.as.Destroy.impl.Op [symbolic = @Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op (constants.%Derived.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Derived.as.Destroy.impl.Op.%pattern_type (%pattern_type.520) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Derived.as.Destroy.impl.Op.%pattern_type (%pattern_type.520) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8_25.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Derived.as.Destroy.impl.Op.%ptr (%ptr.178) = value_param call_param0 +// CHECK:STDOUT: %.loc8_25.2: type = splice_block %Self.ref [symbolic = %Derived (constants.%Derived.85c)] { +// CHECK:STDOUT: %.loc8_25.3: type = specific_constant constants.%Derived.85c, @Derived(constants.%T) [symbolic = %Derived (constants.%Derived.85c)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc8_25.3 [symbolic = %Derived (constants.%Derived.85c)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Derived.as.Destroy.impl.Op.%ptr (%ptr.178) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Base(%T.loc4_17.2: type) { // CHECK:STDOUT: %T.loc4_17.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_17.1 (constants.%T)] // CHECK:STDOUT: @@ -223,6 +293,9 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_17.2 [symbolic = %T.loc4_17.1 (constants.%T)] // CHECK:STDOUT: %.loc5: @Base.%Base.elem (%Base.elem.9af) = field_decl b, element0 [concrete] +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Base.as.Destroy.impl(constants.%T) [symbolic = @Base.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] // CHECK:STDOUT: %struct_type.b.loc6_1.1: type = struct_type {.b: %T} [symbolic = %struct_type.b.loc6_1.2 (constants.%struct_type.b.f69)] // CHECK:STDOUT: %complete_type.loc6_1.1: = complete_type_witness %struct_type.b.loc6_1.1 [symbolic = %complete_type.loc6_1.2 (constants.%complete_type.eaf)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc6_1.1 @@ -254,6 +327,9 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: %.loc9: @Derived.%Derived.elem.loc9 (%Derived.elem.8b3) = base_decl %Base.loc9_22.1, element0 [concrete] // CHECK:STDOUT: %T.ref.loc10: type = name_ref T, %T.loc8_15.2 [symbolic = %T.loc8_15.1 (constants.%T)] // CHECK:STDOUT: %.loc10: @Derived.%Derived.elem.loc10 (%Derived.elem.6d2) = field_decl d, element1 [concrete] +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Derived.as.Destroy.impl(constants.%T) [symbolic = @Derived.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.fa7)] // CHECK:STDOUT: %struct_type.base.d.loc11_1.1: type = struct_type {.base: %Base.370, .d: %T} [symbolic = %struct_type.base.d.loc11_1.2 (constants.%struct_type.base.d.37c)] // CHECK:STDOUT: %complete_type.loc11_1.1: = complete_type_witness %struct_type.base.d.loc11_1.1 [symbolic = %complete_type.loc11_1.2 (constants.%complete_type.8ad)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc11_1.1 @@ -269,6 +345,28 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Base.as.Destroy.impl.Op(@Base.%T.loc4_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Base: type = class_type @Base, @Base(%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %ptr: type = ptr_type %Base [symbolic = %ptr (constants.%ptr.b7c)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.8d4)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Derived.as.Destroy.impl.Op(@Derived.%T.loc8_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Derived: type = class_type @Derived, @Derived(%T) [symbolic = %Derived (constants.%Derived.85c)] +// CHECK:STDOUT: %ptr: type = ptr_type %Derived [symbolic = %ptr (constants.%ptr.178)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.520)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Derived.as.Destroy.impl.Op.%ptr (%ptr.178)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @AccessDerived(%T.loc13_18.2: type) { // CHECK:STDOUT: %T.loc13_18.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc13_18.1 (constants.%T)] // CHECK:STDOUT: %Derived.loc13_40.1: type = class_type @Derived, @Derived(%T.loc13_18.1) [symbolic = %Derived.loc13_40.1 (constants.%Derived.85c)] @@ -337,6 +435,18 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: %complete_type.loc6_1.2 => constants.%complete_type.eaf // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.9f8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Base => constants.%Base.370 +// CHECK:STDOUT: %ptr => constants.%ptr.b7c +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.8d4 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Derived(constants.%T) { // CHECK:STDOUT: %T.loc8_15.1 => constants.%T // CHECK:STDOUT: @@ -351,6 +461,18 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: %complete_type.loc11_1.2 => constants.%complete_type.8ad // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Derived.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.fa7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Derived.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Derived => constants.%Derived.85c +// CHECK:STDOUT: %ptr => constants.%ptr.178 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.520 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @AccessDerived(constants.%T) { // CHECK:STDOUT: %T.loc13_18.1 => constants.%T // CHECK:STDOUT: %Derived.loc13_40.1 => constants.%Derived.85c @@ -400,6 +522,13 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: %Base.370: type = class_type @Base, @Base(%T) [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %Base.elem.9af: type = unbound_element_type %Base.370, %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9f8: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.b7c: type = ptr_type %Base.370 [symbolic] +// CHECK:STDOUT: %pattern_type.8d4: type = pattern_type %ptr.b7c [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.b.f69: type = struct_type {.b: %T} [symbolic] // CHECK:STDOUT: %complete_type.eaf: = complete_type_witness %struct_type.b.f69 [symbolic] // CHECK:STDOUT: %Derived.type: type = generic_class_type @Derived [concrete] @@ -408,6 +537,11 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: %require_complete.97d: = require_complete_type %Base.370 [symbolic] // CHECK:STDOUT: %Derived.elem.8b3: type = unbound_element_type %Derived.85c, %Base.370 [symbolic] // CHECK:STDOUT: %Derived.elem.6d2: type = unbound_element_type %Derived.85c, %T [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.fa7: = impl_witness @Derived.%Destroy.impl_witness_table, @Derived.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.178: type = ptr_type %Derived.85c [symbolic] +// CHECK:STDOUT: %pattern_type.520: type = pattern_type %ptr.178 [symbolic] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op, @Derived.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.base.d.37c: type = struct_type {.base: %Base.370, .d: %T} [symbolic] // CHECK:STDOUT: %complete_type.8ad: = complete_type_witness %struct_type.base.d.37c [symbolic] // CHECK:STDOUT: %pattern_type.9f7: type = pattern_type %Base.370 [symbolic] @@ -441,10 +575,12 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -527,6 +663,62 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Base.as.Destroy.impl(@Base.%T.loc4_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic = %Base.as.Destroy.impl.Op.type (constants.%Base.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Base.370 as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = fn_decl @Base.as.Destroy.impl.Op [symbolic = @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_27.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = value_param call_param0 +// CHECK:STDOUT: %.loc4_27.2: type = splice_block %Self.ref [symbolic = %Base (constants.%Base.370)] { +// CHECK:STDOUT: %.loc4_27.3: type = specific_constant constants.%Base.370, @Base(constants.%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_27.3 [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Derived.as.Destroy.impl(@Derived.%T.loc8_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Derived.%Destroy.impl_witness_table, @Derived.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.fa7)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op, @Derived.as.Destroy.impl(%T) [symbolic = %Derived.as.Destroy.impl.Op.type (constants.%Derived.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: @Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.type (%Derived.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Derived.as.Destroy.impl.Op (constants.%Derived.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Derived.85c as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: @Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.type (%Derived.as.Destroy.impl.Op.type) = fn_decl @Derived.as.Destroy.impl.Op [symbolic = @Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op (constants.%Derived.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Derived.as.Destroy.impl.Op.%pattern_type (%pattern_type.520) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Derived.as.Destroy.impl.Op.%pattern_type (%pattern_type.520) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8_25.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Derived.as.Destroy.impl.Op.%ptr (%ptr.178) = value_param call_param0 +// CHECK:STDOUT: %.loc8_25.2: type = splice_block %Self.ref [symbolic = %Derived (constants.%Derived.85c)] { +// CHECK:STDOUT: %.loc8_25.3: type = specific_constant constants.%Derived.85c, @Derived(constants.%T) [symbolic = %Derived (constants.%Derived.85c)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc8_25.3 [symbolic = %Derived (constants.%Derived.85c)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Derived.as.Destroy.impl.Op.%ptr (%ptr.178) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Base(%T.loc4_17.2: type) { // CHECK:STDOUT: %T.loc4_17.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_17.1 (constants.%T)] // CHECK:STDOUT: @@ -540,6 +732,9 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_17.2 [symbolic = %T.loc4_17.1 (constants.%T)] // CHECK:STDOUT: %.loc5: @Base.%Base.elem (%Base.elem.9af) = field_decl b, element0 [concrete] +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Base.as.Destroy.impl(constants.%T) [symbolic = @Base.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] // CHECK:STDOUT: %struct_type.b.loc6_1.1: type = struct_type {.b: %T} [symbolic = %struct_type.b.loc6_1.2 (constants.%struct_type.b.f69)] // CHECK:STDOUT: %complete_type.loc6_1.1: = complete_type_witness %struct_type.b.loc6_1.1 [symbolic = %complete_type.loc6_1.2 (constants.%complete_type.eaf)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc6_1.1 @@ -572,6 +767,9 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: %.loc9: @Derived.%Derived.elem.loc9 (%Derived.elem.8b3) = base_decl %Base.loc9_22.1, element0 [concrete] // CHECK:STDOUT: %T.ref.loc10: type = name_ref T, %T.loc8_15.2 [symbolic = %T.loc8_15.1 (constants.%T)] // CHECK:STDOUT: %.loc10: @Derived.%Derived.elem.loc10 (%Derived.elem.6d2) = field_decl d, element1 [concrete] +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Derived.as.Destroy.impl(constants.%T) [symbolic = @Derived.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.fa7)] // CHECK:STDOUT: %struct_type.base.d.loc11_1.1: type = struct_type {.base: %Base.370, .d: %T} [symbolic = %struct_type.base.d.loc11_1.2 (constants.%struct_type.base.d.37c)] // CHECK:STDOUT: %complete_type.loc11_1.1: = complete_type_witness %struct_type.base.d.loc11_1.1 [symbolic = %complete_type.loc11_1.2 (constants.%complete_type.8ad)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc11_1.1 @@ -587,6 +785,28 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Base.as.Destroy.impl.Op(@Base.%T.loc4_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Base: type = class_type @Base, @Base(%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %ptr: type = ptr_type %Base [symbolic = %ptr (constants.%ptr.b7c)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.8d4)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Derived.as.Destroy.impl.Op(@Derived.%T.loc8_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Derived: type = class_type @Derived, @Derived(%T) [symbolic = %Derived (constants.%Derived.85c)] +// CHECK:STDOUT: %ptr: type = ptr_type %Derived [symbolic = %ptr (constants.%ptr.178)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.520)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Derived.as.Destroy.impl.Op.%ptr (%ptr.178)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @AccessMissingBase(%T.loc13_22.2: type) { // CHECK:STDOUT: %T.loc13_22.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc13_22.1 (constants.%T)] // CHECK:STDOUT: %Base.loc13_41.1: type = class_type @Base, @Base(%T.loc13_22.1) [symbolic = %Base.loc13_41.1 (constants.%Base.370)] @@ -641,6 +861,18 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: %complete_type.loc6_1.2 => constants.%complete_type.eaf // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.9f8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Base => constants.%Base.370 +// CHECK:STDOUT: %ptr => constants.%ptr.b7c +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.8d4 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Derived(constants.%T) { // CHECK:STDOUT: %T.loc8_15.1 => constants.%T // CHECK:STDOUT: @@ -655,6 +887,18 @@ fn AccessMissingConcrete(x: Derived(i32)) -> i32 { // CHECK:STDOUT: %complete_type.loc11_1.2 => constants.%complete_type.8ad // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Derived.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.fa7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Derived.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Derived => constants.%Derived.85c +// CHECK:STDOUT: %ptr => constants.%ptr.178 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.520 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @AccessMissingBase(constants.%T) { // CHECK:STDOUT: %T.loc13_22.1 => constants.%T // CHECK:STDOUT: %Base.loc13_41.1 => constants.%Base.370 diff --git a/toolchain/check/testdata/class/generic/member_out_of_line.carbon b/toolchain/check/testdata/class/generic/member_out_of_line.carbon index df50e544fddf..931ca6a68a04 100644 --- a/toolchain/check/testdata/class/generic/member_out_of_line.carbon +++ b/toolchain/check/testdata/class/generic/member_out_of_line.carbon @@ -126,6 +126,13 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: %Class.G: %Class.G.type = struct_value () [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.955: type = ptr_type %Class [symbolic] +// CHECK:STDOUT: %pattern_type.9e0: type = pattern_type %ptr.955 [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %T} [symbolic] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n [symbolic] // CHECK:STDOUT: %require_complete.4f8: = require_complete_type %Class [symbolic] @@ -133,9 +140,11 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -182,6 +191,34 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = value_param call_param0 +// CHECK:STDOUT: %.loc4_23.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class)] { +// CHECK:STDOUT: %.loc4_23.3: type = specific_constant constants.%Class, @Class(constants.%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_23.3 [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Class(%T.loc4_13.2: type) { // CHECK:STDOUT: %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: @@ -228,6 +265,9 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: } // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc4_13.2 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: %.loc7: @Class.%Class.elem (%Class.elem) = field_decl n, element0 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%T) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %struct_type.n.loc8_1.1: type = struct_type {.n: %T} [symbolic = %struct_type.n.loc8_1.2 (constants.%struct_type.n)] // CHECK:STDOUT: %complete_type.loc8_1.1: = complete_type_witness %struct_type.n.loc8_1.1 [symbolic = %complete_type.loc8_1.2 (constants.%complete_type)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc8_1.1 @@ -276,6 +316,17 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.955)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.9e0)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Class(constants.%T) { // CHECK:STDOUT: %T.loc4_13.1 => constants.%T // CHECK:STDOUT: @@ -303,6 +354,18 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: %pattern_type.loc6_22 => constants.%pattern_type.7dc // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Class => constants.%Class +// CHECK:STDOUT: %ptr => constants.%ptr.955 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.9e0 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- nested.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -319,17 +382,31 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: %pattern_type.13e: type = pattern_type %B [symbolic] // CHECK:STDOUT: %B.F.type: type = fn_type @B.F, @B(%T, %N) [symbolic] // CHECK:STDOUT: %B.F: %B.F.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e41: = impl_witness @B.%Destroy.impl_witness_table, @B.as.Destroy.impl(%T, %N) [symbolic] +// CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] +// CHECK:STDOUT: %ptr.762: type = ptr_type %B [symbolic] +// CHECK:STDOUT: %pattern_type.fe8: type = pattern_type %ptr.762 [symbolic] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op, @B.as.Destroy.impl(%T, %N) [symbolic] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d93: = impl_witness @A.%Destroy.impl_witness_table, @A.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.ca9: type = ptr_type %A [symbolic] +// CHECK:STDOUT: %pattern_type.09b: type = pattern_type %ptr.ca9 [symbolic] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op, @A.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %require_complete.fca: = require_complete_type %B [symbolic] -// CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -364,6 +441,63 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @B.as.Destroy.impl(@A.%T.loc4_9.2: type, @B.%N.loc5_11.2: @B.%T (%T)) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %N: @B.as.Destroy.impl.%T (%T) = bind_symbolic_name N, 1 [symbolic = %N (constants.%N)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @B.%Destroy.impl_witness_table, @B.as.Destroy.impl(%T, %N) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.e41)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op, @B.as.Destroy.impl(%T, %N) [symbolic = %B.as.Destroy.impl.Op.type (constants.%B.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: @B.as.Destroy.impl.%B.as.Destroy.impl.Op.type (%B.as.Destroy.impl.Op.type) = struct_value () [symbolic = %B.as.Destroy.impl.Op (constants.%B.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: @B.as.Destroy.impl.%B.as.Destroy.impl.Op.type (%B.as.Destroy.impl.Op.type) = fn_decl @B.as.Destroy.impl.Op [symbolic = @B.as.Destroy.impl.%B.as.Destroy.impl.Op (constants.%B.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @B.as.Destroy.impl.Op.%pattern_type (%pattern_type.fe8) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @B.as.Destroy.impl.Op.%pattern_type (%pattern_type.fe8) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5_18.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @B.as.Destroy.impl.Op.%ptr (%ptr.762) = value_param call_param0 +// CHECK:STDOUT: %.loc5_18.2: type = splice_block %Self.ref [symbolic = %B (constants.%B)] { +// CHECK:STDOUT: %.loc5_18.3: type = specific_constant constants.%B, @B(constants.%T, constants.%N) [symbolic = %B (constants.%B)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc5_18.3 [symbolic = %B (constants.%B)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @B.as.Destroy.impl.Op.%ptr (%ptr.762) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @A.as.Destroy.impl(@A.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @A.%Destroy.impl_witness_table, @A.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.d93)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op, @A.as.Destroy.impl(%T) [symbolic = %A.as.Destroy.impl.Op.type (constants.%A.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: @A.as.Destroy.impl.%A.as.Destroy.impl.Op.type (%A.as.Destroy.impl.Op.type) = struct_value () [symbolic = %A.as.Destroy.impl.Op (constants.%A.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: @A.as.Destroy.impl.%A.as.Destroy.impl.Op.type (%A.as.Destroy.impl.Op.type) = fn_decl @A.as.Destroy.impl.Op [symbolic = @A.as.Destroy.impl.%A.as.Destroy.impl.Op (constants.%A.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @A.as.Destroy.impl.Op.%pattern_type (%pattern_type.09b) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @A.as.Destroy.impl.Op.%pattern_type (%pattern_type.09b) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @A.as.Destroy.impl.Op.%ptr (%ptr.ca9) = value_param call_param0 +// CHECK:STDOUT: %.loc4_19.2: type = splice_block %Self.ref [symbolic = %A (constants.%A)] { +// CHECK:STDOUT: %.loc4_19.3: type = specific_constant constants.%A, @A(constants.%T) [symbolic = %A (constants.%A)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_19.3 [symbolic = %A (constants.%A)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @A.as.Destroy.impl.Op.%ptr (%ptr.ca9) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @A(%T.loc4_9.2: type) { // CHECK:STDOUT: %T.loc4_9.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: @@ -378,6 +512,9 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: %T.ref: type = name_ref T, @A.%T.loc4_9.2 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %N.loc5_11.2: @B.%T (%T) = bind_symbolic_name N, 1 [symbolic = %N.loc5_11.1 (constants.%N)] // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @A.as.Destroy.impl(constants.%T) [symbolic = @A.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.d93)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -397,6 +534,7 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: !definition: // CHECK:STDOUT: %B.F.type: type = fn_type @B.F, @B(%T, %N.loc5_11.1) [symbolic = %B.F.type (constants.%B.F.type)] // CHECK:STDOUT: %B.F: @B.%B.F.type (%B.F.type) = struct_value () [symbolic = %B.F (constants.%B.F)] +// CHECK:STDOUT: %require_complete: = require_complete_type %T [symbolic = %require_complete (constants.%require_complete.4ae)] // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: %B.F.decl: @B.%B.F.type (%B.F.type) = fn_decl @B.F [symbolic = @B.%B.F (constants.%B.F)] { @@ -415,6 +553,9 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: %T.ref.loc6: type = name_ref T, @A.%T.loc4_9.2 [symbolic = %T.loc6 (constants.%T)] // CHECK:STDOUT: %a.loc6: @B.F.%T.loc6 (%T) = bind_name a, %a.param.loc6 // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @B.as.Destroy.impl(constants.%T, constants.%N) [symbolic = @B.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.e41)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -443,6 +584,29 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @B.as.Destroy.impl.Op(@A.%T.loc4_9.2: type, @B.%N.loc5_11.2: @B.%T (%T)) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %N: @B.as.Destroy.impl.Op.%T (%T) = bind_symbolic_name N, 1 [symbolic = %N (constants.%N)] +// CHECK:STDOUT: %B: type = class_type @B, @B(%T, %N) [symbolic = %B (constants.%B)] +// CHECK:STDOUT: %ptr: type = ptr_type %B [symbolic = %ptr (constants.%ptr.762)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.fe8)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @B.as.Destroy.impl.Op.%ptr (%ptr.762)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @A.as.Destroy.impl.Op(@A.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %A: type = class_type @A, @A(%T) [symbolic = %A (constants.%A)] +// CHECK:STDOUT: %ptr: type = ptr_type %A [symbolic = %ptr (constants.%ptr.ca9)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.09b)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @A.as.Destroy.impl.Op.%ptr (%ptr.ca9)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @A(constants.%T) { // CHECK:STDOUT: %T.loc4_9.1 => constants.%T // CHECK:STDOUT: @@ -459,6 +623,7 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: !definition: // CHECK:STDOUT: %B.F.type => constants.%B.F.type // CHECK:STDOUT: %B.F => constants.%B.F +// CHECK:STDOUT: %require_complete => constants.%require_complete.4ae // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @B.F(constants.%T, constants.%N) { @@ -469,12 +634,45 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: %pattern_type.loc6_22 => constants.%pattern_type.7dc // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @B.as.Destroy.impl(constants.%T, constants.%N) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %N => constants.%N +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.e41 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @B.as.Destroy.impl.Op(constants.%T, constants.%N) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %N => constants.%N +// CHECK:STDOUT: %B => constants.%B +// CHECK:STDOUT: %ptr => constants.%ptr.762 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.fe8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.d93 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %A => constants.%A +// CHECK:STDOUT: %ptr => constants.%ptr.ca9 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.09b +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_mismatched_not_generic_vs_generic.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %NotGeneric: type = class_type @NotGeneric [concrete] // CHECK:STDOUT: %NotGeneric.F.type: type = fn_type @NotGeneric.F [concrete] // CHECK:STDOUT: %NotGeneric.F: %NotGeneric.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @NotGeneric.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.982: type = ptr_type %NotGeneric [concrete] +// CHECK:STDOUT: %pattern_type.486: type = pattern_type %ptr.982 [concrete] +// CHECK:STDOUT: %NotGeneric.as.Destroy.impl.Op.type: type = fn_type @NotGeneric.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %NotGeneric.as.Destroy.impl.Op: %NotGeneric.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] @@ -484,9 +682,11 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -501,8 +701,27 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @NotGeneric.as.Destroy.impl: constants.%NotGeneric as constants.%Destroy.type { +// CHECK:STDOUT: %NotGeneric.as.Destroy.impl.Op.decl: %NotGeneric.as.Destroy.impl.Op.type = fn_decl @NotGeneric.as.Destroy.impl.Op [concrete = constants.%NotGeneric.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.486 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.486 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.982 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%NotGeneric [concrete = constants.%NotGeneric] +// CHECK:STDOUT: %self: %ptr.982 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %NotGeneric.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @NotGeneric.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @NotGeneric { // CHECK:STDOUT: %NotGeneric.F.decl: %NotGeneric.F.type = fn_decl @NotGeneric.F [concrete = constants.%NotGeneric.F] {} {} +// CHECK:STDOUT: impl_decl @NotGeneric.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@NotGeneric.as.Destroy.impl.%NotGeneric.as.Destroy.impl.Op.decl), @NotGeneric.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -514,6 +733,8 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: // CHECK:STDOUT: fn @NotGeneric.F(); // CHECK:STDOUT: +// CHECK:STDOUT: fn @NotGeneric.as.Destroy.impl.Op(%self.param: %ptr.982) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc15_15.2: type) { // CHECK:STDOUT: %T.loc15_15.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc15_15.1 (constants.%T)] // CHECK:STDOUT: @@ -533,12 +754,19 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] -// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete] +// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %Generic.type: type = generic_class_type @Generic [concrete] // CHECK:STDOUT: %Generic.generic: %Generic.type = struct_value () [concrete] // CHECK:STDOUT: %Generic: type = class_type @Generic, @Generic(%T) [symbolic] // CHECK:STDOUT: %Generic.TooFew.type: type = fn_type @Generic.TooFew, @Generic(%T) [symbolic] // CHECK:STDOUT: %Generic.TooFew: %Generic.TooFew.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Generic.%Destroy.impl_witness_table, @Generic.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.881: type = ptr_type %Generic [symbolic] +// CHECK:STDOUT: %pattern_type.b64: type = pattern_type %ptr.881 [symbolic] +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op.type: type = fn_type @Generic.as.Destroy.impl.Op, @Generic.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op: %Generic.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %TooFew.type: type = fn_type @TooFew [concrete] @@ -547,9 +775,11 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -559,13 +789,41 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %Generic.decl: %Generic.type = class_decl @Generic [concrete = constants.%Generic.generic] { -// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.loc4_15.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_15.1 (constants.%T)] // CHECK:STDOUT: } // CHECK:STDOUT: %TooFew.decl: %TooFew.type = fn_decl @TooFew [concrete = constants.%TooFew] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Generic.as.Destroy.impl(@Generic.%T.loc4_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Generic.%Destroy.impl_witness_table, @Generic.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op.type: type = fn_type @Generic.as.Destroy.impl.Op, @Generic.as.Destroy.impl(%T) [symbolic = %Generic.as.Destroy.impl.Op.type (constants.%Generic.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op: @Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op.type (%Generic.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Generic.as.Destroy.impl.Op (constants.%Generic.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Generic as constants.%Destroy.type { +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op.decl: @Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op.type (%Generic.as.Destroy.impl.Op.type) = fn_decl @Generic.as.Destroy.impl.Op [symbolic = @Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op (constants.%Generic.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Generic.as.Destroy.impl.Op.%pattern_type (%pattern_type.b64) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Generic.as.Destroy.impl.Op.%pattern_type (%pattern_type.b64) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_25.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Generic.as.Destroy.impl.Op.%ptr (%ptr.881) = value_param call_param0 +// CHECK:STDOUT: %.loc4_25.2: type = splice_block %Self.ref [symbolic = %Generic (constants.%Generic)] { +// CHECK:STDOUT: %.loc4_25.3: type = specific_constant constants.%Generic, @Generic(constants.%T) [symbolic = %Generic (constants.%Generic)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_25.3 [symbolic = %Generic (constants.%Generic)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Generic.as.Destroy.impl.Op.%ptr (%ptr.881) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Generic.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Generic.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Generic(%T.loc4_15.2: type) { // CHECK:STDOUT: %T.loc4_15.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_15.1 (constants.%T)] // CHECK:STDOUT: @@ -575,6 +833,9 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: %Generic.TooFew.decl: @Generic.%Generic.TooFew.type (%Generic.TooFew.type) = fn_decl @Generic.TooFew [symbolic = @Generic.%Generic.TooFew (constants.%Generic.TooFew)] {} {} +// CHECK:STDOUT: impl_decl @Generic.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op.decl), @Generic.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Generic.as.Destroy.impl(constants.%T) [symbolic = @Generic.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -589,6 +850,17 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: fn(); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Generic.as.Destroy.impl.Op(@Generic.%T.loc4_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Generic: type = class_type @Generic, @Generic(%T) [symbolic = %Generic (constants.%Generic)] +// CHECK:STDOUT: %ptr: type = ptr_type %Generic [symbolic = %ptr (constants.%ptr.881)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.b64)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Generic.as.Destroy.impl.Op.%ptr (%ptr.881)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @TooFew() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return @@ -600,16 +872,35 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: // CHECK:STDOUT: specific @Generic.TooFew(constants.%T) {} // CHECK:STDOUT: +// CHECK:STDOUT: specific @Generic.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Generic.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Generic => constants.%Generic +// CHECK:STDOUT: %ptr => constants.%ptr.881 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.b64 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_mismatched_too_many_args.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] -// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete] +// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %Generic.type: type = generic_class_type @Generic [concrete] // CHECK:STDOUT: %Generic.generic: %Generic.type = struct_value () [concrete] // CHECK:STDOUT: %Generic: type = class_type @Generic, @Generic(%T) [symbolic] // CHECK:STDOUT: %Generic.TooMany.type: type = fn_type @Generic.TooMany, @Generic(%T) [symbolic] // CHECK:STDOUT: %Generic.TooMany: %Generic.TooMany.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Generic.%Destroy.impl_witness_table, @Generic.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.881: type = ptr_type %Generic [symbolic] +// CHECK:STDOUT: %pattern_type.b64: type = pattern_type %ptr.881 [symbolic] +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op.type: type = fn_type @Generic.as.Destroy.impl.Op, @Generic.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op: %Generic.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %U: type = bind_symbolic_name U, 1 [symbolic] @@ -619,9 +910,11 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -631,7 +924,7 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %Generic.decl: %Generic.type = class_decl @Generic [concrete = constants.%Generic.generic] { -// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.loc4_15.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_15.1 (constants.%T)] // CHECK:STDOUT: } @@ -641,6 +934,34 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Generic.as.Destroy.impl(@Generic.%T.loc4_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Generic.%Destroy.impl_witness_table, @Generic.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op.type: type = fn_type @Generic.as.Destroy.impl.Op, @Generic.as.Destroy.impl(%T) [symbolic = %Generic.as.Destroy.impl.Op.type (constants.%Generic.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op: @Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op.type (%Generic.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Generic.as.Destroy.impl.Op (constants.%Generic.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Generic as constants.%Destroy.type { +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op.decl: @Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op.type (%Generic.as.Destroy.impl.Op.type) = fn_decl @Generic.as.Destroy.impl.Op [symbolic = @Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op (constants.%Generic.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Generic.as.Destroy.impl.Op.%pattern_type (%pattern_type.b64) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Generic.as.Destroy.impl.Op.%pattern_type (%pattern_type.b64) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_25.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Generic.as.Destroy.impl.Op.%ptr (%ptr.881) = value_param call_param0 +// CHECK:STDOUT: %.loc4_25.2: type = splice_block %Self.ref [symbolic = %Generic (constants.%Generic)] { +// CHECK:STDOUT: %.loc4_25.3: type = specific_constant constants.%Generic, @Generic(constants.%T) [symbolic = %Generic (constants.%Generic)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_25.3 [symbolic = %Generic (constants.%Generic)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Generic.as.Destroy.impl.Op.%ptr (%ptr.881) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Generic.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Generic.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Generic(%T.loc4_15.2: type) { // CHECK:STDOUT: %T.loc4_15.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_15.1 (constants.%T)] // CHECK:STDOUT: @@ -650,6 +971,9 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: %Generic.TooMany.decl: @Generic.%Generic.TooMany.type (%Generic.TooMany.type) = fn_decl @Generic.TooMany [symbolic = @Generic.%Generic.TooMany (constants.%Generic.TooMany)] {} {} +// CHECK:STDOUT: impl_decl @Generic.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op.decl), @Generic.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Generic.as.Destroy.impl(constants.%T) [symbolic = @Generic.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -664,6 +988,17 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: fn(); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Generic.as.Destroy.impl.Op(@Generic.%T.loc4_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Generic: type = class_type @Generic, @Generic(%T) [symbolic = %Generic (constants.%Generic)] +// CHECK:STDOUT: %ptr: type = ptr_type %Generic [symbolic = %ptr (constants.%ptr.881)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.b64)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Generic.as.Destroy.impl.Op.%ptr (%ptr.881)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @TooMany(%T.loc15_12.2: type, %U.loc15_22.2: type) { // CHECK:STDOUT: %T.loc15_12.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc15_12.1 (constants.%T)] // CHECK:STDOUT: %U.loc15_22.1: type = bind_symbolic_name U, 1 [symbolic = %U.loc15_22.1 (constants.%U)] @@ -682,6 +1017,18 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: // CHECK:STDOUT: specific @Generic.TooMany(constants.%T) {} // CHECK:STDOUT: +// CHECK:STDOUT: specific @Generic.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Generic.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Generic => constants.%Generic +// CHECK:STDOUT: %ptr => constants.%ptr.881 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.b64 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @TooMany(constants.%T, constants.%U) { // CHECK:STDOUT: %T.loc15_12.1 => constants.%T // CHECK:STDOUT: %U.loc15_22.1 => constants.%U @@ -698,6 +1045,13 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: %Generic: type = class_type @Generic, @Generic(%T.8b3) [symbolic] // CHECK:STDOUT: %Generic.WrongType.type: type = fn_type @Generic.WrongType, @Generic(%T.8b3) [symbolic] // CHECK:STDOUT: %Generic.WrongType: %Generic.WrongType.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Generic.%Destroy.impl_witness_table, @Generic.as.Destroy.impl(%T.8b3) [symbolic] +// CHECK:STDOUT: %ptr.881: type = ptr_type %Generic [symbolic] +// CHECK:STDOUT: %pattern_type.b64: type = pattern_type %ptr.881 [symbolic] +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op.type: type = fn_type @Generic.as.Destroy.impl.Op, @Generic.as.Destroy.impl(%T.8b3) [symbolic] +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op: %Generic.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T.7a6: %empty_tuple.type = bind_symbolic_name T, 0 [symbolic] @@ -707,9 +1061,11 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -732,6 +1088,34 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Generic.as.Destroy.impl(@Generic.%T.loc4_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.8b3)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Generic.%Destroy.impl_witness_table, @Generic.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op.type: type = fn_type @Generic.as.Destroy.impl.Op, @Generic.as.Destroy.impl(%T) [symbolic = %Generic.as.Destroy.impl.Op.type (constants.%Generic.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op: @Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op.type (%Generic.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Generic.as.Destroy.impl.Op (constants.%Generic.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Generic as constants.%Destroy.type { +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op.decl: @Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op.type (%Generic.as.Destroy.impl.Op.type) = fn_decl @Generic.as.Destroy.impl.Op [symbolic = @Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op (constants.%Generic.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Generic.as.Destroy.impl.Op.%pattern_type (%pattern_type.b64) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Generic.as.Destroy.impl.Op.%pattern_type (%pattern_type.b64) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_25.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Generic.as.Destroy.impl.Op.%ptr (%ptr.881) = value_param call_param0 +// CHECK:STDOUT: %.loc4_25.2: type = splice_block %Self.ref [symbolic = %Generic (constants.%Generic)] { +// CHECK:STDOUT: %.loc4_25.3: type = specific_constant constants.%Generic, @Generic(constants.%T.8b3) [symbolic = %Generic (constants.%Generic)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_25.3 [symbolic = %Generic (constants.%Generic)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Generic.as.Destroy.impl.Op.%ptr (%ptr.881) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Generic.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Generic.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Generic(%T.loc4_15.2: type) { // CHECK:STDOUT: %T.loc4_15.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_15.1 (constants.%T.8b3)] // CHECK:STDOUT: @@ -741,6 +1125,9 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: %Generic.WrongType.decl: @Generic.%Generic.WrongType.type (%Generic.WrongType.type) = fn_decl @Generic.WrongType [symbolic = @Generic.%Generic.WrongType (constants.%Generic.WrongType)] {} {} +// CHECK:STDOUT: impl_decl @Generic.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op.decl), @Generic.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Generic.as.Destroy.impl(constants.%T.8b3) [symbolic = @Generic.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -755,6 +1142,17 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: fn(); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Generic.as.Destroy.impl.Op(@Generic.%T.loc4_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.8b3)] +// CHECK:STDOUT: %Generic: type = class_type @Generic, @Generic(%T) [symbolic = %Generic (constants.%Generic)] +// CHECK:STDOUT: %ptr: type = ptr_type %Generic [symbolic = %ptr (constants.%ptr.881)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.b64)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Generic.as.Destroy.impl.Op.%ptr (%ptr.881)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @WrongType(%T.loc15_12.2: %empty_tuple.type) { // CHECK:STDOUT: %T.loc15_12.1: %empty_tuple.type = bind_symbolic_name T, 0 [symbolic = %T.loc15_12.1 (constants.%T.7a6)] // CHECK:STDOUT: @@ -772,6 +1170,18 @@ fn Generic(T:! ()).WrongType() {} // CHECK:STDOUT: // CHECK:STDOUT: specific @Generic.WrongType(constants.%T.8b3) {} // CHECK:STDOUT: +// CHECK:STDOUT: specific @Generic.as.Destroy.impl(constants.%T.8b3) { +// CHECK:STDOUT: %T => constants.%T.8b3 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Generic.as.Destroy.impl.Op(constants.%T.8b3) { +// CHECK:STDOUT: %T => constants.%T.8b3 +// CHECK:STDOUT: %Generic => constants.%Generic +// CHECK:STDOUT: %ptr => constants.%ptr.881 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.b64 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @WrongType(constants.%T.7a6) { // CHECK:STDOUT: %T.loc15_12.1 => constants.%T.7a6 // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/class/generic/member_type.carbon b/toolchain/check/testdata/class/generic/member_type.carbon index 281d0963597a..a6086371fd2f 100644 --- a/toolchain/check/testdata/class/generic/member_type.carbon +++ b/toolchain/check/testdata/class/generic/member_type.carbon @@ -68,12 +68,24 @@ fn Test() -> i32 { // CHECK:STDOUT: %Inner.51b: type = class_type @Inner, @Inner(%T) [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %Inner.elem.310: type = unbound_element_type %Inner.51b, %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.0c4: = impl_witness @Inner.%Destroy.impl_witness_table, @Inner.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.c82: type = ptr_type %Inner.51b [symbolic] +// CHECK:STDOUT: %pattern_type.822: type = pattern_type %ptr.c82 [symbolic] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.type: type = fn_type @Inner.as.Destroy.impl.Op, @Inner.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op: %Inner.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.n.848: type = struct_type {.n: %T} [symbolic] // CHECK:STDOUT: %complete_type.84b: = complete_type_witness %struct_type.n.848 [symbolic] // CHECK:STDOUT: %pattern_type.7dcd0a.1: type = pattern_type %T [symbolic] // CHECK:STDOUT: %pattern_type.253: type = pattern_type %Inner.51b [symbolic] // CHECK:STDOUT: %Outer.F.type.2ee: type = fn_type @Outer.F, @Outer(%T) [symbolic] // CHECK:STDOUT: %Outer.F.384: %Outer.F.type.2ee = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.a35: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.6ff: type = ptr_type %Outer.9d6 [symbolic] +// CHECK:STDOUT: %pattern_type.07e: type = pattern_type %ptr.6ff [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: %Outer.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %require_complete.561: = require_complete_type %Inner.51b [symbolic] @@ -112,7 +124,7 @@ fn Test() -> i32 { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.956, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] // CHECK:STDOUT: %bound_method: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.07c: = impl_witness @Inner.%Destroy.impl_witness_table, @Inner.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a38: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Inner.721) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.27e: %T.as.Destroy.impl.Op.type.a38 = struct_value () [concrete] // CHECK:STDOUT: %ptr.416: type = ptr_type %Inner.721 [concrete] @@ -121,17 +133,17 @@ fn Test() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs -// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -157,6 +169,62 @@ fn Test() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Inner.as.Destroy.impl(@Outer.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Inner.%Destroy.impl_witness_table, @Inner.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.0c4)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.type: type = fn_type @Inner.as.Destroy.impl.Op, @Inner.as.Destroy.impl(%T) [symbolic = %Inner.as.Destroy.impl.Op.type (constants.%Inner.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op: @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.type (%Inner.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Inner.as.Destroy.impl.Op (constants.%Inner.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Inner.51b as constants.%Destroy.type { +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.decl: @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.type (%Inner.as.Destroy.impl.Op.type) = fn_decl @Inner.as.Destroy.impl.Op [symbolic = @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op (constants.%Inner.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Inner.as.Destroy.impl.Op.%pattern_type (%pattern_type.822) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Inner.as.Destroy.impl.Op.%pattern_type (%pattern_type.822) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5_15.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Inner.as.Destroy.impl.Op.%ptr (%ptr.c82) = value_param call_param0 +// CHECK:STDOUT: %.loc5_15.2: type = splice_block %Self.ref [symbolic = %Inner (constants.%Inner.51b)] { +// CHECK:STDOUT: %.loc5_15.3: type = specific_constant constants.%Inner.51b, @Inner(constants.%T) [symbolic = %Inner (constants.%Inner.51b)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc5_15.3 [symbolic = %Inner (constants.%Inner.51b)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Inner.as.Destroy.impl.Op.%ptr (%ptr.c82) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Inner.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Inner.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Outer.as.Destroy.impl(@Outer.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.a35)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%T) [symbolic = %Outer.as.Destroy.impl.Op.type (constants.%Outer.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Outer.9d6 as constants.%Destroy.type { +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.decl: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = fn_decl @Outer.as.Destroy.impl.Op [symbolic = @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.07e) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.07e) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff) = value_param call_param0 +// CHECK:STDOUT: %.loc4_23.2: type = splice_block %Self.ref [symbolic = %Outer (constants.%Outer.9d6)] { +// CHECK:STDOUT: %.loc4_23.3: type = specific_constant constants.%Outer.9d6, @Outer(constants.%T) [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_23.3 [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Outer.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Outer.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Outer(%T.loc4_13.2: type) { // CHECK:STDOUT: %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: @@ -181,6 +249,9 @@ fn Test() -> i32 { // CHECK:STDOUT: %return.param: ref @Outer.F.%Inner (%Inner.51b) = out_param call_param1 // CHECK:STDOUT: %return: ref @Outer.F.%Inner (%Inner.51b) = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Outer.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.decl), @Outer.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Outer.as.Destroy.impl(constants.%T) [symbolic = @Outer.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a35)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -205,6 +276,9 @@ fn Test() -> i32 { // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, @Outer.%T.loc4_13.2 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %.loc6: @Inner.%Inner.elem (%Inner.elem.310) = field_decl n, element0 [concrete] +// CHECK:STDOUT: impl_decl @Inner.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.decl), @Inner.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Inner.as.Destroy.impl(constants.%T) [symbolic = @Inner.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.0c4)] // CHECK:STDOUT: %struct_type.n.loc7_3.1: type = struct_type {.n: %T} [symbolic = %struct_type.n.loc7_3.2 (constants.%struct_type.n.848)] // CHECK:STDOUT: %complete_type.loc7_3.1: = complete_type_witness %struct_type.n.loc7_3.1 [symbolic = %complete_type.loc7_3.2 (constants.%complete_type.84b)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc7_3.1 @@ -216,6 +290,17 @@ fn Test() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Inner.as.Destroy.impl.Op(@Outer.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Inner: type = class_type @Inner, @Inner(%T) [symbolic = %Inner (constants.%Inner.51b)] +// CHECK:STDOUT: %ptr: type = ptr_type %Inner [symbolic = %ptr (constants.%ptr.c82)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.822)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Inner.as.Destroy.impl.Op.%ptr (%ptr.c82)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @Outer.F(@Outer.%T.loc4_13.2: type) { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %pattern_type.loc9_8: type = pattern_type %T [symbolic = %pattern_type.loc9_8 (constants.%pattern_type.7dcd0a.1)] @@ -239,6 +324,17 @@ fn Test() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Outer.as.Destroy.impl.Op(@Outer.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Outer: type = class_type @Outer, @Outer(%T) [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: %ptr: type = ptr_type %Outer [symbolic = %ptr (constants.%ptr.6ff)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.07e)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @Test() -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -309,6 +405,18 @@ fn Test() -> i32 { // CHECK:STDOUT: %complete_type.loc7_3.2 => constants.%complete_type.84b // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Inner.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.0c4 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Inner.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Inner => constants.%Inner.51b +// CHECK:STDOUT: %ptr => constants.%ptr.c82 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.822 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Outer.F(constants.%T) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %pattern_type.loc9_8 => constants.%pattern_type.7dcd0a.1 @@ -316,6 +424,18 @@ fn Test() -> i32 { // CHECK:STDOUT: %pattern_type.loc9_14 => constants.%pattern_type.253 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a35 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Outer => constants.%Outer.9d6 +// CHECK:STDOUT: %ptr => constants.%ptr.6ff +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.07e +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Outer(constants.%i32) { // CHECK:STDOUT: %T.loc4_13.1 => constants.%i32 // CHECK:STDOUT: @@ -347,6 +467,11 @@ fn Test() -> i32 { // CHECK:STDOUT: %struct_type.n => constants.%struct_type.n.033 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Inner.as.Destroy.impl(constants.%i32) { +// CHECK:STDOUT: %T => constants.%i32 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.07c +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- interface.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -372,8 +497,20 @@ fn Test() -> i32 { // CHECK:STDOUT: %C.as.Inner.impl.F.type.77b: type = fn_type @C.as.Inner.impl.F, @C.as.Inner.impl(%T) [symbolic] // CHECK:STDOUT: %C.as.Inner.impl.F.ed9: %C.as.Inner.impl.F.type.77b = struct_value () [symbolic] // CHECK:STDOUT: %Inner.facet.9a3: %Inner.type.392 = facet_value %C.390, (%Inner.impl_witness.b15) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.674: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.306: type = ptr_type %C.390 [symbolic] +// CHECK:STDOUT: %pattern_type.670: type = pattern_type %ptr.306 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.a35: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.6ff: type = ptr_type %Outer.9d6 [symbolic] +// CHECK:STDOUT: %pattern_type.07e: type = pattern_type %ptr.6ff [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: %Outer.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %require_complete.930: = require_complete_type %C.390 [symbolic] // CHECK:STDOUT: %Inner.lookup_impl_witness: = lookup_impl_witness %C.390, @Inner, @Inner(%T) [symbolic] @@ -400,6 +537,11 @@ fn Test() -> i32 { // CHECK:STDOUT: %D.as.Inner.impl.F.type: type = fn_type @D.as.Inner.impl.F [concrete] // CHECK:STDOUT: %D.as.Inner.impl.F: %D.as.Inner.impl.F.type = struct_value () [concrete] // CHECK:STDOUT: %Inner.facet.edc: %Inner.type.52d = facet_value %D, (%Inner.impl_witness.1dc) [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Test.type: type = fn_type @Test [concrete] // CHECK:STDOUT: %Test: %Test.type = struct_value () [concrete] // CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete] @@ -413,7 +555,7 @@ fn Test() -> i32 { // CHECK:STDOUT: %Inner.facet.840: %Inner.type.52d = facet_value %C.70f, (%Inner.impl_witness.47d) [concrete] // CHECK:STDOUT: %.b10: type = fn_type_with_self_type %Inner.F.type.86e, %Inner.facet.840 [concrete] // CHECK:STDOUT: %C.as.Inner.impl.F.specific_fn: = specific_function %C.as.Inner.impl.F.e75, @C.as.Inner.impl.F(%i32) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.82e: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.b66: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.70f) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.369: %T.as.Destroy.impl.Op.type.b66 = struct_value () [concrete] // CHECK:STDOUT: %ptr.18f: type = ptr_type %C.70f [concrete] @@ -422,13 +564,13 @@ fn Test() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { -// CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -534,6 +676,62 @@ fn Test() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@Outer.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.674)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.390 as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.670) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.670) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9_11.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.306) = value_param call_param0 +// CHECK:STDOUT: %.loc9_11.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.390)] { +// CHECK:STDOUT: %.loc9_11.3: type = specific_constant constants.%C.390, @C(constants.%T) [symbolic = %C (constants.%C.390)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc9_11.3 [symbolic = %C (constants.%C.390)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.306) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Outer.as.Destroy.impl(@Outer.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.a35)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%T) [symbolic = %Outer.as.Destroy.impl.Op.type (constants.%Outer.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Outer.9d6 as constants.%Destroy.type { +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.decl: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = fn_decl @Outer.as.Destroy.impl.Op [symbolic = @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.07e) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.07e) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff) = value_param call_param0 +// CHECK:STDOUT: %.loc4_23.2: type = splice_block %Self.ref [symbolic = %Outer (constants.%Outer.9d6)] { +// CHECK:STDOUT: %.loc4_23.3: type = specific_constant constants.%Outer.9d6, @Outer(constants.%T) [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_23.3 [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Outer.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Outer.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @D.as.Inner.impl: %Self.ref as %Inner.ref { // CHECK:STDOUT: %D.as.Inner.impl.F.decl: %D.as.Inner.impl.F.type = fn_decl @D.as.Inner.impl.F [concrete = constants.%D.as.Inner.impl.F] { // CHECK:STDOUT: %self.patt: %pattern_type.510 = binding_pattern self [concrete] @@ -556,6 +754,22 @@ fn Test() -> i32 { // CHECK:STDOUT: witness = @D.%Inner.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc16: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Outer(%T.loc4_13.2: type) { // CHECK:STDOUT: %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: @@ -566,6 +780,9 @@ fn Test() -> i32 { // CHECK:STDOUT: class { // CHECK:STDOUT: %Inner.decl: type = interface_decl @Inner [symbolic = @Outer.%Inner.type (constants.%Inner.type.392)] {} {} // CHECK:STDOUT: %C.decl: type = class_decl @C [symbolic = @Outer.%C (constants.%C.390)] {} {} +// CHECK:STDOUT: impl_decl @Outer.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.decl), @Outer.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Outer.as.Destroy.impl(constants.%T) [symbolic = @Outer.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a35)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -589,6 +806,9 @@ fn Test() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: %Inner.impl_witness_table = impl_witness_table (@C.as.Inner.impl.%C.as.Inner.impl.F.decl), @C.as.Inner.impl [concrete] // CHECK:STDOUT: %Inner.impl_witness: = impl_witness %Inner.impl_witness_table, @C.as.Inner.impl(constants.%T) [symbolic = @C.as.Inner.impl.%Inner.impl_witness (constants.%Inner.impl_witness.b15)] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.674)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -613,6 +833,9 @@ fn Test() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: %Inner.impl_witness_table = impl_witness_table (@D.as.Inner.impl.%D.as.Inner.impl.F.decl), @D.as.Inner.impl [concrete] // CHECK:STDOUT: %Inner.impl_witness: = impl_witness %Inner.impl_witness_table [concrete = constants.%Inner.impl_witness.1dc] +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -672,8 +895,32 @@ fn Test() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@Outer.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.390)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.306)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.670)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.306)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Outer.as.Destroy.impl.Op(@Outer.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Outer: type = class_type @Outer, @Outer(%T) [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: %ptr: type = ptr_type %Outer [symbolic = %ptr (constants.%ptr.6ff)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.07e)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @D.as.Inner.impl.F(%self.param: %D) -> %i32; // CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Test() -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -779,6 +1026,30 @@ fn Test() -> i32 { // CHECK:STDOUT: %pattern_type.loc6_24 => constants.%pattern_type.7dcd0a.1 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.674 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.390 +// CHECK:STDOUT: %ptr => constants.%ptr.306 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.670 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a35 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Outer => constants.%Outer.9d6 +// CHECK:STDOUT: %ptr => constants.%ptr.6ff +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.07e +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Inner.F(constants.%T, constants.%Inner.facet.c18) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %Inner.type => constants.%Inner.type.392 @@ -853,6 +1124,11 @@ fn Test() -> i32 { // CHECK:STDOUT: %specific_impl_fn.loc11_41.2 => constants.%C.as.Inner.impl.F.specific_fn // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%i32) { +// CHECK:STDOUT: %T => constants.%i32 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.82e +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Inner.F(constants.%i32, constants.%Inner.facet.840) { // CHECK:STDOUT: %T => constants.%i32 // CHECK:STDOUT: %Inner.type => constants.%Inner.type.52d diff --git a/toolchain/check/testdata/class/generic/method_deduce.carbon b/toolchain/check/testdata/class/generic/method_deduce.carbon index 1bba3655a8c2..302eea4dd4a6 100644 --- a/toolchain/check/testdata/class/generic/method_deduce.carbon +++ b/toolchain/check/testdata/class/generic/method_deduce.carbon @@ -32,13 +32,26 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %A: type = class_type @A [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %Class.type: type = generic_class_type @Class [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Class.generic: %Class.type = struct_value () [concrete] // CHECK:STDOUT: %Class.fe1: type = class_type @Class, @Class(%T) [symbolic] // CHECK:STDOUT: %U: type = bind_symbolic_name U, 1 [symbolic] @@ -50,11 +63,14 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) { // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] // CHECK:STDOUT: %Class.GetNoDeduce.type.766: type = fn_type @Class.GetNoDeduce, @Class(%T) [symbolic] // CHECK:STDOUT: %Class.GetNoDeduce.c9a: %Class.GetNoDeduce.type.766 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.95a: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.955: type = ptr_type %Class.fe1 [symbolic] +// CHECK:STDOUT: %pattern_type.9e0: type = pattern_type %ptr.955 [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %ptr.937: type = ptr_type %tuple.type.30b [symbolic] // CHECK:STDOUT: %require_complete.fe1: = require_complete_type %tuple.type.30b [symbolic] // CHECK:STDOUT: %Class.Get.specific_fn.f73: = specific_function %Class.Get.cf9, @Class.Get(%T, %U) [symbolic] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.bc9: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%T) [symbolic] // CHECK:STDOUT: %T.as.Destroy.impl.Op.46f: %T.as.Destroy.impl.Op.type.bc9 = struct_value () [symbolic] // CHECK:STDOUT: %require_complete.8fa: = require_complete_type %ptr.937 [symbolic] @@ -83,16 +99,12 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) { // CHECK:STDOUT: %complete_type.a4a: = complete_type_witness %ptr.3b5 [concrete] // CHECK:STDOUT: %Destroy.facet.fae: %Destroy.type = facet_value %tuple.type.cc6, (%Destroy.impl_witness.ae3) [concrete] // CHECK:STDOUT: %.c9f: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.fae [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.8d7: = specific_function %T.as.Destroy.impl.Op.f13, @T.as.Destroy.impl.Op(%tuple.type.cc6) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.f13, @T.as.Destroy.impl.Op(%tuple.type.cc6) [concrete] // CHECK:STDOUT: %CallGenericMethodWithNonDeducedParam.type: type = fn_type @CallGenericMethodWithNonDeducedParam [concrete] // CHECK:STDOUT: %CallGenericMethodWithNonDeducedParam: %CallGenericMethodWithNonDeducedParam.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.c10: type = pattern_type %A [concrete] // CHECK:STDOUT: %Class.GetNoDeduce.specific_fn.438: = specific_function %Class.GetNoDeduce.162, @Class.GetNoDeduce(%A, %B) [concrete] // CHECK:STDOUT: %A.val: %A = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.b96: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%A) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.885: %T.as.Destroy.impl.Op.type.b96 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.716: = specific_function %T.as.Destroy.impl.Op.885, @T.as.Destroy.impl.Op(%A) [concrete] // CHECK:STDOUT: %complete_type.56a: = complete_type_witness %tuple.type.cc6 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -166,7 +178,70 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc16: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%T.loc18_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.95a)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class.fe1 as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc18_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = value_param call_param0 +// CHECK:STDOUT: %.loc18_23.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class.fe1)] { +// CHECK:STDOUT: %.loc18_23.3: type = specific_constant constants.%Class.fe1, @Class(constants.%T) [symbolic = %Class (constants.%Class.fe1)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc18_23.3 [symbolic = %Class (constants.%Class.fe1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -176,6 +251,9 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @B { +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -225,6 +303,9 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) { // CHECK:STDOUT: %return.param: ref @Class.GetNoDeduce.%tuple.type (%tuple.type.30b) = out_param call_param1 // CHECK:STDOUT: %return: ref @Class.GetNoDeduce.%tuple.type (%tuple.type.30b) = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%T) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.95a)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -237,6 +318,10 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @Class.Get(@Class.%T.loc18_13.2: type, %U.loc19_10.2: type) { // CHECK:STDOUT: %U.loc19_10.1: type = bind_symbolic_name U, 1 [symbolic = %U.loc19_10.1 (constants.%U)] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] @@ -314,6 +399,17 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%T.loc18_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.fe1)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.955)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.9e0)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @CallGenericMethod(%c.param: %Class.480) -> %return.param: %tuple.type.cc6 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %c.ref: %Class.480 = name_ref c, %c @@ -324,7 +420,7 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) { // CHECK:STDOUT: %.loc23_35: ref %tuple.type.cc6 = splice_block %return {} // CHECK:STDOUT: %Class.Get.call: init %tuple.type.cc6 = call %Class.Get.specific_fn() to %.loc23_35 // CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc23_35, constants.%T.as.Destroy.impl.Op.f13 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.f13, @T.as.Destroy.impl.Op(constants.%tuple.type.cc6) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.8d7] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.f13, @T.as.Destroy.impl.Op(constants.%tuple.type.cc6) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method: = bound_method %.loc23_35, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr: %ptr.3b5 = addr_of %.loc23_35 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) @@ -346,16 +442,14 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) { // CHECK:STDOUT: %.loc28_25.5: ref %A = converted %.loc28_25.1, %.loc28_25.4 // CHECK:STDOUT: %.loc28_25.6: %A = bind_value %.loc28_25.5 // CHECK:STDOUT: %Class.GetNoDeduce.call: init %tuple.type.cc6 = call %Class.GetNoDeduce.specific_fn(%.loc28_25.6) to %.loc27_54 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc28: = bound_method %.loc28_25.2, constants.%T.as.Destroy.impl.Op.885 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.885, @T.as.Destroy.impl.Op(constants.%A) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.716] -// CHECK:STDOUT: %bound_method.loc28: = bound_method %.loc28_25.2, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %A.as.Destroy.impl.Op.bound: = bound_method %.loc28_25.2, constants.%A.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc28: %ptr.6db = addr_of %.loc28_25.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc28: init %empty_tuple.type = call %bound_method.loc28(%addr.loc28) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc27: = bound_method %.loc27_54, constants.%T.as.Destroy.impl.Op.f13 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.f13, @T.as.Destroy.impl.Op(constants.%tuple.type.cc6) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.8d7] -// CHECK:STDOUT: %bound_method.loc27: = bound_method %.loc27_54, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %A.as.Destroy.impl.Op.call: init %empty_tuple.type = call %A.as.Destroy.impl.Op.bound(%addr.loc28) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc27_54, constants.%T.as.Destroy.impl.Op.f13 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.f13, @T.as.Destroy.impl.Op(constants.%tuple.type.cc6) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method: = bound_method %.loc27_54, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr.loc27: %ptr.3b5 = addr_of %.loc27_54 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc27: init %empty_tuple.type = call %bound_method.loc27(%addr.loc27) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc27) // CHECK:STDOUT: return %Class.GetNoDeduce.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -411,6 +505,18 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) { // CHECK:STDOUT: %require_complete.loc20_34 => constants.%require_complete.8fa // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.95a +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Class => constants.%Class.fe1 +// CHECK:STDOUT: %ptr => constants.%ptr.955 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.9e0 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Class(constants.%A) { // CHECK:STDOUT: %T.loc18_13.1 => constants.%A // CHECK:STDOUT: @@ -436,7 +542,7 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) { // CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.fae // CHECK:STDOUT: %.loc19_20.3 => constants.%.c9f // CHECK:STDOUT: %impl.elem0.loc19_20.2 => constants.%T.as.Destroy.impl.Op.f13 -// CHECK:STDOUT: %specific_impl_fn.loc19_20.2 => constants.%T.as.Destroy.impl.Op.specific_fn.8d7 +// CHECK:STDOUT: %specific_impl_fn.loc19_20.2 => constants.%T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %ptr => constants.%ptr.3b5 // CHECK:STDOUT: %require_complete.loc19_20.2 => constants.%complete_type.a4a // CHECK:STDOUT: } @@ -458,7 +564,7 @@ fn CallGenericMethodWithNonDeducedParam(c: Class(A)) -> (A, B) { // CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.fae // CHECK:STDOUT: %.loc20_34.3 => constants.%.c9f // CHECK:STDOUT: %impl.elem0.loc20_34.2 => constants.%T.as.Destroy.impl.Op.f13 -// CHECK:STDOUT: %specific_impl_fn.loc20_34.2 => constants.%T.as.Destroy.impl.Op.specific_fn.8d7 +// CHECK:STDOUT: %specific_impl_fn.loc20_34.2 => constants.%T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %ptr => constants.%ptr.3b5 // CHECK:STDOUT: %require_complete.loc20_34 => constants.%complete_type.a4a // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/class/generic/redeclare.carbon b/toolchain/check/testdata/class/generic/redeclare.carbon index 374f078512f1..2bd0a92fc437 100644 --- a/toolchain/check/testdata/class/generic/redeclare.carbon +++ b/toolchain/check/testdata/class/generic/redeclare.carbon @@ -101,19 +101,28 @@ class E(U:! type) {} // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] -// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete] +// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %Generic.type: type = generic_class_type @Generic [concrete] // CHECK:STDOUT: %Generic.generic: %Generic.type = struct_value () [concrete] // CHECK:STDOUT: %Generic: type = class_type @Generic, @Generic(%T) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Generic.%Destroy.impl_witness_table, @Generic.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.881: type = ptr_type %Generic [symbolic] +// CHECK:STDOUT: %pattern_type.b64: type = pattern_type %ptr.881 [symbolic] +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op.type: type = fn_type @Generic.as.Destroy.impl.Op, @Generic.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op: %Generic.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -123,23 +132,54 @@ class E(U:! type) {} // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %Generic.decl.loc4: %Generic.type = class_decl @Generic [concrete = constants.%Generic.generic] { -// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.loc4_15.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_15.1 (constants.%T)] // CHECK:STDOUT: } // CHECK:STDOUT: %Generic.decl.loc6: %Generic.type = class_decl @Generic [concrete = constants.%Generic.generic] { -// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.loc6: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_15.1 (constants.%T)] // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Generic.as.Destroy.impl(@Generic.%T.loc6: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Generic.%Destroy.impl_witness_table, @Generic.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op.type: type = fn_type @Generic.as.Destroy.impl.Op, @Generic.as.Destroy.impl(%T) [symbolic = %Generic.as.Destroy.impl.Op.type (constants.%Generic.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op: @Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op.type (%Generic.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Generic.as.Destroy.impl.Op (constants.%Generic.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Generic as constants.%Destroy.type { +// CHECK:STDOUT: %Generic.as.Destroy.impl.Op.decl: @Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op.type (%Generic.as.Destroy.impl.Op.type) = fn_decl @Generic.as.Destroy.impl.Op [symbolic = @Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op (constants.%Generic.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Generic.as.Destroy.impl.Op.%pattern_type (%pattern_type.b64) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Generic.as.Destroy.impl.Op.%pattern_type (%pattern_type.b64) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6_25.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Generic.as.Destroy.impl.Op.%ptr (%ptr.881) = value_param call_param0 +// CHECK:STDOUT: %.loc6_25.2: type = splice_block %Self.ref [symbolic = %Generic (constants.%Generic)] { +// CHECK:STDOUT: %.loc6_25.3: type = specific_constant constants.%Generic, @Generic(constants.%T) [symbolic = %Generic (constants.%Generic)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc6_25.3 [symbolic = %Generic (constants.%Generic)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Generic.as.Destroy.impl.Op.%ptr (%ptr.881) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Generic.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Generic.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Generic(%T.loc4_15.2: type) { // CHECK:STDOUT: %T.loc4_15.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_15.1 (constants.%T)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @Generic.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Generic.as.Destroy.impl.%Generic.as.Destroy.impl.Op.decl), @Generic.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Generic.as.Destroy.impl(constants.%T) [symbolic = @Generic.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -149,28 +189,60 @@ class E(U:! type) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Generic.as.Destroy.impl.Op(@Generic.%T.loc6: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Generic: type = class_type @Generic, @Generic(%T) [symbolic = %Generic (constants.%Generic)] +// CHECK:STDOUT: %ptr: type = ptr_type %Generic [symbolic = %ptr (constants.%ptr.881)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.b64)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Generic.as.Destroy.impl.Op.%ptr (%ptr.881)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Generic(constants.%T) { // CHECK:STDOUT: %T.loc4_15.1 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Generic.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Generic.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Generic => constants.%Generic +// CHECK:STDOUT: %ptr => constants.%ptr.881 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.b64 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_mismatch_param_list.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %A.466: type = class_type @A.loc4 [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] -// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete] +// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %A.type: type = generic_class_type @A.loc12 [concrete] // CHECK:STDOUT: %A.generic: %A.type = struct_value () [concrete] // CHECK:STDOUT: %A.130: type = class_type @A.loc12, @A.loc12(%T) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @A.loc12.%Destroy.impl_witness_table, @A.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.ca9: type = ptr_type %A.130 [symbolic] +// CHECK:STDOUT: %pattern_type.09b: type = pattern_type %ptr.ca9 [symbolic] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op, @A.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -181,12 +253,40 @@ class E(U:! type) {} // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %A.decl.loc4: type = class_decl @A.loc4 [concrete = constants.%A.466] {} {} // CHECK:STDOUT: %A.decl.loc12: %A.type = class_decl @A.loc12 [concrete = constants.%A.generic] { -// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.loc12_9.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc12_9.1 (constants.%T)] // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @A.as.Destroy.impl(@A.loc12.%T.loc12_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @A.loc12.%Destroy.impl_witness_table, @A.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op, @A.as.Destroy.impl(%T) [symbolic = %A.as.Destroy.impl.Op.type (constants.%A.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: @A.as.Destroy.impl.%A.as.Destroy.impl.Op.type (%A.as.Destroy.impl.Op.type) = struct_value () [symbolic = %A.as.Destroy.impl.Op (constants.%A.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%A.130 as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: @A.as.Destroy.impl.%A.as.Destroy.impl.Op.type (%A.as.Destroy.impl.Op.type) = fn_decl @A.as.Destroy.impl.Op [symbolic = @A.as.Destroy.impl.%A.as.Destroy.impl.Op (constants.%A.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @A.as.Destroy.impl.Op.%pattern_type (%pattern_type.09b) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @A.as.Destroy.impl.Op.%pattern_type (%pattern_type.09b) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @A.as.Destroy.impl.Op.%ptr (%ptr.ca9) = value_param call_param0 +// CHECK:STDOUT: %.loc12_19.2: type = splice_block %Self.ref [symbolic = %A (constants.%A.130)] { +// CHECK:STDOUT: %.loc12_19.3: type = specific_constant constants.%A.130, @A.loc12(constants.%T) [symbolic = %A (constants.%A.130)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc12_19.3 [symbolic = %A (constants.%A.130)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @A.as.Destroy.impl.Op.%ptr (%ptr.ca9) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.loc12.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A.loc4; // CHECK:STDOUT: // CHECK:STDOUT: generic class @A.loc12(%T.loc12_9.2: type) { @@ -195,6 +295,9 @@ class E(U:! type) {} // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @A.as.Destroy.impl(constants.%T) [symbolic = @A.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -204,14 +307,44 @@ class E(U:! type) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @A.as.Destroy.impl.Op(@A.loc12.%T.loc12_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %A: type = class_type @A.loc12, @A.loc12(%T) [symbolic = %A (constants.%A.130)] +// CHECK:STDOUT: %ptr: type = ptr_type %A [symbolic = %ptr (constants.%ptr.ca9)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.09b)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @A.as.Destroy.impl.Op.%ptr (%ptr.ca9)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @A.loc12(constants.%T) { // CHECK:STDOUT: %T.loc12_9.1 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @A.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %A => constants.%A.130 +// CHECK:STDOUT: %ptr => constants.%ptr.ca9 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.09b +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_mismatch_implicit_param_list.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %A: type = class_type @A [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %N.9e6: %A = bind_symbolic_name N, 0 [symbolic] @@ -225,13 +358,21 @@ class E(U:! type) {} // CHECK:STDOUT: %B.type.844c0f.2: type = generic_class_type @B.loc14 [concrete] // CHECK:STDOUT: %B.generic.ba299b.2: %B.type.844c0f.2 = struct_value () [concrete] // CHECK:STDOUT: %B.828: type = class_type @B.loc14, @B.loc14(%T, %N.f22) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.33b: = impl_witness @B.loc14.%Destroy.impl_witness_table, @B.as.Destroy.impl(%T, %N.f22) [symbolic] +// CHECK:STDOUT: %require_complete: = require_complete_type %T [symbolic] +// CHECK:STDOUT: %ptr.9e8: type = ptr_type %B.828 [symbolic] +// CHECK:STDOUT: %pattern_type.a6d: type = pattern_type %ptr.9e8 [symbolic] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op, @B.as.Destroy.impl(%T, %N.f22) [symbolic] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -258,7 +399,55 @@ class E(U:! type) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @B.as.Destroy.impl(@B.loc14.%T.loc14_9.2: type, @B.loc14.%N.loc14_19.2: @B.loc14.%T.loc14_9.1 (%T)) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %N: @B.as.Destroy.impl.%T (%T) = bind_symbolic_name N, 1 [symbolic = %N (constants.%N.f22)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @B.loc14.%Destroy.impl_witness_table, @B.as.Destroy.impl(%T, %N) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.33b)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op, @B.as.Destroy.impl(%T, %N) [symbolic = %B.as.Destroy.impl.Op.type (constants.%B.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: @B.as.Destroy.impl.%B.as.Destroy.impl.Op.type (%B.as.Destroy.impl.Op.type) = struct_value () [symbolic = %B.as.Destroy.impl.Op (constants.%B.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%B.828 as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: @B.as.Destroy.impl.%B.as.Destroy.impl.Op.type (%B.as.Destroy.impl.Op.type) = fn_decl @B.as.Destroy.impl.Op [symbolic = @B.as.Destroy.impl.%B.as.Destroy.impl.Op (constants.%B.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @B.as.Destroy.impl.Op.%pattern_type (%pattern_type.a6d) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @B.as.Destroy.impl.Op.%pattern_type (%pattern_type.a6d) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc14_26.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @B.as.Destroy.impl.Op.%ptr (%ptr.9e8) = value_param call_param0 +// CHECK:STDOUT: %.loc14_26.2: type = splice_block %Self.ref [symbolic = %B (constants.%B.828)] { +// CHECK:STDOUT: %.loc14_26.3: type = specific_constant constants.%B.828, @B.loc14(constants.%T, constants.%N.f22) [symbolic = %B (constants.%B.828)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc14_26.3 [symbolic = %B (constants.%B.828)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @B.as.Destroy.impl.Op.%ptr (%ptr.9e8) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.loc14.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -279,8 +468,12 @@ class E(U:! type) {} // CHECK:STDOUT: %pattern_type: type = pattern_type %T.loc14_9.1 [symbolic = %pattern_type (constants.%pattern_type.7dc)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type %T.loc14_9.1 [symbolic = %require_complete (constants.%require_complete)] // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @B.as.Destroy.impl(constants.%T, constants.%N.f22) [symbolic = @B.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.33b)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -290,6 +483,20 @@ class E(U:! type) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @B.as.Destroy.impl.Op(@B.loc14.%T.loc14_9.2: type, @B.loc14.%N.loc14_19.2: @B.loc14.%T.loc14_9.1 (%T)) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %N: @B.as.Destroy.impl.Op.%T (%T) = bind_symbolic_name N, 1 [symbolic = %N (constants.%N.f22)] +// CHECK:STDOUT: %B: type = class_type @B.loc14, @B.loc14(%T, %N) [symbolic = %B (constants.%B.828)] +// CHECK:STDOUT: %ptr: type = ptr_type %B [symbolic = %ptr (constants.%ptr.9e8)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.a6d)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @B.as.Destroy.impl.Op.%ptr (%ptr.9e8)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @B.loc6(constants.%N.9e6) { // CHECK:STDOUT: %N.loc6_9.1 => constants.%N.9e6 // CHECK:STDOUT: } @@ -300,10 +507,31 @@ class E(U:! type) {} // CHECK:STDOUT: %pattern_type => constants.%pattern_type.7dc // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @B.as.Destroy.impl(constants.%T, constants.%N.f22) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %N => constants.%N.f22 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.33b +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @B.as.Destroy.impl.Op(constants.%T, constants.%N.f22) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %N => constants.%N.f22 +// CHECK:STDOUT: %B => constants.%B.828 +// CHECK:STDOUT: %ptr => constants.%ptr.9e8 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.a6d +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_mismatch_param_count.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %A: type = class_type @A [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] @@ -315,13 +543,20 @@ class E(U:! type) {} // CHECK:STDOUT: %C.type.e6e560.2: type = generic_class_type @C.loc14 [concrete] // CHECK:STDOUT: %C.generic.965b12.2: %C.type.e6e560.2 = struct_value () [concrete] // CHECK:STDOUT: %C.3d8: type = class_type @C.loc14, @C.loc14(%T, %U) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.f90: = impl_witness @C.loc14.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T, %U) [symbolic] +// CHECK:STDOUT: %ptr.8f5: type = ptr_type %C.3d8 [symbolic] +// CHECK:STDOUT: %pattern_type.d5b: type = pattern_type %ptr.8f5 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T, %U) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -347,7 +582,55 @@ class E(U:! type) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.loc14.%T.loc14_9.2: type, @C.loc14.%U.loc14_19.2: %A) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %U: %A = bind_symbolic_name U, 1 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.loc14.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T, %U) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.f90)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T, %U) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.3d8 as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.d5b) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.d5b) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc14_26.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.8f5) = value_param call_param0 +// CHECK:STDOUT: %.loc14_26.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.3d8)] { +// CHECK:STDOUT: %.loc14_26.3: type = specific_constant constants.%C.3d8, @C.loc14(constants.%T, constants.%U) [symbolic = %C (constants.%C.3d8)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc14_26.3 [symbolic = %C (constants.%C.3d8)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.8f5) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.loc14.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -369,6 +652,9 @@ class E(U:! type) {} // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T, constants.%U) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.f90)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -378,6 +664,20 @@ class E(U:! type) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.loc14.%T.loc14_9.2: type, @C.loc14.%U.loc14_19.2: %A) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %U: %A = bind_symbolic_name U, 1 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %C: type = class_type @C.loc14, @C.loc14(%T, %U) [symbolic = %C (constants.%C.3d8)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.8f5)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.d5b)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.8f5)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C.loc6(constants.%T) { // CHECK:STDOUT: %T.loc6_9.1 => constants.%T // CHECK:STDOUT: } @@ -387,10 +687,31 @@ class E(U:! type) {} // CHECK:STDOUT: %U.loc14_19.1 => constants.%U // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T, constants.%U) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.f90 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T, constants.%U) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %C => constants.%C.3d8 +// CHECK:STDOUT: %ptr => constants.%ptr.8f5 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d5b +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_mismatch_param_type.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %A: type = class_type @A [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T.8b3: type = bind_symbolic_name T, 0 [symbolic] @@ -402,13 +723,20 @@ class E(U:! type) {} // CHECK:STDOUT: %D.type.bbd080.2: type = generic_class_type @D.loc14 [concrete] // CHECK:STDOUT: %D.generic.4e2319.2: %D.type.bbd080.2 = struct_value () [concrete] // CHECK:STDOUT: %D.384: type = class_type @D.loc14, @D.loc14(%T.9e6) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.7b8: = impl_witness @D.loc14.%Destroy.impl_witness_table, @D.as.Destroy.impl(%T.9e6) [symbolic] +// CHECK:STDOUT: %ptr.988: type = ptr_type %D.384 [symbolic] +// CHECK:STDOUT: %pattern_type.146: type = pattern_type %ptr.988 [symbolic] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op, @D.as.Destroy.impl(%T.9e6) [symbolic] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -432,7 +760,54 @@ class E(U:! type) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @D.as.Destroy.impl(@D.loc14.%T.loc14_9.2: %A) { +// CHECK:STDOUT: %T: %A = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.9e6)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @D.loc14.%Destroy.impl_witness_table, @D.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.7b8)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op, @D.as.Destroy.impl(%T) [symbolic = %D.as.Destroy.impl.Op.type (constants.%D.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: @D.as.Destroy.impl.%D.as.Destroy.impl.Op.type (%D.as.Destroy.impl.Op.type) = struct_value () [symbolic = %D.as.Destroy.impl.Op (constants.%D.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%D.384 as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: @D.as.Destroy.impl.%D.as.Destroy.impl.Op.type (%D.as.Destroy.impl.Op.type) = fn_decl @D.as.Destroy.impl.Op [symbolic = @D.as.Destroy.impl.%D.as.Destroy.impl.Op (constants.%D.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @D.as.Destroy.impl.Op.%pattern_type (%pattern_type.146) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @D.as.Destroy.impl.Op.%pattern_type (%pattern_type.146) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc14_16.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @D.as.Destroy.impl.Op.%ptr (%ptr.988) = value_param call_param0 +// CHECK:STDOUT: %.loc14_16.2: type = splice_block %Self.ref [symbolic = %D (constants.%D.384)] { +// CHECK:STDOUT: %.loc14_16.3: type = specific_constant constants.%D.384, @D.loc14(constants.%T.9e6) [symbolic = %D (constants.%D.384)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc14_16.3 [symbolic = %D (constants.%D.384)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @D.as.Destroy.impl.Op.%ptr (%ptr.988) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.loc14.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -453,6 +828,9 @@ class E(U:! type) {} // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @D.as.Destroy.impl(constants.%T.9e6) [symbolic = @D.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.7b8)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -462,6 +840,19 @@ class E(U:! type) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @D.as.Destroy.impl.Op(@D.loc14.%T.loc14_9.2: %A) { +// CHECK:STDOUT: %T: %A = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.9e6)] +// CHECK:STDOUT: %D: type = class_type @D.loc14, @D.loc14(%T) [symbolic = %D (constants.%D.384)] +// CHECK:STDOUT: %ptr: type = ptr_type %D [symbolic = %ptr (constants.%ptr.988)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.146)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @D.as.Destroy.impl.Op.%ptr (%ptr.988)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @D.loc6(constants.%T.8b3) { // CHECK:STDOUT: %T.loc6_9.1 => constants.%T.8b3 // CHECK:STDOUT: } @@ -470,26 +861,47 @@ class E(U:! type) {} // CHECK:STDOUT: %T.loc14_9.1 => constants.%T.9e6 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @D.as.Destroy.impl(constants.%T.9e6) { +// CHECK:STDOUT: %T => constants.%T.9e6 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.7b8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @D.as.Destroy.impl.Op(constants.%T.9e6) { +// CHECK:STDOUT: %T => constants.%T.9e6 +// CHECK:STDOUT: %D => constants.%D.384 +// CHECK:STDOUT: %ptr => constants.%ptr.988 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.146 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_mismatch_param_name.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] -// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete] +// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %E.type.b0f8dc.1: type = generic_class_type @E.loc4 [concrete] // CHECK:STDOUT: %E.generic.f281ba.1: %E.type.b0f8dc.1 = struct_value () [concrete] // CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic] // CHECK:STDOUT: %E.type.b0f8dc.2: type = generic_class_type @E.loc12 [concrete] // CHECK:STDOUT: %E.generic.f281ba.2: %E.type.b0f8dc.2 = struct_value () [concrete] // CHECK:STDOUT: %E.ec9c10.2: type = class_type @E.loc12, @E.loc12(%U) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @E.loc12.%Destroy.impl_witness_table, @E.as.Destroy.impl(%U) [symbolic] +// CHECK:STDOUT: %ptr.878: type = ptr_type %E.ec9c10.2 [symbolic] +// CHECK:STDOUT: %pattern_type.3d9: type = pattern_type %ptr.878 [symbolic] +// CHECK:STDOUT: %E.as.Destroy.impl.Op.type: type = fn_type @E.as.Destroy.impl.Op, @E.as.Destroy.impl(%U) [symbolic] +// CHECK:STDOUT: %E.as.Destroy.impl.Op: %E.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -499,17 +911,45 @@ class E(U:! type) {} // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %E.decl.loc4: %E.type.b0f8dc.1 = class_decl @E.loc4 [concrete = constants.%E.generic.f281ba.1] { -// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.loc4_9.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: } // CHECK:STDOUT: %E.decl.loc12: %E.type.b0f8dc.2 = class_decl @E.loc12 [concrete = constants.%E.generic.f281ba.2] { -// CHECK:STDOUT: %U.patt: %pattern_type = symbolic_binding_pattern U, 0 [concrete] +// CHECK:STDOUT: %U.patt: %pattern_type.98f = symbolic_binding_pattern U, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %U.loc12_9.2: type = bind_symbolic_name U, 0 [symbolic = %U.loc12_9.1 (constants.%U)] // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @E.as.Destroy.impl(@E.loc12.%U.loc12_9.2: type) { +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @E.loc12.%Destroy.impl_witness_table, @E.as.Destroy.impl(%U) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %E.as.Destroy.impl.Op.type: type = fn_type @E.as.Destroy.impl.Op, @E.as.Destroy.impl(%U) [symbolic = %E.as.Destroy.impl.Op.type (constants.%E.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %E.as.Destroy.impl.Op: @E.as.Destroy.impl.%E.as.Destroy.impl.Op.type (%E.as.Destroy.impl.Op.type) = struct_value () [symbolic = %E.as.Destroy.impl.Op (constants.%E.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%E.ec9c10.2 as constants.%Destroy.type { +// CHECK:STDOUT: %E.as.Destroy.impl.Op.decl: @E.as.Destroy.impl.%E.as.Destroy.impl.Op.type (%E.as.Destroy.impl.Op.type) = fn_decl @E.as.Destroy.impl.Op [symbolic = @E.as.Destroy.impl.%E.as.Destroy.impl.Op (constants.%E.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @E.as.Destroy.impl.Op.%pattern_type (%pattern_type.3d9) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @E.as.Destroy.impl.Op.%pattern_type (%pattern_type.3d9) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @E.as.Destroy.impl.Op.%ptr (%ptr.878) = value_param call_param0 +// CHECK:STDOUT: %.loc12_19.2: type = splice_block %Self.ref [symbolic = %E (constants.%E.ec9c10.2)] { +// CHECK:STDOUT: %.loc12_19.3: type = specific_constant constants.%E.ec9c10.2, @E.loc12(constants.%U) [symbolic = %E (constants.%E.ec9c10.2)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc12_19.3 [symbolic = %E (constants.%E.ec9c10.2)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @E.as.Destroy.impl.Op.%ptr (%ptr.878) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %E.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @E.loc12.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @E.loc4(%T.loc4_9.2: type) { // CHECK:STDOUT: %T.loc4_9.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: @@ -522,6 +962,9 @@ class E(U:! type) {} // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @E.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@E.as.Destroy.impl.%E.as.Destroy.impl.Op.decl), @E.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @E.as.Destroy.impl(constants.%U) [symbolic = @E.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -531,6 +974,17 @@ class E(U:! type) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @E.as.Destroy.impl.Op(@E.loc12.%U.loc12_9.2: type) { +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %E: type = class_type @E.loc12, @E.loc12(%U) [symbolic = %E (constants.%E.ec9c10.2)] +// CHECK:STDOUT: %ptr: type = ptr_type %E [symbolic = %ptr (constants.%ptr.878)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.3d9)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @E.as.Destroy.impl.Op.%ptr (%ptr.878)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @E.loc4(constants.%T) { // CHECK:STDOUT: %T.loc4_9.1 => constants.%T // CHECK:STDOUT: } @@ -539,3 +993,15 @@ class E(U:! type) {} // CHECK:STDOUT: %U.loc12_9.1 => constants.%U // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @E.as.Destroy.impl(constants.%U) { +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @E.as.Destroy.impl.Op(constants.%U) { +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %E => constants.%E.ec9c10.2 +// CHECK:STDOUT: %ptr => constants.%ptr.878 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.3d9 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/generic/self.carbon b/toolchain/check/testdata/class/generic/self.carbon index 6f01dd492e91..25e117b21acf 100644 --- a/toolchain/check/testdata/class/generic/self.carbon +++ b/toolchain/check/testdata/class/generic/self.carbon @@ -39,21 +39,24 @@ class Class(T:! type) { // CHECK:STDOUT: %Class.MakeClass: %Class.MakeClass.type = struct_value () [symbolic] // CHECK:STDOUT: %Class.F.type: type = fn_type @Class.F, @Class(%T) [symbolic] // CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.95a: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.955: type = ptr_type %Class [symbolic] +// CHECK:STDOUT: %pattern_type.9e0: type = pattern_type %ptr.955 [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %Class, (%Destroy.impl_witness.95a) [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %require_complete.4f8: = require_complete_type %Class [symbolic] // CHECK:STDOUT: %Class.val: %Class = struct_value () [symbolic] // CHECK:STDOUT: %Class.MakeSelf.specific_fn: = specific_function %Class.MakeSelf, @Class.MakeSelf(%T) [symbolic] // CHECK:STDOUT: %Class.MakeClass.specific_fn: = specific_function %Class.MakeClass, @Class.MakeClass(%T) [symbolic] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] -// CHECK:STDOUT: %ptr.955: type = ptr_type %Class [symbolic] +// CHECK:STDOUT: %.02c: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.specific_fn: = specific_function %Class.as.Destroy.impl.Op, @Class.as.Destroy.impl.Op(%T) [symbolic] // CHECK:STDOUT: %require_complete.2ae: = require_complete_type %ptr.955 [symbolic] -// CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %Class, @Destroy [symbolic] -// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %Class, (%Destroy.lookup_impl_witness) [symbolic] -// CHECK:STDOUT: %.d76: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet [symbolic] -// CHECK:STDOUT: %impl.elem0: %.d76 = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic] -// CHECK:STDOUT: %specific_impl_fn: = specific_impl_function %impl.elem0, @Destroy.Op(%Destroy.facet) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -78,6 +81,34 @@ class Class(T:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%T.loc15_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.95a)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = value_param call_param0 +// CHECK:STDOUT: %.loc15_23.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class)] { +// CHECK:STDOUT: %.loc15_23.3: type = specific_constant constants.%Class, @Class(constants.%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc15_23.3 [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Class(%T.loc15_13.2: type) { // CHECK:STDOUT: %T.loc15_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc15_13.1 (constants.%T)] // CHECK:STDOUT: @@ -110,6 +141,9 @@ class Class(T:! type) { // CHECK:STDOUT: %return: ref @Class.MakeClass.%Class.loc19_28.1 (%Class) = return_slot %return.param // CHECK:STDOUT: } // CHECK:STDOUT: %Class.F.decl: @Class.%Class.F.type (%Class.F.type) = fn_decl @Class.F [symbolic = @Class.%Class.F (constants.%Class.F)] {} {} +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%T) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.95a)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -172,11 +206,12 @@ class Class(T:! type) { // CHECK:STDOUT: %Class.MakeClass.type: type = fn_type @Class.MakeClass, @Class(%T) [symbolic = %Class.MakeClass.type (constants.%Class.MakeClass.type)] // CHECK:STDOUT: %Class.MakeClass: @Class.F.%Class.MakeClass.type (%Class.MakeClass.type) = struct_value () [symbolic = %Class.MakeClass (constants.%Class.MakeClass)] // CHECK:STDOUT: %Class.MakeClass.specific_fn.loc22_19.2: = specific_function %Class.MakeClass, @Class.MakeClass(%T) [symbolic = %Class.MakeClass.specific_fn.loc22_19.2 (constants.%Class.MakeClass.specific_fn)] -// CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %Class.loc21_19.2, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)] -// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %Class.loc21_19.2, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet)] -// CHECK:STDOUT: %.loc22_5.4: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [symbolic = %.loc22_5.4 (constants.%.d76)] -// CHECK:STDOUT: %impl.elem0.loc22_5.3: @Class.F.%.loc22_5.4 (%.d76) = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc22_5.3 (constants.%impl.elem0)] -// CHECK:STDOUT: %specific_impl_fn.loc22_5.3: = specific_impl_function %impl.elem0.loc22_5.3, @Destroy.Op(%Destroy.facet) [symbolic = %specific_impl_fn.loc22_5.3 (constants.%specific_impl_fn)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.95a)] +// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %Class.loc21_19.2, (%Destroy.impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet)] +// CHECK:STDOUT: %.loc22_5.2: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [symbolic = %.loc22_5.2 (constants.%.02c)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.F.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.specific_fn: = specific_function %Class.as.Destroy.impl.Op, @Class.as.Destroy.impl.Op(%T) [symbolic = %Class.as.Destroy.impl.Op.specific_fn (constants.%Class.as.Destroy.impl.Op.specific_fn)] // CHECK:STDOUT: %ptr: type = ptr_type %Class.loc21_19.2 [symbolic = %ptr (constants.%ptr.955)] // CHECK:STDOUT: %require_complete.loc22: = require_complete_type %ptr [symbolic = %require_complete.loc22 (constants.%require_complete.2ae)] // CHECK:STDOUT: @@ -190,8 +225,8 @@ class Class(T:! type) { // CHECK:STDOUT: %.loc21_23: @Class.F.%Class.MakeSelf.type (%Class.MakeSelf.type) = specific_constant @Class.%Class.MakeSelf.decl, @Class(constants.%T) [symbolic = %Class.MakeSelf (constants.%Class.MakeSelf)] // CHECK:STDOUT: %MakeSelf.ref: @Class.F.%Class.MakeSelf.type (%Class.MakeSelf.type) = name_ref MakeSelf, %.loc21_23 [symbolic = %Class.MakeSelf (constants.%Class.MakeSelf)] // CHECK:STDOUT: %Class.MakeSelf.specific_fn.loc21_23.1: = specific_function %MakeSelf.ref, @Class.MakeSelf(constants.%T) [symbolic = %Class.MakeSelf.specific_fn.loc21_23.2 (constants.%Class.MakeSelf.specific_fn)] -// CHECK:STDOUT: %.loc21_5.1: ref @Class.F.%Class.loc21_19.2 (%Class) = splice_block %c.var {} -// CHECK:STDOUT: %Class.MakeSelf.call: init @Class.F.%Class.loc21_19.2 (%Class) = call %Class.MakeSelf.specific_fn.loc21_23.1() to %.loc21_5.1 +// CHECK:STDOUT: %.loc21_5: ref @Class.F.%Class.loc21_19.2 (%Class) = splice_block %c.var {} +// CHECK:STDOUT: %Class.MakeSelf.call: init @Class.F.%Class.loc21_19.2 (%Class) = call %Class.MakeSelf.specific_fn.loc21_23.1() to %.loc21_5 // CHECK:STDOUT: assign %c.var, %Class.MakeSelf.call // CHECK:STDOUT: %.loc21_19: type = splice_block %Class.loc21_19.1 [symbolic = %Class.loc21_19.2 (constants.%Class)] { // CHECK:STDOUT: %Class.ref: %Class.type = name_ref Class, file.%Class.decl [concrete = constants.%Class.generic] @@ -215,34 +250,45 @@ class Class(T:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc22_12.2 [symbolic = %Class.loc21_19.2 (constants.%Class)] // CHECK:STDOUT: } // CHECK:STDOUT: %s: ref @Class.F.%Class.loc21_19.2 (%Class) = bind_name s, %s.var -// CHECK:STDOUT: %impl.elem0.loc22_5.1: @Class.F.%.loc22_5.4 (%.d76) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc22_5.3 (constants.%impl.elem0)] +// CHECK:STDOUT: %impl.elem0.loc22_5.1: @Class.F.%.loc22_5.2 (%.02c) = impl_witness_access constants.%Destroy.impl_witness.95a, element0 [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] // CHECK:STDOUT: %bound_method.loc22_5.1: = bound_method %.loc22_5.1, %impl.elem0.loc22_5.1 -// CHECK:STDOUT: %specific_impl_fn.loc22_5.1: = specific_impl_function %impl.elem0.loc22_5.1, @Destroy.Op(constants.%Destroy.facet) [symbolic = %specific_impl_fn.loc22_5.3 (constants.%specific_impl_fn)] -// CHECK:STDOUT: %bound_method.loc22_5.2: = bound_method %.loc22_5.1, %specific_impl_fn.loc22_5.1 +// CHECK:STDOUT: %specific_fn.loc22_5.1: = specific_function %impl.elem0.loc22_5.1, @Class.as.Destroy.impl.Op(constants.%T) [symbolic = %Class.as.Destroy.impl.Op.specific_fn (constants.%Class.as.Destroy.impl.Op.specific_fn)] +// CHECK:STDOUT: %bound_method.loc22_5.2: = bound_method %.loc22_5.1, %specific_fn.loc22_5.1 // CHECK:STDOUT: %addr.loc22_5.1: @Class.F.%ptr (%ptr.955) = addr_of %.loc22_5.1 -// CHECK:STDOUT: %.loc22_5.2: init %empty_tuple.type = call %bound_method.loc22_5.2(%addr.loc22_5.1) -// CHECK:STDOUT: %impl.elem0.loc22_5.2: @Class.F.%.loc22_5.4 (%.d76) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc22_5.3 (constants.%impl.elem0)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call.loc22_5.1: init %empty_tuple.type = call %bound_method.loc22_5.2(%addr.loc22_5.1) +// CHECK:STDOUT: %impl.elem0.loc22_5.2: @Class.F.%.loc22_5.2 (%.02c) = impl_witness_access constants.%Destroy.impl_witness.95a, element0 [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] // CHECK:STDOUT: %bound_method.loc22_5.3: = bound_method %s.var, %impl.elem0.loc22_5.2 -// CHECK:STDOUT: %specific_impl_fn.loc22_5.2: = specific_impl_function %impl.elem0.loc22_5.2, @Destroy.Op(constants.%Destroy.facet) [symbolic = %specific_impl_fn.loc22_5.3 (constants.%specific_impl_fn)] -// CHECK:STDOUT: %bound_method.loc22_5.4: = bound_method %s.var, %specific_impl_fn.loc22_5.2 +// CHECK:STDOUT: %specific_fn.loc22_5.2: = specific_function %impl.elem0.loc22_5.2, @Class.as.Destroy.impl.Op(constants.%T) [symbolic = %Class.as.Destroy.impl.Op.specific_fn (constants.%Class.as.Destroy.impl.Op.specific_fn)] +// CHECK:STDOUT: %bound_method.loc22_5.4: = bound_method %s.var, %specific_fn.loc22_5.2 // CHECK:STDOUT: %addr.loc22_5.2: @Class.F.%ptr (%ptr.955) = addr_of %s.var -// CHECK:STDOUT: %.loc22_5.3: init %empty_tuple.type = call %bound_method.loc22_5.4(%addr.loc22_5.2) -// CHECK:STDOUT: %impl.elem0.loc21_5.1: @Class.F.%.loc22_5.4 (%.d76) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc22_5.3 (constants.%impl.elem0)] -// CHECK:STDOUT: %bound_method.loc21_5.1: = bound_method %.loc21_5.1, %impl.elem0.loc21_5.1 -// CHECK:STDOUT: %specific_impl_fn.loc21_5.1: = specific_impl_function %impl.elem0.loc21_5.1, @Destroy.Op(constants.%Destroy.facet) [symbolic = %specific_impl_fn.loc22_5.3 (constants.%specific_impl_fn)] -// CHECK:STDOUT: %bound_method.loc21_5.2: = bound_method %.loc21_5.1, %specific_impl_fn.loc21_5.1 -// CHECK:STDOUT: %addr.loc21_5.1: @Class.F.%ptr (%ptr.955) = addr_of %.loc21_5.1 -// CHECK:STDOUT: %.loc21_5.2: init %empty_tuple.type = call %bound_method.loc21_5.2(%addr.loc21_5.1) -// CHECK:STDOUT: %impl.elem0.loc21_5.2: @Class.F.%.loc22_5.4 (%.d76) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc22_5.3 (constants.%impl.elem0)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call.loc22_5.2: init %empty_tuple.type = call %bound_method.loc22_5.4(%addr.loc22_5.2) +// CHECK:STDOUT: %impl.elem0.loc21_5.1: @Class.F.%.loc22_5.2 (%.02c) = impl_witness_access constants.%Destroy.impl_witness.95a, element0 [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: %bound_method.loc21_5.1: = bound_method %.loc21_5, %impl.elem0.loc21_5.1 +// CHECK:STDOUT: %specific_fn.loc21_5.1: = specific_function %impl.elem0.loc21_5.1, @Class.as.Destroy.impl.Op(constants.%T) [symbolic = %Class.as.Destroy.impl.Op.specific_fn (constants.%Class.as.Destroy.impl.Op.specific_fn)] +// CHECK:STDOUT: %bound_method.loc21_5.2: = bound_method %.loc21_5, %specific_fn.loc21_5.1 +// CHECK:STDOUT: %addr.loc21_5.1: @Class.F.%ptr (%ptr.955) = addr_of %.loc21_5 +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call.loc21_5.1: init %empty_tuple.type = call %bound_method.loc21_5.2(%addr.loc21_5.1) +// CHECK:STDOUT: %impl.elem0.loc21_5.2: @Class.F.%.loc22_5.2 (%.02c) = impl_witness_access constants.%Destroy.impl_witness.95a, element0 [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] // CHECK:STDOUT: %bound_method.loc21_5.3: = bound_method %c.var, %impl.elem0.loc21_5.2 -// CHECK:STDOUT: %specific_impl_fn.loc21_5.2: = specific_impl_function %impl.elem0.loc21_5.2, @Destroy.Op(constants.%Destroy.facet) [symbolic = %specific_impl_fn.loc22_5.3 (constants.%specific_impl_fn)] -// CHECK:STDOUT: %bound_method.loc21_5.4: = bound_method %c.var, %specific_impl_fn.loc21_5.2 +// CHECK:STDOUT: %specific_fn.loc21_5.2: = specific_function %impl.elem0.loc21_5.2, @Class.as.Destroy.impl.Op(constants.%T) [symbolic = %Class.as.Destroy.impl.Op.specific_fn (constants.%Class.as.Destroy.impl.Op.specific_fn)] +// CHECK:STDOUT: %bound_method.loc21_5.4: = bound_method %c.var, %specific_fn.loc21_5.2 // CHECK:STDOUT: %addr.loc21_5.2: @Class.F.%ptr (%ptr.955) = addr_of %c.var -// CHECK:STDOUT: %.loc21_5.3: init %empty_tuple.type = call %bound_method.loc21_5.4(%addr.loc21_5.2) +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call.loc21_5.2: init %empty_tuple.type = call %bound_method.loc21_5.4(%addr.loc21_5.2) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%T.loc15_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.955)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.9e0)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Class(constants.%T) { // CHECK:STDOUT: %T.loc15_13.1 => constants.%T // CHECK:STDOUT: @@ -277,3 +323,19 @@ class Class(T:! type) { // CHECK:STDOUT: // CHECK:STDOUT: specific @Class.F(constants.%T) {} // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.95a +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type => constants.%Class.as.Destroy.impl.Op.type +// CHECK:STDOUT: %Class.as.Destroy.impl.Op => constants.%Class.as.Destroy.impl.Op +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Class => constants.%Class +// CHECK:STDOUT: %ptr => constants.%ptr.955 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.9e0 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/generic/stringify.carbon b/toolchain/check/testdata/class/generic/stringify.carbon index 8aaede4808de..f297c921b003 100644 --- a/toolchain/check/testdata/class/generic/stringify.carbon +++ b/toolchain/check/testdata/class/generic/stringify.carbon @@ -96,11 +96,23 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %NoParams: type = class_type @NoParams [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.c82: = impl_witness @NoParams.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.4c4: type = ptr_type %NoParams [concrete] +// CHECK:STDOUT: %pattern_type.105: type = pattern_type %ptr.4c4 [concrete] +// CHECK:STDOUT: %NoParams.as.Destroy.impl.Op.type: type = fn_type @NoParams.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %NoParams.as.Destroy.impl.Op: %NoParams.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %EmptyParams.type: type = generic_class_type @EmptyParams [concrete] // CHECK:STDOUT: %EmptyParams.generic: %EmptyParams.type = struct_value () [concrete] // CHECK:STDOUT: %EmptyParams: type = class_type @EmptyParams [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.078: = impl_witness @EmptyParams.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.3ae: type = ptr_type %EmptyParams [concrete] +// CHECK:STDOUT: %pattern_type.73b: type = pattern_type %ptr.3ae [concrete] +// CHECK:STDOUT: %EmptyParams.as.Destroy.impl.Op.type: type = fn_type @EmptyParams.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %EmptyParams.as.Destroy.impl.Op: %EmptyParams.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.32d: type = pattern_type %NoParams [concrete] // CHECK:STDOUT: %pattern_type.71c: type = pattern_type %EmptyParams [concrete] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] @@ -109,10 +121,12 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -146,7 +160,42 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: %w: ref %EmptyParams = bind_name w, %w.var [concrete = %w.var] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @NoParams.as.Destroy.impl: constants.%NoParams as constants.%Destroy.type { +// CHECK:STDOUT: %NoParams.as.Destroy.impl.Op.decl: %NoParams.as.Destroy.impl.Op.type = fn_decl @NoParams.as.Destroy.impl.Op [concrete = constants.%NoParams.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.105 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.105 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.4c4 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%NoParams [concrete = constants.%NoParams] +// CHECK:STDOUT: %self: %ptr.4c4 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %NoParams.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @NoParams.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @EmptyParams.as.Destroy.impl: constants.%EmptyParams as constants.%Destroy.type { +// CHECK:STDOUT: %EmptyParams.as.Destroy.impl.Op.decl: %EmptyParams.as.Destroy.impl.Op.type = fn_decl @EmptyParams.as.Destroy.impl.Op [concrete = constants.%EmptyParams.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.73b = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.73b = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.3ae = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%EmptyParams [concrete = constants.%EmptyParams] +// CHECK:STDOUT: %self: %ptr.3ae = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %EmptyParams.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @EmptyParams.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @NoParams { +// CHECK:STDOUT: impl_decl @NoParams.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@NoParams.as.Destroy.impl.%NoParams.as.Destroy.impl.Op.decl), @NoParams.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.c82] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -156,6 +205,9 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @EmptyParams { +// CHECK:STDOUT: impl_decl @EmptyParams.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@EmptyParams.as.Destroy.impl.%EmptyParams.as.Destroy.impl.Op.decl), @EmptyParams.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.078] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -164,6 +216,10 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: .Self = constants.%EmptyParams // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @NoParams.as.Destroy.impl.Op(%self.param: %ptr.4c4) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @EmptyParams.as.Destroy.impl.Op(%self.param: %ptr.3ae) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %v.ref: ref %NoParams = name_ref v, file.%v [concrete = file.%v.var] @@ -184,8 +240,20 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: %Inner.type.eae: type = generic_class_type @Inner, @Outer(%T) [symbolic] // CHECK:STDOUT: %Inner.generic.137: %Inner.type.eae = struct_value () [symbolic] // CHECK:STDOUT: %Inner.c71: type = class_type @Inner, @Inner(%T, %U) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.de8: = impl_witness @Inner.%Destroy.impl_witness_table, @Inner.as.Destroy.impl(%T, %U) [symbolic] +// CHECK:STDOUT: %ptr.276: type = ptr_type %Inner.c71 [symbolic] +// CHECK:STDOUT: %pattern_type.01f: type = pattern_type %ptr.276 [symbolic] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.type: type = fn_type @Inner.as.Destroy.impl.Op, @Inner.as.Destroy.impl(%T, %U) [symbolic] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op: %Inner.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.a35: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.6ff: type = ptr_type %Outer.9d6 [symbolic] +// CHECK:STDOUT: %pattern_type.07e: type = pattern_type %ptr.6ff [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: %Outer.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %ptr.c28: type = ptr_type %empty_struct_type [concrete] // CHECK:STDOUT: %Outer.614: type = class_type @Outer, @Outer(%ptr.c28) [concrete] // CHECK:STDOUT: %Inner.type.5d2: type = generic_class_type @Inner, @Outer(%ptr.c28) [concrete] @@ -205,11 +273,13 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } @@ -262,6 +332,63 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: %w: ref %Inner.277 = bind_name w, %w.var [concrete = %w.var] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Inner.as.Destroy.impl(@Outer.%T.loc4_13.2: type, @Inner.%U.loc5_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 1 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Inner.%Destroy.impl_witness_table, @Inner.as.Destroy.impl(%T, %U) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.de8)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.type: type = fn_type @Inner.as.Destroy.impl.Op, @Inner.as.Destroy.impl(%T, %U) [symbolic = %Inner.as.Destroy.impl.Op.type (constants.%Inner.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op: @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.type (%Inner.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Inner.as.Destroy.impl.Op (constants.%Inner.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Inner.c71 as constants.%Destroy.type { +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.decl: @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.type (%Inner.as.Destroy.impl.Op.type) = fn_decl @Inner.as.Destroy.impl.Op [symbolic = @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op (constants.%Inner.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Inner.as.Destroy.impl.Op.%pattern_type (%pattern_type.01f) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Inner.as.Destroy.impl.Op.%pattern_type (%pattern_type.01f) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5_25.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Inner.as.Destroy.impl.Op.%ptr (%ptr.276) = value_param call_param0 +// CHECK:STDOUT: %.loc5_25.2: type = splice_block %Self.ref [symbolic = %Inner (constants.%Inner.c71)] { +// CHECK:STDOUT: %.loc5_25.3: type = specific_constant constants.%Inner.c71, @Inner(constants.%T, constants.%U) [symbolic = %Inner (constants.%Inner.c71)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc5_25.3 [symbolic = %Inner (constants.%Inner.c71)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Inner.as.Destroy.impl.Op.%ptr (%ptr.276) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Inner.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Inner.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Outer.as.Destroy.impl(@Outer.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.a35)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%T) [symbolic = %Outer.as.Destroy.impl.Op.type (constants.%Outer.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Outer.9d6 as constants.%Destroy.type { +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.decl: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = fn_decl @Outer.as.Destroy.impl.Op [symbolic = @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.07e) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.07e) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff) = value_param call_param0 +// CHECK:STDOUT: %.loc4_23.2: type = splice_block %Self.ref [symbolic = %Outer (constants.%Outer.9d6)] { +// CHECK:STDOUT: %.loc4_23.3: type = specific_constant constants.%Outer.9d6, @Outer(constants.%T) [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_23.3 [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Outer.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Outer.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Outer(%T.loc4_13.2: type) { // CHECK:STDOUT: %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: @@ -275,6 +402,9 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: } { // CHECK:STDOUT: %U.loc5_15.2: type = bind_symbolic_name U, 1 [symbolic = %U.loc5_15.1 (constants.%U)] // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Outer.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.decl), @Outer.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Outer.as.Destroy.impl(constants.%T) [symbolic = @Outer.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a35)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -291,6 +421,9 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @Inner.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.decl), @Inner.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Inner.as.Destroy.impl(constants.%T, constants.%U) [symbolic = @Inner.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.de8)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -300,6 +433,29 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Inner.as.Destroy.impl.Op(@Outer.%T.loc4_13.2: type, @Inner.%U.loc5_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 1 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Inner: type = class_type @Inner, @Inner(%T, %U) [symbolic = %Inner (constants.%Inner.c71)] +// CHECK:STDOUT: %ptr: type = ptr_type %Inner [symbolic = %ptr (constants.%ptr.276)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.01f)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Inner.as.Destroy.impl.Op.%ptr (%ptr.276)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Outer.as.Destroy.impl.Op(@Outer.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Outer: type = class_type @Outer, @Outer(%T) [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: %ptr: type = ptr_type %Outer [symbolic = %ptr (constants.%ptr.6ff)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.07e)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %v.ref: ref %Outer.614 = name_ref v, file.%v [concrete = file.%v.var] @@ -316,6 +472,32 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: %U.loc5_15.1 => constants.%U // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Inner.as.Destroy.impl(constants.%T, constants.%U) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.de8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Inner.as.Destroy.impl.Op(constants.%T, constants.%U) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Inner => constants.%Inner.c71 +// CHECK:STDOUT: %ptr => constants.%ptr.276 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.01f +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a35 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Outer => constants.%Outer.9d6 +// CHECK:STDOUT: %ptr => constants.%ptr.6ff +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.07e +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Outer(constants.%ptr.c28) { // CHECK:STDOUT: %T.loc4_13.1 => constants.%ptr.c28 // CHECK:STDOUT: @@ -343,6 +525,13 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.506: type = class_type @C, @C(%N.51e) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.1ba: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%N.51e) [symbolic] +// CHECK:STDOUT: %ptr.128: type = ptr_type %C.506 [symbolic] +// CHECK:STDOUT: %pattern_type.d64: type = pattern_type %ptr.128 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%N.51e) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %int_123.fff: Core.IntLiteral = int_value 123 [concrete] @@ -369,11 +558,13 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -415,12 +606,43 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: %v: ref %C.4c3 = bind_name v, %v.var [concrete = %v.var] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%N.loc4_9.2: %i32) { +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.51e)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%N) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.1ba)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%N) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.506 as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.d64) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.d64) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_18.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.128) = value_param call_param0 +// CHECK:STDOUT: %.loc4_18.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.506)] { +// CHECK:STDOUT: %.loc4_18.3: type = specific_constant constants.%C.506, @C(constants.%N.51e) [symbolic = %C (constants.%C.506)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_18.3 [symbolic = %C (constants.%C.506)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.128) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%N.loc4_9.2: %i32) { // CHECK:STDOUT: %N.loc4_9.1: %i32 = bind_symbolic_name N, 0 [symbolic = %N.loc4_9.1 (constants.%N.51e)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%N.51e) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.1ba)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -430,6 +652,17 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%N.loc4_9.2: %i32) { +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.51e)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%N) [symbolic = %C (constants.%C.506)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.128)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.d64)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.128)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc13_18: %empty_tuple.type = tuple_literal () @@ -442,6 +675,18 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: %N.loc4_9.1 => constants.%N.51e // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%N.51e) { +// CHECK:STDOUT: %N => constants.%N.51e +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.1ba +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%N.51e) { +// CHECK:STDOUT: %N => constants.%N.51e +// CHECK:STDOUT: %C => constants.%C.506 +// CHECK:STDOUT: %ptr => constants.%ptr.128 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d64 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%int_123.f7f) { // CHECK:STDOUT: %N.loc4_9.1 => constants.%int_123.f7f // CHECK:STDOUT: @@ -457,6 +702,13 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %D.elem: type = unbound_element_type %D, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a.b.501: type = struct_type {.a: %i32, .b: %i32} [concrete] // CHECK:STDOUT: %complete_type.705: = complete_type_witness %struct_type.a.b.501 [concrete] // CHECK:STDOUT: %F: %D = bind_symbolic_name F, 0 [symbolic] @@ -464,6 +716,11 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: %E.type: type = generic_class_type @E [concrete] // CHECK:STDOUT: %E.generic: %E.type = struct_value () [concrete] // CHECK:STDOUT: %E: type = class_type @E, @E(%F) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.a79: = impl_witness @E.%Destroy.impl_witness_table, @E.as.Destroy.impl(%F) [symbolic] +// CHECK:STDOUT: %ptr.4e0: type = ptr_type %E [symbolic] +// CHECK:STDOUT: %pattern_type.72c: type = pattern_type %ptr.4e0 [symbolic] +// CHECK:STDOUT: %E.as.Destroy.impl.Op.type: type = fn_type @E.as.Destroy.impl.Op, @E.as.Destroy.impl(%F) [symbolic] +// CHECK:STDOUT: %E.as.Destroy.impl.Op: %E.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] @@ -503,11 +760,13 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -563,6 +822,50 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: %g: = bind_name g, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @E.as.Destroy.impl(@E.%F.loc9_9.2: %D) { +// CHECK:STDOUT: %F: %D = bind_symbolic_name F, 0 [symbolic = %F (constants.%F)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @E.%Destroy.impl_witness_table, @E.as.Destroy.impl(%F) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.a79)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %E.as.Destroy.impl.Op.type: type = fn_type @E.as.Destroy.impl.Op, @E.as.Destroy.impl(%F) [symbolic = %E.as.Destroy.impl.Op.type (constants.%E.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %E.as.Destroy.impl.Op: @E.as.Destroy.impl.%E.as.Destroy.impl.Op.type (%E.as.Destroy.impl.Op.type) = struct_value () [symbolic = %E.as.Destroy.impl.Op (constants.%E.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%E as constants.%Destroy.type { +// CHECK:STDOUT: %E.as.Destroy.impl.Op.decl: @E.as.Destroy.impl.%E.as.Destroy.impl.Op.type (%E.as.Destroy.impl.Op.type) = fn_decl @E.as.Destroy.impl.Op [symbolic = @E.as.Destroy.impl.%E.as.Destroy.impl.Op (constants.%E.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @E.as.Destroy.impl.Op.%pattern_type (%pattern_type.72c) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @E.as.Destroy.impl.Op.%pattern_type (%pattern_type.72c) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9_16.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @E.as.Destroy.impl.Op.%ptr (%ptr.4e0) = value_param call_param0 +// CHECK:STDOUT: %.loc9_16.2: type = splice_block %Self.ref [symbolic = %E (constants.%E)] { +// CHECK:STDOUT: %.loc9_16.3: type = specific_constant constants.%E, @E(constants.%F) [symbolic = %E (constants.%E)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc9_16.3 [symbolic = %E (constants.%E)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @E.as.Destroy.impl.Op.%ptr (%ptr.4e0) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %E.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @E.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @D { // CHECK:STDOUT: %int_32.loc5: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -570,6 +873,9 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: %int_32.loc6: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc6: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc6: %D.elem = field_decl b, element1 [concrete] +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete = constants.%struct_type.a.b.501] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a.b [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -586,6 +892,9 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @E.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@E.as.Destroy.impl.%E.as.Destroy.impl.Op.decl), @E.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @E.as.Destroy.impl(constants.%F) [symbolic = @E.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a79)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -595,6 +904,19 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @E.as.Destroy.impl.Op(@E.%F.loc9_9.2: %D) { +// CHECK:STDOUT: %F: %D = bind_symbolic_name F, 0 [symbolic = %F (constants.%F)] +// CHECK:STDOUT: %E: type = class_type @E, @E(%F) [symbolic = %E (constants.%E)] +// CHECK:STDOUT: %ptr: type = ptr_type %E [symbolic = %ptr (constants.%ptr.4e0)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.72c)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @E.as.Destroy.impl.Op.%ptr (%ptr.4e0)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc25_31: %empty_struct_type = struct_literal () @@ -632,3 +954,15 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D); // CHECK:STDOUT: %F.loc9_9.1 => constants.%F // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @E.as.Destroy.impl(constants.%F) { +// CHECK:STDOUT: %F => constants.%F +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a79 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @E.as.Destroy.impl.Op(constants.%F) { +// CHECK:STDOUT: %F => constants.%F +// CHECK:STDOUT: %E => constants.%E +// CHECK:STDOUT: %ptr => constants.%ptr.4e0 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.72c +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/generic_method.carbon b/toolchain/check/testdata/class/generic_method.carbon index 5e6d14b6d1d8..8dd2c6787363 100644 --- a/toolchain/check/testdata/class/generic_method.carbon +++ b/toolchain/check/testdata/class/generic_method.carbon @@ -33,6 +33,13 @@ fn Class(T:! type).F[self: Self](n: T) {} // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] // CHECK:STDOUT: %Class.F.type: type = fn_type @Class.F, @Class(%T) [symbolic] // CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.955: type = ptr_type %Class [symbolic] +// CHECK:STDOUT: %pattern_type.9e0: type = pattern_type %ptr.955 [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %T} [symbolic] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a [symbolic] // CHECK:STDOUT: %require_complete.4f8: = require_complete_type %Class [symbolic] @@ -40,9 +47,11 @@ fn Class(T:! type).F[self: Self](n: T) {} // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -75,6 +84,34 @@ fn Class(T:! type).F[self: Self](n: T) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%T.loc15_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%T) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = value_param call_param0 +// CHECK:STDOUT: %.loc15_23.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class)] { +// CHECK:STDOUT: %.loc15_23.3: type = specific_constant constants.%Class, @Class(constants.%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc15_23.3 [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Class(%T.loc15_13.2: type) { // CHECK:STDOUT: %T.loc15_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc15_13.1 (constants.%T)] // CHECK:STDOUT: @@ -106,6 +143,9 @@ fn Class(T:! type).F[self: Self](n: T) {} // CHECK:STDOUT: %T.ref.loc17: type = name_ref T, @Class.%T.loc15_13.2 [symbolic = %T.loc17 (constants.%T)] // CHECK:STDOUT: %n.loc17: @Class.F.%T.loc17 (%T) = bind_name n, %n.param.loc17 // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%T) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %struct_type.a.loc18_1.1: type = struct_type {.a: %T} [symbolic = %struct_type.a.loc18_1.2 (constants.%struct_type.a)] // CHECK:STDOUT: %complete_type.loc18_1.1: = complete_type_witness %struct_type.a.loc18_1.1 [symbolic = %complete_type.loc18_1.2 (constants.%complete_type)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc18_1.1 @@ -134,6 +174,17 @@ fn Class(T:! type).F[self: Self](n: T) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%T.loc15_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.955)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.9e0)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Class(constants.%T) { // CHECK:STDOUT: %T.loc15_13.1 => constants.%T // CHECK:STDOUT: @@ -154,3 +205,15 @@ fn Class(T:! type).F[self: Self](n: T) {} // CHECK:STDOUT: %pattern_type.loc17_20 => constants.%pattern_type.7dc // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Class => constants.%Class +// CHECK:STDOUT: %ptr => constants.%ptr.955 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.9e0 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/import.carbon b/toolchain/check/testdata/class/import.carbon index c7f4196d57f8..ee5772daa6ea 100644 --- a/toolchain/check/testdata/class/import.carbon +++ b/toolchain/check/testdata/class/import.carbon @@ -57,6 +57,13 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Empty: type = class_type @Empty [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.0e8: = impl_witness @Empty.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.961: type = ptr_type %Empty [concrete] +// CHECK:STDOUT: %pattern_type.00f: type = pattern_type %ptr.961 [concrete] +// CHECK:STDOUT: %Empty.as.Destroy.impl.Op.type: type = fn_type @Empty.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Empty.as.Destroy.impl.Op: %Empty.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Field: type = class_type @Field [concrete] @@ -65,26 +72,35 @@ fn Run() { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Field.elem: type = unbound_element_type %Field, %i32 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e24: = impl_witness @Field.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.d8b: type = ptr_type %Field [concrete] +// CHECK:STDOUT: %pattern_type.8bd: type = pattern_type %ptr.d8b [concrete] +// CHECK:STDOUT: %Field.as.Destroy.impl.Op.type: type = fn_type @Field.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Field.as.Destroy.impl.Op: %Field.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.x: type = struct_type {.x: %i32} [concrete] // CHECK:STDOUT: %complete_type.1ec: = complete_type_witness %struct_type.x [concrete] // CHECK:STDOUT: %ForwardDeclared: type = class_type @ForwardDeclared [concrete] // CHECK:STDOUT: %pattern_type.1b8: type = pattern_type %ForwardDeclared [concrete] // CHECK:STDOUT: %ForwardDeclared.F.type: type = fn_type @ForwardDeclared.F [concrete] // CHECK:STDOUT: %ForwardDeclared.F: %ForwardDeclared.F.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %ForwardDeclared [concrete] -// CHECK:STDOUT: %pattern_type.ebb: type = pattern_type %ptr [concrete] -// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %ptr.6cf: type = ptr_type %ForwardDeclared [concrete] +// CHECK:STDOUT: %pattern_type.ebb: type = pattern_type %ptr.6cf [concrete] // CHECK:STDOUT: %ForwardDeclared.G.type: type = fn_type @ForwardDeclared.G [concrete] // CHECK:STDOUT: %ForwardDeclared.G: %ForwardDeclared.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.bf4: = impl_witness @ForwardDeclared.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ForwardDeclared.as.Destroy.impl.Op.type: type = fn_type @ForwardDeclared.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %ForwardDeclared.as.Destroy.impl.Op: %ForwardDeclared.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Incomplete: type = class_type @Incomplete [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -104,7 +120,58 @@ fn Run() { // CHECK:STDOUT: %Incomplete.decl: type = class_decl @Incomplete [concrete = constants.%Incomplete] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Empty.as.Destroy.impl: constants.%Empty as constants.%Destroy.type { +// CHECK:STDOUT: %Empty.as.Destroy.impl.Op.decl: %Empty.as.Destroy.impl.Op.type = fn_decl @Empty.as.Destroy.impl.Op [concrete = constants.%Empty.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.00f = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.00f = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.961 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Empty [concrete = constants.%Empty] +// CHECK:STDOUT: %self: %ptr.961 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Empty.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Empty.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Field.as.Destroy.impl: constants.%Field as constants.%Destroy.type { +// CHECK:STDOUT: %Field.as.Destroy.impl.Op.decl: %Field.as.Destroy.impl.Op.type = fn_decl @Field.as.Destroy.impl.Op [concrete = constants.%Field.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.8bd = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.8bd = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.d8b = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Field [concrete = constants.%Field] +// CHECK:STDOUT: %self: %ptr.d8b = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Field.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Field.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @ForwardDeclared.as.Destroy.impl: constants.%ForwardDeclared as constants.%Destroy.type { +// CHECK:STDOUT: %ForwardDeclared.as.Destroy.impl.Op.decl: %ForwardDeclared.as.Destroy.impl.Op.type = fn_decl @ForwardDeclared.as.Destroy.impl.Op [concrete = constants.%ForwardDeclared.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.ebb = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.ebb = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc13: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6cf = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%ForwardDeclared [concrete = constants.%ForwardDeclared] +// CHECK:STDOUT: %self: %ptr.6cf = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %ForwardDeclared.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @ForwardDeclared.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Empty { +// CHECK:STDOUT: impl_decl @Empty.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Empty.as.Destroy.impl.%Empty.as.Destroy.impl.Op.decl), @Empty.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.0e8] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -117,6 +184,9 @@ fn Run() { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc8: %Field.elem = field_decl x, element0 [concrete] +// CHECK:STDOUT: impl_decl @Field.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Field.as.Destroy.impl.%Field.as.Destroy.impl.Op.decl), @Field.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e24] // CHECK:STDOUT: %struct_type.x: type = struct_type {.x: %i32} [concrete = constants.%struct_type.x] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.x [concrete = constants.%complete_type.1ec] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -140,13 +210,16 @@ fn Run() { // CHECK:STDOUT: %self.param_patt: %pattern_type.ebb = value_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: %.loc15_8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param: %ptr = value_param call_param0 -// CHECK:STDOUT: %.loc15_23: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %self.param: %ptr.6cf = value_param call_param0 +// CHECK:STDOUT: %.loc15_23: type = splice_block %ptr [concrete = constants.%ptr.6cf] { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%ForwardDeclared [concrete = constants.%ForwardDeclared] -// CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr.6cf] // CHECK:STDOUT: } -// CHECK:STDOUT: %self: %ptr = bind_name self, %self.param +// CHECK:STDOUT: %self: %ptr.6cf = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @ForwardDeclared.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@ForwardDeclared.as.Destroy.impl.%ForwardDeclared.as.Destroy.impl.Op.decl), @ForwardDeclared.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.bf4] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -159,9 +232,15 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: class @Incomplete; // CHECK:STDOUT: +// CHECK:STDOUT: fn @Empty.as.Destroy.impl.Op(%self.param: %ptr.961) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Field.as.Destroy.impl.Op(%self.param: %ptr.d8b) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @ForwardDeclared.F(%self.param: %ForwardDeclared); // CHECK:STDOUT: -// CHECK:STDOUT: fn @ForwardDeclared.G(%self.param: %ptr); +// CHECK:STDOUT: fn @ForwardDeclared.G(%self.param: %ptr.6cf); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ForwardDeclared.as.Destroy.impl.Op(%self.param: %ptr.6cf) = "no_op"; // CHECK:STDOUT: // CHECK:STDOUT: --- b.carbon // CHECK:STDOUT: @@ -186,6 +265,7 @@ fn Run() { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.9ba: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.6da: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.6d7: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2 = struct_value () [symbolic] @@ -216,7 +296,6 @@ fn Run() { // CHECK:STDOUT: %Incomplete: type = class_type @Incomplete [concrete] // CHECK:STDOUT: %ptr.c62: type = ptr_type %Incomplete [concrete] // CHECK:STDOUT: %pattern_type.275: type = pattern_type %ptr.c62 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.7f0: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%ptr.c62) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.90d: %T.as.Destroy.impl.Op.type.7f0 = struct_value () [concrete] // CHECK:STDOUT: %ptr.c22: type = ptr_type %ptr.c62 [concrete] @@ -225,17 +304,17 @@ fn Run() { // CHECK:STDOUT: %T.as.Destroy.impl.Op.3b0: %T.as.Destroy.impl.Op.type.d2a = struct_value () [concrete] // CHECK:STDOUT: %ptr.df0: type = ptr_type %ptr.6cf [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3de: = specific_function %T.as.Destroy.impl.Op.3b0, @T.as.Destroy.impl.Op(%ptr.6cf) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.308: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%ForwardDeclared.7b34f2.1) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.9e2: %T.as.Destroy.impl.Op.type.308 = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.09a: = specific_function %T.as.Destroy.impl.Op.9e2, @T.as.Destroy.impl.Op(%ForwardDeclared.7b34f2.1) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.47c: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Field) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.576: %T.as.Destroy.impl.Op.type.47c = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.c7e: = impl_witness imports.%Destroy.impl_witness_table.e4f [concrete] +// CHECK:STDOUT: %ForwardDeclared.as.Destroy.impl.Op.type: type = fn_type @ForwardDeclared.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %ForwardDeclared.as.Destroy.impl.Op: %ForwardDeclared.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.7bf: = impl_witness imports.%Destroy.impl_witness_table.169 [concrete] +// CHECK:STDOUT: %Field.as.Destroy.impl.Op.type: type = fn_type @Field.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Field.as.Destroy.impl.Op: %Field.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.d8b: type = ptr_type %Field [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.29d: = specific_function %T.as.Destroy.impl.Op.576, @T.as.Destroy.impl.Op(%Field) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.b74: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Empty) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.6e4: %T.as.Destroy.impl.Op.type.b74 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b5a: = impl_witness imports.%Destroy.impl_witness_table.587 [concrete] +// CHECK:STDOUT: %Empty.as.Destroy.impl.Op.type: type = fn_type @Empty.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Empty.as.Destroy.impl.Op: %Empty.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.961: type = ptr_type %Empty [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1a5: = specific_function %T.as.Destroy.impl.Op.6e4, @T.as.Destroy.impl.Op(%Empty) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -252,21 +331,36 @@ fn Run() { // CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//a, loc5_1, loaded [concrete = constants.%complete_type.357] // CHECK:STDOUT: %Main.import_ref.fd7 = import_ref Main//a, inst18 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.709: = import_ref Main//a, loc9_1, loaded [concrete = constants.%complete_type.c07] -// CHECK:STDOUT: %Main.import_ref.845 = import_ref Main//a, inst24 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.845 = import_ref Main//a, inst63 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.4d2: %Field.elem = import_ref Main//a, loc8_8, loaded [concrete = %.d33] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] -// CHECK:STDOUT: %Core.import_ref.a86: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.6d7)] -// CHECK:STDOUT: %ImplicitAs.impl_witness_table.e36 = impl_witness_table (%Core.import_ref.a86), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %Core.import_ref.a86c: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.6d7)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table.e36 = impl_witness_table (%Core.import_ref.a86c), @Core.IntLiteral.as.ImplicitAs.impl [concrete] // CHECK:STDOUT: %.d33: %Field.elem = field_decl x, element0 [concrete] // CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//a, loc16_1, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Main.import_ref.39e731.1 = import_ref Main//a, inst59 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.39e731.1 = import_ref Main//a, inst113 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.760: %ForwardDeclared.F.type = import_ref Main//a, loc14_21, loaded [concrete = constants.%ForwardDeclared.F] // CHECK:STDOUT: %Main.import_ref.26e: %ForwardDeclared.G.type = import_ref Main//a, loc15_27, loaded [concrete = constants.%ForwardDeclared.G] // CHECK:STDOUT: %Main.import_ref.8f24d3.3: = import_ref Main//a, loc16_1, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Main.import_ref.39e731.2 = import_ref Main//a, inst59 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.39e731.2 = import_ref Main//a, inst113 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.42a = import_ref Main//a, loc14_21, unloaded // CHECK:STDOUT: %Main.import_ref.67a = import_ref Main//a, loc15_27, unloaded // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.9a0: = import_ref Main//a, loc4_13, loaded [concrete = constants.%Destroy.impl_witness.b5a] +// CHECK:STDOUT: %Main.import_ref.db3: type = import_ref Main//a, inst18 [no loc], loaded [concrete = constants.%Empty] +// CHECK:STDOUT: %Main.import_ref.cb9298.1: type = import_ref Main//a, inst21 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.d40: = import_ref Main//a, loc7_13, loaded [concrete = constants.%Destroy.impl_witness.7bf] +// CHECK:STDOUT: %Main.import_ref.923: type = import_ref Main//a, inst63 [no loc], loaded [concrete = constants.%Field] +// CHECK:STDOUT: %Main.import_ref.cb9298.2: type = import_ref Main//a, inst21 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.8eb: = import_ref Main//a, loc13_23, loaded [concrete = constants.%Destroy.impl_witness.c7e] +// CHECK:STDOUT: %Main.import_ref.e73: type = import_ref Main//a, inst113 [no loc], loaded [concrete = constants.%ForwardDeclared.7b34f2.1] +// CHECK:STDOUT: %Main.import_ref.cb9298.3: type = import_ref Main//a, inst21 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.dd3: %ForwardDeclared.as.Destroy.impl.Op.type = import_ref Main//a, loc13_23, loaded [concrete = constants.%ForwardDeclared.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.e4f = impl_witness_table (%Main.import_ref.dd3), @ForwardDeclared.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.006: %Field.as.Destroy.impl.Op.type = import_ref Main//a, loc7_13, loaded [concrete = constants.%Field.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.169 = impl_witness_table (%Main.import_ref.006), @Field.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.6ec: %Empty.as.Destroy.impl.Op.type = import_ref Main//a, loc4_13, loaded [concrete = constants.%Empty.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.587 = impl_witness_table (%Main.import_ref.6ec), @Empty.as.Destroy.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -283,6 +377,21 @@ fn Run() { // CHECK:STDOUT: %Run.decl: %Run.type = fn_decl @Run [concrete = constants.%Run] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Empty.as.Destroy.impl: imports.%Main.import_ref.db3 as imports.%Main.import_ref.cb9298.1 [from "a.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.9a0 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Field.as.Destroy.impl: imports.%Main.import_ref.923 as imports.%Main.import_ref.cb9298.2 [from "a.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.d40 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @ForwardDeclared.as.Destroy.impl: imports.%Main.import_ref.e73 as imports.%Main.import_ref.cb9298.3 [from "a.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.8eb +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Empty [from "a.carbon"] { // CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.1 // CHECK:STDOUT: @@ -416,21 +525,15 @@ fn Run() { // CHECK:STDOUT: %bound_method.loc16: = bound_method %d.var, %T.as.Destroy.impl.Op.specific_fn.2 // CHECK:STDOUT: %addr.loc16_3: %ptr.df0 = addr_of %d.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc16: init %empty_tuple.type = call %bound_method.loc16(%addr.loc16_3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12: = bound_method %c.var, constants.%T.as.Destroy.impl.Op.9e2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.9e2, @T.as.Destroy.impl.Op(constants.%ForwardDeclared.7b34f2.1) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.09a] -// CHECK:STDOUT: %bound_method.loc12: = bound_method %c.var, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %ForwardDeclared.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%ForwardDeclared.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc12: %ptr.6cf = addr_of %c.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12: init %empty_tuple.type = call %bound_method.loc12(%addr.loc12) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9: = bound_method %b.var, constants.%T.as.Destroy.impl.Op.576 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.4: = specific_function constants.%T.as.Destroy.impl.Op.576, @T.as.Destroy.impl.Op(constants.%Field) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.29d] -// CHECK:STDOUT: %bound_method.loc9_3: = bound_method %b.var, %T.as.Destroy.impl.Op.specific_fn.4 +// CHECK:STDOUT: %ForwardDeclared.as.Destroy.impl.Op.call: init %empty_tuple.type = call %ForwardDeclared.as.Destroy.impl.Op.bound(%addr.loc12) +// CHECK:STDOUT: %Field.as.Destroy.impl.Op.bound: = bound_method %b.var, constants.%Field.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc9: %ptr.d8b = addr_of %b.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9: init %empty_tuple.type = call %bound_method.loc9_3(%addr.loc9) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7: = bound_method %a.var, constants.%T.as.Destroy.impl.Op.6e4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.5: = specific_function constants.%T.as.Destroy.impl.Op.6e4, @T.as.Destroy.impl.Op(constants.%Empty) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.1a5] -// CHECK:STDOUT: %bound_method.loc7: = bound_method %a.var, %T.as.Destroy.impl.Op.specific_fn.5 +// CHECK:STDOUT: %Field.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Field.as.Destroy.impl.Op.bound(%addr.loc9) +// CHECK:STDOUT: %Empty.as.Destroy.impl.Op.bound: = bound_method %a.var, constants.%Empty.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc7: %ptr.961 = addr_of %a.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7: init %empty_tuple.type = call %bound_method.loc7(%addr.loc7) +// CHECK:STDOUT: %Empty.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Empty.as.Destroy.impl.Op.bound(%addr.loc7) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -438,3 +541,9 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: fn @ForwardDeclared.G [from "a.carbon"]; // CHECK:STDOUT: +// CHECK:STDOUT: fn @ForwardDeclared.as.Destroy.impl.Op = "no_op" [from "a.carbon"]; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Field.as.Destroy.impl.Op = "no_op" [from "a.carbon"]; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Empty.as.Destroy.impl.Op = "no_op" [from "a.carbon"]; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/import_base.carbon b/toolchain/check/testdata/class/import_base.carbon index d3f3250068c5..c6038d25a9b6 100644 --- a/toolchain/check/testdata/class/import_base.carbon +++ b/toolchain/check/testdata/class/import_base.carbon @@ -54,10 +54,22 @@ fn Run() { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Base.elem: type = unbound_element_type %Base, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.x.unused: type = struct_type {.x: %i32, .unused: %i32} [concrete] // CHECK:STDOUT: %complete_type.20c: = complete_type_witness %struct_type.x.unused [concrete] // CHECK:STDOUT: %Child: type = class_type @Child [concrete] // CHECK:STDOUT: %Child.elem: type = unbound_element_type %Child, %Base [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.6fe: = impl_witness @Child.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.dc0: type = ptr_type %Child [concrete] +// CHECK:STDOUT: %pattern_type.b70: type = pattern_type %ptr.dc0 [concrete] +// CHECK:STDOUT: %Child.as.Destroy.impl.Op.type: type = fn_type @Child.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Child.as.Destroy.impl.Op: %Child.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base} [concrete] // CHECK:STDOUT: %complete_type.15c: = complete_type_witness %struct_type.base [concrete] // CHECK:STDOUT: } @@ -65,10 +77,12 @@ fn Run() { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -82,6 +96,38 @@ fn Run() { // CHECK:STDOUT: %Child.decl: type = class_decl @Child [concrete = constants.%Child] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Child.as.Destroy.impl: constants.%Child as constants.%Destroy.type { +// CHECK:STDOUT: %Child.as.Destroy.impl.Op.decl: %Child.as.Destroy.impl.Op.type = fn_decl @Child.as.Destroy.impl.Op [concrete = constants.%Child.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.b70 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.b70 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.dc0 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Child [concrete = constants.%Child] +// CHECK:STDOUT: %self: %ptr.dc0 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Child.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Child.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Base { // CHECK:STDOUT: %Base.F.decl: %Base.F.type = fn_decl @Base.F [concrete = constants.%Base.F] { // CHECK:STDOUT: %self.patt: %pattern_type.bcc = binding_pattern self [concrete] @@ -105,6 +151,9 @@ fn Run() { // CHECK:STDOUT: %int_32.loc9: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc9: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc9: %Base.elem = field_decl unused, element1 [concrete] +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] // CHECK:STDOUT: %struct_type.x.unused: type = struct_type {.x: %i32, .unused: %i32} [concrete = constants.%struct_type.x.unused] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.x.unused [concrete = constants.%complete_type.20c] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -120,6 +169,9 @@ fn Run() { // CHECK:STDOUT: class @Child { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] // CHECK:STDOUT: %.loc13: %Child.elem = base_decl %Base.ref, element0 [concrete] +// CHECK:STDOUT: impl_decl @Child.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Child.as.Destroy.impl.%Child.as.Destroy.impl.Op.decl), @Child.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.6fe] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base} [concrete = constants.%struct_type.base] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.15c] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -135,6 +187,10 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: fn @Base.Unused(%self.param: %Base); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Child.as.Destroy.impl.Op(%self.param: %ptr.dc0) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- b.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -158,6 +214,7 @@ fn Run() { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.9ba: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.6da: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.6d7: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2 = struct_value () [symbolic] @@ -182,11 +239,10 @@ fn Run() { // CHECK:STDOUT: %int_2.d0d: %i32 = int_value 2 [concrete] // CHECK:STDOUT: %Base.F.type: type = fn_type @Base.F [concrete] // CHECK:STDOUT: %Base.F: %Base.F.type = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.ea2: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Child) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.c04: %T.as.Destroy.impl.Op.type.ea2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.cef: = impl_witness imports.%Destroy.impl_witness_table.ad3 [concrete] +// CHECK:STDOUT: %Child.as.Destroy.impl.Op.type: type = fn_type @Child.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Child.as.Destroy.impl.Op: %Child.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.dc0: type = ptr_type %Child [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.c04, @T.as.Destroy.impl.Op(%Child) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -205,14 +261,22 @@ fn Run() { // CHECK:STDOUT: %Main.import_ref.e67: %Base.elem = import_ref Main//a, loc8_8, loaded [concrete = %.720] // CHECK:STDOUT: %Main.import_ref.2e4 = import_ref Main//a, loc9_13, unloaded // CHECK:STDOUT: %Main.import_ref.c5f: = import_ref Main//a, loc14_1, loaded [concrete = constants.%complete_type.15c] -// CHECK:STDOUT: %Main.import_ref.9a9 = import_ref Main//a, inst73 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.9a9 = import_ref Main//a, inst111 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.7e5 = import_ref Main//a, loc13_20, unloaded // CHECK:STDOUT: %Main.import_ref.a21640.2: type = import_ref Main//a, loc13_16, loaded [concrete = constants.%Base] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] -// CHECK:STDOUT: %Core.import_ref.a86: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.6d7)] -// CHECK:STDOUT: %ImplicitAs.impl_witness_table.e36 = impl_witness_table (%Core.import_ref.a86), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %Core.import_ref.a86c: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.6d7)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table.e36 = impl_witness_table (%Core.import_ref.a86c), @Core.IntLiteral.as.ImplicitAs.impl [concrete] // CHECK:STDOUT: %.720: %Base.elem = field_decl x, element0 [concrete] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.9cd = import_ref Main//a, loc4_17, unloaded +// CHECK:STDOUT: %Main.import_ref.f8f: type = import_ref Main//a, inst18 [no loc], loaded [concrete = constants.%Base] +// CHECK:STDOUT: %Main.import_ref.cb9298.1: type = import_ref Main//a, inst70 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.9d9: = import_ref Main//a, loc12_13, loaded [concrete = constants.%Destroy.impl_witness.cef] +// CHECK:STDOUT: %Main.import_ref.19d: type = import_ref Main//a, inst111 [no loc], loaded [concrete = constants.%Child] +// CHECK:STDOUT: %Main.import_ref.cb9298.2: type = import_ref Main//a, inst70 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.141: %Child.as.Destroy.impl.Op.type = import_ref Main//a, loc12_13, loaded [concrete = constants.%Child.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.ad3 = impl_witness_table (%Main.import_ref.141), @Child.as.Destroy.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -227,6 +291,16 @@ fn Run() { // CHECK:STDOUT: %Run.decl: %Run.type = fn_decl @Run [concrete = constants.%Run] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: imports.%Main.import_ref.f8f as imports.%Main.import_ref.cb9298.1 [from "a.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.9cd +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Child.as.Destroy.impl: imports.%Main.import_ref.19d as imports.%Main.import_ref.cb9298.2 [from "a.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.9d9 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Child [from "a.carbon"] { // CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.c5f // CHECK:STDOUT: @@ -304,13 +378,13 @@ fn Run() { // CHECK:STDOUT: %.loc9_3.2: ref %Base = converted %a.ref.loc9, %.loc9_3.1 // CHECK:STDOUT: %.loc9_3.3: %Base = bind_value %.loc9_3.2 // CHECK:STDOUT: %Base.F.call: init %empty_tuple.type = call %Base.F.bound(%.loc9_3.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %a.var, constants.%T.as.Destroy.impl.Op.c04 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.c04, @T.as.Destroy.impl.Op(constants.%Child) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc7_3: = bound_method %a.var, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Child.as.Destroy.impl.Op.bound: = bound_method %a.var, constants.%Child.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.dc0 = addr_of %a.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc7_3(%addr) +// CHECK:STDOUT: %Child.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Child.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @Base.F [from "a.carbon"]; // CHECK:STDOUT: +// CHECK:STDOUT: fn @Child.as.Destroy.impl.Op = "no_op" [from "a.carbon"]; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/import_forward_decl.carbon b/toolchain/check/testdata/class/import_forward_decl.carbon index 697b5a4b7df5..2e2c546f5f9a 100644 --- a/toolchain/check/testdata/class/import_forward_decl.carbon +++ b/toolchain/check/testdata/class/import_forward_decl.carbon @@ -53,15 +53,24 @@ class ForwardDecl { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %ForwardDecl: type = class_type @ForwardDecl [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @ForwardDecl.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.83c: type = ptr_type %ForwardDecl [concrete] +// CHECK:STDOUT: %pattern_type.fd7: type = pattern_type %ptr.83c [concrete] +// CHECK:STDOUT: %ForwardDecl.as.Destroy.impl.Op.type: type = fn_type @ForwardDecl.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %ForwardDecl.as.Destroy.impl.Op: %ForwardDecl.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -75,7 +84,26 @@ class ForwardDecl { // CHECK:STDOUT: %ForwardDecl.decl: type = class_decl @ForwardDecl [concrete = constants.%ForwardDecl] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @ForwardDecl.as.Destroy.impl: constants.%ForwardDecl as constants.%Destroy.type { +// CHECK:STDOUT: %ForwardDecl.as.Destroy.impl.Op.decl: %ForwardDecl.as.Destroy.impl.Op.type = fn_decl @ForwardDecl.as.Destroy.impl.Op [concrete = constants.%ForwardDecl.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.fd7 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.fd7 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.83c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%ForwardDecl [concrete = constants.%ForwardDecl] +// CHECK:STDOUT: %self: %ptr.83c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %ForwardDecl.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @ForwardDecl.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @ForwardDecl { +// CHECK:STDOUT: impl_decl @ForwardDecl.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@ForwardDecl.as.Destroy.impl.%ForwardDecl.as.Destroy.impl.Op.decl), @ForwardDecl.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -84,3 +112,5 @@ class ForwardDecl { // CHECK:STDOUT: .Self = constants.%ForwardDecl // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @ForwardDecl.as.Destroy.impl.Op(%self.param: %ptr.83c) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/import_indirect.carbon b/toolchain/check/testdata/class/import_indirect.carbon index df78c4323bb6..6dd4fb2352de 100644 --- a/toolchain/check/testdata/class/import_indirect.carbon +++ b/toolchain/check/testdata/class/import_indirect.carbon @@ -108,15 +108,24 @@ var ptr: E* = &val; // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -128,7 +137,26 @@ var ptr: E* = &val; // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -137,6 +165,8 @@ var ptr: E* = &val; // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- b.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/class/import_member_cycle.carbon b/toolchain/check/testdata/class/import_member_cycle.carbon index b7dec052c653..4bf04221dab0 100644 --- a/toolchain/check/testdata/class/import_member_cycle.carbon +++ b/toolchain/check/testdata/class/import_member_cycle.carbon @@ -34,17 +34,25 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Cycle: type = class_type @Cycle [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %Cycle [concrete] -// CHECK:STDOUT: %Cycle.elem: type = unbound_element_type %Cycle, %ptr [concrete] -// CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %ptr} [concrete] +// CHECK:STDOUT: %ptr.257: type = ptr_type %Cycle [concrete] +// CHECK:STDOUT: %Cycle.elem: type = unbound_element_type %Cycle, %ptr.257 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Cycle.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %pattern_type.d3d: type = pattern_type %ptr.257 [concrete] +// CHECK:STDOUT: %Cycle.as.Destroy.impl.Op.type: type = fn_type @Cycle.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Cycle.as.Destroy.impl.Op: %Cycle.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %ptr.257} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -56,11 +64,30 @@ fn Run() { // CHECK:STDOUT: %Cycle.decl: type = class_decl @Cycle [concrete = constants.%Cycle] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Cycle.as.Destroy.impl: constants.%Cycle as constants.%Destroy.type { +// CHECK:STDOUT: %Cycle.as.Destroy.impl.Op.decl: %Cycle.as.Destroy.impl.Op.type = fn_decl @Cycle.as.Destroy.impl.Op [concrete = constants.%Cycle.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.d3d = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.d3d = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.257 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Cycle [concrete = constants.%Cycle] +// CHECK:STDOUT: %self: %ptr.257 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Cycle.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Cycle.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Cycle { // CHECK:STDOUT: %Cycle.ref: type = name_ref Cycle, file.%Cycle.decl [concrete = constants.%Cycle] -// CHECK:STDOUT: %ptr: type = ptr_type %Cycle.ref [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr: type = ptr_type %Cycle.ref [concrete = constants.%ptr.257] // CHECK:STDOUT: %.loc5: %Cycle.elem = field_decl a, element0 [concrete] -// CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %ptr} [concrete = constants.%struct_type.a] +// CHECK:STDOUT: impl_decl @Cycle.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Cycle.as.Destroy.impl.%Cycle.as.Destroy.impl.Op.decl), @Cycle.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] +// CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %ptr.257} [concrete = constants.%struct_type.a] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -70,6 +97,8 @@ fn Run() { // CHECK:STDOUT: .a = %.loc5 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Cycle.as.Destroy.impl.Op(%self.param: %ptr.257) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- b.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -99,6 +128,9 @@ fn Run() { // CHECK:STDOUT: %Main.import_ref.3a6 = import_ref Main//a, inst18 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.4e0 = import_ref Main//a, loc5_8, unloaded // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.4ac = import_ref Main//a, loc4_13, unloaded +// CHECK:STDOUT: %Main.import_ref.8fb: type = import_ref Main//a, inst18 [no loc], loaded [concrete = constants.%Cycle] +// CHECK:STDOUT: %Main.import_ref.cb9: type = import_ref Main//a, inst26 [no loc], loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -112,6 +144,11 @@ fn Run() { // CHECK:STDOUT: %Run.decl: %Run.type = fn_decl @Run [concrete = constants.%Run] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Cycle.as.Destroy.impl: imports.%Main.import_ref.8fb as imports.%Main.import_ref.cb9 [from "a.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.4ac +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Cycle [from "a.carbon"] { // CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.72d // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/import_struct_cyle.carbon b/toolchain/check/testdata/class/import_struct_cyle.carbon index 8ce1bec145fa..38c515335b3c 100644 --- a/toolchain/check/testdata/class/import_struct_cyle.carbon +++ b/toolchain/check/testdata/class/import_struct_cyle.carbon @@ -39,19 +39,27 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Cycle: type = class_type @Cycle [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %Cycle [concrete] -// CHECK:STDOUT: %struct_type.b: type = struct_type {.b: %ptr} [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %struct_type.b [concrete] +// CHECK:STDOUT: %ptr.257: type = ptr_type %Cycle [concrete] +// CHECK:STDOUT: %struct_type.b: type = struct_type {.b: %ptr.257} [concrete] +// CHECK:STDOUT: %pattern_type.afd: type = pattern_type %struct_type.b [concrete] // CHECK:STDOUT: %Cycle.elem: type = unbound_element_type %Cycle, %struct_type.b [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Cycle.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %pattern_type.d3d: type = pattern_type %ptr.257 [concrete] +// CHECK:STDOUT: %Cycle.as.Destroy.impl.Op.type: type = fn_type @Cycle.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Cycle.as.Destroy.impl.Op: %Cycle.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.c: type = struct_type {.c: %struct_type.b} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.c [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -63,24 +71,43 @@ fn Run() { // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %Cycle.decl.loc4: type = class_decl @Cycle [concrete = constants.%Cycle] {} {} // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %a.patt: %pattern_type = binding_pattern a [concrete] -// CHECK:STDOUT: %a.var_patt: %pattern_type = var_pattern %a.patt [concrete] +// CHECK:STDOUT: %a.patt: %pattern_type.afd = binding_pattern a [concrete] +// CHECK:STDOUT: %a.var_patt: %pattern_type.afd = var_pattern %a.patt [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %a.var: ref %struct_type.b = var %a.var_patt [concrete] // CHECK:STDOUT: %.loc6: type = splice_block %struct_type.b [concrete = constants.%struct_type.b] { // CHECK:STDOUT: %Cycle.ref: type = name_ref Cycle, %Cycle.decl.loc4 [concrete = constants.%Cycle] -// CHECK:STDOUT: %ptr: type = ptr_type %Cycle.ref [concrete = constants.%ptr] -// CHECK:STDOUT: %struct_type.b: type = struct_type {.b: %ptr} [concrete = constants.%struct_type.b] +// CHECK:STDOUT: %ptr: type = ptr_type %Cycle.ref [concrete = constants.%ptr.257] +// CHECK:STDOUT: %struct_type.b: type = struct_type {.b: %ptr.257} [concrete = constants.%struct_type.b] // CHECK:STDOUT: } // CHECK:STDOUT: %a: ref %struct_type.b = bind_name a, %a.var [concrete = %a.var] // CHECK:STDOUT: %Cycle.decl.loc8: type = class_decl @Cycle [concrete = constants.%Cycle] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Cycle.as.Destroy.impl: constants.%Cycle as constants.%Destroy.type { +// CHECK:STDOUT: %Cycle.as.Destroy.impl.Op.decl: %Cycle.as.Destroy.impl.Op.type = fn_decl @Cycle.as.Destroy.impl.Op [concrete = constants.%Cycle.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.d3d = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.d3d = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.257 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Cycle [concrete = constants.%Cycle] +// CHECK:STDOUT: %self: %ptr.257 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Cycle.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Cycle.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Cycle { // CHECK:STDOUT: %Cycle.ref: type = name_ref Cycle, file.%Cycle.decl.loc4 [concrete = constants.%Cycle] -// CHECK:STDOUT: %ptr: type = ptr_type %Cycle.ref [concrete = constants.%ptr] -// CHECK:STDOUT: %struct_type.b: type = struct_type {.b: %ptr} [concrete = constants.%struct_type.b] +// CHECK:STDOUT: %ptr: type = ptr_type %Cycle.ref [concrete = constants.%ptr.257] +// CHECK:STDOUT: %struct_type.b: type = struct_type {.b: %ptr.257} [concrete = constants.%struct_type.b] // CHECK:STDOUT: %.loc10: %Cycle.elem = field_decl c, element0 [concrete] +// CHECK:STDOUT: impl_decl @Cycle.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Cycle.as.Destroy.impl.%Cycle.as.Destroy.impl.Op.decl), @Cycle.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %struct_type.c: type = struct_type {.c: %struct_type.b} [concrete = constants.%struct_type.c] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.c [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -91,6 +118,8 @@ fn Run() { // CHECK:STDOUT: .c = %.loc10 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Cycle.as.Destroy.impl.Op(%self.param: %ptr.257) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- b.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/class/inheritance_access.carbon b/toolchain/check/testdata/class/inheritance_access.carbon index 37bfef04913c..d61683d9c5f3 100644 --- a/toolchain/check/testdata/class/inheritance_access.carbon +++ b/toolchain/check/testdata/class/inheritance_access.carbon @@ -240,6 +240,13 @@ class B { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Shape.elem: type = unbound_element_type %Shape, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.35e: = impl_witness @Shape.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.d62: type = ptr_type %Shape [concrete] +// CHECK:STDOUT: %pattern_type.77d: type = pattern_type %ptr.d62 [concrete] +// CHECK:STDOUT: %Shape.as.Destroy.impl.Op.type: type = fn_type @Shape.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Shape.as.Destroy.impl.Op: %Shape.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.x.y: type = struct_type {.x: %i32, .y: %i32} [concrete] // CHECK:STDOUT: %complete_type.70a: = complete_type_witness %struct_type.x.y [concrete] // CHECK:STDOUT: %Circle: type = class_type @Circle [concrete] @@ -250,6 +257,11 @@ class B { // CHECK:STDOUT: %pattern_type.511: type = pattern_type %tuple.type.d07 [concrete] // CHECK:STDOUT: %Circle.GetPosition.type: type = fn_type @Circle.GetPosition [concrete] // CHECK:STDOUT: %Circle.GetPosition: %Circle.GetPosition.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.2a8: = impl_witness @Circle.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.54d: type = ptr_type %Circle [concrete] +// CHECK:STDOUT: %pattern_type.f32: type = pattern_type %ptr.54d [concrete] +// CHECK:STDOUT: %Circle.as.Destroy.impl.Op.type: type = fn_type @Circle.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Circle.as.Destroy.impl.Op: %Circle.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.0ed: type = struct_type {.base: %Shape} [concrete] // CHECK:STDOUT: %complete_type.a2b: = complete_type_witness %struct_type.base.0ed [concrete] // CHECK:STDOUT: } @@ -257,10 +269,12 @@ class B { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -274,6 +288,38 @@ class B { // CHECK:STDOUT: %Circle.decl: type = class_decl @Circle [concrete = constants.%Circle] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Shape.as.Destroy.impl: constants.%Shape as constants.%Destroy.type { +// CHECK:STDOUT: %Shape.as.Destroy.impl.Op.decl: %Shape.as.Destroy.impl.Op.type = fn_decl @Shape.as.Destroy.impl.Op [concrete = constants.%Shape.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.77d = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.77d = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.d62 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Shape [concrete = constants.%Shape] +// CHECK:STDOUT: %self: %ptr.d62 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Shape.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Shape.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Circle.as.Destroy.impl: constants.%Circle as constants.%Destroy.type { +// CHECK:STDOUT: %Circle.as.Destroy.impl.Op.decl: %Circle.as.Destroy.impl.Op.type = fn_decl @Circle.as.Destroy.impl.Op [concrete = constants.%Circle.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f32 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f32 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.54d = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Circle [concrete = constants.%Circle] +// CHECK:STDOUT: %self: %ptr.54d = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Circle.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Circle.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Shape { // CHECK:STDOUT: %int_32.loc5: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -281,6 +327,9 @@ class B { // CHECK:STDOUT: %int_32.loc6: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc6: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc6: %Shape.elem = field_decl y, element1 [concrete] +// CHECK:STDOUT: impl_decl @Shape.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Shape.as.Destroy.impl.%Shape.as.Destroy.impl.Op.decl), @Shape.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.35e] // CHECK:STDOUT: %struct_type.x.y: type = struct_type {.x: %i32, .y: %i32} [concrete = constants.%struct_type.x.y] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.x.y [concrete = constants.%complete_type.70a] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -312,6 +361,9 @@ class B { // CHECK:STDOUT: %return.param: ref %tuple.type.d07 = out_param call_param1 // CHECK:STDOUT: %return: ref %tuple.type.d07 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Circle.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Circle.as.Destroy.impl.%Circle.as.Destroy.impl.Op.decl), @Circle.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.2a8] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Shape} [concrete = constants.%struct_type.base.0ed] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.a2b] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -326,6 +378,8 @@ class B { // CHECK:STDOUT: extend %Shape.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Shape.as.Destroy.impl.Op(%self.param: %ptr.d62) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Circle.GetPosition(%self.param: %Circle) -> %return.param: %tuple.type.d07 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %self.ref.loc13_13: %Circle = name_ref self, %self @@ -350,6 +404,8 @@ class B { // CHECK:STDOUT: return %.loc13_28 to %return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Circle.as.Destroy.impl.Op(%self.param: %ptr.54d) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- shadowing_access.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -357,6 +413,13 @@ class B { // CHECK:STDOUT: %A.F.type: type = fn_type @A.F [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %A.F: %A.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] @@ -368,6 +431,11 @@ class B { // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %B.F.type: type = fn_type @B.F [concrete] // CHECK:STDOUT: %B.F: %B.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.953: type = struct_type {.base: %A} [concrete] // CHECK:STDOUT: %complete_type.020: = complete_type_witness %struct_type.base.953 [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] @@ -376,10 +444,14 @@ class B { // CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete] // CHECK:STDOUT: %C.G.type: type = fn_type @C.G [concrete] // CHECK:STDOUT: %C.G: %C.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.0ff: type = struct_type {.base: %B} [concrete] // CHECK:STDOUT: %complete_type.98e: = complete_type_witness %struct_type.base.0ff [concrete] // CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a63: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%empty_tuple.type) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.ea3: %T.as.Destroy.impl.Op.type.a63 = struct_value () [concrete] // CHECK:STDOUT: %ptr.843: type = ptr_type %empty_tuple.type [concrete] @@ -388,13 +460,13 @@ class B { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { -// CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -410,8 +482,59 @@ class B { // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc13: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { // CHECK:STDOUT: %A.F.decl: %A.F.type = fn_decl @A.F [concrete = constants.%A.F] {} {} +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -433,6 +556,9 @@ class B { // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %A} [concrete = constants.%struct_type.base.953] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.020] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -462,6 +588,9 @@ class B { // CHECK:STDOUT: %return.param: ref %empty_tuple.type = out_param call_param1 // CHECK:STDOUT: %return: ref %empty_tuple.type = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %B} [concrete = constants.%struct_type.base.0ff] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.98e] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -477,8 +606,12 @@ class B { // CHECK:STDOUT: // CHECK:STDOUT: fn @A.F(); // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @B.F() -> %i32; // CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.G(%self.param: %C) -> %empty_tuple.type { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %self.ref: %C = name_ref self, %self @@ -496,6 +629,8 @@ class B { // CHECK:STDOUT: return %.loc15_45 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- inherited_member_access.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -510,6 +645,8 @@ class B { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -524,6 +661,11 @@ class B { // CHECK:STDOUT: %int_5.0f6: %i32 = int_value 5 [concrete] // CHECK:STDOUT: %A.SomeProtectedFunction.type: type = fn_type @A.SomeProtectedFunction [concrete] // CHECK:STDOUT: %A.SomeProtectedFunction: %A.SomeProtectedFunction.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] @@ -532,6 +674,11 @@ class B { // CHECK:STDOUT: %B.G: %B.G.type = struct_value () [concrete] // CHECK:STDOUT: %B.H.type: type = fn_type @B.H [concrete] // CHECK:STDOUT: %B.H: %B.H.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %A} [concrete] // CHECK:STDOUT: %complete_type.020: = complete_type_witness %struct_type.base [concrete] // CHECK:STDOUT: } @@ -540,6 +687,7 @@ class B { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -547,6 +695,7 @@ class B { // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -560,6 +709,38 @@ class B { // CHECK:STDOUT: %B.decl: type = class_decl @B [concrete = constants.%B] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %SOME_CONSTANT.patt: %pattern_type.7ce = binding_pattern SOME_CONSTANT [concrete] @@ -586,6 +767,9 @@ class B { // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -618,6 +802,9 @@ class B { // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %A} [concrete = constants.%struct_type.base] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.020] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -644,6 +831,8 @@ class B { // CHECK:STDOUT: return %.loc7_13.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @B.G() -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A] @@ -661,6 +850,8 @@ class B { // CHECK:STDOUT: return %.loc19_37.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_inherited_private_field_access.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -670,6 +861,13 @@ class B { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Shape.elem: type = unbound_element_type %Shape, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.35e: = impl_witness @Shape.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.d62: type = ptr_type %Shape [concrete] +// CHECK:STDOUT: %pattern_type.77d: type = pattern_type %ptr.d62 [concrete] +// CHECK:STDOUT: %Shape.as.Destroy.impl.Op.type: type = fn_type @Shape.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Shape.as.Destroy.impl.Op: %Shape.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.y: type = struct_type {.y: %i32} [concrete] // CHECK:STDOUT: %complete_type.0f9: = complete_type_witness %struct_type.y [concrete] // CHECK:STDOUT: %Square: type = class_type @Square [concrete] @@ -678,6 +876,11 @@ class B { // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %Square.GetPosition.type: type = fn_type @Square.GetPosition [concrete] // CHECK:STDOUT: %Square.GetPosition: %Square.GetPosition.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.17d: = impl_witness @Square.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.671: type = ptr_type %Square [concrete] +// CHECK:STDOUT: %pattern_type.dc2: type = pattern_type %ptr.671 [concrete] +// CHECK:STDOUT: %Square.as.Destroy.impl.Op.type: type = fn_type @Square.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Square.as.Destroy.impl.Op: %Square.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.0ed: type = struct_type {.base: %Shape} [concrete] // CHECK:STDOUT: %complete_type.a2b: = complete_type_witness %struct_type.base.0ed [concrete] // CHECK:STDOUT: } @@ -685,10 +888,12 @@ class B { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -702,10 +907,45 @@ class B { // CHECK:STDOUT: %Square.decl: type = class_decl @Square [concrete = constants.%Square] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Shape.as.Destroy.impl: constants.%Shape as constants.%Destroy.type { +// CHECK:STDOUT: %Shape.as.Destroy.impl.Op.decl: %Shape.as.Destroy.impl.Op.type = fn_decl @Shape.as.Destroy.impl.Op [concrete = constants.%Shape.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.77d = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.77d = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.d62 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Shape [concrete = constants.%Shape] +// CHECK:STDOUT: %self: %ptr.d62 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Shape.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Shape.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Square.as.Destroy.impl: constants.%Square as constants.%Destroy.type { +// CHECK:STDOUT: %Square.as.Destroy.impl.Op.decl: %Square.as.Destroy.impl.Op.type = fn_decl @Square.as.Destroy.impl.Op [concrete = constants.%Square.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.dc2 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.dc2 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.671 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Square [concrete = constants.%Square] +// CHECK:STDOUT: %self: %ptr.671 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Square.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Square.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Shape { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc5: %Shape.elem = field_decl y, element0 [concrete] +// CHECK:STDOUT: impl_decl @Shape.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Shape.as.Destroy.impl.%Shape.as.Destroy.impl.Op.decl), @Shape.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.35e] // CHECK:STDOUT: %struct_type.y: type = struct_type {.y: %i32} [concrete = constants.%struct_type.y] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.y [concrete = constants.%complete_type.0f9] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -732,6 +972,9 @@ class B { // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Square.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Square.as.Destroy.impl.%Square.as.Destroy.impl.Op.decl), @Square.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.17d] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Shape} [concrete = constants.%struct_type.base.0ed] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.a2b] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -745,6 +988,8 @@ class B { // CHECK:STDOUT: extend %Shape.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Shape.as.Destroy.impl.Op(%self.param: %ptr.d62) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Square.GetPosition(%self.param: %Square) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %self.ref: %Square = name_ref self, %self @@ -752,6 +997,8 @@ class B { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Square.as.Destroy.impl.Op(%self.param: %ptr.671) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- noninstance_private_on_self.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -761,15 +1008,24 @@ class B { // CHECK:STDOUT: %C.F: %C.F.type = struct_value () [concrete] // CHECK:STDOUT: %C.G.type: type = fn_type @C.G [concrete] // CHECK:STDOUT: %C.G: %C.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -781,9 +1037,28 @@ class B { // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %C.F.decl: %C.F.type = fn_decl @C.F [concrete = constants.%C.F] {} {} // CHECK:STDOUT: %C.G.decl: %C.G.type = fn_decl @C.G [concrete = constants.%C.G] {} {} +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -807,6 +1082,8 @@ class B { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- noninstance_protected_on_self.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -816,15 +1093,24 @@ class B { // CHECK:STDOUT: %C.F: %C.F.type = struct_value () [concrete] // CHECK:STDOUT: %C.G.type: type = fn_type @C.G [concrete] // CHECK:STDOUT: %C.G: %C.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -836,9 +1122,28 @@ class B { // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %C.F.decl: %C.F.type = fn_decl @C.F [concrete = constants.%C.F] {} {} // CHECK:STDOUT: %C.G.decl: %C.G.type = fn_decl @C.G [concrete = constants.%C.G] {} {} +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -862,27 +1167,43 @@ class B { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_noninstance_private_on_parent.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %B.F.type: type = fn_type @B.F [concrete] // CHECK:STDOUT: %B.F: %B.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %B [concrete] // CHECK:STDOUT: %C.G.type: type = fn_type @C.G [concrete] // CHECK:STDOUT: %C.G: %C.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.0ff: type = struct_type {.base: %B} [concrete] // CHECK:STDOUT: %complete_type.98e: = complete_type_witness %struct_type.base.0ff [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -896,8 +1217,43 @@ class B { // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %B.F.decl: %B.F.type = fn_decl @B.F [concrete = constants.%B.F] {} {} +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -911,6 +1267,9 @@ class B { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [concrete = constants.%B] // CHECK:STDOUT: %.loc9: %C.elem = base_decl %B.ref, element0 [concrete] // CHECK:STDOUT: %C.G.decl: %C.G.type = fn_decl @C.G [concrete = constants.%C.G] {} {} +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %B} [concrete = constants.%struct_type.base.0ff] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.98e] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -929,6 +1288,8 @@ class B { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.G() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] @@ -936,6 +1297,8 @@ class B { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- noninstance_protected_on_parent.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -943,21 +1306,35 @@ class B { // CHECK:STDOUT: %B.F.type: type = fn_type @B.F [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %B.F: %B.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %B [concrete] // CHECK:STDOUT: %C.G.type: type = fn_type @C.G [concrete] // CHECK:STDOUT: %C.G: %C.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.0ff: type = struct_type {.base: %B} [concrete] // CHECK:STDOUT: %complete_type.98e: = complete_type_witness %struct_type.base.0ff [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -971,8 +1348,43 @@ class B { // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @B { // CHECK:STDOUT: %B.F.decl: %B.F.type = fn_decl @B.F [concrete = constants.%B.F] {} {} +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -986,6 +1398,9 @@ class B { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [concrete = constants.%B] // CHECK:STDOUT: %.loc9: %C.elem = base_decl %B.ref, element0 [concrete] // CHECK:STDOUT: %C.G.decl: %C.G.type = fn_decl @C.G [concrete = constants.%C.G] {} {} +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %B} [concrete = constants.%struct_type.base.0ff] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.98e] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1004,6 +1419,8 @@ class B { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.G() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] @@ -1012,6 +1429,8 @@ class B { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_non_inherited_access.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -1026,6 +1445,8 @@ class B { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -1038,9 +1459,19 @@ class B { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.956, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] // CHECK:STDOUT: %bound_method: = bound_method %int_5.64b, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_5.0f6: %i32 = int_value 5 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Internal: type = class_type @Internal [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.909: = impl_witness @Internal.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.84a: type = ptr_type %Internal [concrete] +// CHECK:STDOUT: %pattern_type.e1d: type = pattern_type %ptr.84a [concrete] +// CHECK:STDOUT: %Internal.as.Destroy.impl.Op.type: type = fn_type @Internal.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Internal.as.Destroy.impl.Op: %Internal.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %B.elem: type = unbound_element_type %B, %Internal [concrete] // CHECK:STDOUT: %B.G.type: type = fn_type @B.G [concrete] @@ -1048,6 +1479,11 @@ class B { // CHECK:STDOUT: %pattern_type.049: type = pattern_type %B [concrete] // CHECK:STDOUT: %B.SomeFunc.type: type = fn_type @B.SomeFunc [concrete] // CHECK:STDOUT: %B.SomeFunc: %B.SomeFunc.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.internal.6f5: type = struct_type {.internal: %Internal} [concrete] // CHECK:STDOUT: %complete_type.d77: = complete_type_witness %struct_type.internal.6f5 [concrete] // CHECK:STDOUT: } @@ -1056,6 +1492,7 @@ class B { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -1063,6 +1500,7 @@ class B { // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1078,6 +1516,54 @@ class B { // CHECK:STDOUT: %B.decl: type = class_decl @B [concrete = constants.%B] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Internal.as.Destroy.impl: constants.%Internal as constants.%Destroy.type { +// CHECK:STDOUT: %Internal.as.Destroy.impl.Op.decl: %Internal.as.Destroy.impl.Op.type = fn_decl @Internal.as.Destroy.impl.Op [concrete = constants.%Internal.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.e1d = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.e1d = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.84a = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Internal [concrete = constants.%Internal] +// CHECK:STDOUT: %self: %ptr.84a = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Internal.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Internal.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc13: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %SOME_PROTECTED_CONSTANT.patt: %pattern_type.7ce = binding_pattern SOME_PROTECTED_CONSTANT [concrete] @@ -1111,6 +1597,9 @@ class B { // CHECK:STDOUT: %.loc6_44.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc6 [concrete = constants.%int_5.0f6] // CHECK:STDOUT: %.loc6_44.2: %i32 = converted %int_5.loc6, %.loc6_44.1 [concrete = constants.%int_5.0f6] // CHECK:STDOUT: %SOME_PRIVATE_CONSTANT: %i32 = bind_name SOME_PRIVATE_CONSTANT, %.loc6_44.2 +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1138,6 +1627,9 @@ class B { // CHECK:STDOUT: %.loc10_42.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_5.0f6] // CHECK:STDOUT: %.loc10_42.2: %i32 = converted %int_5, %.loc10_42.1 [concrete = constants.%int_5.0f6] // CHECK:STDOUT: %INTERNAL_CONSTANT: %i32 = bind_name INTERNAL_CONSTANT, %.loc10_42.2 +// CHECK:STDOUT: impl_decl @Internal.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Internal.as.Destroy.impl.%Internal.as.Destroy.impl.Op.decl), @Internal.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.909] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1173,6 +1665,9 @@ class B { // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %struct_type.internal: type = struct_type {.internal: %Internal} [concrete = constants.%struct_type.internal.6f5] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.internal [concrete = constants.%complete_type.d77] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1186,6 +1681,10 @@ class B { // CHECK:STDOUT: .A = // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Internal.as.Destroy.impl.Op(%self.param: %ptr.84a) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @B.G() -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %A.ref.loc24: type = name_ref A, file.%A.decl [concrete = constants.%A] @@ -1205,6 +1704,8 @@ class B { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_compound_member_access.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -1214,6 +1715,13 @@ class B { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %A.elem: type = unbound_element_type %A, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.x: type = struct_type {.x: %i32} [concrete] // CHECK:STDOUT: %complete_type.1ec: = complete_type_witness %struct_type.x [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] @@ -1221,6 +1729,11 @@ class B { // CHECK:STDOUT: %pattern_type.049: type = pattern_type %B [concrete] // CHECK:STDOUT: %B.F.type: type = fn_type @B.F [concrete] // CHECK:STDOUT: %B.F: %B.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.953: type = struct_type {.base: %A} [concrete] // CHECK:STDOUT: %complete_type.020: = complete_type_witness %struct_type.base.953 [concrete] // CHECK:STDOUT: } @@ -1228,10 +1741,12 @@ class B { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1245,10 +1760,45 @@ class B { // CHECK:STDOUT: %B.decl: type = class_decl @B [concrete = constants.%B] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc5: %A.elem = field_decl x, element0 [concrete] +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %struct_type.x: type = struct_type {.x: %i32} [concrete = constants.%struct_type.x] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.x [concrete = constants.%complete_type.1ec] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1270,6 +1820,9 @@ class B { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] // CHECK:STDOUT: %self: %B = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %A} [concrete = constants.%struct_type.base.953] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.020] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1282,6 +1835,8 @@ class B { // CHECK:STDOUT: extend %A.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @B.F(%self.param: %B) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %self.ref: %B = name_ref self, %self @@ -1290,6 +1845,8 @@ class B { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- inherited_compound_member_access.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -1299,6 +1856,13 @@ class B { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %A.elem: type = unbound_element_type %A, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.x: type = struct_type {.x: %i32} [concrete] // CHECK:STDOUT: %complete_type.1ec: = complete_type_witness %struct_type.x [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] @@ -1306,6 +1870,11 @@ class B { // CHECK:STDOUT: %pattern_type.049: type = pattern_type %B [concrete] // CHECK:STDOUT: %B.F.type: type = fn_type @B.F [concrete] // CHECK:STDOUT: %B.F: %B.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.953: type = struct_type {.base: %A} [concrete] // CHECK:STDOUT: %complete_type.020: = complete_type_witness %struct_type.base.953 [concrete] // CHECK:STDOUT: } @@ -1313,10 +1882,12 @@ class B { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1330,10 +1901,45 @@ class B { // CHECK:STDOUT: %B.decl: type = class_decl @B [concrete = constants.%B] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc5: %A.elem = field_decl x, element0 [concrete] +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %struct_type.x: type = struct_type {.x: %i32} [concrete = constants.%struct_type.x] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.x [concrete = constants.%complete_type.1ec] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1355,6 +1961,9 @@ class B { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] // CHECK:STDOUT: %self: %B = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %A} [concrete = constants.%struct_type.base.953] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.020] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1367,6 +1976,8 @@ class B { // CHECK:STDOUT: extend %A.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @B.F(%self.param: %B) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %self.ref: %B = name_ref self, %self @@ -1378,3 +1989,5 @@ class B { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/init.carbon b/toolchain/check/testdata/class/init.carbon index 4eeb8e59df6b..066c0e880ffe 100644 --- a/toolchain/check/testdata/class/init.carbon +++ b/toolchain/check/testdata/class/init.carbon @@ -36,10 +36,15 @@ fn MakeReorder(n: i32, next: Class*) -> Class { // CHECK:STDOUT: %Class.elem.c91: type = unbound_element_type %Class, %i32 [concrete] // CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] // CHECK:STDOUT: %Class.elem.0c0: type = unbound_element_type %Class, %ptr.e71 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.n.next: type = struct_type {.n: %i32, .next: %ptr.e71} [concrete] // CHECK:STDOUT: %complete_type.78f: = complete_type_witness %struct_type.n.next [concrete] // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] -// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] // CHECK:STDOUT: %pattern_type.761: type = pattern_type %Class [concrete] // CHECK:STDOUT: %Make.type: type = fn_type @Make [concrete] // CHECK:STDOUT: %Make: %Make.type = struct_value () [concrete] @@ -51,10 +56,12 @@ fn MakeReorder(n: i32, next: Class*) -> Class { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -116,6 +123,22 @@ fn MakeReorder(n: i32, next: Class*) -> Class { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -123,6 +146,9 @@ fn MakeReorder(n: i32, next: Class*) -> Class { // CHECK:STDOUT: %Class.ref: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] // CHECK:STDOUT: %ptr: type = ptr_type %Class.ref [concrete = constants.%ptr.e71] // CHECK:STDOUT: %.loc17: %Class.elem.0c0 = field_decl next, element1 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %struct_type.n.next: type = struct_type {.n: %i32, .next: %ptr.e71} [concrete = constants.%struct_type.n.next] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n.next [concrete = constants.%complete_type.78f] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -134,6 +160,8 @@ fn MakeReorder(n: i32, next: Class*) -> Class { // CHECK:STDOUT: .next = %.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Make(%n.param: %i32, %next.param: %ptr.e71) -> %return.param: %Class { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %n.ref: %i32 = name_ref n, %n diff --git a/toolchain/check/testdata/class/init_as.carbon b/toolchain/check/testdata/class/init_as.carbon index 92e35c2a7230..7d346546f703 100644 --- a/toolchain/check/testdata/class/init_as.carbon +++ b/toolchain/check/testdata/class/init_as.carbon @@ -31,6 +31,13 @@ fn F() -> i32 { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b40: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a.b.501: type = struct_type {.a: %i32, .b: %i32} [concrete] // CHECK:STDOUT: %complete_type.705: = complete_type_witness %struct_type.a.b.501 [concrete] // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] @@ -59,26 +66,21 @@ fn F() -> i32 { // CHECK:STDOUT: %bound_method.b92: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_2.ef8: %i32 = int_value 2 [concrete] // CHECK:STDOUT: %Class.val: %Class = struct_value (%int_1.5d2, %int_2.ef8) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.7de: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Class) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d64: %T.as.Destroy.impl.Op.type.7de = struct_value () [concrete] -// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(%Class) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -100,6 +102,22 @@ fn F() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %int_32.loc16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -107,6 +125,9 @@ fn F() -> i32 { // CHECK:STDOUT: %int_32.loc17: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc17: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc17: %Class.elem = field_decl b, element1 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b40] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete = constants.%struct_type.a.b.501] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a.b [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -117,6 +138,8 @@ fn F() -> i32 { // CHECK:STDOUT: .b = %.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] @@ -146,11 +169,9 @@ fn F() -> i32 { // CHECK:STDOUT: %a.ref: %Class.elem = name_ref a, @Class.%.loc16 [concrete = @Class.%.loc16] // CHECK:STDOUT: %.loc21_37.1: ref %i32 = class_element_access %.loc21_28, element0 // CHECK:STDOUT: %.loc21_37.2: %i32 = bind_value %.loc21_37.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc21_26.3, constants.%T.as.Destroy.impl.Op.d64 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(constants.%Class) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc21_26.5: = bound_method %.loc21_26.3, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.bound: = bound_method %.loc21_26.3, constants.%Class.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.e71 = addr_of %.loc21_26.3 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc21_26.5(%addr) +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Class.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %.loc21_37.2 // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/init_nested.carbon b/toolchain/check/testdata/class/init_nested.carbon index b87425b9b4a8..e806aeef151c 100644 --- a/toolchain/check/testdata/class/init_nested.carbon +++ b/toolchain/check/testdata/class/init_nested.carbon @@ -38,6 +38,13 @@ fn MakeOuter() -> Outer { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Inner.elem: type = unbound_element_type %Inner, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.def: = impl_witness @Inner.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.78b: type = ptr_type %Inner [concrete] +// CHECK:STDOUT: %pattern_type.6f5: type = pattern_type %ptr.78b [concrete] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.type: type = fn_type @Inner.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op: %Inner.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete] // CHECK:STDOUT: %complete_type.705: = complete_type_witness %struct_type.a.b [concrete] // CHECK:STDOUT: %pattern_type.a31: type = pattern_type %Inner [concrete] @@ -45,16 +52,16 @@ fn MakeOuter() -> Outer { // CHECK:STDOUT: %MakeInner: %MakeInner.type = struct_value () [concrete] // CHECK:STDOUT: %Outer: type = class_type @Outer [concrete] // CHECK:STDOUT: %Outer.elem: type = unbound_element_type %Outer, %Inner [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d28: = impl_witness @Outer.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.5df: type = ptr_type %Outer [concrete] +// CHECK:STDOUT: %pattern_type.95c: type = pattern_type %ptr.5df [concrete] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: %Outer.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.c.d.dce: type = struct_type {.c: %Inner, .d: %Inner} [concrete] // CHECK:STDOUT: %complete_type.8b6: = complete_type_witness %struct_type.c.d.dce [concrete] // CHECK:STDOUT: %pattern_type.e74: type = pattern_type %Outer [concrete] // CHECK:STDOUT: %MakeOuter.type: type = fn_type @MakeOuter [concrete] // CHECK:STDOUT: %MakeOuter: %MakeOuter.type = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.e24: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Inner) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.7b1: %T.as.Destroy.impl.Op.type.e24 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.78b: type = ptr_type %Inner [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.7b1, @T.as.Destroy.impl.Op(%Inner) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -97,6 +104,38 @@ fn MakeOuter() -> Outer { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Inner.as.Destroy.impl: constants.%Inner as constants.%Destroy.type { +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.decl: %Inner.as.Destroy.impl.Op.type = fn_decl @Inner.as.Destroy.impl.Op [concrete = constants.%Inner.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.6f5 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.6f5 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.78b = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Inner [concrete = constants.%Inner] +// CHECK:STDOUT: %self: %ptr.78b = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Inner.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Inner.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Outer.as.Destroy.impl: constants.%Outer as constants.%Destroy.type { +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.decl: %Outer.as.Destroy.impl.Op.type = fn_decl @Outer.as.Destroy.impl.Op [concrete = constants.%Outer.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.95c = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.95c = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc22: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.5df = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Outer [concrete = constants.%Outer] +// CHECK:STDOUT: %self: %ptr.5df = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Outer.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Outer.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Inner { // CHECK:STDOUT: %int_32.loc16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -104,6 +143,9 @@ fn MakeOuter() -> Outer { // CHECK:STDOUT: %int_32.loc17: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc17: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc17: %Inner.elem = field_decl b, element1 [concrete] +// CHECK:STDOUT: impl_decl @Inner.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.decl), @Inner.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.def] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete = constants.%struct_type.a.b] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a.b [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -119,6 +161,9 @@ fn MakeOuter() -> Outer { // CHECK:STDOUT: %.loc23: %Outer.elem = field_decl c, element0 [concrete] // CHECK:STDOUT: %Inner.ref.loc24: type = name_ref Inner, file.%Inner.decl [concrete = constants.%Inner] // CHECK:STDOUT: %.loc24: %Outer.elem = field_decl d, element1 [concrete] +// CHECK:STDOUT: impl_decl @Outer.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.decl), @Outer.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.d28] // CHECK:STDOUT: %struct_type.c.d: type = struct_type {.c: %Inner, .d: %Inner} [concrete = constants.%struct_type.c.d.dce] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.c.d [concrete = constants.%complete_type.8b6] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -130,8 +175,12 @@ fn MakeOuter() -> Outer { // CHECK:STDOUT: .d = %.loc24 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Inner.as.Destroy.impl.Op(%self.param: %ptr.78b) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @MakeInner() -> %return.param: %Inner; // CHECK:STDOUT: +// CHECK:STDOUT: fn @Outer.as.Destroy.impl.Op(%self.param: %ptr.5df) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @MakeOuter() -> %return.param: %Outer { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %MakeInner.ref.loc28_16: %MakeInner.type = name_ref MakeInner, file.%MakeInner.decl [concrete = constants.%MakeInner] @@ -143,16 +192,12 @@ fn MakeOuter() -> Outer { // CHECK:STDOUT: %.loc28_45.3: %struct_type.c.d.dce = struct_literal (%MakeInner.call.loc28_26, %MakeInner.call.loc28_44) // CHECK:STDOUT: %.loc28_45.4: init %Outer = class_init (%MakeInner.call.loc28_26, %MakeInner.call.loc28_44), %return // CHECK:STDOUT: %.loc28_46: init %Outer = converted %.loc28_45.3, %.loc28_45.4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc28_45.1: = bound_method %.loc28_45.2, constants.%T.as.Destroy.impl.Op.7b1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.7b1, @T.as.Destroy.impl.Op(constants.%Inner) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc28_45.1: = bound_method %.loc28_45.2, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.bound.loc28_45.1: = bound_method %.loc28_45.2, constants.%Inner.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc28_45.1: %ptr.78b = addr_of %.loc28_45.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc28_45.1: init %empty_tuple.type = call %bound_method.loc28_45.1(%addr.loc28_45.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc28_45.2: = bound_method %.loc28_45.1, constants.%T.as.Destroy.impl.Op.7b1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.7b1, @T.as.Destroy.impl.Op(constants.%Inner) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc28_45.2: = bound_method %.loc28_45.1, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.call.loc28_45.1: init %empty_tuple.type = call %Inner.as.Destroy.impl.Op.bound.loc28_45.1(%addr.loc28_45.1) +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.bound.loc28_45.2: = bound_method %.loc28_45.1, constants.%Inner.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc28_45.2: %ptr.78b = addr_of %.loc28_45.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc28_45.2: init %empty_tuple.type = call %bound_method.loc28_45.2(%addr.loc28_45.2) +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.call.loc28_45.2: init %empty_tuple.type = call %Inner.as.Destroy.impl.Op.bound.loc28_45.2(%addr.loc28_45.2) // CHECK:STDOUT: return %.loc28_46 to %return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/local.carbon b/toolchain/check/testdata/class/local.carbon index 0ffd81217414..105798a85372 100644 --- a/toolchain/check/testdata/class/local.carbon +++ b/toolchain/check/testdata/class/local.carbon @@ -39,6 +39,13 @@ class A { // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %A.F.type: type = fn_type @A.F [concrete] // CHECK:STDOUT: %A.F: %A.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] @@ -46,6 +53,11 @@ class A { // CHECK:STDOUT: %B.Make.type: type = fn_type @B.Make [concrete] // CHECK:STDOUT: %B.Make: %B.Make.type = struct_value () [concrete] // CHECK:STDOUT: %B.elem: type = unbound_element_type %B, %i32 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.742: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.bac: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.e9c: type = pattern_type %ptr.bac [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.n.033: type = struct_type {.n: %i32} [concrete] // CHECK:STDOUT: %complete_type.54b: = complete_type_witness %struct_type.n.033 [concrete] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] @@ -67,26 +79,21 @@ class A { // CHECK:STDOUT: %bound_method: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] // CHECK:STDOUT: %B.val: %B = struct_value (%int_1.5d2) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.96c: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%B) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.c53: %T.as.Destroy.impl.Op.type.96c = struct_value () [concrete] -// CHECK:STDOUT: %ptr.bac: type = ptr_type %B [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.c53, @T.as.Destroy.impl.Op(%B) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -98,6 +105,38 @@ class A { // CHECK:STDOUT: %A.decl: type = class_decl @A [concrete = constants.%A] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.e9c = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.e9c = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc17: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.bac = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.bac = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { // CHECK:STDOUT: %A.F.decl: %A.F.type = fn_decl @A.F [concrete = constants.%A.F] { // CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] @@ -108,6 +147,9 @@ class A { // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -129,6 +171,9 @@ class A { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc23: %B.elem = field_decl n, element0 [concrete] +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.742] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete = constants.%struct_type.n.033] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n [concrete = constants.%complete_type.54b] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -150,14 +195,14 @@ class A { // CHECK:STDOUT: %n.ref: %B.elem = name_ref n, @B.%.loc23 [concrete = @B.%.loc23] // CHECK:STDOUT: %.loc26_20.1: ref %i32 = class_element_access %.loc26_19.2, element0 // CHECK:STDOUT: %.loc26_20.2: %i32 = bind_value %.loc26_20.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc26_19.1, constants.%T.as.Destroy.impl.Op.c53 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.c53, @T.as.Destroy.impl.Op(constants.%B) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc26_19.1, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %B.as.Destroy.impl.Op.bound: = bound_method %.loc26_19.1, constants.%B.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.bac = addr_of %.loc26_19.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %B.as.Destroy.impl.Op.call: init %empty_tuple.type = call %B.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %.loc26_20.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @B.Make() -> %return.param: %B { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -182,3 +227,5 @@ class A { // CHECK:STDOUT: return %b to %return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.bac) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/method.carbon b/toolchain/check/testdata/class/method.carbon index eeac5425a6c8..b560fb861a51 100644 --- a/toolchain/check/testdata/class/method.carbon +++ b/toolchain/check/testdata/class/method.carbon @@ -81,6 +81,10 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: %Class.G.type: type = fn_type @Class.G [concrete] // CHECK:STDOUT: %Class.G: %Class.G.type = struct_value () [concrete] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b40: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.k.0bf: type = struct_type {.k: %i32} [concrete] // CHECK:STDOUT: %complete_type.954: = complete_type_witness %struct_type.k.0bf [concrete] // CHECK:STDOUT: %Call.type: type = fn_type @Call [concrete] @@ -108,10 +112,6 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: %bound_method: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] // CHECK:STDOUT: %Class.val: %Class = struct_value (%int_1.5d2) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.7de: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Class) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d64: %T.as.Destroy.impl.Op.type.7de = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(%Class) [concrete] // CHECK:STDOUT: %CallWithAddr.type: type = fn_type @CallWithAddr [concrete] // CHECK:STDOUT: %CallWithAddr: %CallWithAddr.type = struct_value () [concrete] // CHECK:STDOUT: %CallFThroughPointer.type: type = fn_type @CallFThroughPointer [concrete] @@ -129,16 +129,16 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -279,6 +279,22 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { // CHECK:STDOUT: %self.patt: %pattern_type.761 = binding_pattern self [concrete] @@ -317,6 +333,9 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc21: %Class.elem = field_decl k, element0 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b40] // CHECK:STDOUT: %struct_type.k: type = struct_type {.k: %i32} [concrete = constants.%struct_type.k.0bf] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.k [concrete = constants.%complete_type.954] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -340,6 +359,8 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: fn @Class.G(%self.param: %ptr.e71) -> %i32; // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Call(%c.param: %Class) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %c.ref: %Class = name_ref c, %c @@ -385,11 +406,9 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: %Class.F.call: init %i32 = call %Class.F.bound(%.loc39_20.2) // CHECK:STDOUT: %.loc39_33.1: %i32 = value_of_initializer %Class.F.call // CHECK:STDOUT: %.loc39_33.2: %i32 = converted %Class.F.call, %.loc39_33.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc39_18.3, constants.%T.as.Destroy.impl.Op.d64 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(constants.%Class) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc39_18.3: = bound_method %.loc39_18.3, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.bound: = bound_method %.loc39_18.3, constants.%Class.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.e71 = addr_of %.loc39_18.3 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc39_18.3(%addr) +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Class.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %.loc39_33.2 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -409,11 +428,9 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: %Class.G.call: init %i32 = call %Class.G.bound(%addr.loc44) // CHECK:STDOUT: %.loc44_15.1: %i32 = value_of_initializer %Class.G.call // CHECK:STDOUT: %.loc44_15.2: %i32 = converted %Class.G.call, %.loc44_15.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%T.as.Destroy.impl.Op.d64 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(constants.%Class) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %c.var, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%Class.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc43: %ptr.e71 = addr_of %c.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc43) +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Class.as.Destroy.impl.Op.bound(%addr.loc43) // CHECK:STDOUT: return %.loc44_15.2 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -457,11 +474,9 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: %Class.F.call: init %i32 = call %Class.F.bound(%.loc58_15.3) // CHECK:STDOUT: %.loc58_20.1: %i32 = value_of_initializer %Class.F.call // CHECK:STDOUT: %.loc58_20.2: %i32 = converted %Class.F.call, %.loc58_20.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc58_15.1, constants.%T.as.Destroy.impl.Op.d64 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(constants.%Class) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc58_15.1, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.bound: = bound_method %.loc58_15.1, constants.%Class.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.e71 = addr_of %.loc58_15.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Class.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %.loc58_20.2 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -477,11 +492,9 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: %Class.G.call: init %i32 = call %Class.G.bound(%addr.loc62_15.1) // CHECK:STDOUT: %.loc62_20.1: %i32 = value_of_initializer %Class.G.call // CHECK:STDOUT: %.loc62_20.2: %i32 = converted %Class.G.call, %.loc62_20.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc62_15.1, constants.%T.as.Destroy.impl.Op.d64 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(constants.%Class) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc62_15.1, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.bound: = bound_method %.loc62_15.1, constants.%Class.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc62_15.2: %ptr.e71 = addr_of %.loc62_15.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc62_15.2) +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Class.as.Destroy.impl.Op.bound(%addr.loc62_15.2) // CHECK:STDOUT: return %.loc62_20.2 // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/nested.carbon b/toolchain/check/testdata/class/nested.carbon index 73a998dc2e40..f442f4efd371 100644 --- a/toolchain/check/testdata/class/nested.carbon +++ b/toolchain/check/testdata/class/nested.carbon @@ -67,25 +67,26 @@ fn F(a: Outer*) { // CHECK:STDOUT: %Inner.elem.c30: type = unbound_element_type %Inner, %ptr.5df [concrete] // CHECK:STDOUT: %Inner.G.type: type = fn_type @Inner.G [concrete] // CHECK:STDOUT: %Inner.G: %Inner.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.75f: = impl_witness @Inner.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %pattern_type.27f: type = pattern_type %ptr.36a [concrete] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.type: type = fn_type @Inner.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op: %Inner.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.pi.po.qi: type = struct_type {.pi: %ptr.36a, .po: %ptr.5df, .qi: %ptr.36a} [concrete] // CHECK:STDOUT: %complete_type.7ae: = complete_type_witness %struct_type.pi.po.qi [concrete] // CHECK:STDOUT: %Outer.H.type: type = fn_type @Outer.H [concrete] // CHECK:STDOUT: %Outer.H: %Outer.H.type = struct_value () [concrete] // CHECK:STDOUT: %Outer.elem.a16: type = unbound_element_type %Outer, %ptr.5df [concrete] // CHECK:STDOUT: %Outer.elem.fe9: type = unbound_element_type %Outer, %ptr.36a [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d28: = impl_witness @Outer.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %pattern_type.95c: type = pattern_type %ptr.5df [concrete] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: %Outer.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.po.qo.pi: type = struct_type {.po: %ptr.5df, .qo: %ptr.5df, .pi: %ptr.36a} [concrete] // CHECK:STDOUT: %complete_type.e99: = complete_type_witness %struct_type.po.qo.pi [concrete] // CHECK:STDOUT: %pattern_type.e74: type = pattern_type %Outer [concrete] // CHECK:STDOUT: %pattern_type.906: type = pattern_type %Inner [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.9bc: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Inner) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.754: %T.as.Destroy.impl.Op.type.9bc = struct_value () [concrete] -// CHECK:STDOUT: %pattern_type.27f: type = pattern_type %ptr.36a [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.72f: = specific_function %T.as.Destroy.impl.Op.754, @T.as.Destroy.impl.Op(%Inner) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.50c: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Outer) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.8d4: %T.as.Destroy.impl.Op.type.50c = struct_value () [concrete] -// CHECK:STDOUT: %pattern_type.95c: type = pattern_type %ptr.5df [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2a1: = specific_function %T.as.Destroy.impl.Op.8d4, @T.as.Destroy.impl.Op(%Outer) [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -120,6 +121,38 @@ fn F(a: Outer*) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Inner.as.Destroy.impl: constants.%Inner as constants.%Destroy.type { +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.decl: %Inner.as.Destroy.impl.Op.type = fn_decl @Inner.as.Destroy.impl.Op [concrete = constants.%Inner.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.27f = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.27f = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc22: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.36a = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Inner [concrete = constants.%Inner] +// CHECK:STDOUT: %self: %ptr.36a = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Inner.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Inner.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Outer.as.Destroy.impl: constants.%Outer as constants.%Destroy.type { +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.decl: %Outer.as.Destroy.impl.Op.type = fn_decl @Outer.as.Destroy.impl.Op [concrete = constants.%Outer.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.95c = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.95c = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.5df = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Outer [concrete = constants.%Outer] +// CHECK:STDOUT: %self: %ptr.5df = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Outer.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Outer.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Outer { // CHECK:STDOUT: %Outer.F.decl: %Outer.F.type = fn_decl @Outer.F [concrete = constants.%Outer.F] {} {} // CHECK:STDOUT: %Inner.decl: type = class_decl @Inner [concrete = constants.%Inner] {} {} @@ -133,6 +166,9 @@ fn F(a: Outer*) { // CHECK:STDOUT: %Inner.ref: type = name_ref Inner, %Inner.decl [concrete = constants.%Inner] // CHECK:STDOUT: %ptr.loc42: type = ptr_type %Inner.ref [concrete = constants.%ptr.36a] // CHECK:STDOUT: %.loc42: %Outer.elem.fe9 = field_decl pi, element2 [concrete] +// CHECK:STDOUT: impl_decl @Outer.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.decl), @Outer.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.d28] // CHECK:STDOUT: %struct_type.po.qo.pi: type = struct_type {.po: %ptr.5df, .qo: %ptr.5df, .pi: %ptr.36a} [concrete = constants.%struct_type.po.qo.pi] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.po.qo.pi [concrete = constants.%complete_type.e99] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -159,6 +195,9 @@ fn F(a: Outer*) { // CHECK:STDOUT: %ptr.loc25: type = ptr_type %Inner.ref [concrete = constants.%ptr.36a] // CHECK:STDOUT: %.loc25: %Inner.elem.640 = field_decl qi, element2 [concrete] // CHECK:STDOUT: %Inner.G.decl: %Inner.G.type = fn_decl @Inner.G [concrete = constants.%Inner.G] {} {} +// CHECK:STDOUT: impl_decl @Inner.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.decl), @Inner.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.75f] // CHECK:STDOUT: %struct_type.pi.po.qi: type = struct_type {.pi: %ptr.36a, .po: %ptr.5df, .qi: %ptr.36a} [concrete = constants.%struct_type.pi.po.qi] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.pi.po.qi [concrete = constants.%complete_type.7ae] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -189,16 +228,12 @@ fn F(a: Outer*) { // CHECK:STDOUT: %i.var: ref %Inner = var %i.var_patt // CHECK:STDOUT: %Inner.ref: type = name_ref Inner, @Outer.%Inner.decl [concrete = constants.%Inner] // CHECK:STDOUT: %i: ref %Inner = bind_name i, %i.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc19: = bound_method %i.var, constants.%T.as.Destroy.impl.Op.754 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.754, @T.as.Destroy.impl.Op(constants.%Inner) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.72f] -// CHECK:STDOUT: %bound_method.loc19: = bound_method %i.var, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.bound: = bound_method %i.var, constants.%Inner.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc19: %ptr.36a = addr_of %i.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc19: init %empty_tuple.type = call %bound_method.loc19(%addr.loc19) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc18: = bound_method %o.var, constants.%T.as.Destroy.impl.Op.8d4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.8d4, @T.as.Destroy.impl.Op(constants.%Outer) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.2a1] -// CHECK:STDOUT: %bound_method.loc18: = bound_method %o.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Inner.as.Destroy.impl.Op.bound(%addr.loc19) +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.bound: = bound_method %o.var, constants.%Outer.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc18: %ptr.5df = addr_of %o.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc18: init %empty_tuple.type = call %bound_method.loc18(%addr.loc18) +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Outer.as.Destroy.impl.Op.bound(%addr.loc18) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -218,19 +253,17 @@ fn F(a: Outer*) { // CHECK:STDOUT: %i.var: ref %Inner = var %i.var_patt // CHECK:STDOUT: %Inner.ref: type = name_ref Inner, @Outer.%Inner.decl [concrete = constants.%Inner] // CHECK:STDOUT: %i: ref %Inner = bind_name i, %i.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc30: = bound_method %i.var, constants.%T.as.Destroy.impl.Op.754 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.754, @T.as.Destroy.impl.Op(constants.%Inner) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.72f] -// CHECK:STDOUT: %bound_method.loc30: = bound_method %i.var, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.bound: = bound_method %i.var, constants.%Inner.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc30: %ptr.36a = addr_of %i.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc30: init %empty_tuple.type = call %bound_method.loc30(%addr.loc30) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc29: = bound_method %o.var, constants.%T.as.Destroy.impl.Op.8d4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.8d4, @T.as.Destroy.impl.Op(constants.%Outer) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.2a1] -// CHECK:STDOUT: %bound_method.loc29: = bound_method %o.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Inner.as.Destroy.impl.Op.bound(%addr.loc30) +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.bound: = bound_method %o.var, constants.%Outer.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc29: %ptr.5df = addr_of %o.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc29: init %empty_tuple.type = call %bound_method.loc29(%addr.loc29) +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Outer.as.Destroy.impl.Op.bound(%addr.loc29) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Inner.as.Destroy.impl.Op(%self.param: %ptr.36a) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Outer.H() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -247,19 +280,17 @@ fn F(a: Outer*) { // CHECK:STDOUT: %i.var: ref %Inner = var %i.var_patt // CHECK:STDOUT: %Inner.ref: type = name_ref Inner, @Outer.%Inner.decl [concrete = constants.%Inner] // CHECK:STDOUT: %i: ref %Inner = bind_name i, %i.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc37: = bound_method %i.var, constants.%T.as.Destroy.impl.Op.754 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.754, @T.as.Destroy.impl.Op(constants.%Inner) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.72f] -// CHECK:STDOUT: %bound_method.loc37: = bound_method %i.var, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.bound: = bound_method %i.var, constants.%Inner.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc37: %ptr.36a = addr_of %i.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc37: init %empty_tuple.type = call %bound_method.loc37(%addr.loc37) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc36: = bound_method %o.var, constants.%T.as.Destroy.impl.Op.8d4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.8d4, @T.as.Destroy.impl.Op(constants.%Outer) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.2a1] -// CHECK:STDOUT: %bound_method.loc36: = bound_method %o.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Inner.as.Destroy.impl.Op.bound(%addr.loc37) +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.bound: = bound_method %o.var, constants.%Outer.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc36: %ptr.5df = addr_of %o.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc36: init %empty_tuple.type = call %bound_method.loc36(%addr.loc36) +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Outer.as.Destroy.impl.Op.bound(%addr.loc36) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Outer.as.Destroy.impl.Op(%self.param: %ptr.5df) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%a.param: %ptr.5df) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { diff --git a/toolchain/check/testdata/class/nested_name.carbon b/toolchain/check/testdata/class/nested_name.carbon index e0534a39bad9..799cb358eb7c 100644 --- a/toolchain/check/testdata/class/nested_name.carbon +++ b/toolchain/check/testdata/class/nested_name.carbon @@ -37,8 +37,20 @@ fn G(o: Outer) { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Inner.elem: type = unbound_element_type %Inner, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.75f: = impl_witness @Inner.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.36a: type = ptr_type %Inner [concrete] +// CHECK:STDOUT: %pattern_type.27f: type = pattern_type %ptr.36a [concrete] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.type: type = fn_type @Inner.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op: %Inner.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete] // CHECK:STDOUT: %complete_type.54b: = complete_type_witness %struct_type.n [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d28: = impl_witness @Outer.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.5df: type = ptr_type %Outer [concrete] +// CHECK:STDOUT: %pattern_type.95c: type = pattern_type %ptr.5df [concrete] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: %Outer.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.906: type = pattern_type %Inner [concrete] @@ -48,11 +60,6 @@ fn G(o: Outer) { // CHECK:STDOUT: %pattern_type.e74: type = pattern_type %Outer [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.9bc: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Inner) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.754: %T.as.Destroy.impl.Op.type.9bc = struct_value () [concrete] -// CHECK:STDOUT: %ptr.36a: type = ptr_type %Inner [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.754, @T.as.Destroy.impl.Op(%Inner) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -102,8 +109,43 @@ fn G(o: Outer) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Inner.as.Destroy.impl: constants.%Inner as constants.%Destroy.type { +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.decl: %Inner.as.Destroy.impl.Op.type = fn_decl @Inner.as.Destroy.impl.Op [concrete = constants.%Inner.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.27f = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.27f = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc16: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.36a = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Inner [concrete = constants.%Inner] +// CHECK:STDOUT: %self: %ptr.36a = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Inner.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Inner.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Outer.as.Destroy.impl: constants.%Outer as constants.%Destroy.type { +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.decl: %Outer.as.Destroy.impl.Op.type = fn_decl @Outer.as.Destroy.impl.Op [concrete = constants.%Outer.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.95c = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.95c = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.5df = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Outer [concrete = constants.%Outer] +// CHECK:STDOUT: %self: %ptr.5df = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Outer.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Outer.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Outer { // CHECK:STDOUT: %Inner.decl: type = class_decl @Inner [concrete = constants.%Inner] {} {} +// CHECK:STDOUT: impl_decl @Outer.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.decl), @Outer.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.d28] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -117,6 +159,9 @@ fn G(o: Outer) { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc17: %Inner.elem = field_decl n, element0 [concrete] +// CHECK:STDOUT: impl_decl @Inner.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.decl), @Inner.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.75f] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete = constants.%struct_type.n] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n [concrete = constants.%complete_type.54b] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -126,6 +171,10 @@ fn G(o: Outer) { // CHECK:STDOUT: .n = %.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Inner.as.Destroy.impl.Op(%self.param: %ptr.36a) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Outer.as.Destroy.impl.Op(%self.param: %ptr.5df) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%oi.param: %Inner) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %oi.ref: %Inner = name_ref oi, %oi @@ -147,11 +196,9 @@ fn G(o: Outer) { // CHECK:STDOUT: %Inner.ref: type = name_ref Inner, @Outer.%Inner.decl [concrete = constants.%Inner] // CHECK:STDOUT: } // CHECK:STDOUT: %i: ref %Inner = bind_name i, %i.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %i.var, constants.%T.as.Destroy.impl.Op.754 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.754, @T.as.Destroy.impl.Op(constants.%Inner) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %i.var, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.bound: = bound_method %i.var, constants.%Inner.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.36a = addr_of %i.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Inner.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/partial.carbon b/toolchain/check/testdata/class/partial.carbon index eba65cc3d3a3..2d22828b41c1 100644 --- a/toolchain/check/testdata/class/partial.carbon +++ b/toolchain/check/testdata/class/partial.carbon @@ -171,7 +171,7 @@ fn F[T:! type](p: partial T*); // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %.43f: type = partial_type %C [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %.43f [concrete] +// CHECK:STDOUT: %pattern_type.249: type = pattern_type %.43f [concrete] // CHECK:STDOUT: %A.type: type = fn_type @A [concrete] // CHECK:STDOUT: %A: %A.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -181,8 +181,8 @@ fn F[T:! type](p: partial T*); // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: %A.decl: %A.type = fn_decl @A [concrete = constants.%A] { -// CHECK:STDOUT: %p.patt: %pattern_type = binding_pattern p [concrete] -// CHECK:STDOUT: %p.param_patt: %pattern_type = value_param_pattern %p.patt, call_param0 [concrete] +// CHECK:STDOUT: %p.patt: %pattern_type.249 = binding_pattern p [concrete] +// CHECK:STDOUT: %p.param_patt: %pattern_type.249 = value_param_pattern %p.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %p.param: %.43f = value_param call_param0 // CHECK:STDOUT: %.loc6_9.1: type = splice_block %.loc6_9.2 [concrete = constants.%.43f] { @@ -200,7 +200,7 @@ fn F[T:! type](p: partial T*); // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %.43f: type = partial_type %C [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %.43f [concrete] +// CHECK:STDOUT: %pattern_type.249: type = pattern_type %.43f [concrete] // CHECK:STDOUT: %A.type: type = fn_type @A [concrete] // CHECK:STDOUT: %A: %A.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -210,8 +210,8 @@ fn F[T:! type](p: partial T*); // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: %A.decl: %A.type = fn_decl @A [concrete = constants.%A] { -// CHECK:STDOUT: %p.patt: %pattern_type = binding_pattern p [concrete] -// CHECK:STDOUT: %p.param_patt: %pattern_type = value_param_pattern %p.patt, call_param0 [concrete] +// CHECK:STDOUT: %p.patt: %pattern_type.249 = binding_pattern p [concrete] +// CHECK:STDOUT: %p.param_patt: %pattern_type.249 = value_param_pattern %p.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %p.param: %.43f = value_param call_param0 // CHECK:STDOUT: %.loc6_9.1: type = splice_block %.loc6_9.2 [concrete = constants.%.43f] { @@ -229,7 +229,7 @@ fn F[T:! type](p: partial T*); // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %.43f: type = partial_type %C [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %.43f [concrete] +// CHECK:STDOUT: %pattern_type.249: type = pattern_type %.43f [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -239,8 +239,8 @@ fn F[T:! type](p: partial T*); // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] { -// CHECK:STDOUT: %p.patt: %pattern_type = binding_pattern p [concrete] -// CHECK:STDOUT: %p.param_patt: %pattern_type = value_param_pattern %p.patt, call_param0 [concrete] +// CHECK:STDOUT: %p.patt: %pattern_type.249 = binding_pattern p [concrete] +// CHECK:STDOUT: %p.param_patt: %pattern_type.249 = value_param_pattern %p.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %p.param: %.43f = value_param call_param0 // CHECK:STDOUT: %.loc10_9.1: type = splice_block %.loc10_9.2 [concrete = constants.%.43f] { @@ -258,7 +258,7 @@ fn F[T:! type](p: partial T*); // CHECK:STDOUT: constants { // CHECK:STDOUT: %Derived: type = class_type @Derived [concrete] // CHECK:STDOUT: %.604: type = partial_type %Derived [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %.604 [concrete] +// CHECK:STDOUT: %pattern_type.f79: type = pattern_type %.604 [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -268,8 +268,8 @@ fn F[T:! type](p: partial T*); // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] { -// CHECK:STDOUT: %p.patt: %pattern_type = binding_pattern p [concrete] -// CHECK:STDOUT: %p.param_patt: %pattern_type = value_param_pattern %p.patt, call_param0 [concrete] +// CHECK:STDOUT: %p.patt: %pattern_type.f79 = binding_pattern p [concrete] +// CHECK:STDOUT: %p.param_patt: %pattern_type.f79 = value_param_pattern %p.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %p.param: %.604 = value_param call_param0 // CHECK:STDOUT: %.loc13_9.1: type = splice_block %.loc13_9.2 [concrete = constants.%.604] { @@ -382,7 +382,7 @@ fn F[T:! type](p: partial T*); // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %.43f: type = partial_type %C [concrete] // CHECK:STDOUT: %.a34: type = partial_type %.43f [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %.a34 [concrete] +// CHECK:STDOUT: %pattern_type.2e7: type = pattern_type %.a34 [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -392,8 +392,8 @@ fn F[T:! type](p: partial T*); // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %p.patt: %pattern_type = binding_pattern p [concrete] -// CHECK:STDOUT: %p.param_patt: %pattern_type = value_param_pattern %p.patt, call_param0 [concrete] +// CHECK:STDOUT: %p.patt: %pattern_type.2e7 = binding_pattern p [concrete] +// CHECK:STDOUT: %p.param_patt: %pattern_type.2e7 = value_param_pattern %p.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %p.param: %.a34 = value_param call_param0 // CHECK:STDOUT: %.loc10_9.1: type = splice_block %.loc10_9.2 [concrete = constants.%.a34] { diff --git a/toolchain/check/testdata/class/raw_self.carbon b/toolchain/check/testdata/class/raw_self.carbon index 0ce2af41e14e..25171b325fc1 100644 --- a/toolchain/check/testdata/class/raw_self.carbon +++ b/toolchain/check/testdata/class/raw_self.carbon @@ -47,6 +47,10 @@ fn Class.G[self: Self](r#self: i32) -> (i32, i32) { // CHECK:STDOUT: %Class.G.type: type = fn_type @Class.G [concrete] // CHECK:STDOUT: %Class.G: %Class.G.type = struct_value () [concrete] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete] // CHECK:STDOUT: %complete_type.54b: = complete_type_witness %struct_type.n [concrete] // CHECK:STDOUT: } @@ -54,10 +58,12 @@ fn Class.G[self: Self](r#self: i32) -> (i32, i32) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -115,6 +121,22 @@ fn Class.G[self: Self](r#self: i32) -> (i32, i32) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { // CHECK:STDOUT: %self.patt.loc21_17: %pattern_type.796 = binding_pattern self [concrete] @@ -165,6 +187,9 @@ fn Class.G[self: Self](r#self: i32) -> (i32, i32) { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc18: %Class.elem = field_decl n, element0 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete = constants.%struct_type.n] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n [concrete = constants.%complete_type.54b] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -204,3 +229,5 @@ fn Class.G[self: Self](r#self: i32) -> (i32, i32) { // CHECK:STDOUT: return %.loc26_26 to %return.loc25 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/raw_self_type.carbon b/toolchain/check/testdata/class/raw_self_type.carbon index 1a11695dd327..0ade617d5ba2 100644 --- a/toolchain/check/testdata/class/raw_self_type.carbon +++ b/toolchain/check/testdata/class/raw_self_type.carbon @@ -34,21 +34,35 @@ fn MemberNamedSelf.F(x: Self, y: r#Self) {} // CHECK:STDOUT: %Class.F.type: type = fn_type @Class.F [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b40: = impl_witness @Class.%Destroy.impl_witness_table [concrete] // CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] // CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.faa: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%ptr.e71) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.5a3: %T.as.Destroy.impl.Op.type.faa = struct_value () [concrete] // CHECK:STDOUT: %ptr.0dd: type = ptr_type %ptr.e71 [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5a3, @T.as.Destroy.impl.Op(%ptr.e71) [concrete] // CHECK:STDOUT: %MemberNamedSelf: type = class_type @MemberNamedSelf [concrete] // CHECK:STDOUT: %Self.362: type = class_type @Self [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.077: = impl_witness @Self.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.fbf: type = ptr_type %Self.362 [concrete] +// CHECK:STDOUT: %pattern_type.364: type = pattern_type %ptr.fbf [concrete] +// CHECK:STDOUT: %Self.as.Destroy.impl.Op.type: type = fn_type @Self.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Self.as.Destroy.impl.Op: %Self.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.356: type = pattern_type %MemberNamedSelf [concrete] // CHECK:STDOUT: %pattern_type.c06: type = pattern_type %Self.362 [concrete] // CHECK:STDOUT: %MemberNamedSelf.F.type: type = fn_type @MemberNamedSelf.F [concrete] // CHECK:STDOUT: %MemberNamedSelf.F: %MemberNamedSelf.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.a94: = impl_witness @MemberNamedSelf.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.9b1: type = ptr_type %MemberNamedSelf [concrete] +// CHECK:STDOUT: %pattern_type.64a: type = pattern_type %ptr.9b1 [concrete] +// CHECK:STDOUT: %MemberNamedSelf.as.Destroy.impl.Op.type: type = fn_type @MemberNamedSelf.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %MemberNamedSelf.as.Destroy.impl.Op: %MemberNamedSelf.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -84,8 +98,59 @@ fn MemberNamedSelf.F(x: Self, y: r#Self) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Self.as.Destroy.impl: constants.%Self.362 as constants.%Destroy.type { +// CHECK:STDOUT: %Self.as.Destroy.impl.Op.decl: %Self.as.Destroy.impl.Op.type = fn_decl @Self.as.Destroy.impl.Op [concrete = constants.%Self.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.364 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.364 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc23: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.fbf = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Self.362 [concrete = constants.%Self.362] +// CHECK:STDOUT: %self: %ptr.fbf = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Self.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Self.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @MemberNamedSelf.as.Destroy.impl: constants.%MemberNamedSelf as constants.%Destroy.type { +// CHECK:STDOUT: %MemberNamedSelf.as.Destroy.impl.Op.decl: %MemberNamedSelf.as.Destroy.impl.Op.type = fn_decl @MemberNamedSelf.as.Destroy.impl.Op [concrete = constants.%MemberNamedSelf.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.64a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.64a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc22: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.9b1 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%MemberNamedSelf [concrete = constants.%MemberNamedSelf] +// CHECK:STDOUT: %self: %ptr.9b1 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %MemberNamedSelf.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @MemberNamedSelf.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] {} {} +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b40] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -110,6 +175,9 @@ fn MemberNamedSelf.F(x: Self, y: r#Self) {} // CHECK:STDOUT: %Self.ref.loc25_20: type = name_ref r#Self, @MemberNamedSelf.%Self.decl [concrete = constants.%Self.362] // CHECK:STDOUT: %y.loc25: %Self.362 = bind_name y, %y.param.loc25 // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @MemberNamedSelf.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@MemberNamedSelf.as.Destroy.impl.%MemberNamedSelf.as.Destroy.impl.Op.decl), @MemberNamedSelf.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.a94] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -121,6 +189,9 @@ fn MemberNamedSelf.F(x: Self, y: r#Self) {} // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Self { +// CHECK:STDOUT: impl_decl @Self.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Self.as.Destroy.impl.%Self.as.Destroy.impl.Op.decl), @Self.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.077] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -167,8 +238,14 @@ fn MemberNamedSelf.F(x: Self, y: r#Self) {} // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Self.as.Destroy.impl.Op(%self.param: %ptr.fbf) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @MemberNamedSelf.F(%x.param.loc28: %MemberNamedSelf, %y.param.loc28: %Self.362) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @MemberNamedSelf.as.Destroy.impl.Op(%self.param: %ptr.9b1) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/redeclaration.carbon b/toolchain/check/testdata/class/redeclaration.carbon index dc1ff75045d8..4e326f025f74 100644 --- a/toolchain/check/testdata/class/redeclaration.carbon +++ b/toolchain/check/testdata/class/redeclaration.carbon @@ -29,15 +29,24 @@ fn Class.F[self: Self](b: ()) {} // CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete] // CHECK:STDOUT: %Class.F.type: type = fn_type @Class.F [concrete] // CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -66,6 +75,22 @@ fn Class.F[self: Self](b: ()) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc17: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { // CHECK:STDOUT: %self.patt: %pattern_type.761 = binding_pattern self [concrete] @@ -83,6 +108,9 @@ fn Class.F[self: Self](b: ()) {} // CHECK:STDOUT: } // CHECK:STDOUT: %b.loc18: %empty_tuple.type = bind_name b, %b.param.loc18 // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -97,3 +125,5 @@ fn Class.F[self: Self](b: ()) {} // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/redeclaration_introducer.carbon b/toolchain/check/testdata/class/redeclaration_introducer.carbon index 6bfb4d184aec..20bc99e93b67 100644 --- a/toolchain/check/testdata/class/redeclaration_introducer.carbon +++ b/toolchain/check/testdata/class/redeclaration_introducer.carbon @@ -26,15 +26,34 @@ abstract class C {} // CHECK:STDOUT: %A: type = class_type @A [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -53,7 +72,58 @@ abstract class C {} // CHECK:STDOUT: %C.decl.loc21: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc19: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc20: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc21: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -63,6 +133,9 @@ abstract class C {} // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @B { +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -72,6 +145,9 @@ abstract class C {} // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -80,3 +156,9 @@ abstract class C {} // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/reenter_scope.carbon b/toolchain/check/testdata/class/reenter_scope.carbon index 6e06abba2da9..f13a76a990bb 100644 --- a/toolchain/check/testdata/class/reenter_scope.carbon +++ b/toolchain/check/testdata/class/reenter_scope.carbon @@ -35,6 +35,13 @@ fn Class.F() -> i32 { // CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [concrete] // CHECK:STDOUT: %Class.G.type: type = fn_type @Class.G [concrete] // CHECK:STDOUT: %Class.G: %Class.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } @@ -42,10 +49,12 @@ fn Class.F() -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -66,6 +75,22 @@ fn Class.F() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { // CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] @@ -85,6 +110,9 @@ fn Class.F() -> i32 { // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -109,3 +137,5 @@ fn Class.F() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: fn @Class.G() -> %i32; // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/reorder.carbon b/toolchain/check/testdata/class/reorder.carbon index ecaca4a85eb8..70b0a06e6bdb 100644 --- a/toolchain/check/testdata/class/reorder.carbon +++ b/toolchain/check/testdata/class/reorder.carbon @@ -35,6 +35,13 @@ class Class { // CHECK:STDOUT: %Class.G: %Class.G.type = struct_value () [concrete] // CHECK:STDOUT: %Class.F.type: type = fn_type @Class.F [concrete] // CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b40: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] @@ -59,11 +66,13 @@ class Class { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -78,6 +87,22 @@ class Class { // CHECK:STDOUT: %Class.decl: type = class_decl @Class [concrete = constants.%Class] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %Class.G.decl: %Class.G.type = fn_decl @Class.G [concrete = constants.%Class.G] { // CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] @@ -97,6 +122,9 @@ class Class { // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b40] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -131,3 +159,5 @@ class Class { // CHECK:STDOUT: return %.loc21_13.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/reorder_qualified.carbon b/toolchain/check/testdata/class/reorder_qualified.carbon index 86ecc67b9e84..49698fa13842 100644 --- a/toolchain/check/testdata/class/reorder_qualified.carbon +++ b/toolchain/check/testdata/class/reorder_qualified.carbon @@ -64,6 +64,13 @@ class A { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %B.elem: type = unbound_element_type %B, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d1a: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.01b: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.11c: type = pattern_type %ptr.01b [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.b.0a3: type = struct_type {.b: %i32} [concrete] // CHECK:STDOUT: %complete_type.ba8: = complete_type_witness %struct_type.b.0a3 [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] @@ -72,16 +79,31 @@ class A { // CHECK:STDOUT: %D.DF.type: type = fn_type @D.DF [concrete] // CHECK:STDOUT: %D.DF: %D.DF.type = struct_value () [concrete] // CHECK:STDOUT: %D.elem: type = unbound_element_type %D, %i32 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.74b: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.321: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.37e: type = pattern_type %ptr.321 [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.d.b7b: type = struct_type {.d: %i32} [concrete] // CHECK:STDOUT: %complete_type.860: = complete_type_witness %struct_type.d.b7b [concrete] // CHECK:STDOUT: %C.CF.type: type = fn_type @C.CF [concrete] // CHECK:STDOUT: %C.CF: %C.CF.type = struct_value () [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %i32 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.898: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.388: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.093: type = pattern_type %ptr.388 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.c.b66: type = struct_type {.c: %i32} [concrete] // CHECK:STDOUT: %complete_type.836: = complete_type_witness %struct_type.c.b66 [concrete] // CHECK:STDOUT: %A.AF.type: type = fn_type @A.AF [concrete] // CHECK:STDOUT: %A.AF: %A.AF.type = struct_value () [concrete] // CHECK:STDOUT: %A.elem: type = unbound_element_type %A, %i32 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a.ba9: type = struct_type {.a: %i32} [concrete] // CHECK:STDOUT: %complete_type.fd7: = complete_type_witness %struct_type.a.ba9 [concrete] // CHECK:STDOUT: %pattern_type.c10: type = pattern_type %A [concrete] @@ -125,38 +147,21 @@ class A { // CHECK:STDOUT: %bound_method.1da: = bound_method %int_4.0c1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_4.940: %i32 = int_value 4 [concrete] // CHECK:STDOUT: %D.val: %D = struct_value (%int_4.940) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.7e3: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%D) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.47c: %T.as.Destroy.impl.Op.type.7e3 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.321: type = ptr_type %D [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.ceb: = specific_function %T.as.Destroy.impl.Op.47c, @T.as.Destroy.impl.Op(%D) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.2eb: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.f77: %T.as.Destroy.impl.Op.type.2eb = struct_value () [concrete] -// CHECK:STDOUT: %ptr.388: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.c65: = specific_function %T.as.Destroy.impl.Op.f77, @T.as.Destroy.impl.Op(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.266: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%B) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.4a4: %T.as.Destroy.impl.Op.type.266 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.01b: type = ptr_type %B [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.70c: = specific_function %T.as.Destroy.impl.Op.4a4, @T.as.Destroy.impl.Op(%B) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.b96: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%A) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.885: %T.as.Destroy.impl.Op.type.b96 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.716: = specific_function %T.as.Destroy.impl.Op.885, @T.as.Destroy.impl.Op(%A) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -168,6 +173,70 @@ class A { // CHECK:STDOUT: %A.decl: type = class_decl @A [concrete = constants.%A] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.11c = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.11c = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc16: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.01b = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.01b = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.37e = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.37e = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc24: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.321 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.321 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.093 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.093 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc23: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.388 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.388 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { // CHECK:STDOUT: %B.decl: type = class_decl @B [concrete = constants.%B] {} {} // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} @@ -175,6 +244,9 @@ class A { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc50: %A.elem = field_decl a, element0 [concrete] +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %i32} [concrete = constants.%struct_type.a.ba9] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a [concrete = constants.%complete_type.fd7] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -193,6 +265,9 @@ class A { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc20: %B.elem = field_decl b, element0 [concrete] +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.d1a] // CHECK:STDOUT: %struct_type.b: type = struct_type {.b: %i32} [concrete = constants.%struct_type.b.0a3] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.b [concrete = constants.%complete_type.ba8] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -214,6 +289,9 @@ class A { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc46: %C.elem = field_decl c, element0 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.898] // CHECK:STDOUT: %struct_type.c: type = struct_type {.c: %i32} [concrete = constants.%struct_type.c.b66] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.c [concrete = constants.%complete_type.836] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -236,6 +314,9 @@ class A { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc28: %D.elem = field_decl d, element0 [concrete] +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.74b] // CHECK:STDOUT: %struct_type.d: type = struct_type {.d: %i32} [concrete = constants.%struct_type.d.b7b] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.d [concrete = constants.%complete_type.860] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -256,6 +337,8 @@ class A { // CHECK:STDOUT: // CHECK:STDOUT: fn @B.BF(); // CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.01b) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @D.F(); // CHECK:STDOUT: // CHECK:STDOUT: fn @D.DF() { @@ -348,30 +431,28 @@ class A { // CHECK:STDOUT: %C.CF.call: init %empty_tuple.type = call %CF.ref() // CHECK:STDOUT: %DF.ref: %D.DF.type = name_ref DF, @D.%D.DF.decl [concrete = constants.%D.DF] // CHECK:STDOUT: %D.DF.call: init %empty_tuple.type = call %DF.ref() -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc36: = bound_method %d.var, constants.%T.as.Destroy.impl.Op.47c -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.47c, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.ceb] -// CHECK:STDOUT: %bound_method.loc36_7: = bound_method %d.var, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound: = bound_method %d.var, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc36: %ptr.321 = addr_of %d.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc36: init %empty_tuple.type = call %bound_method.loc36_7(%addr.loc36) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc35: = bound_method %c.var, constants.%T.as.Destroy.impl.Op.f77 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.f77, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.c65] -// CHECK:STDOUT: %bound_method.loc35_7: = bound_method %c.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound(%addr.loc36) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc35: %ptr.388 = addr_of %c.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc35: init %empty_tuple.type = call %bound_method.loc35_7(%addr.loc35) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc34: = bound_method %b.var, constants.%T.as.Destroy.impl.Op.4a4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.4a4, @T.as.Destroy.impl.Op(constants.%B) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.70c] -// CHECK:STDOUT: %bound_method.loc34_7: = bound_method %b.var, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr.loc35) +// CHECK:STDOUT: %B.as.Destroy.impl.Op.bound: = bound_method %b.var, constants.%B.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc34: %ptr.01b = addr_of %b.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc34: init %empty_tuple.type = call %bound_method.loc34_7(%addr.loc34) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc33: = bound_method %a.var, constants.%T.as.Destroy.impl.Op.885 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.4: = specific_function constants.%T.as.Destroy.impl.Op.885, @T.as.Destroy.impl.Op(constants.%A) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.716] -// CHECK:STDOUT: %bound_method.loc33_7: = bound_method %a.var, %T.as.Destroy.impl.Op.specific_fn.4 +// CHECK:STDOUT: %B.as.Destroy.impl.Op.call: init %empty_tuple.type = call %B.as.Destroy.impl.Op.bound(%addr.loc34) +// CHECK:STDOUT: %A.as.Destroy.impl.Op.bound: = bound_method %a.var, constants.%A.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc33: %ptr.6db = addr_of %a.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc33: init %empty_tuple.type = call %bound_method.loc33_7(%addr.loc33) +// CHECK:STDOUT: %A.as.Destroy.impl.Op.call: init %empty_tuple.type = call %A.as.Destroy.impl.Op.bound(%addr.loc33) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.321) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.CF(); // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.388) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @A.AF(); // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/scope.carbon b/toolchain/check/testdata/class/scope.carbon index 9a97ed988b6f..a2954c5b879b 100644 --- a/toolchain/check/testdata/class/scope.carbon +++ b/toolchain/check/testdata/class/scope.carbon @@ -45,6 +45,13 @@ fn Run() { // CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [concrete] // CHECK:STDOUT: %Class.G.type: type = fn_type @Class.G [concrete] // CHECK:STDOUT: %Class.G: %Class.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b40: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] @@ -72,7 +79,6 @@ fn Run() { // CHECK:STDOUT: %int_2.ef8: %i32 = int_value 2 [concrete] // CHECK:STDOUT: %Run.type: type = fn_type @Run [concrete] // CHECK:STDOUT: %Run: %Run.type = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] @@ -82,16 +88,16 @@ fn Run() { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -115,6 +121,22 @@ fn Run() { // CHECK:STDOUT: %Run.decl: %Run.type = fn_decl @Run [concrete = constants.%Run] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { // CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] @@ -134,6 +156,9 @@ fn Run() { // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b40] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -166,6 +191,8 @@ fn Run() { // CHECK:STDOUT: return %.loc21_15.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] diff --git a/toolchain/check/testdata/class/self.carbon b/toolchain/check/testdata/class/self.carbon index 8a9c979377a0..0d473a2f0938 100644 --- a/toolchain/check/testdata/class/self.carbon +++ b/toolchain/check/testdata/class/self.carbon @@ -64,6 +64,10 @@ class Class { // CHECK:STDOUT: %Class.G.type: type = fn_type @Class.G [concrete] // CHECK:STDOUT: %Class.G: %Class.G.type = struct_value () [concrete] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete] // CHECK:STDOUT: %complete_type.54b: = complete_type_witness %struct_type.n [concrete] // CHECK:STDOUT: } @@ -71,10 +75,12 @@ class Class { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -118,6 +124,22 @@ class Class { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { // CHECK:STDOUT: %self.patt: %pattern_type.761 = binding_pattern self [concrete] @@ -154,6 +176,9 @@ class Class { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc8: %Class.elem = field_decl n, element0 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete = constants.%struct_type.n] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n [concrete = constants.%complete_type.54b] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -184,6 +209,8 @@ class Class { // CHECK:STDOUT: return %.loc16_17.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_return_self_value.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -193,6 +220,13 @@ class Class { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %Class.F.type: type = fn_type @Class.F [concrete] // CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } @@ -200,10 +234,12 @@ class Class { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -215,6 +251,22 @@ class Class { // CHECK:STDOUT: %Class.decl: type = class_decl @Class [concrete = constants.%Class] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { // CHECK:STDOUT: %self.patt: %pattern_type.761 = binding_pattern self [concrete] @@ -230,6 +282,9 @@ class Class { // CHECK:STDOUT: %return.param: ref = out_param call_param1 // CHECK:STDOUT: %return: ref = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -241,3 +296,5 @@ class Class { // CHECK:STDOUT: // CHECK:STDOUT: fn @Class.F(%self.param: %Class) -> ; // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/self_conversion.carbon b/toolchain/check/testdata/class/self_conversion.carbon index 40744fbee978..cd7e4105b6bd 100644 --- a/toolchain/check/testdata/class/self_conversion.carbon +++ b/toolchain/check/testdata/class/self_conversion.carbon @@ -46,6 +46,13 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Base.elem: type = unbound_element_type %Base, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %i32} [concrete] // CHECK:STDOUT: %complete_type.fd7: = complete_type_witness %struct_type.a [concrete] // CHECK:STDOUT: %Derived: type = class_type @Derived [concrete] @@ -54,11 +61,13 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %Derived.SelfBase.type: type = fn_type @Derived.SelfBase [concrete] // CHECK:STDOUT: %Derived.SelfBase: %Derived.SelfBase.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] -// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] -// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %Derived.AddrSelfBase.type: type = fn_type @Derived.AddrSelfBase [concrete] // CHECK:STDOUT: %Derived.AddrSelfBase: %Derived.AddrSelfBase.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.b1e: type = struct_type {.base: %Base} [concrete] // CHECK:STDOUT: %complete_type.15c: = complete_type_witness %struct_type.base.b1e [concrete] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] @@ -78,8 +87,6 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.956, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] // CHECK:STDOUT: %bound_method: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] -// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] -// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] // CHECK:STDOUT: %Call.type: type = fn_type @Call [concrete] // CHECK:STDOUT: %Call: %Call.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -87,11 +94,13 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -152,10 +161,45 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc19: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Base { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc16: %Base.elem = field_decl a, element0 [concrete] +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %i32} [concrete = constants.%struct_type.a] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a [concrete = constants.%complete_type.fd7] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -195,6 +239,9 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: %self.loc23: %ptr.11f = bind_name self, %self.param.loc23 // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base} [concrete = constants.%struct_type.base.b1e] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.15c] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -208,6 +255,8 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: extend %Base.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Derived.SelfBase(%self.param.loc26: %Base) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %self.ref: %Base = name_ref self, %self.loc26 @@ -234,6 +283,8 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Call(%p.param: %ptr.404) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %p.ref.loc35: %ptr.404 = name_ref p, %p diff --git a/toolchain/check/testdata/class/self_type.carbon b/toolchain/check/testdata/class/self_type.carbon index 93f136894164..eaa82c0175bf 100644 --- a/toolchain/check/testdata/class/self_type.carbon +++ b/toolchain/check/testdata/class/self_type.carbon @@ -42,6 +42,12 @@ fn Class.F[self: Self]() -> i32 { // CHECK:STDOUT: %Class.Make: %Class.Make.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %ptr.e71 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.p: type = struct_type {.p: %ptr.e71} [concrete] // CHECK:STDOUT: %complete_type.56d: = complete_type_witness %struct_type.p [concrete] // CHECK:STDOUT: } @@ -49,10 +55,12 @@ fn Class.F[self: Self]() -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -78,6 +86,22 @@ fn Class.F[self: Self]() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { // CHECK:STDOUT: %self.patt: %pattern_type.761 = binding_pattern self [concrete] @@ -104,6 +128,9 @@ fn Class.F[self: Self]() -> i32 { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] // CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr.e71] // CHECK:STDOUT: %.loc22: %Class.elem = field_decl p, element0 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %struct_type.p: type = struct_type {.p: %ptr.e71} [concrete = constants.%struct_type.p] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.p [concrete = constants.%complete_type.56d] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -151,3 +178,5 @@ fn Class.F[self: Self]() -> i32 { // CHECK:STDOUT: return %s to %return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/static_method.carbon b/toolchain/check/testdata/class/static_method.carbon index 6d01ae60ebe4..1b783c1c003a 100644 --- a/toolchain/check/testdata/class/static_method.carbon +++ b/toolchain/check/testdata/class/static_method.carbon @@ -33,16 +33,18 @@ fn Run() -> i32 { // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %Class.F.type: type = fn_type @Class.F [concrete] // CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b40: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Run.type: type = fn_type @Run [concrete] // CHECK:STDOUT: %Run: %Run.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.761: type = pattern_type %Class [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.7de: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Class) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d64: %T.as.Destroy.impl.Op.type.7de = struct_value () [concrete] -// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(%Class) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -77,6 +79,22 @@ fn Run() -> i32 { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { // CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] @@ -87,6 +105,9 @@ fn Run() -> i32 { // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b40] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -98,6 +119,8 @@ fn Run() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: fn @Class.F() -> %i32; // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Run() -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -112,11 +135,9 @@ fn Run() -> i32 { // CHECK:STDOUT: %Class.F.call: init %i32 = call %F.ref() // CHECK:STDOUT: %.loc21_15.1: %i32 = value_of_initializer %Class.F.call // CHECK:STDOUT: %.loc21_15.2: %i32 = converted %Class.F.call, %.loc21_15.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%T.as.Destroy.impl.Op.d64 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(constants.%Class) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %c.var, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%Class.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.e71 = addr_of %c.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Class.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %.loc21_15.2 // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/syntactic_merge_literal.carbon b/toolchain/check/testdata/class/syntactic_merge_literal.carbon index 80f2dd04b6d1..4d73561531d4 100644 --- a/toolchain/check/testdata/class/syntactic_merge_literal.carbon +++ b/toolchain/check/testdata/class/syntactic_merge_literal.carbon @@ -47,6 +47,13 @@ class D(b:! C(1_000)) {} // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.506: type = class_type @C, @C(%a) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.1ba: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%a) [symbolic] +// CHECK:STDOUT: %ptr.128: type = ptr_type %C.506 [symbolic] +// CHECK:STDOUT: %pattern_type.d64: type = pattern_type %ptr.128 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%a) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %int_1000.ff9: Core.IntLiteral = int_value 1000 [concrete] @@ -72,16 +79,23 @@ class D(b:! C(1_000)) {} // CHECK:STDOUT: %D.type: type = generic_class_type @D [concrete] // CHECK:STDOUT: %D.generic: %D.type = struct_value () [concrete] // CHECK:STDOUT: %D: type = class_type @D, @D(%b) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.5ad: = impl_witness @D.%Destroy.impl_witness_table, @D.as.Destroy.impl(%b) [symbolic] +// CHECK:STDOUT: %ptr.779: type = ptr_type %D [symbolic] +// CHECK:STDOUT: %pattern_type.bf6: type = pattern_type %ptr.779 [symbolic] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op, @D.as.Destroy.impl(%b) [symbolic] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -139,12 +153,71 @@ class D(b:! C(1_000)) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%a.loc4_9.2: %i32) { +// CHECK:STDOUT: %a: %i32 = bind_symbolic_name a, 0 [symbolic = %a (constants.%a)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%a) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.1ba)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%a) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.506 as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.d64) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.d64) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_18.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.128) = value_param call_param0 +// CHECK:STDOUT: %.loc4_18.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.506)] { +// CHECK:STDOUT: %.loc4_18.3: type = specific_constant constants.%C.506, @C(constants.%a) [symbolic = %C (constants.%C.506)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_18.3 [symbolic = %C (constants.%C.506)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.128) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @D.as.Destroy.impl(@D.%b.loc6: %C.262) { +// CHECK:STDOUT: %b: %C.262 = bind_symbolic_name b, 0 [symbolic = %b (constants.%b)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @D.%Destroy.impl_witness_table, @D.as.Destroy.impl(%b) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.5ad)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op, @D.as.Destroy.impl(%b) [symbolic = %D.as.Destroy.impl.Op.type (constants.%D.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: @D.as.Destroy.impl.%D.as.Destroy.impl.Op.type (%D.as.Destroy.impl.Op.type) = struct_value () [symbolic = %D.as.Destroy.impl.Op (constants.%D.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: @D.as.Destroy.impl.%D.as.Destroy.impl.Op.type (%D.as.Destroy.impl.Op.type) = fn_decl @D.as.Destroy.impl.Op [symbolic = @D.as.Destroy.impl.%D.as.Destroy.impl.Op (constants.%D.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @D.as.Destroy.impl.Op.%pattern_type (%pattern_type.bf6) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @D.as.Destroy.impl.Op.%pattern_type (%pattern_type.bf6) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @D.as.Destroy.impl.Op.%ptr (%ptr.779) = value_param call_param0 +// CHECK:STDOUT: %.loc6_23.2: type = splice_block %Self.ref [symbolic = %D (constants.%D)] { +// CHECK:STDOUT: %.loc6_23.3: type = specific_constant constants.%D, @D(constants.%b) [symbolic = %D (constants.%D)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc6_23.3 [symbolic = %D (constants.%D)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @D.as.Destroy.impl.Op.%ptr (%ptr.779) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%a.loc4_9.2: %i32) { // CHECK:STDOUT: %a.loc4_9.1: %i32 = bind_symbolic_name a, 0 [symbolic = %a.loc4_9.1 (constants.%a)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%a) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.1ba)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -160,6 +233,9 @@ class D(b:! C(1_000)) {} // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @D.as.Destroy.impl(constants.%b) [symbolic = @D.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.5ad)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -169,18 +245,66 @@ class D(b:! C(1_000)) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%a.loc4_9.2: %i32) { +// CHECK:STDOUT: %a: %i32 = bind_symbolic_name a, 0 [symbolic = %a (constants.%a)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%a) [symbolic = %C (constants.%C.506)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.128)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.d64)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.128)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @D.as.Destroy.impl.Op(@D.%b.loc6: %C.262) { +// CHECK:STDOUT: %b: %C.262 = bind_symbolic_name b, 0 [symbolic = %b (constants.%b)] +// CHECK:STDOUT: %D: type = class_type @D, @D(%b) [symbolic = %D (constants.%D)] +// CHECK:STDOUT: %ptr: type = ptr_type %D [symbolic = %ptr (constants.%ptr.779)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.bf6)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @D.as.Destroy.impl.Op.%ptr (%ptr.779)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%a) { // CHECK:STDOUT: %a.loc4_9.1 => constants.%a // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%a) { +// CHECK:STDOUT: %a => constants.%a +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.1ba +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%a) { +// CHECK:STDOUT: %a => constants.%a +// CHECK:STDOUT: %C => constants.%C.506 +// CHECK:STDOUT: %ptr => constants.%ptr.128 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d64 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%int_1000.1b6) { // CHECK:STDOUT: %a.loc4_9.1 => constants.%int_1000.1b6 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @D(constants.%b) { // CHECK:STDOUT: %b.loc5_9.1 => constants.%b // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @D.as.Destroy.impl(constants.%b) { +// CHECK:STDOUT: %b => constants.%b +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.5ad +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @D.as.Destroy.impl.Op(constants.%b) { +// CHECK:STDOUT: %b => constants.%b +// CHECK:STDOUT: %D => constants.%D +// CHECK:STDOUT: %ptr => constants.%ptr.779 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.bf6 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_int_mismatch.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -193,6 +317,13 @@ class D(b:! C(1_000)) {} // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.506: type = class_type @C, @C(%a) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.1ba: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%a) [symbolic] +// CHECK:STDOUT: %ptr.128: type = ptr_type %C.506 [symbolic] +// CHECK:STDOUT: %pattern_type.d64: type = pattern_type %ptr.128 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%a) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %int_1000.ff9: Core.IntLiteral = int_value 1000 [concrete] @@ -220,16 +351,23 @@ class D(b:! C(1_000)) {} // CHECK:STDOUT: %D.type.bbd080.2: type = generic_class_type @D.loc13 [concrete] // CHECK:STDOUT: %D.generic.4e2319.2: %D.type.bbd080.2 = struct_value () [concrete] // CHECK:STDOUT: %D.126b2d.2: type = class_type @D.loc13, @D.loc13(%b) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.5ad: = impl_witness @D.loc13.%Destroy.impl_witness_table, @D.as.Destroy.impl(%b) [symbolic] +// CHECK:STDOUT: %ptr.779: type = ptr_type %D.126b2d.2 [symbolic] +// CHECK:STDOUT: %pattern_type.bf6: type = pattern_type %ptr.779 [symbolic] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op, @D.as.Destroy.impl(%b) [symbolic] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -287,12 +425,71 @@ class D(b:! C(1_000)) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%a.loc4_9.2: %i32) { +// CHECK:STDOUT: %a: %i32 = bind_symbolic_name a, 0 [symbolic = %a (constants.%a)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%a) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.1ba)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%a) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.506 as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.d64) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.d64) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_18.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.128) = value_param call_param0 +// CHECK:STDOUT: %.loc4_18.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.506)] { +// CHECK:STDOUT: %.loc4_18.3: type = specific_constant constants.%C.506, @C(constants.%a) [symbolic = %C (constants.%C.506)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_18.3 [symbolic = %C (constants.%C.506)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.128) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @D.as.Destroy.impl(@D.loc13.%b.loc13_9.2: %C.262) { +// CHECK:STDOUT: %b: %C.262 = bind_symbolic_name b, 0 [symbolic = %b (constants.%b)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @D.loc13.%Destroy.impl_witness_table, @D.as.Destroy.impl(%b) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.5ad)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op, @D.as.Destroy.impl(%b) [symbolic = %D.as.Destroy.impl.Op.type (constants.%D.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: @D.as.Destroy.impl.%D.as.Destroy.impl.Op.type (%D.as.Destroy.impl.Op.type) = struct_value () [symbolic = %D.as.Destroy.impl.Op (constants.%D.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%D.126b2d.2 as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: @D.as.Destroy.impl.%D.as.Destroy.impl.Op.type (%D.as.Destroy.impl.Op.type) = fn_decl @D.as.Destroy.impl.Op [symbolic = @D.as.Destroy.impl.%D.as.Destroy.impl.Op (constants.%D.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @D.as.Destroy.impl.Op.%pattern_type (%pattern_type.bf6) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @D.as.Destroy.impl.Op.%pattern_type (%pattern_type.bf6) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc13_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @D.as.Destroy.impl.Op.%ptr (%ptr.779) = value_param call_param0 +// CHECK:STDOUT: %.loc13_23.2: type = splice_block %Self.ref [symbolic = %D (constants.%D.126b2d.2)] { +// CHECK:STDOUT: %.loc13_23.3: type = specific_constant constants.%D.126b2d.2, @D.loc13(constants.%b) [symbolic = %D (constants.%D.126b2d.2)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc13_23.3 [symbolic = %D (constants.%D.126b2d.2)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @D.as.Destroy.impl.Op.%ptr (%ptr.779) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.loc13.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%a.loc4_9.2: %i32) { // CHECK:STDOUT: %a.loc4_9.1: %i32 = bind_symbolic_name a, 0 [symbolic = %a.loc4_9.1 (constants.%a)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%a) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.1ba)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -314,6 +511,9 @@ class D(b:! C(1_000)) {} // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @D.as.Destroy.impl(constants.%b) [symbolic = @D.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.5ad)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -323,12 +523,48 @@ class D(b:! C(1_000)) {} // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%a.loc4_9.2: %i32) { +// CHECK:STDOUT: %a: %i32 = bind_symbolic_name a, 0 [symbolic = %a (constants.%a)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%a) [symbolic = %C (constants.%C.506)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.128)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.d64)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.128)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @D.as.Destroy.impl.Op(@D.loc13.%b.loc13_9.2: %C.262) { +// CHECK:STDOUT: %b: %C.262 = bind_symbolic_name b, 0 [symbolic = %b (constants.%b)] +// CHECK:STDOUT: %D: type = class_type @D.loc13, @D.loc13(%b) [symbolic = %D (constants.%D.126b2d.2)] +// CHECK:STDOUT: %ptr: type = ptr_type %D [symbolic = %ptr (constants.%ptr.779)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.bf6)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @D.as.Destroy.impl.Op.%ptr (%ptr.779)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%a) { // CHECK:STDOUT: %a.loc4_9.1 => constants.%a // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%a) { +// CHECK:STDOUT: %a => constants.%a +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.1ba +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%a) { +// CHECK:STDOUT: %a => constants.%a +// CHECK:STDOUT: %C => constants.%C.506 +// CHECK:STDOUT: %ptr => constants.%ptr.128 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d64 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%int_1000.1b6) { // CHECK:STDOUT: %a.loc4_9.1 => constants.%int_1000.1b6 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @D.loc5(constants.%b) { @@ -339,3 +575,15 @@ class D(b:! C(1_000)) {} // CHECK:STDOUT: %b.loc13_9.1 => constants.%b // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @D.as.Destroy.impl(constants.%b) { +// CHECK:STDOUT: %b => constants.%b +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.5ad +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @D.as.Destroy.impl.Op(constants.%b) { +// CHECK:STDOUT: %b => constants.%b +// CHECK:STDOUT: %D => constants.%D.126b2d.2 +// CHECK:STDOUT: %ptr => constants.%ptr.779 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.bf6 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/todo_access_modifiers.carbon b/toolchain/check/testdata/class/todo_access_modifiers.carbon index 15eba971f4f6..28e8bbd25081 100644 --- a/toolchain/check/testdata/class/todo_access_modifiers.carbon +++ b/toolchain/check/testdata/class/todo_access_modifiers.carbon @@ -36,6 +36,13 @@ class Access { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Access.elem: type = unbound_element_type %Access, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Access.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.2af: type = ptr_type %Access [concrete] +// CHECK:STDOUT: %pattern_type.010: type = pattern_type %ptr.2af [concrete] +// CHECK:STDOUT: %Access.as.Destroy.impl.Op.type: type = fn_type @Access.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Access.as.Destroy.impl.Op: %Access.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.k.l: type = struct_type {.k: %i32, .l: %i32} [concrete] // CHECK:STDOUT: %complete_type.48a: = complete_type_witness %struct_type.k.l [concrete] // CHECK:STDOUT: } @@ -43,10 +50,12 @@ class Access { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -58,6 +67,22 @@ class Access { // CHECK:STDOUT: %Access.decl: type = class_decl @Access [concrete = constants.%Access] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Access.as.Destroy.impl: constants.%Access as constants.%Destroy.type { +// CHECK:STDOUT: %Access.as.Destroy.impl.Op.decl: %Access.as.Destroy.impl.Op.type = fn_decl @Access.as.Destroy.impl.Op [concrete = constants.%Access.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.010 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.010 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc16: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.2af = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Access [concrete = constants.%Access] +// CHECK:STDOUT: %self: %ptr.2af = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Access.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Access.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Access { // CHECK:STDOUT: %Access.F.decl: %Access.F.type = fn_decl @Access.F [concrete = constants.%Access.F] {} {} // CHECK:STDOUT: %Access.G.decl: %Access.G.type = fn_decl @Access.G [concrete = constants.%Access.G] {} {} @@ -67,6 +92,9 @@ class Access { // CHECK:STDOUT: %int_32.loc23: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc23: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc23: %Access.elem = field_decl l, element1 [concrete] +// CHECK:STDOUT: impl_decl @Access.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Access.as.Destroy.impl.%Access.as.Destroy.impl.Op.decl), @Access.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %struct_type.k.l: type = struct_type {.k: %i32, .l: %i32} [concrete = constants.%struct_type.k.l] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.k.l [concrete = constants.%complete_type.48a] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -83,3 +111,5 @@ class Access { // CHECK:STDOUT: // CHECK:STDOUT: fn @Access.G(); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Access.as.Destroy.impl.Op(%self.param: %ptr.2af) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/virtual_modifiers.carbon b/toolchain/check/testdata/class/virtual_modifiers.carbon index 08f3783ff12f..bdccfaece086 100644 --- a/toolchain/check/testdata/class/virtual_modifiers.carbon +++ b/toolchain/check/testdata/class/virtual_modifiers.carbon @@ -523,9 +523,16 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.bcc: type = pattern_type %Base [concrete] // CHECK:STDOUT: %Base.H.type: type = fn_type @Base.H [concrete] // CHECK:STDOUT: %Base.H: %Base.H.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type [concrete] -// CHECK:STDOUT: %Base.vtable_ptr: ref %ptr = vtable_ptr @Base.vtable [concrete] -// CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr} [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] +// CHECK:STDOUT: %Base.vtable_ptr: ref %ptr.454 = vtable_ptr @Base.vtable [concrete] +// CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete] // CHECK:STDOUT: %Abstract: type = class_type @Abstract [concrete] // CHECK:STDOUT: %pattern_type.41e: type = pattern_type %Abstract [concrete] @@ -533,14 +540,21 @@ class T2(G2:! type) { // CHECK:STDOUT: %Abstract.J: %Abstract.J.type = struct_value () [concrete] // CHECK:STDOUT: %Abstract.K.type: type = fn_type @Abstract.K [concrete] // CHECK:STDOUT: %Abstract.K: %Abstract.K.type = struct_value () [concrete] -// CHECK:STDOUT: %Abstract.vtable_ptr: ref %ptr = vtable_ptr @Abstract.vtable [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9d1: = impl_witness @Abstract.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Abstract [concrete] +// CHECK:STDOUT: %pattern_type.f31: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.type: type = fn_type @Abstract.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op: %Abstract.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %Abstract.vtable_ptr: ref %ptr.454 = vtable_ptr @Abstract.vtable [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -554,6 +568,38 @@ class T2(G2:! type) { // CHECK:STDOUT: %Abstract.decl: type = class_decl @Abstract [concrete = constants.%Abstract] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract.as.Destroy.impl: constants.%Abstract as constants.%Destroy.type { +// CHECK:STDOUT: %Abstract.as.Destroy.impl.Op.decl: %Abstract.as.Destroy.impl.Op.type = fn_decl @Abstract.as.Destroy.impl.Op [concrete = constants.%Abstract.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f31 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f31 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract [concrete = constants.%Abstract] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Abstract.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Abstract.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Base { // CHECK:STDOUT: %Base.H.decl: %Base.H.type = fn_decl @Base.H [concrete = constants.%Base.H] { // CHECK:STDOUT: %self.patt: %pattern_type.bcc = binding_pattern self [concrete] @@ -563,8 +609,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] // CHECK:STDOUT: %self: %Base = bind_name self, %self.param // CHECK:STDOUT: } -// CHECK:STDOUT: %vtable_ptr: ref %ptr = vtable_ptr @Base.vtable [concrete = constants.%Base.vtable_ptr] -// CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr} [concrete = constants.%struct_type.vptr] +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] +// CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @Base.vtable [concrete = constants.%Base.vtable_ptr] +// CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: vtable_ptr = %vtable_ptr @@ -591,8 +640,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Abstract [concrete = constants.%Abstract] // CHECK:STDOUT: %self: %Abstract = bind_name self, %self.param // CHECK:STDOUT: } -// CHECK:STDOUT: %vtable_ptr: ref %ptr = vtable_ptr @Abstract.vtable [concrete = constants.%Abstract.vtable_ptr] -// CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr} [concrete = constants.%struct_type.vptr] +// CHECK:STDOUT: impl_decl @Abstract.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Abstract.as.Destroy.impl.%Abstract.as.Destroy.impl.Op.decl), @Abstract.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.9d1] +// CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @Abstract.vtable [concrete = constants.%Abstract.vtable_ptr] +// CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: vtable_ptr = %vtable_ptr @@ -614,10 +666,14 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: virtual fn @Base.H(%self.param: %Base); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: abstract fn @Abstract.J(%self.param: %Abstract); // CHECK:STDOUT: // CHECK:STDOUT: virtual fn @Abstract.K(%self.param: %Abstract); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Abstract.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- override_import.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -631,6 +687,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %Derived.H.type: type = fn_type @Derived.H [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Derived.H: %Derived.H.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Base.H.type: type = fn_type @Base.H [concrete] // CHECK:STDOUT: %Base.H: %Base.H.type = struct_value () [concrete] // CHECK:STDOUT: %Base.vtable_ptr: ref %ptr.454 = vtable_ptr @Base.vtable [concrete] @@ -643,11 +706,6 @@ class T2(G2:! type) { // CHECK:STDOUT: %struct_type.base.f5e: type = struct_type {.base: %empty_struct_type} [concrete] // CHECK:STDOUT: %Base.val: %Base = struct_value (%Derived.vtable_ptr) [concrete] // CHECK:STDOUT: %Derived.val: %Derived = struct_value (%Base.val) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.102: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Derived) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.539: %T.as.Destroy.impl.Op.type.102 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.539, @T.as.Destroy.impl.Op(%Derived) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -681,6 +739,22 @@ class T2(G2:! type) { // CHECK:STDOUT: %Use.decl: %Use.type = fn_decl @Use [concrete = constants.%Use] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Modifiers.ref: = name_ref Modifiers, imports.%Modifiers [concrete = imports.%Modifiers] // CHECK:STDOUT: %Base.ref: type = name_ref Base, imports.%Modifiers.Base [concrete = constants.%Base] @@ -693,6 +767,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] // CHECK:STDOUT: %self: %Derived = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete = constants.%Derived.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base} [concrete = constants.%struct_type.base.96c] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.0e2] @@ -726,6 +803,8 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: impl fn @Derived.H(%self.param: %Derived); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: virtual fn @Base.H [from "modifiers.carbon"]; // CHECK:STDOUT: // CHECK:STDOUT: fn @Use() { @@ -747,11 +826,9 @@ class T2(G2:! type) { // CHECK:STDOUT: assign %d.var, %.loc12_3 // CHECK:STDOUT: %Derived.ref: type = name_ref Derived, file.%Derived.decl [concrete = constants.%Derived] // CHECK:STDOUT: %d: ref %Derived = bind_name d, %d.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %d.var, constants.%T.as.Destroy.impl.Op.539 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.539, @T.as.Destroy.impl.Op(constants.%Derived) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %d.var, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.bound: = bound_method %d.var, constants.%Derived.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.404 = addr_of %d.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Derived.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -767,6 +844,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] // CHECK:STDOUT: %complete_type.513: = complete_type_witness %struct_type.vptr [concrete] // CHECK:STDOUT: %Derived.elem: type = unbound_element_type %Derived, %Base [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Base.H.type: type = fn_type @Base.H [concrete] // CHECK:STDOUT: %Base.H: %Base.H.type = struct_value () [concrete] // CHECK:STDOUT: %Base.vtable_ptr: ref %ptr.454 = vtable_ptr @Base.vtable [concrete] @@ -777,6 +861,7 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -789,6 +874,7 @@ class T2(G2:! type) { // CHECK:STDOUT: %Modifiers.import_ref.05e: = import_ref Modifiers//default, loc6_1, loaded [concrete = constants.%complete_type.513] // CHECK:STDOUT: %Modifiers.import_ref.1f3 = import_ref Modifiers//default, inst18 [no loc], unloaded // CHECK:STDOUT: %Modifiers.import_ref.2cc = import_ref Modifiers//default, loc5_29, unloaded +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -802,6 +888,22 @@ class T2(G2:! type) { // CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [concrete = constants.%Derived] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Derived.F.decl: %Derived.F.type = fn_decl @Derived.F [concrete = constants.%Derived.F] { // CHECK:STDOUT: %self.patt: %pattern_type.fb9 = binding_pattern self [concrete] @@ -814,6 +916,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Modifiers.ref: = name_ref Modifiers, imports.%Modifiers [concrete = imports.%Modifiers] // CHECK:STDOUT: %Base.ref: type = name_ref Base, imports.%Modifiers.Base [concrete = constants.%Base] // CHECK:STDOUT: %.loc8: %Derived.elem = base_decl %Base.ref, element0 [concrete] +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete = constants.%Derived.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base} [concrete = constants.%struct_type.base] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.0e2] @@ -848,6 +953,8 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: virtual fn @Derived.F(%self.param: %Derived); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: virtual fn @Base.H [from "modifiers.carbon"]; // CHECK:STDOUT: // CHECK:STDOUT: --- init.carbon @@ -859,7 +966,7 @@ class T2(G2:! type) { // CHECK:STDOUT: %Base: type = class_type @Base [concrete] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] -// CHECK:STDOUT: %complete_type.513: = complete_type_witness %struct_type.vptr [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete] // CHECK:STDOUT: %pattern_type.80f: type = pattern_type %Base [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %Base.H.type: type = fn_type @Base.H [concrete] @@ -867,10 +974,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %Base.vtable_ptr: ref %ptr.454 = vtable_ptr @Base.vtable [concrete] // CHECK:STDOUT: %Base.val: %Base = struct_value (%Base.vtable_ptr) [concrete] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.47e: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Base) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.033: %T.as.Destroy.impl.Op.type.47e = struct_value () [concrete] +// CHECK:STDOUT: %Abstract: type = class_type @Abstract [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.2fb: = impl_witness imports.%Destroy.impl_witness_table.37d [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.f03: type = ptr_type %Base [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.033, @T.as.Destroy.impl.Op(%Base) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -885,10 +993,23 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %Modifiers.Base: type = import_ref Modifiers//default, Base, loaded [concrete = constants.%Base] // CHECK:STDOUT: %Modifiers.import_ref.be7: ref %ptr.454 = import_ref Modifiers//default, loc6_1, loaded [concrete = constants.%Base.vtable_ptr] -// CHECK:STDOUT: %Modifiers.import_ref.05e: = import_ref Modifiers//default, loc6_1, loaded [concrete = constants.%complete_type.513] +// CHECK:STDOUT: %Modifiers.import_ref.05ec96.1: = import_ref Modifiers//default, loc6_1, loaded [concrete = constants.%complete_type] // CHECK:STDOUT: %Modifiers.import_ref.1f3 = import_ref Modifiers//default, inst18 [no loc], unloaded // CHECK:STDOUT: %Modifiers.import_ref.2cc = import_ref Modifiers//default, loc5_29, unloaded // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Modifiers.import_ref.fe3: = import_ref Modifiers//default, loc4_17, loaded [concrete = constants.%Destroy.impl_witness.2fb] +// CHECK:STDOUT: %Modifiers.import_ref.f8f: type = import_ref Modifiers//default, inst18 [no loc], loaded [concrete = constants.%Base] +// CHECK:STDOUT: %Modifiers.import_ref.cb9298.1: type = import_ref Modifiers//default, inst31 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Modifiers.import_ref.5f6 = import_ref Modifiers//default, loc8_25, unloaded +// CHECK:STDOUT: %Modifiers.import_ref.e657ad.2 = import_ref Modifiers//default, loc12_1, unloaded +// CHECK:STDOUT: %Modifiers.import_ref.05ec96.2: = import_ref Modifiers//default, loc12_1, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Modifiers.import_ref.ee1 = import_ref Modifiers//default, inst75 [no loc], unloaded +// CHECK:STDOUT: %Modifiers.import_ref.bf4 = import_ref Modifiers//default, loc9_30, unloaded +// CHECK:STDOUT: %Modifiers.import_ref.b87 = import_ref Modifiers//default, loc11_29, unloaded +// CHECK:STDOUT: %Modifiers.import_ref.ce7: type = import_ref Modifiers//default, inst75 [no loc], loaded [concrete = constants.%Abstract] +// CHECK:STDOUT: %Modifiers.import_ref.cb9298.2: type = import_ref Modifiers//default, inst31 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Modifiers.import_ref.39f: %Base.as.Destroy.impl.Op.type = import_ref Modifiers//default, loc4_17, loaded [concrete = constants.%Base.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.37d = impl_witness_table (%Modifiers.import_ref.39f), @Base.as.Destroy.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -902,8 +1023,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: imports.%Modifiers.import_ref.f8f as imports.%Modifiers.import_ref.cb9298.1 [from "modifiers.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Modifiers.import_ref.fe3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Abstract.as.Destroy.impl: imports.%Modifiers.import_ref.ce7 as imports.%Modifiers.import_ref.cb9298.2 [from "modifiers.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Modifiers.import_ref.5f6 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Base [from "modifiers.carbon"] { -// CHECK:STDOUT: complete_type_witness = imports.%Modifiers.import_ref.05e +// CHECK:STDOUT: complete_type_witness = imports.%Modifiers.import_ref.05ec96.1 // CHECK:STDOUT: vtable_ptr = imports.%Modifiers.import_ref.be7 // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -911,6 +1042,16 @@ class T2(G2:! type) { // CHECK:STDOUT: .H = imports.%Modifiers.import_ref.2cc // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: class @Abstract [from "modifiers.carbon"] { +// CHECK:STDOUT: complete_type_witness = imports.%Modifiers.import_ref.05ec96.2 +// CHECK:STDOUT: vtable_ptr = imports.%Modifiers.import_ref.e657ad.2 +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Modifiers.import_ref.ee1 +// CHECK:STDOUT: .J = imports.%Modifiers.import_ref.bf4 +// CHECK:STDOUT: .K = imports.%Modifiers.import_ref.b87 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: vtable @Base.vtable { // CHECK:STDOUT: constants.%Base.H // CHECK:STDOUT: } @@ -933,16 +1074,16 @@ class T2(G2:! type) { // CHECK:STDOUT: %Base.ref: type = name_ref Base, imports.%Modifiers.Base [concrete = constants.%Base] // CHECK:STDOUT: } // CHECK:STDOUT: %v: ref %Base = bind_name v, %v.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %v.var, constants.%T.as.Destroy.impl.Op.033 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.033, @T.as.Destroy.impl.Op(constants.%Base) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %v.var, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.bound: = bound_method %v.var, constants.%Base.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.f03 = addr_of %v.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Base.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: virtual fn @Base.H [from "modifiers.carbon"]; // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op = "no_op" [from "modifiers.carbon"]; +// CHECK:STDOUT: // CHECK:STDOUT: --- impl_abstract.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -950,6 +1091,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.ddb: type = pattern_type %A1 [concrete] // CHECK:STDOUT: %A1.F.type: type = fn_type @A1.F [concrete] // CHECK:STDOUT: %A1.F: %A1.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.169: = impl_witness @A1.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.678: type = ptr_type %A1 [concrete] +// CHECK:STDOUT: %pattern_type.d72: type = pattern_type %ptr.678 [concrete] +// CHECK:STDOUT: %A1.as.Destroy.impl.Op.type: type = fn_type @A1.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A1.as.Destroy.impl.Op: %A1.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %A1.vtable_ptr: ref %ptr.454 = vtable_ptr @A1.vtable [concrete] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] @@ -959,6 +1107,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.b21: type = pattern_type %A2 [concrete] // CHECK:STDOUT: %A2.F.type: type = fn_type @A2.F [concrete] // CHECK:STDOUT: %A2.F: %A2.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ed9: = impl_witness @A2.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.590: type = ptr_type %A2 [concrete] +// CHECK:STDOUT: %pattern_type.2c5: type = pattern_type %ptr.590 [concrete] +// CHECK:STDOUT: %A2.as.Destroy.impl.Op.type: type = fn_type @A2.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A2.as.Destroy.impl.Op: %A2.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %A2.vtable_ptr: ref %ptr.454 = vtable_ptr @A2.vtable [concrete] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %A1} [concrete] // CHECK:STDOUT: %complete_type.a6f: = complete_type_witness %struct_type.base [concrete] @@ -966,9 +1119,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -982,6 +1137,38 @@ class T2(G2:! type) { // CHECK:STDOUT: %A2.decl: type = class_decl @A2 [concrete = constants.%A2] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A1.as.Destroy.impl: constants.%A1 as constants.%Destroy.type { +// CHECK:STDOUT: %A1.as.Destroy.impl.Op.decl: %A1.as.Destroy.impl.Op.type = fn_decl @A1.as.Destroy.impl.Op [concrete = constants.%A1.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.d72 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.d72 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.678 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A1 [concrete = constants.%A1] +// CHECK:STDOUT: %self: %ptr.678 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @A2.as.Destroy.impl: constants.%A2 as constants.%Destroy.type { +// CHECK:STDOUT: %A2.as.Destroy.impl.Op.decl: %A2.as.Destroy.impl.Op.type = fn_decl @A2.as.Destroy.impl.Op [concrete = constants.%A2.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.2c5 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.2c5 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.590 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A2 [concrete = constants.%A2] +// CHECK:STDOUT: %self: %ptr.590 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A2.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A2.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A1 { // CHECK:STDOUT: %A1.F.decl: %A1.F.type = fn_decl @A1.F [concrete = constants.%A1.F] { // CHECK:STDOUT: %self.patt: %pattern_type.ddb = binding_pattern self [concrete] @@ -991,6 +1178,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A1 [concrete = constants.%A1] // CHECK:STDOUT: %self: %A1 = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @A1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A1.as.Destroy.impl.%A1.as.Destroy.impl.Op.decl), @A1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.169] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @A1.vtable [concrete = constants.%A1.vtable_ptr] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] @@ -1013,6 +1203,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A2 [concrete = constants.%A2] // CHECK:STDOUT: %self: %A2 = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @A2.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A2.as.Destroy.impl.%A2.as.Destroy.impl.Op.decl), @A2.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ed9] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @A2.vtable [concrete = constants.%A2.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %A1} [concrete = constants.%struct_type.base] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.a6f] @@ -1037,8 +1230,12 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: virtual fn @A1.F(%self.param: %A1); // CHECK:STDOUT: +// CHECK:STDOUT: fn @A1.as.Destroy.impl.Op(%self.param: %ptr.678) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: impl fn @A2.F(%self.param: %A2); // CHECK:STDOUT: +// CHECK:STDOUT: fn @A2.as.Destroy.impl.Op(%self.param: %ptr.590) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- impl_base.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -1047,6 +1244,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %B1.F.type: type = fn_type @B1.F [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %B1.F: %B1.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.20e: = impl_witness @B1.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.890: type = ptr_type %B1 [concrete] +// CHECK:STDOUT: %pattern_type.b78: type = pattern_type %ptr.890 [concrete] +// CHECK:STDOUT: %B1.as.Destroy.impl.Op.type: type = fn_type @B1.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B1.as.Destroy.impl.Op: %B1.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %B1.vtable_ptr: ref %ptr.454 = vtable_ptr @B1.vtable [concrete] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] @@ -1056,6 +1260,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.b19: type = pattern_type %B2 [concrete] // CHECK:STDOUT: %B2.F.type: type = fn_type @B2.F [concrete] // CHECK:STDOUT: %B2.F: %B2.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.594: = impl_witness @B2.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.afe: type = ptr_type %B2 [concrete] +// CHECK:STDOUT: %pattern_type.98e: type = pattern_type %ptr.afe [concrete] +// CHECK:STDOUT: %B2.as.Destroy.impl.Op.type: type = fn_type @B2.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B2.as.Destroy.impl.Op: %B2.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %B2.vtable_ptr: ref %ptr.454 = vtable_ptr @B2.vtable [concrete] // CHECK:STDOUT: %struct_type.base.508: type = struct_type {.base: %B1} [concrete] // CHECK:STDOUT: %complete_type.5ac: = complete_type_witness %struct_type.base.508 [concrete] @@ -1064,6 +1273,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %C.F.type: type = fn_type @C.F [concrete] // CHECK:STDOUT: %C.F: %C.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %C.vtable_ptr: ref %ptr.454 = vtable_ptr @C.vtable [concrete] // CHECK:STDOUT: %struct_type.base.421: type = struct_type {.base: %B2} [concrete] // CHECK:STDOUT: %complete_type.066: = complete_type_witness %struct_type.base.421 [concrete] @@ -1078,19 +1292,6 @@ class T2(G2:! type) { // CHECK:STDOUT: %B1.val.b9d: %B1 = struct_value (%C.vtable_ptr) [concrete] // CHECK:STDOUT: %B2.val.426: %B2 = struct_value (%B1.val.b9d) [concrete] // CHECK:STDOUT: %C.val: %C = struct_value (%B2.val.426) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.6eb: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.49c: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%B2) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bb0: %T.as.Destroy.impl.Op.type.49c = struct_value () [concrete] -// CHECK:STDOUT: %ptr.afe: type = ptr_type %B2 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.a6f: = specific_function %T.as.Destroy.impl.Op.bb0, @T.as.Destroy.impl.Op(%B2) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.5ba: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%B1) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.a5c: %T.as.Destroy.impl.Op.type.5ba = struct_value () [concrete] -// CHECK:STDOUT: %ptr.890: type = ptr_type %B1 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.075: = specific_function %T.as.Destroy.impl.Op.a5c, @T.as.Destroy.impl.Op(%B1) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -1117,6 +1318,54 @@ class T2(G2:! type) { // CHECK:STDOUT: %Use.decl: %Use.type = fn_decl @Use [concrete = constants.%Use] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @B1.as.Destroy.impl: constants.%B1 as constants.%Destroy.type { +// CHECK:STDOUT: %B1.as.Destroy.impl.Op.decl: %B1.as.Destroy.impl.Op.type = fn_decl @B1.as.Destroy.impl.Op [concrete = constants.%B1.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.b78 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.b78 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.890 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B1 [concrete = constants.%B1] +// CHECK:STDOUT: %self: %ptr.890 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B2.as.Destroy.impl: constants.%B2 as constants.%Destroy.type { +// CHECK:STDOUT: %B2.as.Destroy.impl.Op.decl: %B2.as.Destroy.impl.Op.type = fn_decl @B2.as.Destroy.impl.Op [concrete = constants.%B2.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.98e = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.98e = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.afe = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B2 [concrete = constants.%B2] +// CHECK:STDOUT: %self: %ptr.afe = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B2.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B2.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc13: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @B1 { // CHECK:STDOUT: %B1.F.decl: %B1.F.type = fn_decl @B1.F [concrete = constants.%B1.F] { // CHECK:STDOUT: %self.patt: %pattern_type.e47 = binding_pattern self [concrete] @@ -1126,6 +1375,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B1 [concrete = constants.%B1] // CHECK:STDOUT: %self: %B1 = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @B1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B1.as.Destroy.impl.%B1.as.Destroy.impl.Op.decl), @B1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.20e] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @B1.vtable [concrete = constants.%B1.vtable_ptr] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] @@ -1148,6 +1400,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B2 [concrete = constants.%B2] // CHECK:STDOUT: %self: %B2 = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @B2.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B2.as.Destroy.impl.%B2.as.Destroy.impl.Op.decl), @B2.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.594] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @B2.vtable [concrete = constants.%B2.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %B1} [concrete = constants.%struct_type.base.508] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.5ac] @@ -1173,6 +1428,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] // CHECK:STDOUT: %self: %C = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @C.vtable [concrete = constants.%C.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %B2} [concrete = constants.%struct_type.base.421] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.066] @@ -1201,10 +1459,16 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: virtual fn @B1.F(%self.param: %B1); // CHECK:STDOUT: +// CHECK:STDOUT: fn @B1.as.Destroy.impl.Op(%self.param: %ptr.890) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: impl fn @B2.F(%self.param: %B2); // CHECK:STDOUT: +// CHECK:STDOUT: fn @B2.as.Destroy.impl.Op(%self.param: %ptr.afe) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: impl fn @C.F(%self.param: %C); // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Use() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -1258,21 +1522,15 @@ class T2(G2:! type) { // CHECK:STDOUT: assign %c.var, %.loc21_3 // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %c: ref %C = bind_name c, %c.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc21: = bound_method %c.var, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6eb] -// CHECK:STDOUT: %bound_method.loc21: = bound_method %c.var, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc21: %ptr.019 = addr_of %c.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc21: init %empty_tuple.type = call %bound_method.loc21(%addr.loc21) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc20: = bound_method %b2.var, constants.%T.as.Destroy.impl.Op.bb0 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.bb0, @T.as.Destroy.impl.Op(constants.%B2) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.a6f] -// CHECK:STDOUT: %bound_method.loc20: = bound_method %b2.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr.loc21) +// CHECK:STDOUT: %B2.as.Destroy.impl.Op.bound: = bound_method %b2.var, constants.%B2.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc20: %ptr.afe = addr_of %b2.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc20: init %empty_tuple.type = call %bound_method.loc20(%addr.loc20) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc19: = bound_method %b1.var, constants.%T.as.Destroy.impl.Op.a5c -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.a5c, @T.as.Destroy.impl.Op(constants.%B1) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.075] -// CHECK:STDOUT: %bound_method.loc19: = bound_method %b1.var, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %B2.as.Destroy.impl.Op.call: init %empty_tuple.type = call %B2.as.Destroy.impl.Op.bound(%addr.loc20) +// CHECK:STDOUT: %B1.as.Destroy.impl.Op.bound: = bound_method %b1.var, constants.%B1.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc19: %ptr.890 = addr_of %b1.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc19: init %empty_tuple.type = call %bound_method.loc19(%addr.loc19) +// CHECK:STDOUT: %B1.as.Destroy.impl.Op.call: init %empty_tuple.type = call %B1.as.Destroy.impl.Op.bound(%addr.loc19) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -1280,18 +1538,27 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %C [concrete] +// CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %C.F.type: type = fn_type @C.F [concrete] // CHECK:STDOUT: %C.F: %C.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1303,15 +1570,34 @@ class T2(G2:! type) { // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %C.F.decl: %C.F.type = fn_decl @C.F [concrete = constants.%C.F] { -// CHECK:STDOUT: %self.patt: %pattern_type = binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: %pattern_type = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %self.patt: %pattern_type.c48 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.c48 = value_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %self.param: %C = value_param call_param0 // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] // CHECK:STDOUT: %self: %C = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1323,6 +1609,8 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: impl fn @C.F(%self.param: %C); // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- init_members.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -1336,6 +1624,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.bcc: type = pattern_type %Base [concrete] // CHECK:STDOUT: %Base.F.type: type = fn_type @Base.F [concrete] // CHECK:STDOUT: %Base.F: %Base.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %Base.vtable_ptr: ref %ptr.454 = vtable_ptr @Base.vtable [concrete] // CHECK:STDOUT: %struct_type.vptr.m1.m2: type = struct_type {.: %ptr.454, .m1: %i32, .m2: %i32} [concrete] @@ -1371,30 +1666,25 @@ class T2(G2:! type) { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.ac3: = bound_method %int_4.0c1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.1da: = bound_method %int_4.0c1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_4.940: %i32 = int_value 4 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.193: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Base) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.345: %T.as.Destroy.impl.Op.type.193 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.083: = specific_function %T.as.Destroy.impl.Op.345, @T.as.Destroy.impl.Op(%Base) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.014: = specific_function %T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(%i32) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(%i32) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1408,6 +1698,22 @@ class T2(G2:! type) { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Base { // CHECK:STDOUT: %int_32.loc5: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -1423,6 +1729,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] // CHECK:STDOUT: %self: %Base = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @Base.vtable [concrete = constants.%Base.vtable_ptr] // CHECK:STDOUT: %struct_type.vptr.m1.m2: type = struct_type {.: %ptr.454, .m1: %i32, .m2: %i32} [concrete = constants.%struct_type.vptr.m1.m2] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr.m1.m2 [concrete = constants.%complete_type.cf7] @@ -1442,6 +1751,8 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: virtual fn @Base.F(%self.param: %Base); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -1525,21 +1836,17 @@ class T2(G2:! type) { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc16: init %i32 = call %bound_method.loc16_9.2(%int_4) [concrete = constants.%int_4.940] // CHECK:STDOUT: %.loc16_9: init %i32 = converted %int_4, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc16 [concrete = constants.%int_4.940] // CHECK:STDOUT: assign %.loc16_5, %.loc16_9 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc14: = bound_method %b2.var, constants.%T.as.Destroy.impl.Op.345 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.345, @T.as.Destroy.impl.Op(constants.%Base) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.083] -// CHECK:STDOUT: %bound_method.loc14_3: = bound_method %b2.var, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.bound.loc14: = bound_method %b2.var, constants.%Base.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc14: %ptr.11f = addr_of %b2.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc14: init %empty_tuple.type = call %bound_method.loc14_3(%addr.loc14) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13: = bound_method %b1.var, constants.%T.as.Destroy.impl.Op.345 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.345, @T.as.Destroy.impl.Op(constants.%Base) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.083] -// CHECK:STDOUT: %bound_method.loc13: = bound_method %b1.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.call.loc14: init %empty_tuple.type = call %Base.as.Destroy.impl.Op.bound.loc14(%addr.loc14) +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.bound.loc13: = bound_method %b1.var, constants.%Base.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc13: %ptr.11f = addr_of %b1.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc13: init %empty_tuple.type = call %bound_method.loc13(%addr.loc13) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12: = bound_method %i.var, constants.%T.as.Destroy.impl.Op.e6a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.014] -// CHECK:STDOUT: %bound_method.loc12_3.3: = bound_method %i.var, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.call.loc13: init %empty_tuple.type = call %Base.as.Destroy.impl.Op.bound.loc13(%addr.loc13) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %i.var, constants.%T.as.Destroy.impl.Op.e6a +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc12_3.3: = bound_method %i.var, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr.loc12: %ptr.235 = addr_of %i.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12: init %empty_tuple.type = call %bound_method.loc12_3.3(%addr.loc12) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc12_3.3(%addr.loc12) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -1547,13 +1854,25 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Base: type = class_type @Base [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Derived: type = class_type @Derived [concrete] // CHECK:STDOUT: %Derived.elem: type = unbound_element_type %Derived, %Base [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.fb9: type = pattern_type %Derived [concrete] // CHECK:STDOUT: %Derived.F.type: type = fn_type @Derived.F [concrete] // CHECK:STDOUT: %Derived.F: %Derived.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %Derived.vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete] // CHECK:STDOUT: %struct_type.vptr.base: type = struct_type {.: %ptr.454, .base: %Base} [concrete] @@ -1562,9 +1881,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1578,7 +1899,42 @@ class T2(G2:! type) { // CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [concrete = constants.%Derived] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Base { +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1591,13 +1947,16 @@ class T2(G2:! type) { // CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] // CHECK:STDOUT: %.loc8: %Derived.elem = base_decl %Base.ref, element1 [concrete] // CHECK:STDOUT: %Derived.F.decl: %Derived.F.type = fn_decl @Derived.F [concrete = constants.%Derived.F] { -// CHECK:STDOUT: %self.patt: %pattern_type = binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: %pattern_type = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %self.patt: %pattern_type.fb9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.fb9 = value_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %self.param: %Derived = value_param call_param0 // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] // CHECK:STDOUT: %self: %Derived = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete = constants.%Derived.vtable_ptr] // CHECK:STDOUT: %struct_type.vptr.base: type = struct_type {.: %ptr.454, .base: %Base} [concrete = constants.%struct_type.vptr.base] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr.base [concrete = constants.%complete_type.336] @@ -1614,8 +1973,12 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: vtable @Derived.vtable {} // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: impl fn @Derived.F(%self.param: %Derived); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- abstract_impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -1623,12 +1986,24 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.27c: type = pattern_type %AbstractBase [concrete] // CHECK:STDOUT: %AbstractBase.F.type: type = fn_type @AbstractBase.F [concrete] // CHECK:STDOUT: %AbstractBase.F: %AbstractBase.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ac3: = impl_witness @AbstractBase.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e86: type = ptr_type %AbstractBase [concrete] +// CHECK:STDOUT: %pattern_type.35f: type = pattern_type %ptr.e86 [concrete] +// CHECK:STDOUT: %AbstractBase.as.Destroy.impl.Op.type: type = fn_type @AbstractBase.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %AbstractBase.as.Destroy.impl.Op: %AbstractBase.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %AbstractBase.vtable_ptr: ref %ptr.454 = vtable_ptr @AbstractBase.vtable [concrete] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] // CHECK:STDOUT: %complete_type.513: = complete_type_witness %struct_type.vptr [concrete] // CHECK:STDOUT: %AbstractIntermediate: type = class_type @AbstractIntermediate [concrete] // CHECK:STDOUT: %AbstractIntermediate.elem: type = unbound_element_type %AbstractIntermediate, %AbstractBase [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.93a: = impl_witness @AbstractIntermediate.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.fd8: type = ptr_type %AbstractIntermediate [concrete] +// CHECK:STDOUT: %pattern_type.28b: type = pattern_type %ptr.fd8 [concrete] +// CHECK:STDOUT: %AbstractIntermediate.as.Destroy.impl.Op.type: type = fn_type @AbstractIntermediate.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %AbstractIntermediate.as.Destroy.impl.Op: %AbstractIntermediate.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %AbstractIntermediate.vtable_ptr: ref %ptr.454 = vtable_ptr @AbstractIntermediate.vtable [concrete] // CHECK:STDOUT: %struct_type.base.efd: type = struct_type {.base: %AbstractBase} [concrete] // CHECK:STDOUT: %complete_type.2d3: = complete_type_witness %struct_type.base.efd [concrete] @@ -1637,6 +2012,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.fb9: type = pattern_type %Derived [concrete] // CHECK:STDOUT: %Derived.F.type: type = fn_type @Derived.F [concrete] // CHECK:STDOUT: %Derived.F: %Derived.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Derived.vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete] // CHECK:STDOUT: %struct_type.base.da5: type = struct_type {.base: %AbstractIntermediate} [concrete] // CHECK:STDOUT: %complete_type.f8c: = complete_type_witness %struct_type.base.da5 [concrete] @@ -1644,9 +2024,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1662,6 +2044,54 @@ class T2(G2:! type) { // CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [concrete = constants.%Derived] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @AbstractBase.as.Destroy.impl: constants.%AbstractBase as constants.%Destroy.type { +// CHECK:STDOUT: %AbstractBase.as.Destroy.impl.Op.decl: %AbstractBase.as.Destroy.impl.Op.type = fn_decl @AbstractBase.as.Destroy.impl.Op [concrete = constants.%AbstractBase.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.35f = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.35f = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e86 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AbstractBase [concrete = constants.%AbstractBase] +// CHECK:STDOUT: %self: %ptr.e86 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %AbstractBase.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @AbstractBase.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @AbstractIntermediate.as.Destroy.impl: constants.%AbstractIntermediate as constants.%Destroy.type { +// CHECK:STDOUT: %AbstractIntermediate.as.Destroy.impl.Op.decl: %AbstractIntermediate.as.Destroy.impl.Op.type = fn_decl @AbstractIntermediate.as.Destroy.impl.Op [concrete = constants.%AbstractIntermediate.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.28b = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.28b = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.fd8 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AbstractIntermediate [concrete = constants.%AbstractIntermediate] +// CHECK:STDOUT: %self: %ptr.fd8 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %AbstractIntermediate.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @AbstractIntermediate.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @AbstractBase { // CHECK:STDOUT: %AbstractBase.F.decl: %AbstractBase.F.type = fn_decl @AbstractBase.F [concrete = constants.%AbstractBase.F] { // CHECK:STDOUT: %self.patt: %pattern_type.27c = binding_pattern self [concrete] @@ -1671,6 +2101,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%AbstractBase [concrete = constants.%AbstractBase] // CHECK:STDOUT: %self: %AbstractBase = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @AbstractBase.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@AbstractBase.as.Destroy.impl.%AbstractBase.as.Destroy.impl.Op.decl), @AbstractBase.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ac3] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @AbstractBase.vtable [concrete = constants.%AbstractBase.vtable_ptr] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] @@ -1685,6 +2118,9 @@ class T2(G2:! type) { // CHECK:STDOUT: class @AbstractIntermediate { // CHECK:STDOUT: %AbstractBase.ref: type = name_ref AbstractBase, file.%AbstractBase.decl [concrete = constants.%AbstractBase] // CHECK:STDOUT: %.loc9: %AbstractIntermediate.elem = base_decl %AbstractBase.ref, element0 [concrete] +// CHECK:STDOUT: impl_decl @AbstractIntermediate.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@AbstractIntermediate.as.Destroy.impl.%AbstractIntermediate.as.Destroy.impl.Op.decl), @AbstractIntermediate.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.93a] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @AbstractIntermediate.vtable [concrete = constants.%AbstractIntermediate.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %AbstractBase} [concrete = constants.%struct_type.base.efd] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.2d3] @@ -1709,6 +2145,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] // CHECK:STDOUT: %self: %Derived = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete = constants.%Derived.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %AbstractIntermediate} [concrete = constants.%struct_type.base.da5] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.f8c] @@ -1737,8 +2176,14 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: abstract fn @AbstractBase.F(%self.param: %AbstractBase); // CHECK:STDOUT: +// CHECK:STDOUT: fn @AbstractBase.as.Destroy.impl.Op(%self.param: %ptr.e86) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @AbstractIntermediate.as.Destroy.impl.Op(%self.param: %ptr.fd8) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: impl fn @Derived.F(%self.param: %Derived); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- virtual_impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -1746,12 +2191,24 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.ad4: type = pattern_type %VirtualBase [concrete] // CHECK:STDOUT: %VirtualBase.F.type: type = fn_type @VirtualBase.F [concrete] // CHECK:STDOUT: %VirtualBase.F: %VirtualBase.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.8a3: = impl_witness @VirtualBase.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e57: type = ptr_type %VirtualBase [concrete] +// CHECK:STDOUT: %pattern_type.f17: type = pattern_type %ptr.e57 [concrete] +// CHECK:STDOUT: %VirtualBase.as.Destroy.impl.Op.type: type = fn_type @VirtualBase.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %VirtualBase.as.Destroy.impl.Op: %VirtualBase.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %VirtualBase.vtable_ptr: ref %ptr.454 = vtable_ptr @VirtualBase.vtable [concrete] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] // CHECK:STDOUT: %complete_type.513: = complete_type_witness %struct_type.vptr [concrete] // CHECK:STDOUT: %VirtualIntermediate: type = class_type @VirtualIntermediate [concrete] // CHECK:STDOUT: %VirtualIntermediate.elem: type = unbound_element_type %VirtualIntermediate, %VirtualBase [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.3cb: = impl_witness @VirtualIntermediate.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.7dc: type = ptr_type %VirtualIntermediate [concrete] +// CHECK:STDOUT: %pattern_type.906: type = pattern_type %ptr.7dc [concrete] +// CHECK:STDOUT: %VirtualIntermediate.as.Destroy.impl.Op.type: type = fn_type @VirtualIntermediate.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %VirtualIntermediate.as.Destroy.impl.Op: %VirtualIntermediate.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %VirtualIntermediate.vtable_ptr: ref %ptr.454 = vtable_ptr @VirtualIntermediate.vtable [concrete] // CHECK:STDOUT: %struct_type.base.61e: type = struct_type {.base: %VirtualBase} [concrete] // CHECK:STDOUT: %complete_type.f09: = complete_type_witness %struct_type.base.61e [concrete] @@ -1760,6 +2217,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.fb9: type = pattern_type %Derived [concrete] // CHECK:STDOUT: %Derived.F.type: type = fn_type @Derived.F [concrete] // CHECK:STDOUT: %Derived.F: %Derived.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Derived.vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete] // CHECK:STDOUT: %struct_type.base.43c: type = struct_type {.base: %VirtualIntermediate} [concrete] // CHECK:STDOUT: %complete_type.fa6: = complete_type_witness %struct_type.base.43c [concrete] @@ -1767,9 +2229,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1785,6 +2249,54 @@ class T2(G2:! type) { // CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [concrete = constants.%Derived] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @VirtualBase.as.Destroy.impl: constants.%VirtualBase as constants.%Destroy.type { +// CHECK:STDOUT: %VirtualBase.as.Destroy.impl.Op.decl: %VirtualBase.as.Destroy.impl.Op.type = fn_decl @VirtualBase.as.Destroy.impl.Op [concrete = constants.%VirtualBase.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f17 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f17 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e57 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%VirtualBase [concrete = constants.%VirtualBase] +// CHECK:STDOUT: %self: %ptr.e57 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %VirtualBase.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @VirtualBase.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @VirtualIntermediate.as.Destroy.impl: constants.%VirtualIntermediate as constants.%Destroy.type { +// CHECK:STDOUT: %VirtualIntermediate.as.Destroy.impl.Op.decl: %VirtualIntermediate.as.Destroy.impl.Op.type = fn_decl @VirtualIntermediate.as.Destroy.impl.Op [concrete = constants.%VirtualIntermediate.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.906 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.906 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.7dc = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%VirtualIntermediate [concrete = constants.%VirtualIntermediate] +// CHECK:STDOUT: %self: %ptr.7dc = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %VirtualIntermediate.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @VirtualIntermediate.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @VirtualBase { // CHECK:STDOUT: %VirtualBase.F.decl: %VirtualBase.F.type = fn_decl @VirtualBase.F [concrete = constants.%VirtualBase.F] { // CHECK:STDOUT: %self.patt: %pattern_type.ad4 = binding_pattern self [concrete] @@ -1794,6 +2306,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%VirtualBase [concrete = constants.%VirtualBase] // CHECK:STDOUT: %self: %VirtualBase = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @VirtualBase.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@VirtualBase.as.Destroy.impl.%VirtualBase.as.Destroy.impl.Op.decl), @VirtualBase.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.8a3] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @VirtualBase.vtable [concrete = constants.%VirtualBase.vtable_ptr] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] @@ -1808,6 +2323,9 @@ class T2(G2:! type) { // CHECK:STDOUT: class @VirtualIntermediate { // CHECK:STDOUT: %VirtualBase.ref: type = name_ref VirtualBase, file.%VirtualBase.decl [concrete = constants.%VirtualBase] // CHECK:STDOUT: %.loc9: %VirtualIntermediate.elem = base_decl %VirtualBase.ref, element0 [concrete] +// CHECK:STDOUT: impl_decl @VirtualIntermediate.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@VirtualIntermediate.as.Destroy.impl.%VirtualIntermediate.as.Destroy.impl.Op.decl), @VirtualIntermediate.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.3cb] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @VirtualIntermediate.vtable [concrete = constants.%VirtualIntermediate.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %VirtualBase} [concrete = constants.%struct_type.base.61e] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.f09] @@ -1832,6 +2350,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] // CHECK:STDOUT: %self: %Derived = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete = constants.%Derived.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %VirtualIntermediate} [concrete = constants.%struct_type.base.43c] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.fa6] @@ -1860,8 +2381,14 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: virtual fn @VirtualBase.F(%self.param: %VirtualBase); // CHECK:STDOUT: +// CHECK:STDOUT: fn @VirtualBase.as.Destroy.impl.Op(%self.param: %ptr.e57) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @VirtualIntermediate.as.Destroy.impl.Op(%self.param: %ptr.7dc) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: impl fn @Derived.F(%self.param: %Derived); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_impl_mismatch.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -1869,6 +2396,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.bcc: type = pattern_type %Base [concrete] // CHECK:STDOUT: %Base.F.type: type = fn_type @Base.F [concrete] // CHECK:STDOUT: %Base.F: %Base.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %Base.vtable_ptr: ref %ptr.454 = vtable_ptr @Base.vtable [concrete] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] @@ -1883,6 +2417,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %Derived.F.type: type = fn_type @Derived.F [concrete] // CHECK:STDOUT: %Derived.F: %Derived.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Derived.vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base} [concrete] // CHECK:STDOUT: %complete_type.15c: = complete_type_witness %struct_type.base [concrete] @@ -1890,10 +2429,12 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -1908,6 +2449,38 @@ class T2(G2:! type) { // CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [concrete = constants.%Derived] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Base { // CHECK:STDOUT: %Base.F.decl: %Base.F.type = fn_decl @Base.F [concrete = constants.%Base.F] { // CHECK:STDOUT: %self.patt: %pattern_type.bcc = binding_pattern self [concrete] @@ -1917,6 +2490,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] // CHECK:STDOUT: %self: %Base = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @Base.vtable [concrete = constants.%Base.vtable_ptr] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] @@ -1947,6 +2523,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %v: %i32 = bind_name v, %v.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete = constants.%Derived.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base} [concrete = constants.%struct_type.base] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.15c] @@ -1971,15 +2550,31 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: virtual fn @Base.F(%self.param: %Base); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: impl fn @Derived.F(%self.param: %Derived, %v.param: %i32); // CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_todo_impl_conversion.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %T1: type = class_type @T1 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ccf: = impl_witness @T1.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.87b: type = ptr_type %T1 [concrete] +// CHECK:STDOUT: %pattern_type.a36: type = pattern_type %ptr.87b [concrete] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.type: type = fn_type @T1.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op: %T1.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T2: type = class_type @T2 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.658: = impl_witness @T2.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.63e: type = ptr_type %T2 [concrete] +// CHECK:STDOUT: %pattern_type.fb8: type = pattern_type %ptr.63e [concrete] +// CHECK:STDOUT: %T2.as.Destroy.impl.Op.type: type = fn_type @T2.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %T2.as.Destroy.impl.Op: %T2.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.e40: type = facet_type <@ImplicitAs, @ImplicitAs(%T1)> [concrete] @@ -1993,6 +2588,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.bcc: type = pattern_type %Base [concrete] // CHECK:STDOUT: %Base.F.type: type = fn_type @Base.F [concrete] // CHECK:STDOUT: %Base.F: %Base.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness @Base.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %Base.vtable_ptr: ref %ptr.454 = vtable_ptr @Base.vtable [concrete] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] @@ -2002,6 +2602,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.fb9: type = pattern_type %Derived [concrete] // CHECK:STDOUT: %Derived.F.type: type = fn_type @Derived.F [concrete] // CHECK:STDOUT: %Derived.F: %Derived.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Derived.vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base} [concrete] // CHECK:STDOUT: %complete_type.15c: = complete_type_witness %struct_type.base [concrete] @@ -2009,10 +2614,12 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -2040,6 +2647,38 @@ class T2(G2:! type) { // CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [concrete = constants.%Derived] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @T1.as.Destroy.impl: constants.%T1 as constants.%Destroy.type { +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.decl: %T1.as.Destroy.impl.Op.type = fn_decl @T1.as.Destroy.impl.Op [concrete = constants.%T1.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a36 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a36 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.87b = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%T1 [concrete = constants.%T1] +// CHECK:STDOUT: %self: %ptr.87b = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @T2.as.Destroy.impl: constants.%T2 as constants.%Destroy.type { +// CHECK:STDOUT: %T2.as.Destroy.impl.Op.decl: %T2.as.Destroy.impl.Op.type = fn_decl @T2.as.Destroy.impl.Op [concrete = constants.%T2.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.fb8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.fb8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.63e = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%T2 [concrete = constants.%T2] +// CHECK:STDOUT: %self: %ptr.63e = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T2.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T2.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @T2.as.ImplicitAs.impl: %T2.ref as %ImplicitAs.type { // CHECK:STDOUT: %T2.as.ImplicitAs.impl.Convert.decl: %T2.as.ImplicitAs.impl.Convert.type = fn_decl @T2.as.ImplicitAs.impl.Convert [concrete = constants.%T2.as.ImplicitAs.impl.Convert] { // CHECK:STDOUT: %self.patt: %pattern_type.682 = binding_pattern self [concrete] @@ -2061,7 +2700,42 @@ class T2(G2:! type) { // CHECK:STDOUT: witness = file.%ImplicitAs.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Base.as.Destroy.impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: %Base.as.Destroy.impl.Op.type = fn_decl @Base.as.Destroy.impl.Op [concrete = constants.%Base.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc16: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: %ptr.11f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc20: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @T1 { +// CHECK:STDOUT: impl_decl @T1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.decl), @T1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ccf] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -2071,6 +2745,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @T2 { +// CHECK:STDOUT: impl_decl @T2.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T2.as.Destroy.impl.%T2.as.Destroy.impl.Op.decl), @T2.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.658] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -2093,6 +2770,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %return.param: ref %T1 = out_param call_param1 // CHECK:STDOUT: %return: ref %T1 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae4] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @Base.vtable [concrete = constants.%Base.vtable_ptr] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] @@ -2122,6 +2802,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %return.param: ref %T2 = out_param call_param1 // CHECK:STDOUT: %return: ref %T2 = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete = constants.%Derived.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base} [concrete = constants.%struct_type.base] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.15c] @@ -2145,6 +2828,10 @@ class T2(G2:! type) { // CHECK:STDOUT: @Derived.%Derived.F.decl // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @T1.as.Destroy.impl.Op(%self.param: %ptr.87b) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @T2.as.Destroy.impl.Op(%self.param: %ptr.63e) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @T2.as.ImplicitAs.impl.Convert(%self.param: %T2) -> %return.param: %T1 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc12_13.1: %empty_struct_type = struct_literal () @@ -2155,8 +2842,12 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: virtual fn @Base.F(%self.param: %Base) -> %return.param: %T1; // CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.as.Destroy.impl.Op(%self.param: %ptr.11f) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: impl fn @Derived.F(%self.param: %Derived) -> %return.param: %T2; // CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_generic_virtual_decl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -2168,18 +2859,27 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.9f7: type = pattern_type %Base [symbolic] // CHECK:STDOUT: %Base.F.type: type = fn_type @Base.F, @Base(%T) [symbolic] // CHECK:STDOUT: %Base.F: %Base.F.type = struct_value () [symbolic] -// CHECK:STDOUT: %ptr: type = ptr_type [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.b7c: type = ptr_type %Base [symbolic] +// CHECK:STDOUT: %pattern_type.8d4: type = pattern_type %ptr.b7c [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %Base.F.specific_fn: = specific_function %Base.F, @Base.F(%T) [symbolic] -// CHECK:STDOUT: %Base.vtable_ptr: ref %ptr = vtable_ptr @Base.vtable, @Base(%T) [symbolic] -// CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr} [concrete] +// CHECK:STDOUT: %Base.vtable_ptr: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(%T) [symbolic] +// CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -2195,6 +2895,34 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Base.as.Destroy.impl(@Base.%T.loc7_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic = %Base.as.Destroy.impl.Op.type (constants.%Base.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = fn_decl @Base.as.Destroy.impl.Op [symbolic = @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7_27.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = value_param call_param0 +// CHECK:STDOUT: %.loc7_27.2: type = splice_block %Self.ref [symbolic = %Base (constants.%Base)] { +// CHECK:STDOUT: %.loc7_27.3: type = specific_constant constants.%Base, @Base(constants.%T) [symbolic = %Base (constants.%Base)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc7_27.3 [symbolic = %Base (constants.%Base)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Base(%T.loc7_17.2: type) { // CHECK:STDOUT: %T.loc7_17.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc7_17.1 (constants.%T)] // CHECK:STDOUT: @@ -2202,7 +2930,7 @@ class T2(G2:! type) { // CHECK:STDOUT: %Base.F.type: type = fn_type @Base.F, @Base(%T.loc7_17.1) [symbolic = %Base.F.type (constants.%Base.F.type)] // CHECK:STDOUT: %Base.F: @Base.%Base.F.type (%Base.F.type) = struct_value () [symbolic = %Base.F (constants.%Base.F)] // CHECK:STDOUT: %Base.F.specific_fn.loc13_1.2: = specific_function %Base.F, @Base.F(%T.loc7_17.1) [symbolic = %Base.F.specific_fn.loc13_1.2 (constants.%Base.F.specific_fn)] -// CHECK:STDOUT: %vtable_ptr.loc13_1.2: ref %ptr = vtable_ptr @Base.vtable, @Base(%T.loc7_17.1) [symbolic = %vtable_ptr.loc13_1.2 (constants.%Base.vtable_ptr)] +// CHECK:STDOUT: %vtable_ptr.loc13_1.2: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(%T.loc7_17.1) [symbolic = %vtable_ptr.loc13_1.2 (constants.%Base.vtable_ptr)] // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: %Base.F.decl: @Base.%Base.F.type (%Base.F.type) = fn_decl @Base.F [symbolic = @Base.%Base.F (constants.%Base.F)] { @@ -2216,9 +2944,12 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %self: @Base.F.%Base (%Base) = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Base.as.Destroy.impl(constants.%T) [symbolic = @Base.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %Base.F.specific_fn.loc13_1.1: = specific_function %Base.F.decl, @Base.F(constants.%T) [symbolic = %Base.F.specific_fn.loc13_1.2 (constants.%Base.F.specific_fn)] -// CHECK:STDOUT: %vtable_ptr.loc13_1.1: ref %ptr = vtable_ptr @Base.vtable, @Base(constants.%T) [symbolic = %vtable_ptr.loc13_1.2 (constants.%Base.vtable_ptr)] -// CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr} [concrete = constants.%struct_type.vptr] +// CHECK:STDOUT: %vtable_ptr.loc13_1.1: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(constants.%T) [symbolic = %vtable_ptr.loc13_1.2 (constants.%Base.vtable_ptr)] +// CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: vtable_ptr = %vtable_ptr.loc13_1.1 @@ -2241,6 +2972,17 @@ class T2(G2:! type) { // CHECK:STDOUT: virtual fn(%self.param: @Base.F.%Base (%Base)); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Base.as.Destroy.impl.Op(@Base.%T.loc7_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Base: type = class_type @Base, @Base(%T) [symbolic = %Base (constants.%Base)] +// CHECK:STDOUT: %ptr: type = ptr_type %Base [symbolic = %ptr (constants.%ptr.b7c)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.8d4)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Base(constants.%T) { // CHECK:STDOUT: %T.loc7_17.1 => constants.%T // CHECK:STDOUT: } @@ -2251,10 +2993,29 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.9f7 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Base => constants.%Base +// CHECK:STDOUT: %ptr => constants.%ptr.b7c +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.8d4 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- impl_generic_base.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %T1: type = class_type @T1 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ccf: = impl_witness @T1.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.87b: type = ptr_type %T1 [concrete] +// CHECK:STDOUT: %pattern_type.a36: type = pattern_type %ptr.87b [concrete] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.type: type = fn_type @T1.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op: %T1.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] @@ -2266,6 +3027,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] // CHECK:STDOUT: %Base.F.type.f17: type = fn_type @Base.F, @Base(%T) [symbolic] // CHECK:STDOUT: %Base.F.e26: %Base.F.type.f17 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.9f8: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.b7c: type = ptr_type %Base.370 [symbolic] +// CHECK:STDOUT: %pattern_type.8d4: type = pattern_type %ptr.b7c [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %Base.F.specific_fn.892: = specific_function %Base.F.e26, @Base.F(%T) [symbolic] // CHECK:STDOUT: %Base.vtable_ptr.573: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(%T) [symbolic] @@ -2285,6 +3051,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.fb9: type = pattern_type %Derived [concrete] // CHECK:STDOUT: %Derived.F.type: type = fn_type @Derived.F [concrete] // CHECK:STDOUT: %Derived.F: %Derived.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Derived.vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete] // CHECK:STDOUT: %struct_type.base.fda: type = struct_type {.base: %Base.ea5} [concrete] // CHECK:STDOUT: %complete_type.65a: = complete_type_witness %struct_type.base.fda [concrete] @@ -2292,9 +3063,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -2314,7 +3087,70 @@ class T2(G2:! type) { // CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [concrete = constants.%Derived] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @T1.as.Destroy.impl: constants.%T1 as constants.%Destroy.type { +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.decl: %T1.as.Destroy.impl.Op.type = fn_decl @T1.as.Destroy.impl.Op [concrete = constants.%T1.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a36 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a36 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.87b = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%T1 [concrete = constants.%T1] +// CHECK:STDOUT: %self: %ptr.87b = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Base.as.Destroy.impl(@Base.%T.loc7_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic = %Base.as.Destroy.impl.Op.type (constants.%Base.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Base.370 as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = fn_decl @Base.as.Destroy.impl.Op [symbolic = @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7_27.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = value_param call_param0 +// CHECK:STDOUT: %.loc7_27.2: type = splice_block %Self.ref [symbolic = %Base (constants.%Base.370)] { +// CHECK:STDOUT: %.loc7_27.3: type = specific_constant constants.%Base.370, @Base(constants.%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc7_27.3 [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @T1 { +// CHECK:STDOUT: impl_decl @T1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.decl), @T1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ccf] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -2349,6 +3185,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %T.ref: type = name_ref T, @Base.%T.loc7_17.2 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %t: @Base.F.%T (%T) = bind_name t, %t.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Base.as.Destroy.impl(constants.%T) [symbolic = @Base.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] // CHECK:STDOUT: %Base.F.specific_fn.loc9_1.1: = specific_function %Base.F.decl, @Base.F(constants.%T) [symbolic = %Base.F.specific_fn.loc9_1.2 (constants.%Base.F.specific_fn.892)] // CHECK:STDOUT: %vtable_ptr.loc9_1.1: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(constants.%T) [symbolic = %vtable_ptr.loc9_1.2 (constants.%Base.vtable_ptr.573)] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] @@ -2382,6 +3221,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %T1.ref: type = name_ref T1, file.%T1.decl [concrete = constants.%T1] // CHECK:STDOUT: %t: %T1 = bind_name t, %t.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete = constants.%Derived.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base.ea5} [concrete = constants.%struct_type.base.fda] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.65a] @@ -2405,6 +3247,8 @@ class T2(G2:! type) { // CHECK:STDOUT: @Derived.%Derived.F.decl // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @T1.as.Destroy.impl.Op(%self.param: %ptr.87b) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic virtual fn @Base.F(@Base.%T.loc7_17.2: type) { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %Base: type = class_type @Base, @Base(%T) [symbolic = %Base (constants.%Base.370)] @@ -2421,11 +3265,24 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Base.as.Destroy.impl.Op(@Base.%T.loc7_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Base: type = class_type @Base, @Base(%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %ptr: type = ptr_type %Base [symbolic = %ptr (constants.%ptr.b7c)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.8d4)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl fn @Derived.F(%self.param: %Derived, %t.param: %T1) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @Base(constants.%T) { // CHECK:STDOUT: %T.loc7_17.1 => constants.%T // CHECK:STDOUT: @@ -2447,6 +3304,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete.loc8_29 => constants.%require_complete.4ae // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.9f8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Base => constants.%Base.370 +// CHECK:STDOUT: %ptr => constants.%ptr.b7c +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.8d4 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Base(constants.%T1) { // CHECK:STDOUT: %T.loc7_17.1 => constants.%T1 // CHECK:STDOUT: @@ -2476,21 +3345,35 @@ class T2(G2:! type) { // CHECK:STDOUT: %T1.F: %T1.F.type = struct_value () [concrete] // CHECK:STDOUT: %T1.G.type: type = fn_type @T1.G [concrete] // CHECK:STDOUT: %T1.G: %T1.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ccf: = impl_witness @T1.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.87b: type = ptr_type %T1 [concrete] +// CHECK:STDOUT: %pattern_type.a36: type = pattern_type %ptr.87b [concrete] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.type: type = fn_type @T1.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op: %T1.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T2: type = class_type @T2 [concrete] // CHECK:STDOUT: %T2.elem: type = unbound_element_type %T2, %T1 [concrete] // CHECK:STDOUT: %T2.F.type: type = fn_type @T2.F [concrete] // CHECK:STDOUT: %T2.F: %T2.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.658: = impl_witness @T2.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.63e: type = ptr_type %T2 [concrete] +// CHECK:STDOUT: %pattern_type.fb8: type = pattern_type %ptr.63e [concrete] +// CHECK:STDOUT: %T2.as.Destroy.impl.Op.type: type = fn_type @T2.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %T2.as.Destroy.impl.Op: %T2.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %T1} [concrete] // CHECK:STDOUT: %complete_type.e14: = complete_type_witness %struct_type.base [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -2504,9 +3387,44 @@ class T2(G2:! type) { // CHECK:STDOUT: %T2.decl: type = class_decl @T2 [concrete = constants.%T2] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @T1.as.Destroy.impl: constants.%T1 as constants.%Destroy.type { +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.decl: %T1.as.Destroy.impl.Op.type = fn_decl @T1.as.Destroy.impl.Op [concrete = constants.%T1.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a36 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a36 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.87b = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%T1 [concrete = constants.%T1] +// CHECK:STDOUT: %self: %ptr.87b = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @T2.as.Destroy.impl: constants.%T2 as constants.%Destroy.type { +// CHECK:STDOUT: %T2.as.Destroy.impl.Op.decl: %T2.as.Destroy.impl.Op.type = fn_decl @T2.as.Destroy.impl.Op [concrete = constants.%T2.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.fb8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.fb8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc17: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.63e = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%T2 [concrete = constants.%T2] +// CHECK:STDOUT: %self: %ptr.63e = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T2.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T2.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @T1 { // CHECK:STDOUT: %T1.F.decl: %T1.F.type = fn_decl @T1.F [concrete = constants.%T1.F] {} {} // CHECK:STDOUT: %T1.G.decl: %T1.G.type = fn_decl @T1.G [concrete = constants.%T1.G] {} {} +// CHECK:STDOUT: impl_decl @T1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.decl), @T1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ccf] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -2521,6 +3439,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %T1.ref: type = name_ref T1, file.%T1.decl [concrete = constants.%T1] // CHECK:STDOUT: %.loc18: %T2.elem = base_decl %T1.ref, element0 [concrete] // CHECK:STDOUT: %T2.F.decl: %T2.F.type = fn_decl @T2.F [concrete = constants.%T2.F] {} {} +// CHECK:STDOUT: impl_decl @T2.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T2.as.Destroy.impl.%T2.as.Destroy.impl.Op.decl), @T2.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.658] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %T1} [concrete = constants.%struct_type.base] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.e14] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -2537,8 +3458,12 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: fn @T1.G(); // CHECK:STDOUT: +// CHECK:STDOUT: fn @T1.as.Destroy.impl.Op(%self.param: %ptr.87b) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @T2.F(); // CHECK:STDOUT: +// CHECK:STDOUT: fn @T2.as.Destroy.impl.Op(%self.param: %ptr.63e) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_addr_self_mismatch.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -2547,6 +3472,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.a36: type = pattern_type %ptr.87b [concrete] // CHECK:STDOUT: %T1.F1.type: type = fn_type @T1.F1 [concrete] // CHECK:STDOUT: %T1.F1: %T1.F1.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ccf: = impl_witness @T1.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.type: type = fn_type @T1.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op: %T1.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %T1.vtable_ptr: ref %ptr.454 = vtable_ptr @T1.vtable [concrete] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] @@ -2555,9 +3485,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %T2.elem: type = unbound_element_type %T2, %T1 [concrete] // CHECK:STDOUT: %ptr.63e: type = ptr_type %T2 [concrete] // CHECK:STDOUT: %pattern_type.fb8: type = pattern_type %ptr.63e [concrete] -// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %T2.F1.type: type = fn_type @T2.F1 [concrete] // CHECK:STDOUT: %T2.F1: %T2.F1.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.658: = impl_witness @T2.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %T2.as.Destroy.impl.Op.type: type = fn_type @T2.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %T2.as.Destroy.impl.Op: %T2.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %T2.vtable_ptr: ref %ptr.454 = vtable_ptr @T2.vtable [concrete] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %T1} [concrete] // CHECK:STDOUT: %complete_type.e14: = complete_type_witness %struct_type.base [concrete] @@ -2565,9 +3497,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -2581,6 +3515,38 @@ class T2(G2:! type) { // CHECK:STDOUT: %T2.decl: type = class_decl @T2 [concrete = constants.%T2] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @T1.as.Destroy.impl: constants.%T1 as constants.%Destroy.type { +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.decl: %T1.as.Destroy.impl.Op.type = fn_decl @T1.as.Destroy.impl.Op [concrete = constants.%T1.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a36 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a36 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.87b = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%T1 [concrete = constants.%T1] +// CHECK:STDOUT: %self: %ptr.87b = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @T2.as.Destroy.impl: constants.%T2 as constants.%Destroy.type { +// CHECK:STDOUT: %T2.as.Destroy.impl.Op.decl: %T2.as.Destroy.impl.Op.type = fn_decl @T2.as.Destroy.impl.Op [concrete = constants.%T2.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.fb8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.fb8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.63e = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%T2 [concrete = constants.%T2] +// CHECK:STDOUT: %self: %ptr.63e = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T2.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T2.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @T1 { // CHECK:STDOUT: %T1.F1.decl: %T1.F1.type = fn_decl @T1.F1 [concrete = constants.%T1.F1] { // CHECK:STDOUT: %self.patt: %pattern_type.a36 = binding_pattern self [concrete] @@ -2593,6 +3559,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %self: %ptr.87b = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @T1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.decl), @T1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ccf] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @T1.vtable [concrete = constants.%T1.vtable_ptr] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] @@ -2619,6 +3588,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %self: %ptr.63e = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @T2.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T2.as.Destroy.impl.%T2.as.Destroy.impl.Op.decl), @T2.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.658] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @T2.vtable [concrete = constants.%T2.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %T1} [concrete = constants.%struct_type.base] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.e14] @@ -2643,8 +3615,12 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: virtual fn @T1.F1(%self.param: %ptr.87b); // CHECK:STDOUT: +// CHECK:STDOUT: fn @T1.as.Destroy.impl.Op(%self.param: %ptr.87b) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: impl fn @T2.F1(%self.param: %ptr.63e); // CHECK:STDOUT: +// CHECK:STDOUT: fn @T2.as.Destroy.impl.Op(%self.param: %ptr.63e) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_generic_virtual.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -2654,15 +3630,24 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %T1.F.type: type = fn_type @T1.F [concrete] // CHECK:STDOUT: %T1.F: %T1.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @T1.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.87b: type = ptr_type %T1 [concrete] +// CHECK:STDOUT: %pattern_type.a36: type = pattern_type %ptr.87b [concrete] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.type: type = fn_type @T1.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op: %T1.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -2674,6 +3659,22 @@ class T2(G2:! type) { // CHECK:STDOUT: %T1.decl: type = class_decl @T1 [concrete = constants.%T1] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @T1.as.Destroy.impl: constants.%T1 as constants.%Destroy.type { +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.decl: %T1.as.Destroy.impl.Op.type = fn_decl @T1.as.Destroy.impl.Op [concrete = constants.%T1.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a36 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a36 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.87b = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%T1 [concrete = constants.%T1] +// CHECK:STDOUT: %self: %ptr.87b = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @T1 { // CHECK:STDOUT: %T1.F.decl: %T1.F.type = fn_decl @T1.F [concrete = constants.%T1.F] { // CHECK:STDOUT: %self.patt: %pattern_type.28b = binding_pattern self [concrete] @@ -2685,6 +3686,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %self: %T1 = bind_name self, %self.param // CHECK:STDOUT: %T.loc9_28.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc9_28.1 (constants.%T)] // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @T1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.decl), @T1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -2700,6 +3704,8 @@ class T2(G2:! type) { // CHECK:STDOUT: virtual fn(%self.param: %T1); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @T1.as.Destroy.impl.Op(%self.param: %ptr.87b) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @T1.F(constants.%T) { // CHECK:STDOUT: %T.loc9_28.1 => constants.%T // CHECK:STDOUT: } @@ -2716,15 +3722,24 @@ class T2(G2:! type) { // CHECK:STDOUT: %T.336: type = bind_symbolic_name T, 1 [symbolic] // CHECK:STDOUT: %T1.F.type: type = fn_type @T1.F, @T1(%T.8b3) [symbolic] // CHECK:STDOUT: %T1.F: %T1.F.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @T1.%Destroy.impl_witness_table, @T1.as.Destroy.impl(%T.8b3) [symbolic] +// CHECK:STDOUT: %ptr.997: type = ptr_type %T1 [symbolic] +// CHECK:STDOUT: %pattern_type.f06: type = pattern_type %ptr.997 [symbolic] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.type: type = fn_type @T1.as.Destroy.impl.Op, @T1.as.Destroy.impl(%T.8b3) [symbolic] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op: %T1.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -2740,6 +3755,34 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @T1.as.Destroy.impl(@T1.%T.loc4_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.8b3)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @T1.%Destroy.impl_witness_table, @T1.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.type: type = fn_type @T1.as.Destroy.impl.Op, @T1.as.Destroy.impl(%T) [symbolic = %T1.as.Destroy.impl.Op.type (constants.%T1.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op: @T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.type (%T1.as.Destroy.impl.Op.type) = struct_value () [symbolic = %T1.as.Destroy.impl.Op (constants.%T1.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%T1 as constants.%Destroy.type { +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.decl: @T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.type (%T1.as.Destroy.impl.Op.type) = fn_decl @T1.as.Destroy.impl.Op [symbolic = @T1.as.Destroy.impl.%T1.as.Destroy.impl.Op (constants.%T1.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @T1.as.Destroy.impl.Op.%pattern_type (%pattern_type.f06) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @T1.as.Destroy.impl.Op.%pattern_type (%pattern_type.f06) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_25.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @T1.as.Destroy.impl.Op.%ptr (%ptr.997) = value_param call_param0 +// CHECK:STDOUT: %.loc4_25.2: type = splice_block %Self.ref [symbolic = %T1 (constants.%T1)] { +// CHECK:STDOUT: %.loc4_25.3: type = specific_constant constants.%T1, @T1(constants.%T.8b3) [symbolic = %T1 (constants.%T1)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_25.3 [symbolic = %T1 (constants.%T1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @T1.as.Destroy.impl.Op.%ptr (%ptr.997) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @T1(%T.loc4_15.2: type) { // CHECK:STDOUT: %T.loc4_15.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_15.1 (constants.%T.8b3)] // CHECK:STDOUT: @@ -2761,6 +3804,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %self: @T1.F.%T1 (%T1) = bind_name self, %self.param // CHECK:STDOUT: %T.loc9_28.2: type = bind_symbolic_name T, 1 [symbolic = %T.loc9_28.1 (constants.%T.336)] // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @T1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.decl), @T1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @T1.as.Destroy.impl(constants.%T.8b3) [symbolic = @T1.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -2780,6 +3826,17 @@ class T2(G2:! type) { // CHECK:STDOUT: virtual fn(%self.param: @T1.F.%T1 (%T1)); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @T1.as.Destroy.impl.Op(@T1.%T.loc4_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.8b3)] +// CHECK:STDOUT: %T1: type = class_type @T1, @T1(%T) [symbolic = %T1 (constants.%T1)] +// CHECK:STDOUT: %ptr: type = ptr_type %T1 [symbolic = %ptr (constants.%ptr.997)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.f06)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @T1.as.Destroy.impl.Op.%ptr (%ptr.997)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @T1(constants.%T.8b3) { // CHECK:STDOUT: %T.loc4_15.1 => constants.%T.8b3 // CHECK:STDOUT: } @@ -2791,6 +3848,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %T.loc9_28.1 => constants.%T.336 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @T1.as.Destroy.impl(constants.%T.8b3) { +// CHECK:STDOUT: %T => constants.%T.8b3 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @T1.as.Destroy.impl.Op(constants.%T.8b3) { +// CHECK:STDOUT: %T => constants.%T.8b3 +// CHECK:STDOUT: %T1 => constants.%T1 +// CHECK:STDOUT: %ptr => constants.%ptr.997 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.f06 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- generic_with_virtual.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -2802,6 +3871,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.48e: type = pattern_type %T1 [symbolic] // CHECK:STDOUT: %T1.F.type: type = fn_type @T1.F, @T1(%T) [symbolic] // CHECK:STDOUT: %T1.F: %T1.F.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @T1.%Destroy.impl_witness_table, @T1.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.997: type = ptr_type %T1 [symbolic] +// CHECK:STDOUT: %pattern_type.f06: type = pattern_type %ptr.997 [symbolic] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.type: type = fn_type @T1.as.Destroy.impl.Op, @T1.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op: %T1.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %T1.F.specific_fn: = specific_function %T1.F, @T1.F(%T) [symbolic] // CHECK:STDOUT: %T1.vtable_ptr: ref %ptr.454 = vtable_ptr @T1.vtable, @T1(%T) [symbolic] @@ -2812,9 +3888,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -2830,6 +3908,34 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @T1.as.Destroy.impl(@T1.%T.loc4_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @T1.%Destroy.impl_witness_table, @T1.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.type: type = fn_type @T1.as.Destroy.impl.Op, @T1.as.Destroy.impl(%T) [symbolic = %T1.as.Destroy.impl.Op.type (constants.%T1.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op: @T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.type (%T1.as.Destroy.impl.Op.type) = struct_value () [symbolic = %T1.as.Destroy.impl.Op (constants.%T1.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%T1 as constants.%Destroy.type { +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.decl: @T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.type (%T1.as.Destroy.impl.Op.type) = fn_decl @T1.as.Destroy.impl.Op [symbolic = @T1.as.Destroy.impl.%T1.as.Destroy.impl.Op (constants.%T1.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @T1.as.Destroy.impl.Op.%pattern_type (%pattern_type.f06) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @T1.as.Destroy.impl.Op.%pattern_type (%pattern_type.f06) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_25.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @T1.as.Destroy.impl.Op.%ptr (%ptr.997) = value_param call_param0 +// CHECK:STDOUT: %.loc4_25.2: type = splice_block %Self.ref [symbolic = %T1 (constants.%T1)] { +// CHECK:STDOUT: %.loc4_25.3: type = specific_constant constants.%T1, @T1(constants.%T) [symbolic = %T1 (constants.%T1)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_25.3 [symbolic = %T1 (constants.%T1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @T1.as.Destroy.impl.Op.%ptr (%ptr.997) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @T1(%T.loc4_15.2: type) { // CHECK:STDOUT: %T.loc4_15.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_15.1 (constants.%T)] // CHECK:STDOUT: @@ -2851,6 +3957,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %self: @T1.F.%T1 (%T1) = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @T1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.decl), @T1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @T1.as.Destroy.impl(constants.%T) [symbolic = @T1.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %T1.F.specific_fn.loc6_1.1: = specific_function %T1.F.decl, @T1.F(constants.%T) [symbolic = %T1.F.specific_fn.loc6_1.2 (constants.%T1.F.specific_fn)] // CHECK:STDOUT: %vtable_ptr.loc6_1.1: ref %ptr.454 = vtable_ptr @T1.vtable, @T1(constants.%T) [symbolic = %vtable_ptr.loc6_1.2 (constants.%T1.vtable_ptr)] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] @@ -2882,6 +3991,17 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @T1.as.Destroy.impl.Op(@T1.%T.loc4_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %T1: type = class_type @T1, @T1(%T) [symbolic = %T1 (constants.%T1)] +// CHECK:STDOUT: %ptr: type = ptr_type %T1 [symbolic = %ptr (constants.%ptr.997)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.f06)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @T1.as.Destroy.impl.Op.%ptr (%ptr.997)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @T1(constants.%T) { // CHECK:STDOUT: %T.loc4_15.1 => constants.%T // CHECK:STDOUT: @@ -2901,6 +4021,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete => constants.%require_complete // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @T1.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @T1.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %T1 => constants.%T1 +// CHECK:STDOUT: %ptr => constants.%ptr.997 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.f06 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- with_dependent_arg.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -2913,6 +4045,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] // CHECK:STDOUT: %T1.F.type: type = fn_type @T1.F, @T1(%T) [symbolic] // CHECK:STDOUT: %T1.F: %T1.F.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @T1.%Destroy.impl_witness_table, @T1.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.997: type = ptr_type %T1 [symbolic] +// CHECK:STDOUT: %pattern_type.f06: type = pattern_type %ptr.997 [symbolic] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.type: type = fn_type @T1.as.Destroy.impl.Op, @T1.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op: %T1.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %T1.F.specific_fn: = specific_function %T1.F, @T1.F(%T) [symbolic] // CHECK:STDOUT: %T1.vtable_ptr: ref %ptr.454 = vtable_ptr @T1.vtable, @T1(%T) [symbolic] @@ -2924,9 +4063,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -2942,6 +4083,34 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @T1.as.Destroy.impl(@T1.%T.loc4_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @T1.%Destroy.impl_witness_table, @T1.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.type: type = fn_type @T1.as.Destroy.impl.Op, @T1.as.Destroy.impl(%T) [symbolic = %T1.as.Destroy.impl.Op.type (constants.%T1.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op: @T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.type (%T1.as.Destroy.impl.Op.type) = struct_value () [symbolic = %T1.as.Destroy.impl.Op (constants.%T1.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%T1 as constants.%Destroy.type { +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.decl: @T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.type (%T1.as.Destroy.impl.Op.type) = fn_decl @T1.as.Destroy.impl.Op [symbolic = @T1.as.Destroy.impl.%T1.as.Destroy.impl.Op (constants.%T1.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @T1.as.Destroy.impl.Op.%pattern_type (%pattern_type.f06) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @T1.as.Destroy.impl.Op.%pattern_type (%pattern_type.f06) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_25.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @T1.as.Destroy.impl.Op.%ptr (%ptr.997) = value_param call_param0 +// CHECK:STDOUT: %.loc4_25.2: type = splice_block %Self.ref [symbolic = %T1 (constants.%T1)] { +// CHECK:STDOUT: %.loc4_25.3: type = specific_constant constants.%T1, @T1(constants.%T) [symbolic = %T1 (constants.%T1)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_25.3 [symbolic = %T1 (constants.%T1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @T1.as.Destroy.impl.Op.%ptr (%ptr.997) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @T1(%T.loc4_15.2: type) { // CHECK:STDOUT: %T.loc4_15.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_15.1 (constants.%T)] // CHECK:STDOUT: @@ -2968,6 +4137,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %T.ref: type = name_ref T, @T1.%T.loc4_15.2 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %t: @T1.F.%T (%T) = bind_name t, %t.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @T1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.decl), @T1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @T1.as.Destroy.impl(constants.%T) [symbolic = @T1.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %T1.F.specific_fn.loc6_1.1: = specific_function %T1.F.decl, @T1.F(constants.%T) [symbolic = %T1.F.specific_fn.loc6_1.2 (constants.%T1.F.specific_fn)] // CHECK:STDOUT: %vtable_ptr.loc6_1.1: ref %ptr.454 = vtable_ptr @T1.vtable, @T1(constants.%T) [symbolic = %vtable_ptr.loc6_1.2 (constants.%T1.vtable_ptr)] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] @@ -3002,6 +4174,17 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @T1.as.Destroy.impl.Op(@T1.%T.loc4_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %T1: type = class_type @T1, @T1(%T) [symbolic = %T1 (constants.%T1)] +// CHECK:STDOUT: %ptr: type = ptr_type %T1 [symbolic = %ptr (constants.%ptr.997)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.f06)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @T1.as.Destroy.impl.Op.%ptr (%ptr.997)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @T1(constants.%T) { // CHECK:STDOUT: %T.loc4_15.1 => constants.%T // CHECK:STDOUT: @@ -3023,6 +4206,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete.loc5_29 => constants.%require_complete.4ae // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @T1.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @T1.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %T1 => constants.%T1 +// CHECK:STDOUT: %ptr => constants.%ptr.997 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.f06 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- vtable_import_unneeded.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -3092,6 +4287,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %NonGenericBase.F1: %NonGenericBase.F1.type = struct_value () [concrete] // CHECK:STDOUT: %NonGenericBase.F2.type: type = fn_type @NonGenericBase.F2 [concrete] // CHECK:STDOUT: %NonGenericBase.F2: %NonGenericBase.F2.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e51: = impl_witness @NonGenericBase.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.806: type = ptr_type %NonGenericBase [concrete] +// CHECK:STDOUT: %pattern_type.f69: type = pattern_type %ptr.806 [concrete] +// CHECK:STDOUT: %NonGenericBase.as.Destroy.impl.Op.type: type = fn_type @NonGenericBase.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %NonGenericBase.as.Destroy.impl.Op: %NonGenericBase.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %NonGenericBase.vtable_ptr: ref %ptr.454 = vtable_ptr @NonGenericBase.vtable [concrete] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] @@ -3107,6 +4309,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %GenericDerived.F2: %GenericDerived.F2.type = struct_value () [symbolic] // CHECK:STDOUT: %GenericDerived.F3.type: type = fn_type @GenericDerived.F3, @GenericDerived(%T) [symbolic] // CHECK:STDOUT: %GenericDerived.F3: %GenericDerived.F3.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.885: = impl_witness @GenericDerived.%Destroy.impl_witness_table, @GenericDerived.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.6eb: type = ptr_type %GenericDerived [symbolic] +// CHECK:STDOUT: %pattern_type.d95: type = pattern_type %ptr.6eb [symbolic] +// CHECK:STDOUT: %GenericDerived.as.Destroy.impl.Op.type: type = fn_type @GenericDerived.as.Destroy.impl.Op, @GenericDerived.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %GenericDerived.as.Destroy.impl.Op: %GenericDerived.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %GenericDerived.F2.specific_fn: = specific_function %GenericDerived.F2, @GenericDerived.F2(%T) [symbolic] // CHECK:STDOUT: %GenericDerived.F3.specific_fn: = specific_function %GenericDerived.F3, @GenericDerived.F3(%T) [symbolic] // CHECK:STDOUT: %GenericDerived.vtable_ptr: ref %ptr.454 = vtable_ptr @GenericDerived.vtable, @GenericDerived(%T) [symbolic] @@ -3117,9 +4324,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -3137,6 +4346,50 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @NonGenericBase.as.Destroy.impl: constants.%NonGenericBase as constants.%Destroy.type { +// CHECK:STDOUT: %NonGenericBase.as.Destroy.impl.Op.decl: %NonGenericBase.as.Destroy.impl.Op.type = fn_decl @NonGenericBase.as.Destroy.impl.Op [concrete = constants.%NonGenericBase.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f69 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f69 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.806 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%NonGenericBase [concrete = constants.%NonGenericBase] +// CHECK:STDOUT: %self: %ptr.806 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %NonGenericBase.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @NonGenericBase.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @GenericDerived.as.Destroy.impl(@GenericDerived.%T.loc9_27.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @GenericDerived.%Destroy.impl_witness_table, @GenericDerived.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.885)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %GenericDerived.as.Destroy.impl.Op.type: type = fn_type @GenericDerived.as.Destroy.impl.Op, @GenericDerived.as.Destroy.impl(%T) [symbolic = %GenericDerived.as.Destroy.impl.Op.type (constants.%GenericDerived.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %GenericDerived.as.Destroy.impl.Op: @GenericDerived.as.Destroy.impl.%GenericDerived.as.Destroy.impl.Op.type (%GenericDerived.as.Destroy.impl.Op.type) = struct_value () [symbolic = %GenericDerived.as.Destroy.impl.Op (constants.%GenericDerived.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%GenericDerived as constants.%Destroy.type { +// CHECK:STDOUT: %GenericDerived.as.Destroy.impl.Op.decl: @GenericDerived.as.Destroy.impl.%GenericDerived.as.Destroy.impl.Op.type (%GenericDerived.as.Destroy.impl.Op.type) = fn_decl @GenericDerived.as.Destroy.impl.Op [symbolic = @GenericDerived.as.Destroy.impl.%GenericDerived.as.Destroy.impl.Op (constants.%GenericDerived.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @GenericDerived.as.Destroy.impl.Op.%pattern_type (%pattern_type.d95) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @GenericDerived.as.Destroy.impl.Op.%pattern_type (%pattern_type.d95) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9_37.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @GenericDerived.as.Destroy.impl.Op.%ptr (%ptr.6eb) = value_param call_param0 +// CHECK:STDOUT: %.loc9_37.2: type = splice_block %Self.ref [symbolic = %GenericDerived (constants.%GenericDerived)] { +// CHECK:STDOUT: %.loc9_37.3: type = specific_constant constants.%GenericDerived, @GenericDerived(constants.%T) [symbolic = %GenericDerived (constants.%GenericDerived)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc9_37.3 [symbolic = %GenericDerived (constants.%GenericDerived)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @GenericDerived.as.Destroy.impl.Op.%ptr (%ptr.6eb) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %GenericDerived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @GenericDerived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @NonGenericBase { // CHECK:STDOUT: %NonGenericBase.F1.decl: %NonGenericBase.F1.type = fn_decl @NonGenericBase.F1 [concrete = constants.%NonGenericBase.F1] { // CHECK:STDOUT: %self.patt: %pattern_type.0b8 = binding_pattern self [concrete] @@ -3154,6 +4407,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%NonGenericBase [concrete = constants.%NonGenericBase] // CHECK:STDOUT: %self: %NonGenericBase = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @NonGenericBase.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@NonGenericBase.as.Destroy.impl.%NonGenericBase.as.Destroy.impl.Op.decl), @NonGenericBase.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e51] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @NonGenericBase.vtable [concrete = constants.%NonGenericBase.vtable_ptr] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.vptr [concrete = constants.%complete_type.513] @@ -3205,6 +4461,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %self: @GenericDerived.F3.%GenericDerived (%GenericDerived) = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @GenericDerived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@GenericDerived.as.Destroy.impl.%GenericDerived.as.Destroy.impl.Op.decl), @GenericDerived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @GenericDerived.as.Destroy.impl(constants.%T) [symbolic = @GenericDerived.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.885)] // CHECK:STDOUT: %GenericDerived.F2.specific_fn.loc13_1.1: = specific_function %GenericDerived.F2.decl, @GenericDerived.F2(constants.%T) [symbolic = %GenericDerived.F2.specific_fn.loc13_1.2 (constants.%GenericDerived.F2.specific_fn)] // CHECK:STDOUT: %GenericDerived.F3.specific_fn.loc13_1.1: = specific_function %GenericDerived.F3.decl, @GenericDerived.F3(constants.%T) [symbolic = %GenericDerived.F3.specific_fn.loc13_1.2 (constants.%GenericDerived.F3.specific_fn)] // CHECK:STDOUT: %vtable_ptr.loc13_1.1: ref %ptr.454 = vtable_ptr @GenericDerived.vtable, @GenericDerived(constants.%T) [symbolic = %vtable_ptr.loc13_1.2 (constants.%GenericDerived.vtable_ptr)] @@ -3244,6 +4503,8 @@ class T2(G2:! type) { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @NonGenericBase.as.Destroy.impl.Op(%self.param: %ptr.806) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic impl fn @GenericDerived.F2(@GenericDerived.%T.loc9_27.2: type) { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %GenericDerived: type = class_type @GenericDerived, @GenericDerived(%T) [symbolic = %GenericDerived (constants.%GenericDerived)] @@ -3272,6 +4533,17 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @GenericDerived.as.Destroy.impl.Op(@GenericDerived.%T.loc9_27.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %GenericDerived: type = class_type @GenericDerived, @GenericDerived(%T) [symbolic = %GenericDerived (constants.%GenericDerived)] +// CHECK:STDOUT: %ptr: type = ptr_type %GenericDerived [symbolic = %ptr (constants.%ptr.6eb)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.d95)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @GenericDerived.as.Destroy.impl.Op.%ptr (%ptr.6eb)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @GenericDerived(constants.%T) { // CHECK:STDOUT: %T.loc9_27.1 => constants.%T // CHECK:STDOUT: @@ -3305,6 +4577,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete => constants.%require_complete // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @GenericDerived.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.885 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @GenericDerived.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %GenericDerived => constants.%GenericDerived +// CHECK:STDOUT: %ptr => constants.%ptr.6eb +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d95 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- nongeneric_derived_from_generic.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -3318,6 +4602,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %GenericBase.F1.80a: %GenericBase.F1.type.2af = struct_value () [symbolic] // CHECK:STDOUT: %GenericBase.F2.type.2ca: type = fn_type @GenericBase.F2, @GenericBase(%T) [symbolic] // CHECK:STDOUT: %GenericBase.F2.414: %GenericBase.F2.type.2ca = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.c7e: = impl_witness @GenericBase.%Destroy.impl_witness_table, @GenericBase.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.b68: type = ptr_type %GenericBase.018 [symbolic] +// CHECK:STDOUT: %pattern_type.bbc: type = pattern_type %ptr.b68 [symbolic] +// CHECK:STDOUT: %GenericBase.as.Destroy.impl.Op.type: type = fn_type @GenericBase.as.Destroy.impl.Op, @GenericBase.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %GenericBase.as.Destroy.impl.Op: %GenericBase.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %GenericBase.F1.specific_fn.aea: = specific_function %GenericBase.F1.80a, @GenericBase.F1(%T) [symbolic] // CHECK:STDOUT: %GenericBase.F2.specific_fn.758: = specific_function %GenericBase.F2.414, @GenericBase.F2(%T) [symbolic] @@ -3342,6 +4633,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %NonGenericDerived.F2: %NonGenericDerived.F2.type = struct_value () [concrete] // CHECK:STDOUT: %NonGenericDerived.F3.type: type = fn_type @NonGenericDerived.F3 [concrete] // CHECK:STDOUT: %NonGenericDerived.F3: %NonGenericDerived.F3.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.330: = impl_witness @NonGenericDerived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.821: type = ptr_type %NonGenericDerived [concrete] +// CHECK:STDOUT: %pattern_type.eb2: type = pattern_type %ptr.821 [concrete] +// CHECK:STDOUT: %NonGenericDerived.as.Destroy.impl.Op.type: type = fn_type @NonGenericDerived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %NonGenericDerived.as.Destroy.impl.Op: %NonGenericDerived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %NonGenericDerived.vtable_ptr: ref %ptr.454 = vtable_ptr @NonGenericDerived.vtable [concrete] // CHECK:STDOUT: %struct_type.base.29a: type = struct_type {.base: %GenericBase.f84} [concrete] // CHECK:STDOUT: %complete_type.b6e: = complete_type_witness %struct_type.base.29a [concrete] @@ -3349,9 +4645,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -3371,6 +4669,50 @@ class T2(G2:! type) { // CHECK:STDOUT: %NonGenericDerived.decl: type = class_decl @NonGenericDerived [concrete = constants.%NonGenericDerived] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @GenericBase.as.Destroy.impl(@GenericBase.%T.loc4_24.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @GenericBase.%Destroy.impl_witness_table, @GenericBase.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.c7e)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %GenericBase.as.Destroy.impl.Op.type: type = fn_type @GenericBase.as.Destroy.impl.Op, @GenericBase.as.Destroy.impl(%T) [symbolic = %GenericBase.as.Destroy.impl.Op.type (constants.%GenericBase.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %GenericBase.as.Destroy.impl.Op: @GenericBase.as.Destroy.impl.%GenericBase.as.Destroy.impl.Op.type (%GenericBase.as.Destroy.impl.Op.type) = struct_value () [symbolic = %GenericBase.as.Destroy.impl.Op (constants.%GenericBase.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%GenericBase.018 as constants.%Destroy.type { +// CHECK:STDOUT: %GenericBase.as.Destroy.impl.Op.decl: @GenericBase.as.Destroy.impl.%GenericBase.as.Destroy.impl.Op.type (%GenericBase.as.Destroy.impl.Op.type) = fn_decl @GenericBase.as.Destroy.impl.Op [symbolic = @GenericBase.as.Destroy.impl.%GenericBase.as.Destroy.impl.Op (constants.%GenericBase.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @GenericBase.as.Destroy.impl.Op.%pattern_type (%pattern_type.bbc) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @GenericBase.as.Destroy.impl.Op.%pattern_type (%pattern_type.bbc) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_34.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @GenericBase.as.Destroy.impl.Op.%ptr (%ptr.b68) = value_param call_param0 +// CHECK:STDOUT: %.loc4_34.2: type = splice_block %Self.ref [symbolic = %GenericBase (constants.%GenericBase.018)] { +// CHECK:STDOUT: %.loc4_34.3: type = specific_constant constants.%GenericBase.018, @GenericBase(constants.%T) [symbolic = %GenericBase (constants.%GenericBase.018)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_34.3 [symbolic = %GenericBase (constants.%GenericBase.018)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @GenericBase.as.Destroy.impl.Op.%ptr (%ptr.b68) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %GenericBase.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @GenericBase.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @NonGenericDerived.as.Destroy.impl: constants.%NonGenericDerived as constants.%Destroy.type { +// CHECK:STDOUT: %NonGenericDerived.as.Destroy.impl.Op.decl: %NonGenericDerived.as.Destroy.impl.Op.type = fn_decl @NonGenericDerived.as.Destroy.impl.Op [concrete = constants.%NonGenericDerived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.eb2 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.eb2 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.821 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%NonGenericDerived [concrete = constants.%NonGenericDerived] +// CHECK:STDOUT: %self: %ptr.821 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %NonGenericDerived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @NonGenericDerived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @GenericBase(%T.loc4_24.2: type) { // CHECK:STDOUT: %T.loc4_24.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_24.1 (constants.%T)] // CHECK:STDOUT: @@ -3406,6 +4748,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %self: @GenericBase.F2.%GenericBase (%GenericBase.018) = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @GenericBase.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@GenericBase.as.Destroy.impl.%GenericBase.as.Destroy.impl.Op.decl), @GenericBase.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @GenericBase.as.Destroy.impl(constants.%T) [symbolic = @GenericBase.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.c7e)] // CHECK:STDOUT: %GenericBase.F1.specific_fn.loc7_1.1: = specific_function %GenericBase.F1.decl, @GenericBase.F1(constants.%T) [symbolic = %GenericBase.F1.specific_fn.loc7_1.2 (constants.%GenericBase.F1.specific_fn.aea)] // CHECK:STDOUT: %GenericBase.F2.specific_fn.loc7_1.1: = specific_function %GenericBase.F2.decl, @GenericBase.F2(constants.%T) [symbolic = %GenericBase.F2.specific_fn.loc7_1.2 (constants.%GenericBase.F2.specific_fn.758)] // CHECK:STDOUT: %vtable_ptr.loc7_1.1: ref %ptr.454 = vtable_ptr @GenericBase.vtable, @GenericBase(constants.%T) [symbolic = %vtable_ptr.loc7_1.2 (constants.%GenericBase.vtable_ptr.e41)] @@ -3444,6 +4789,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%NonGenericDerived [concrete = constants.%NonGenericDerived] // CHECK:STDOUT: %self: %NonGenericDerived = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @NonGenericDerived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@NonGenericDerived.as.Destroy.impl.%NonGenericDerived.as.Destroy.impl.Op.decl), @NonGenericDerived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.330] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @NonGenericDerived.vtable [concrete = constants.%NonGenericDerived.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %GenericBase.f84} [concrete = constants.%struct_type.base.29a] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.b6e] @@ -3499,6 +4847,17 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @GenericBase.as.Destroy.impl.Op(@GenericBase.%T.loc4_24.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %GenericBase: type = class_type @GenericBase, @GenericBase(%T) [symbolic = %GenericBase (constants.%GenericBase.018)] +// CHECK:STDOUT: %ptr: type = ptr_type %GenericBase [symbolic = %ptr (constants.%ptr.b68)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.bbc)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @GenericBase.as.Destroy.impl.Op.%ptr (%ptr.b68)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl fn @NonGenericDerived.F2(%self.param: %NonGenericDerived) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return @@ -3509,6 +4868,8 @@ class T2(G2:! type) { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @NonGenericDerived.as.Destroy.impl.Op(%self.param: %ptr.821) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @GenericBase(constants.%T) { // CHECK:STDOUT: %T.loc4_24.1 => constants.%T // CHECK:STDOUT: @@ -3540,6 +4901,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete => constants.%require_complete // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @GenericBase.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.c7e +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @GenericBase.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %GenericBase => constants.%GenericBase.018 +// CHECK:STDOUT: %ptr => constants.%ptr.b68 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.bbc +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @GenericBase(constants.%T1) { // CHECK:STDOUT: %T.loc4_24.1 => constants.%T1 // CHECK:STDOUT: @@ -3584,6 +4957,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.8d4: type = pattern_type %ptr.b7c [symbolic] // CHECK:STDOUT: %Base.F.type.f17: type = fn_type @Base.F, @Base(%T) [symbolic] // CHECK:STDOUT: %Base.F.e26: %Base.F.type.f17 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9f8: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %Base.F.specific_fn.892: = specific_function %Base.F.e26, @Base.F(%T) [symbolic] // CHECK:STDOUT: %Base.vtable_ptr.573: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(%T) [symbolic] @@ -3605,6 +4983,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.550: type = pattern_type %D1 [concrete] // CHECK:STDOUT: %D1.F.type: type = fn_type @D1.F [concrete] // CHECK:STDOUT: %D1.F: %D1.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.087: = impl_witness @D1.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.7a4: type = ptr_type %D1 [concrete] +// CHECK:STDOUT: %pattern_type.138: type = pattern_type %ptr.7a4 [concrete] +// CHECK:STDOUT: %D1.as.Destroy.impl.Op.type: type = fn_type @D1.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D1.as.Destroy.impl.Op: %D1.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %D1.vtable_ptr: ref %ptr.454 = vtable_ptr @D1.vtable [concrete] // CHECK:STDOUT: %struct_type.base.fda: type = struct_type {.base: %Base.ea5} [concrete] // CHECK:STDOUT: %complete_type.65a: = complete_type_witness %struct_type.base.fda [concrete] @@ -3613,9 +4996,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -3635,6 +5020,50 @@ class T2(G2:! type) { // CHECK:STDOUT: %D1.decl: type = class_decl @D1 [concrete = constants.%D1] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Base.as.Destroy.impl(@Base.%T.loc4_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic = %Base.as.Destroy.impl.Op.type (constants.%Base.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Base.370 as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = fn_decl @Base.as.Destroy.impl.Op [symbolic = @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_27.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = value_param call_param0 +// CHECK:STDOUT: %.loc4_27.2: type = splice_block %Self.ref [symbolic = %Base (constants.%Base.370)] { +// CHECK:STDOUT: %.loc4_27.3: type = specific_constant constants.%Base.370, @Base(constants.%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_27.3 [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @D1.as.Destroy.impl: constants.%D1 as constants.%Destroy.type { +// CHECK:STDOUT: %D1.as.Destroy.impl.Op.decl: %D1.as.Destroy.impl.Op.type = fn_decl @D1.as.Destroy.impl.Op [concrete = constants.%D1.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.138 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.138 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.7a4 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D1 [concrete = constants.%D1] +// CHECK:STDOUT: %self: %ptr.7a4 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Base(%T.loc4_17.2: type) { // CHECK:STDOUT: %T.loc4_17.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_17.1 (constants.%T)] // CHECK:STDOUT: @@ -3666,6 +5095,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %t: @Base.F.%ptr.loc5_38.1 (%ptr.b7c) = bind_name t, %t.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Base.as.Destroy.impl(constants.%T) [symbolic = @Base.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] // CHECK:STDOUT: %Base.F.specific_fn.loc6_1.1: = specific_function %Base.F.decl, @Base.F(constants.%T) [symbolic = %Base.F.specific_fn.loc6_1.2 (constants.%Base.F.specific_fn.892)] // CHECK:STDOUT: %vtable_ptr.loc6_1.1: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(constants.%T) [symbolic = %vtable_ptr.loc6_1.2 (constants.%Base.vtable_ptr.573)] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] @@ -3707,6 +5139,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %t: %ptr.184 = bind_name t, %t.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @D1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D1.as.Destroy.impl.%D1.as.Destroy.impl.Op.decl), @D1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.087] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @D1.vtable [concrete = constants.%D1.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base.ea5} [concrete = constants.%struct_type.base.fda] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.65a] @@ -3747,11 +5182,24 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Base.as.Destroy.impl.Op(@Base.%T.loc4_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Base: type = class_type @Base, @Base(%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %ptr: type = ptr_type %Base [symbolic = %ptr (constants.%ptr.b7c)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.8d4)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl fn @D1.F(%self.param: %D1, %t.param: %ptr.184) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @D1.as.Destroy.impl.Op(%self.param: %ptr.7a4) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @Base(constants.%T) { // CHECK:STDOUT: %T.loc4_17.1 => constants.%T // CHECK:STDOUT: @@ -3774,6 +5222,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete.loc5_29 => constants.%require_complete.cbc // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.9f8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Base => constants.%Base.370 +// CHECK:STDOUT: %ptr => constants.%ptr.b7c +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.8d4 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Base(constants.%T1) { // CHECK:STDOUT: %T.loc4_17.1 => constants.%T1 // CHECK:STDOUT: @@ -3811,6 +5271,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.a36: type = pattern_type %ptr.87b [concrete] // CHECK:STDOUT: %Base.F.type.f17: type = fn_type @Base.F, @Base(%T) [symbolic] // CHECK:STDOUT: %Base.F.e26: %Base.F.type.f17 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9f8: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.b7c: type = ptr_type %Base.370 [symbolic] +// CHECK:STDOUT: %pattern_type.8d4: type = pattern_type %ptr.b7c [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %Base.F.specific_fn.892: = specific_function %Base.F.e26, @Base.F(%T) [symbolic] // CHECK:STDOUT: %Base.vtable_ptr.573: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(%T) [symbolic] @@ -3830,6 +5297,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.fb8: type = pattern_type %ptr.63e [concrete] // CHECK:STDOUT: %D1.F.type: type = fn_type @D1.F [concrete] // CHECK:STDOUT: %D1.F: %D1.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.087: = impl_witness @D1.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.7a4: type = ptr_type %D1 [concrete] +// CHECK:STDOUT: %pattern_type.138: type = pattern_type %ptr.7a4 [concrete] +// CHECK:STDOUT: %D1.as.Destroy.impl.Op.type: type = fn_type @D1.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D1.as.Destroy.impl.Op: %D1.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %D1.vtable_ptr: ref %ptr.454 = vtable_ptr @D1.vtable [concrete] // CHECK:STDOUT: %struct_type.base.fda: type = struct_type {.base: %Base.ea5} [concrete] // CHECK:STDOUT: %complete_type.65a: = complete_type_witness %struct_type.base.fda [concrete] @@ -3837,9 +5309,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -3861,6 +5335,50 @@ class T2(G2:! type) { // CHECK:STDOUT: %D1.decl: type = class_decl @D1 [concrete = constants.%D1] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Base.as.Destroy.impl(@Base.%T.loc7_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic = %Base.as.Destroy.impl.Op.type (constants.%Base.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Base.370 as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = fn_decl @Base.as.Destroy.impl.Op [symbolic = @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7_27.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = value_param call_param0 +// CHECK:STDOUT: %.loc7_27.2: type = splice_block %Self.ref [symbolic = %Base (constants.%Base.370)] { +// CHECK:STDOUT: %.loc7_27.3: type = specific_constant constants.%Base.370, @Base(constants.%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc7_27.3 [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @D1.as.Destroy.impl: constants.%D1 as constants.%Destroy.type { +// CHECK:STDOUT: %D1.as.Destroy.impl.Op.decl: %D1.as.Destroy.impl.Op.type = fn_decl @D1.as.Destroy.impl.Op [concrete = constants.%D1.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.138 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.138 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.7a4 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D1 [concrete = constants.%D1] +// CHECK:STDOUT: %self: %ptr.7a4 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @T1; // CHECK:STDOUT: // CHECK:STDOUT: class @T2; @@ -3894,6 +5412,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %t: %ptr.87b = bind_name t, %t.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Base.as.Destroy.impl(constants.%T) [symbolic = @Base.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] // CHECK:STDOUT: %Base.F.specific_fn.loc9_1.1: = specific_function %Base.F.decl, @Base.F(constants.%T) [symbolic = %Base.F.specific_fn.loc9_1.2 (constants.%Base.F.specific_fn.892)] // CHECK:STDOUT: %vtable_ptr.loc9_1.1: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(constants.%T) [symbolic = %vtable_ptr.loc9_1.2 (constants.%Base.vtable_ptr.573)] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] @@ -3930,6 +5451,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %t: %ptr.63e = bind_name t, %t.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @D1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D1.as.Destroy.impl.%D1.as.Destroy.impl.Op.decl), @D1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.087] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @D1.vtable [concrete = constants.%D1.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base.ea5} [concrete = constants.%struct_type.base.fda] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.65a] @@ -3968,11 +5492,24 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Base.as.Destroy.impl.Op(@Base.%T.loc7_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Base: type = class_type @Base, @Base(%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %ptr: type = ptr_type %Base [symbolic = %ptr (constants.%ptr.b7c)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.8d4)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl fn @D1.F(%self.param: %D1, %t.param: %ptr.63e) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @D1.as.Destroy.impl.Op(%self.param: %ptr.7a4) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @Base(constants.%T) { // CHECK:STDOUT: %T.loc7_17.1 => constants.%T // CHECK:STDOUT: @@ -3992,6 +5529,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete => constants.%require_complete // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.9f8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Base => constants.%Base.370 +// CHECK:STDOUT: %ptr => constants.%ptr.b7c +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.8d4 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Base(constants.%T1) { // CHECK:STDOUT: %T.loc7_17.1 => constants.%T1 // CHECK:STDOUT: @@ -4024,6 +5573,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.afe: type = pattern_type %ptr.79f [symbolic] // CHECK:STDOUT: %Base.F.type: type = fn_type @Base.F, @Base(%T) [symbolic] // CHECK:STDOUT: %Base.F: %Base.F.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9f8: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.b7c: type = ptr_type %Base [symbolic] +// CHECK:STDOUT: %pattern_type.8d4: type = pattern_type %ptr.b7c [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %Base.F.specific_fn: = specific_function %Base.F, @Base.F(%T) [symbolic] // CHECK:STDOUT: %Base.vtable_ptr: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(%T) [symbolic] @@ -4039,6 +5595,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] // CHECK:STDOUT: %Derived.F.type: type = fn_type @Derived.F, @Derived(%T) [symbolic] // CHECK:STDOUT: %Derived.F: %Derived.F.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.fa7: = impl_witness @Derived.%Destroy.impl_witness_table, @Derived.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.178: type = ptr_type %Derived [symbolic] +// CHECK:STDOUT: %pattern_type.520: type = pattern_type %ptr.178 [symbolic] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op, @Derived.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %Derived.F.specific_fn: = specific_function %Derived.F, @Derived.F(%T) [symbolic] // CHECK:STDOUT: %Derived.vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable, @Derived(%T) [symbolic] // CHECK:STDOUT: %struct_type.base.8ea: type = struct_type {.base: %Base} [symbolic] @@ -4049,9 +5610,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -4073,6 +5636,62 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Base.as.Destroy.impl(@Base.%T.loc4_21.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic = %Base.as.Destroy.impl.Op.type (constants.%Base.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = fn_decl @Base.as.Destroy.impl.Op [symbolic = @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_31.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = value_param call_param0 +// CHECK:STDOUT: %.loc4_31.2: type = splice_block %Self.ref [symbolic = %Base (constants.%Base)] { +// CHECK:STDOUT: %.loc4_31.3: type = specific_constant constants.%Base, @Base(constants.%T) [symbolic = %Base (constants.%Base)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_31.3 [symbolic = %Base (constants.%Base)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Derived.as.Destroy.impl(@Derived.%T.loc7_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Derived.%Destroy.impl_witness_table, @Derived.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.fa7)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op, @Derived.as.Destroy.impl(%T) [symbolic = %Derived.as.Destroy.impl.Op.type (constants.%Derived.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: @Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.type (%Derived.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Derived.as.Destroy.impl.Op (constants.%Derived.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: @Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.type (%Derived.as.Destroy.impl.Op.type) = fn_decl @Derived.as.Destroy.impl.Op [symbolic = @Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op (constants.%Derived.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Derived.as.Destroy.impl.Op.%pattern_type (%pattern_type.520) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Derived.as.Destroy.impl.Op.%pattern_type (%pattern_type.520) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7_25.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Derived.as.Destroy.impl.Op.%ptr (%ptr.178) = value_param call_param0 +// CHECK:STDOUT: %.loc7_25.2: type = splice_block %Self.ref [symbolic = %Derived (constants.%Derived)] { +// CHECK:STDOUT: %.loc7_25.3: type = specific_constant constants.%Derived, @Derived(constants.%T) [symbolic = %Derived (constants.%Derived)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc7_25.3 [symbolic = %Derived (constants.%Derived)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Derived.as.Destroy.impl.Op.%ptr (%ptr.178) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Base(%T.loc4_21.2: type) { // CHECK:STDOUT: %T.loc4_21.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_21.1 (constants.%T)] // CHECK:STDOUT: @@ -4102,6 +5721,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %t: @Base.F.%ptr.loc5_32.1 (%ptr.79f) = bind_name t, %t.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Base.as.Destroy.impl(constants.%T) [symbolic = @Base.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] // CHECK:STDOUT: %Base.F.specific_fn.loc6_1.1: = specific_function %Base.F.decl, @Base.F(constants.%T) [symbolic = %Base.F.specific_fn.loc6_1.2 (constants.%Base.F.specific_fn)] // CHECK:STDOUT: %vtable_ptr.loc6_1.1: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(constants.%T) [symbolic = %vtable_ptr.loc6_1.2 (constants.%Base.vtable_ptr)] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] @@ -4152,6 +5774,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %T.ref: type = name_ref T, @Derived.%T.loc7_15.2 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %t: @Derived.F.%T (%T) = bind_name t, %t.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Derived.as.Destroy.impl(constants.%T) [symbolic = @Derived.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.fa7)] // CHECK:STDOUT: %Derived.F.specific_fn.loc17_1.1: = specific_function %Derived.F.decl, @Derived.F(constants.%T) [symbolic = %Derived.F.specific_fn.loc17_1.2 (constants.%Derived.F.specific_fn)] // CHECK:STDOUT: %vtable_ptr.loc17_1.1: ref %ptr.454 = vtable_ptr @Derived.vtable, @Derived(constants.%T) [symbolic = %vtable_ptr.loc17_1.2 (constants.%Derived.vtable_ptr)] // CHECK:STDOUT: %struct_type.base.loc17_1.1: type = struct_type {.base: %Base} [symbolic = %struct_type.base.loc17_1.2 (constants.%struct_type.base.8ea)] @@ -4194,6 +5819,17 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Base.as.Destroy.impl.Op(@Base.%T.loc4_21.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Base: type = class_type @Base, @Base(%T) [symbolic = %Base (constants.%Base)] +// CHECK:STDOUT: %ptr: type = ptr_type %Base [symbolic = %ptr (constants.%ptr.b7c)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.8d4)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl fn @Derived.F(@Derived.%T.loc7_15.2: type) { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %Derived: type = class_type @Derived, @Derived(%T) [symbolic = %Derived (constants.%Derived)] @@ -4212,6 +5848,17 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Derived.as.Destroy.impl.Op(@Derived.%T.loc7_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Derived: type = class_type @Derived, @Derived(%T) [symbolic = %Derived (constants.%Derived)] +// CHECK:STDOUT: %ptr: type = ptr_type %Derived [symbolic = %ptr (constants.%ptr.178)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.520)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Derived.as.Destroy.impl.Op.%ptr (%ptr.178)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Base(constants.%T) { // CHECK:STDOUT: %T.loc4_21.1 => constants.%T // CHECK:STDOUT: @@ -4234,6 +5881,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete.loc5_29 => constants.%require_complete.6e5 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.9f8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Base => constants.%Base +// CHECK:STDOUT: %ptr => constants.%ptr.b7c +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.8d4 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Derived(constants.%T) { // CHECK:STDOUT: %T.loc7_15.1 => constants.%T // CHECK:STDOUT: @@ -4263,6 +5922,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete.loc16_26 => constants.%require_complete.4ae // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Derived.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.fa7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Derived.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Derived => constants.%Derived +// CHECK:STDOUT: %ptr => constants.%ptr.178 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.520 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- impl_generic_generic.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -4275,6 +5946,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] // CHECK:STDOUT: %Base.F.type.f17: type = fn_type @Base.F, @Base(%T) [symbolic] // CHECK:STDOUT: %Base.F.e26: %Base.F.type.f17 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9f8: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.b7c: type = ptr_type %Base.370 [symbolic] +// CHECK:STDOUT: %pattern_type.8d4: type = pattern_type %ptr.b7c [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %Base.F.specific_fn.892: = specific_function %Base.F.e26, @Base.F(%T) [symbolic] // CHECK:STDOUT: %Base.vtable_ptr.573: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(%T) [symbolic] @@ -4298,6 +5976,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.423: type = pattern_type %Derived [symbolic] // CHECK:STDOUT: %Derived.F.type: type = fn_type @Derived.F, @Derived(%T) [symbolic] // CHECK:STDOUT: %Derived.F: %Derived.F.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.fa7: = impl_witness @Derived.%Destroy.impl_witness_table, @Derived.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.178: type = ptr_type %Derived [symbolic] +// CHECK:STDOUT: %pattern_type.520: type = pattern_type %ptr.178 [symbolic] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op, @Derived.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %Derived.F.specific_fn: = specific_function %Derived.F, @Derived.F(%T) [symbolic] // CHECK:STDOUT: %Derived.vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable, @Derived(%T) [symbolic] // CHECK:STDOUT: %struct_type.base.d96: type = struct_type {.base: %Base.16b} [symbolic] @@ -4308,9 +5991,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -4332,6 +6017,62 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Base.as.Destroy.impl(@Base.%T.loc4_21.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic = %Base.as.Destroy.impl.Op.type (constants.%Base.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Base.370 as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = fn_decl @Base.as.Destroy.impl.Op [symbolic = @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_31.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = value_param call_param0 +// CHECK:STDOUT: %.loc4_31.2: type = splice_block %Self.ref [symbolic = %Base (constants.%Base.370)] { +// CHECK:STDOUT: %.loc4_31.3: type = specific_constant constants.%Base.370, @Base(constants.%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_31.3 [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Derived.as.Destroy.impl(@Derived.%T.loc7_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Derived.%Destroy.impl_witness_table, @Derived.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.fa7)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op, @Derived.as.Destroy.impl(%T) [symbolic = %Derived.as.Destroy.impl.Op.type (constants.%Derived.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: @Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.type (%Derived.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Derived.as.Destroy.impl.Op (constants.%Derived.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: @Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.type (%Derived.as.Destroy.impl.Op.type) = fn_decl @Derived.as.Destroy.impl.Op [symbolic = @Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op (constants.%Derived.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Derived.as.Destroy.impl.Op.%pattern_type (%pattern_type.520) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Derived.as.Destroy.impl.Op.%pattern_type (%pattern_type.520) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7_25.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Derived.as.Destroy.impl.Op.%ptr (%ptr.178) = value_param call_param0 +// CHECK:STDOUT: %.loc7_25.2: type = splice_block %Self.ref [symbolic = %Derived (constants.%Derived)] { +// CHECK:STDOUT: %.loc7_25.3: type = specific_constant constants.%Derived, @Derived(constants.%T) [symbolic = %Derived (constants.%Derived)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc7_25.3 [symbolic = %Derived (constants.%Derived)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Derived.as.Destroy.impl.Op.%ptr (%ptr.178) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Base(%T.loc4_21.2: type) { // CHECK:STDOUT: %T.loc4_21.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_21.1 (constants.%T)] // CHECK:STDOUT: @@ -4358,6 +6099,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %T.ref: type = name_ref T, @Base.%T.loc4_21.2 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %t: @Base.F.%T (%T) = bind_name t, %t.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Base.as.Destroy.impl(constants.%T) [symbolic = @Base.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] // CHECK:STDOUT: %Base.F.specific_fn.loc6_1.1: = specific_function %Base.F.decl, @Base.F(constants.%T) [symbolic = %Base.F.specific_fn.loc6_1.2 (constants.%Base.F.specific_fn.892)] // CHECK:STDOUT: %vtable_ptr.loc6_1.1: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(constants.%T) [symbolic = %vtable_ptr.loc6_1.2 (constants.%Base.vtable_ptr.573)] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] @@ -4413,6 +6157,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %t: @Derived.F.%ptr.loc9_28 (%ptr.79f) = bind_name t, %t.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Derived.as.Destroy.impl(constants.%T) [symbolic = @Derived.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.fa7)] // CHECK:STDOUT: %Derived.F.specific_fn.loc10_1.1: = specific_function %Derived.F.decl, @Derived.F(constants.%T) [symbolic = %Derived.F.specific_fn.loc10_1.2 (constants.%Derived.F.specific_fn)] // CHECK:STDOUT: %vtable_ptr.loc10_1.1: ref %ptr.454 = vtable_ptr @Derived.vtable, @Derived(constants.%T) [symbolic = %vtable_ptr.loc10_1.2 (constants.%Derived.vtable_ptr)] // CHECK:STDOUT: %struct_type.base.loc10_1.1: type = struct_type {.base: %Base.16b} [symbolic = %struct_type.base.loc10_1.2 (constants.%struct_type.base.d96)] @@ -4454,6 +6201,17 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Base.as.Destroy.impl.Op(@Base.%T.loc4_21.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Base: type = class_type @Base, @Base(%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %ptr: type = ptr_type %Base [symbolic = %ptr (constants.%ptr.b7c)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.8d4)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl fn @Derived.F(@Derived.%T.loc7_15.2: type) { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %Derived: type = class_type @Derived, @Derived(%T) [symbolic = %Derived (constants.%Derived)] @@ -4473,6 +6231,17 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Derived.as.Destroy.impl.Op(@Derived.%T.loc7_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Derived: type = class_type @Derived, @Derived(%T) [symbolic = %Derived (constants.%Derived)] +// CHECK:STDOUT: %ptr: type = ptr_type %Derived [symbolic = %ptr (constants.%ptr.178)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.520)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Derived.as.Destroy.impl.Op.%ptr (%ptr.178)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Base(constants.%T) { // CHECK:STDOUT: %T.loc4_21.1 => constants.%T // CHECK:STDOUT: @@ -4494,6 +6263,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete.loc5_29 => constants.%require_complete.4ae // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.9f8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Base => constants.%Base.370 +// CHECK:STDOUT: %ptr => constants.%ptr.b7c +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.8d4 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Derived(constants.%T) { // CHECK:STDOUT: %T.loc7_15.1 => constants.%T // CHECK:STDOUT: @@ -4546,6 +6327,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete.loc9_26 => constants.%require_complete.6e5 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Derived.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.fa7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Derived.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Derived => constants.%Derived +// CHECK:STDOUT: %ptr => constants.%ptr.178 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.520 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- abstract_generic_undefined.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -4557,6 +6350,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.9f7: type = pattern_type %Base.370 [symbolic] // CHECK:STDOUT: %Base.F.type.f17: type = fn_type @Base.F, @Base(%T) [symbolic] // CHECK:STDOUT: %Base.F.e26: %Base.F.type.f17 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9f8: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.b7c: type = ptr_type %Base.370 [symbolic] +// CHECK:STDOUT: %pattern_type.8d4: type = pattern_type %ptr.b7c [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %Base.F.specific_fn.892: = specific_function %Base.F.e26, @Base.F(%T) [symbolic] // CHECK:STDOUT: %Base.vtable_ptr.573: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(%T) [symbolic] @@ -4574,6 +6374,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.fb9: type = pattern_type %Derived [concrete] // CHECK:STDOUT: %Derived.F.type: type = fn_type @Derived.F [concrete] // CHECK:STDOUT: %Derived.F: %Derived.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e52: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Derived.vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete] // CHECK:STDOUT: %struct_type.base.fda: type = struct_type {.base: %Base.ea5} [concrete] // CHECK:STDOUT: %complete_type.65a: = complete_type_witness %struct_type.base.fda [concrete] @@ -4581,9 +6386,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -4603,6 +6410,50 @@ class T2(G2:! type) { // CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [concrete = constants.%Derived] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Base.as.Destroy.impl(@Base.%T.loc4_21.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic = %Base.as.Destroy.impl.Op.type (constants.%Base.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Base.370 as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = fn_decl @Base.as.Destroy.impl.Op [symbolic = @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_31.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = value_param call_param0 +// CHECK:STDOUT: %.loc4_31.2: type = splice_block %Self.ref [symbolic = %Base (constants.%Base.370)] { +// CHECK:STDOUT: %.loc4_31.3: type = specific_constant constants.%Base.370, @Base(constants.%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_31.3 [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc10: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Base(%T.loc4_21.2: type) { // CHECK:STDOUT: %T.loc4_21.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_21.1 (constants.%T)] // CHECK:STDOUT: @@ -4624,6 +6475,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %self: @Base.F.%Base (%Base.370) = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Base.as.Destroy.impl(constants.%T) [symbolic = @Base.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.9f8)] // CHECK:STDOUT: %Base.F.specific_fn.loc6_1.1: = specific_function %Base.F.decl, @Base.F(constants.%T) [symbolic = %Base.F.specific_fn.loc6_1.2 (constants.%Base.F.specific_fn.892)] // CHECK:STDOUT: %vtable_ptr.loc6_1.1: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(constants.%T) [symbolic = %vtable_ptr.loc6_1.2 (constants.%Base.vtable_ptr.573)] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] @@ -4652,6 +6506,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] // CHECK:STDOUT: %self: %Derived = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e52] // CHECK:STDOUT: %vtable_ptr: ref %ptr.454 = vtable_ptr @Derived.vtable [concrete = constants.%Derived.vtable_ptr] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Base.ea5} [concrete = constants.%struct_type.base.fda] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.65a] @@ -4683,11 +6540,24 @@ class T2(G2:! type) { // CHECK:STDOUT: abstract fn(%self.param: @Base.F.%Base (%Base.370)); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Base.as.Destroy.impl.Op(@Base.%T.loc4_21.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Base: type = class_type @Base, @Base(%T) [symbolic = %Base (constants.%Base.370)] +// CHECK:STDOUT: %ptr: type = ptr_type %Base [symbolic = %ptr (constants.%ptr.b7c)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.8d4)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl fn @Derived.F(%self.param: %Derived) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @Base(constants.%T) { // CHECK:STDOUT: %T.loc4_21.1 => constants.%T // CHECK:STDOUT: } @@ -4698,6 +6568,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.9f7 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.9f8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Base => constants.%Base.370 +// CHECK:STDOUT: %ptr => constants.%ptr.b7c +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.8d4 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Base(constants.%T1) { // CHECK:STDOUT: %T.loc4_21.1 => constants.%T1 // CHECK:STDOUT: @@ -4725,6 +6607,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.9f7: type = pattern_type %Base [symbolic] // CHECK:STDOUT: %Base.F.type: type = fn_type @Base.F, @Base(%T) [symbolic] // CHECK:STDOUT: %Base.F: %Base.F.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.b7c: type = ptr_type %Base [symbolic] +// CHECK:STDOUT: %pattern_type.8d4: type = pattern_type %ptr.b7c [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: %Base.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %Base.F.specific_fn: = specific_function %Base.F, @Base.F(%T) [symbolic] // CHECK:STDOUT: %Base.vtable_ptr: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(%T) [symbolic] @@ -4735,9 +6624,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -4753,6 +6644,34 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Base.as.Destroy.impl(@Base.%T.loc4_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Base.%Destroy.impl_witness_table, @Base.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.type: type = fn_type @Base.as.Destroy.impl.Op, @Base.as.Destroy.impl(%T) [symbolic = %Base.as.Destroy.impl.Op.type (constants.%Base.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Base.as.Destroy.impl.Op: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Base as constants.%Destroy.type { +// CHECK:STDOUT: %Base.as.Destroy.impl.Op.decl: @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.type (%Base.as.Destroy.impl.Op.type) = fn_decl @Base.as.Destroy.impl.Op [symbolic = @Base.as.Destroy.impl.%Base.as.Destroy.impl.Op (constants.%Base.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Base.as.Destroy.impl.Op.%pattern_type (%pattern_type.8d4) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_27.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = value_param call_param0 +// CHECK:STDOUT: %.loc4_27.2: type = splice_block %Self.ref [symbolic = %Base (constants.%Base)] { +// CHECK:STDOUT: %.loc4_27.3: type = specific_constant constants.%Base, @Base(constants.%T) [symbolic = %Base (constants.%Base)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_27.3 [symbolic = %Base (constants.%Base)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Base.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Base.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Base(%T.loc4_17.2: type) { // CHECK:STDOUT: %T.loc4_17.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_17.1 (constants.%T)] // CHECK:STDOUT: @@ -4774,6 +6693,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %self: @Base.F.%Base (%Base) = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Base.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Base.as.Destroy.impl.%Base.as.Destroy.impl.Op.decl), @Base.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Base.as.Destroy.impl(constants.%T) [symbolic = @Base.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %Base.F.specific_fn.loc6_1.1: = specific_function %Base.F.decl, @Base.F(constants.%T) [symbolic = %Base.F.specific_fn.loc6_1.2 (constants.%Base.F.specific_fn)] // CHECK:STDOUT: %vtable_ptr.loc6_1.1: ref %ptr.454 = vtable_ptr @Base.vtable, @Base(constants.%T) [symbolic = %vtable_ptr.loc6_1.2 (constants.%Base.vtable_ptr)] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] @@ -4805,6 +6727,17 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Base.as.Destroy.impl.Op(@Base.%T.loc4_17.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Base: type = class_type @Base, @Base(%T) [symbolic = %Base (constants.%Base)] +// CHECK:STDOUT: %ptr: type = ptr_type %Base [symbolic = %ptr (constants.%ptr.b7c)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.8d4)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Base.as.Destroy.impl.Op.%ptr (%ptr.b7c)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Base(constants.%T) { // CHECK:STDOUT: %T.loc4_17.1 => constants.%T // CHECK:STDOUT: @@ -4824,6 +6757,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete => constants.%require_complete // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Base.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Base => constants.%Base +// CHECK:STDOUT: %ptr => constants.%ptr.b7c +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.8d4 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- generic_import.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -4995,6 +6940,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.48ecf1.1: type = pattern_type %T1.18aea2.1 [symbolic] // CHECK:STDOUT: %T1.F.type.ebcc3f.1: type = fn_type @T1.F, @T1(%G1) [symbolic] // CHECK:STDOUT: %T1.F.0df085.1: %T1.F.type.ebcc3f.1 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.fdd: = impl_witness @T1.%Destroy.impl_witness_table, @T1.as.Destroy.impl(%G1) [symbolic] +// CHECK:STDOUT: %ptr.997: type = ptr_type %T1.18aea2.1 [symbolic] +// CHECK:STDOUT: %pattern_type.f06: type = pattern_type %ptr.997 [symbolic] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.type: type = fn_type @T1.as.Destroy.impl.Op, @T1.as.Destroy.impl(%G1) [symbolic] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op: %T1.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %T1.F.specific_fn.1e2a8c.1: = specific_function %T1.F.0df085.1, @T1.F(%G1) [symbolic] // CHECK:STDOUT: %T1.vtable_ptr.b5fc91.1: ref %ptr.454 = vtable_ptr @T1.vtable, @T1(%G1) [symbolic] @@ -5013,6 +6965,11 @@ class T2(G2:! type) { // CHECK:STDOUT: %T1.vtable_ptr.b5fc91.2: ref %ptr.454 = vtable_ptr @T1.vtable, @T1(%G2) [symbolic] // CHECK:STDOUT: %require_complete.86d019.2: = require_complete_type %T1.18aea2.2 [symbolic] // CHECK:STDOUT: %T2.elem: type = unbound_element_type %T2, %T1.18aea2.2 [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.fb2: = impl_witness @T2.%Destroy.impl_witness_table, @T2.as.Destroy.impl(%G2) [symbolic] +// CHECK:STDOUT: %ptr.112: type = ptr_type %T2 [symbolic] +// CHECK:STDOUT: %pattern_type.8f6: type = pattern_type %ptr.112 [symbolic] +// CHECK:STDOUT: %T2.as.Destroy.impl.Op.type: type = fn_type @T2.as.Destroy.impl.Op, @T2.as.Destroy.impl(%G2) [symbolic] +// CHECK:STDOUT: %T2.as.Destroy.impl.Op: %T2.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %T2.vtable_ptr: ref %ptr.454 = vtable_ptr @T2.vtable, @T2(%G2) [symbolic] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %T1.18aea2.2} [symbolic] // CHECK:STDOUT: %complete_type.987: = complete_type_witness %struct_type.base [symbolic] @@ -5020,9 +6977,11 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -5044,6 +7003,62 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @T1.as.Destroy.impl(@T1.%G1.loc4_15.2: type) { +// CHECK:STDOUT: %G1: type = bind_symbolic_name G1, 0 [symbolic = %G1 (constants.%G1)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @T1.%Destroy.impl_witness_table, @T1.as.Destroy.impl(%G1) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.fdd)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.type: type = fn_type @T1.as.Destroy.impl.Op, @T1.as.Destroy.impl(%G1) [symbolic = %T1.as.Destroy.impl.Op.type (constants.%T1.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op: @T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.type (%T1.as.Destroy.impl.Op.type) = struct_value () [symbolic = %T1.as.Destroy.impl.Op (constants.%T1.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%T1.18aea2.1 as constants.%Destroy.type { +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.decl: @T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.type (%T1.as.Destroy.impl.Op.type) = fn_decl @T1.as.Destroy.impl.Op [symbolic = @T1.as.Destroy.impl.%T1.as.Destroy.impl.Op (constants.%T1.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @T1.as.Destroy.impl.Op.%pattern_type (%pattern_type.f06) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @T1.as.Destroy.impl.Op.%pattern_type (%pattern_type.f06) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_26.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @T1.as.Destroy.impl.Op.%ptr (%ptr.997) = value_param call_param0 +// CHECK:STDOUT: %.loc4_26.2: type = splice_block %Self.ref [symbolic = %T1 (constants.%T1.18aea2.1)] { +// CHECK:STDOUT: %.loc4_26.3: type = specific_constant constants.%T1.18aea2.1, @T1(constants.%G1) [symbolic = %T1 (constants.%T1.18aea2.1)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_26.3 [symbolic = %T1 (constants.%T1.18aea2.1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @T1.as.Destroy.impl.Op.%ptr (%ptr.997) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @T2.as.Destroy.impl(@T2.%G2.loc8_10.2: type) { +// CHECK:STDOUT: %G2: type = bind_symbolic_name G2, 0 [symbolic = %G2 (constants.%G2)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @T2.%Destroy.impl_witness_table, @T2.as.Destroy.impl(%G2) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.fb2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %T2.as.Destroy.impl.Op.type: type = fn_type @T2.as.Destroy.impl.Op, @T2.as.Destroy.impl(%G2) [symbolic = %T2.as.Destroy.impl.Op.type (constants.%T2.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %T2.as.Destroy.impl.Op: @T2.as.Destroy.impl.%T2.as.Destroy.impl.Op.type (%T2.as.Destroy.impl.Op.type) = struct_value () [symbolic = %T2.as.Destroy.impl.Op (constants.%T2.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%T2 as constants.%Destroy.type { +// CHECK:STDOUT: %T2.as.Destroy.impl.Op.decl: @T2.as.Destroy.impl.%T2.as.Destroy.impl.Op.type (%T2.as.Destroy.impl.Op.type) = fn_decl @T2.as.Destroy.impl.Op [symbolic = @T2.as.Destroy.impl.%T2.as.Destroy.impl.Op (constants.%T2.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @T2.as.Destroy.impl.Op.%pattern_type (%pattern_type.8f6) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @T2.as.Destroy.impl.Op.%pattern_type (%pattern_type.8f6) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8_21.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @T2.as.Destroy.impl.Op.%ptr (%ptr.112) = value_param call_param0 +// CHECK:STDOUT: %.loc8_21.2: type = splice_block %Self.ref [symbolic = %T2 (constants.%T2)] { +// CHECK:STDOUT: %.loc8_21.3: type = specific_constant constants.%T2, @T2(constants.%G2) [symbolic = %T2 (constants.%T2)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc8_21.3 [symbolic = %T2 (constants.%T2)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @T2.as.Destroy.impl.Op.%ptr (%ptr.112) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T2.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T2.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @T1(%G1.loc4_15.2: type) { // CHECK:STDOUT: %G1.loc4_15.1: type = bind_symbolic_name G1, 0 [symbolic = %G1.loc4_15.1 (constants.%G1)] // CHECK:STDOUT: @@ -5065,6 +7080,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %self: @T1.F.%T1 (%T1.18aea2.1) = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @T1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.decl), @T1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @T1.as.Destroy.impl(constants.%G1) [symbolic = @T1.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.fdd)] // CHECK:STDOUT: %T1.F.specific_fn.loc6_1.1: = specific_function %T1.F.decl, @T1.F(constants.%G1) [symbolic = %T1.F.specific_fn.loc6_1.2 (constants.%T1.F.specific_fn.1e2a8c.1)] // CHECK:STDOUT: %vtable_ptr.loc6_1.1: ref %ptr.454 = vtable_ptr @T1.vtable, @T1(constants.%G1) [symbolic = %vtable_ptr.loc6_1.2 (constants.%T1.vtable_ptr.b5fc91.1)] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] @@ -5098,6 +7116,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %G2.ref: type = name_ref G2, %G2.loc8_10.2 [symbolic = %G2.loc8_10.1 (constants.%G2)] // CHECK:STDOUT: %T1.loc9_21.1: type = class_type @T1, @T1(constants.%G2) [symbolic = %T1.loc9_21.2 (constants.%T1.18aea2.2)] // CHECK:STDOUT: %.loc9: @T2.%T2.elem (%T2.elem) = base_decl %T1.loc9_21.1, element0 [concrete] +// CHECK:STDOUT: impl_decl @T2.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T2.as.Destroy.impl.%T2.as.Destroy.impl.Op.decl), @T2.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @T2.as.Destroy.impl(constants.%G2) [symbolic = @T2.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.fb2)] // CHECK:STDOUT: %T1.F.specific_fn.loc10_1.1: = specific_function constants.%T1.F.0df085.2, @T1.F(constants.%G2) [symbolic = %T1.F.specific_fn.loc10_1.2 (constants.%T1.F.specific_fn.1e2a8c.2)] // CHECK:STDOUT: %vtable_ptr.loc10_1.1: ref %ptr.454 = vtable_ptr @T2.vtable, @T2(constants.%G2) [symbolic = %vtable_ptr.loc10_1.2 (constants.%T2.vtable_ptr)] // CHECK:STDOUT: %struct_type.base.loc10_1.1: type = struct_type {.base: %T1.18aea2.2} [symbolic = %struct_type.base.loc10_1.2 (constants.%struct_type.base)] @@ -5136,6 +7157,28 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @T1.as.Destroy.impl.Op(@T1.%G1.loc4_15.2: type) { +// CHECK:STDOUT: %G1: type = bind_symbolic_name G1, 0 [symbolic = %G1 (constants.%G1)] +// CHECK:STDOUT: %T1: type = class_type @T1, @T1(%G1) [symbolic = %T1 (constants.%T1.18aea2.1)] +// CHECK:STDOUT: %ptr: type = ptr_type %T1 [symbolic = %ptr (constants.%ptr.997)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.f06)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @T1.as.Destroy.impl.Op.%ptr (%ptr.997)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @T2.as.Destroy.impl.Op(@T2.%G2.loc8_10.2: type) { +// CHECK:STDOUT: %G2: type = bind_symbolic_name G2, 0 [symbolic = %G2 (constants.%G2)] +// CHECK:STDOUT: %T2: type = class_type @T2, @T2(%G2) [symbolic = %T2 (constants.%T2)] +// CHECK:STDOUT: %ptr: type = ptr_type %T2 [symbolic = %ptr (constants.%ptr.112)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.8f6)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @T2.as.Destroy.impl.Op.%ptr (%ptr.112)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @T1(constants.%G1) { // CHECK:STDOUT: %G1.loc4_15.1 => constants.%G1 // CHECK:STDOUT: @@ -5155,6 +7198,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete => constants.%require_complete.86d019.1 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @T1.as.Destroy.impl(constants.%G1) { +// CHECK:STDOUT: %G1 => constants.%G1 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.fdd +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @T1.as.Destroy.impl.Op(constants.%G1) { +// CHECK:STDOUT: %G1 => constants.%G1 +// CHECK:STDOUT: %T1 => constants.%T1.18aea2.1 +// CHECK:STDOUT: %ptr => constants.%ptr.997 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.f06 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @T2(constants.%G2) { // CHECK:STDOUT: %G2.loc8_10.1 => constants.%G2 // CHECK:STDOUT: } @@ -5178,6 +7233,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete => constants.%require_complete.86d019.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @T2.as.Destroy.impl(constants.%G2) { +// CHECK:STDOUT: %G2 => constants.%G2 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.fb2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @T2.as.Destroy.impl.Op(constants.%G2) { +// CHECK:STDOUT: %G2 => constants.%G2 +// CHECK:STDOUT: %T2 => constants.%T2 +// CHECK:STDOUT: %ptr => constants.%ptr.112 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.8f6 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- generic_derived_generic_context.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -5189,6 +7256,13 @@ class T2(G2:! type) { // CHECK:STDOUT: %pattern_type.48ecf1.1: type = pattern_type %T1.18aea2.1 [symbolic] // CHECK:STDOUT: %T1.F.type.ebcc3f.1: type = fn_type @T1.F, @T1(%G1) [symbolic] // CHECK:STDOUT: %T1.F.0df085.1: %T1.F.type.ebcc3f.1 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.fdd: = impl_witness @T1.%Destroy.impl_witness_table, @T1.as.Destroy.impl(%G1) [symbolic] +// CHECK:STDOUT: %ptr.997: type = ptr_type %T1.18aea2.1 [symbolic] +// CHECK:STDOUT: %pattern_type.f06: type = pattern_type %ptr.997 [symbolic] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.type: type = fn_type @T1.as.Destroy.impl.Op, @T1.as.Destroy.impl(%G1) [symbolic] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op: %T1.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] // CHECK:STDOUT: %T1.F.specific_fn.1e2a8c.1: = specific_function %T1.F.0df085.1, @T1.F(%G1) [symbolic] // CHECK:STDOUT: %T1.vtable_ptr.b5fc91.1: ref %ptr.454 = vtable_ptr @T1.vtable, @T1(%G1) [symbolic] @@ -5208,18 +7282,30 @@ class T2(G2:! type) { // CHECK:STDOUT: %T1.vtable_ptr.b5fc91.2: ref %ptr.454 = vtable_ptr @T1.vtable, @T1(%G2) [symbolic] // CHECK:STDOUT: %require_complete.86d019.2: = require_complete_type %T1.18aea2.2 [symbolic] // CHECK:STDOUT: %T3.elem: type = unbound_element_type %T3, %T1.18aea2.2 [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.7f3: = impl_witness @T3.%Destroy.impl_witness_table, @T3.as.Destroy.impl(%G2) [symbolic] +// CHECK:STDOUT: %ptr.625: type = ptr_type %T3 [symbolic] +// CHECK:STDOUT: %pattern_type.753: type = pattern_type %ptr.625 [symbolic] +// CHECK:STDOUT: %T3.as.Destroy.impl.Op.type: type = fn_type @T3.as.Destroy.impl.Op, @T3.as.Destroy.impl(%G2) [symbolic] +// CHECK:STDOUT: %T3.as.Destroy.impl.Op: %T3.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %T3.vtable_ptr: ref %ptr.454 = vtable_ptr @T3.vtable, @T3(%G2) [symbolic] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %T1.18aea2.2} [symbolic] // CHECK:STDOUT: %complete_type.987: = complete_type_witness %struct_type.base [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.fb2: = impl_witness @T2.%Destroy.impl_witness_table, @T2.as.Destroy.impl(%G2) [symbolic] +// CHECK:STDOUT: %ptr.112: type = ptr_type %T2 [symbolic] +// CHECK:STDOUT: %pattern_type.8f6: type = pattern_type %ptr.112 [symbolic] +// CHECK:STDOUT: %T2.as.Destroy.impl.Op.type: type = fn_type @T2.as.Destroy.impl.Op, @T2.as.Destroy.impl(%G2) [symbolic] +// CHECK:STDOUT: %T2.as.Destroy.impl.Op: %T2.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -5241,6 +7327,90 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @T1.as.Destroy.impl(@T1.%G1.loc4_15.2: type) { +// CHECK:STDOUT: %G1: type = bind_symbolic_name G1, 0 [symbolic = %G1 (constants.%G1)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @T1.%Destroy.impl_witness_table, @T1.as.Destroy.impl(%G1) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.fdd)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.type: type = fn_type @T1.as.Destroy.impl.Op, @T1.as.Destroy.impl(%G1) [symbolic = %T1.as.Destroy.impl.Op.type (constants.%T1.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %T1.as.Destroy.impl.Op: @T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.type (%T1.as.Destroy.impl.Op.type) = struct_value () [symbolic = %T1.as.Destroy.impl.Op (constants.%T1.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%T1.18aea2.1 as constants.%Destroy.type { +// CHECK:STDOUT: %T1.as.Destroy.impl.Op.decl: @T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.type (%T1.as.Destroy.impl.Op.type) = fn_decl @T1.as.Destroy.impl.Op [symbolic = @T1.as.Destroy.impl.%T1.as.Destroy.impl.Op (constants.%T1.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @T1.as.Destroy.impl.Op.%pattern_type (%pattern_type.f06) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @T1.as.Destroy.impl.Op.%pattern_type (%pattern_type.f06) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_26.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @T1.as.Destroy.impl.Op.%ptr (%ptr.997) = value_param call_param0 +// CHECK:STDOUT: %.loc4_26.2: type = splice_block %Self.ref [symbolic = %T1 (constants.%T1.18aea2.1)] { +// CHECK:STDOUT: %.loc4_26.3: type = specific_constant constants.%T1.18aea2.1, @T1(constants.%G1) [symbolic = %T1 (constants.%T1.18aea2.1)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_26.3 [symbolic = %T1 (constants.%T1.18aea2.1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @T1.as.Destroy.impl.Op.%ptr (%ptr.997) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @T3.as.Destroy.impl(@T2.%G2.loc8_10.2: type) { +// CHECK:STDOUT: %G2: type = bind_symbolic_name G2, 0 [symbolic = %G2 (constants.%G2)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @T3.%Destroy.impl_witness_table, @T3.as.Destroy.impl(%G2) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.7f3)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %T3.as.Destroy.impl.Op.type: type = fn_type @T3.as.Destroy.impl.Op, @T3.as.Destroy.impl(%G2) [symbolic = %T3.as.Destroy.impl.Op.type (constants.%T3.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %T3.as.Destroy.impl.Op: @T3.as.Destroy.impl.%T3.as.Destroy.impl.Op.type (%T3.as.Destroy.impl.Op.type) = struct_value () [symbolic = %T3.as.Destroy.impl.Op (constants.%T3.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%T3 as constants.%Destroy.type { +// CHECK:STDOUT: %T3.as.Destroy.impl.Op.decl: @T3.as.Destroy.impl.%T3.as.Destroy.impl.Op.type (%T3.as.Destroy.impl.Op.type) = fn_decl @T3.as.Destroy.impl.Op [symbolic = @T3.as.Destroy.impl.%T3.as.Destroy.impl.Op (constants.%T3.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @T3.as.Destroy.impl.Op.%pattern_type (%pattern_type.753) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @T3.as.Destroy.impl.Op.%pattern_type (%pattern_type.753) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9_12.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @T3.as.Destroy.impl.Op.%ptr (%ptr.625) = value_param call_param0 +// CHECK:STDOUT: %.loc9_12.2: type = splice_block %Self.ref [symbolic = %T3 (constants.%T3)] { +// CHECK:STDOUT: %.loc9_12.3: type = specific_constant constants.%T3, @T3(constants.%G2) [symbolic = %T3 (constants.%T3)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc9_12.3 [symbolic = %T3 (constants.%T3)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @T3.as.Destroy.impl.Op.%ptr (%ptr.625) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T3.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T3.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @T2.as.Destroy.impl(@T2.%G2.loc8_10.2: type) { +// CHECK:STDOUT: %G2: type = bind_symbolic_name G2, 0 [symbolic = %G2 (constants.%G2)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @T2.%Destroy.impl_witness_table, @T2.as.Destroy.impl(%G2) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.fb2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %T2.as.Destroy.impl.Op.type: type = fn_type @T2.as.Destroy.impl.Op, @T2.as.Destroy.impl(%G2) [symbolic = %T2.as.Destroy.impl.Op.type (constants.%T2.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %T2.as.Destroy.impl.Op: @T2.as.Destroy.impl.%T2.as.Destroy.impl.Op.type (%T2.as.Destroy.impl.Op.type) = struct_value () [symbolic = %T2.as.Destroy.impl.Op (constants.%T2.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%T2 as constants.%Destroy.type { +// CHECK:STDOUT: %T2.as.Destroy.impl.Op.decl: @T2.as.Destroy.impl.%T2.as.Destroy.impl.Op.type (%T2.as.Destroy.impl.Op.type) = fn_decl @T2.as.Destroy.impl.Op [symbolic = @T2.as.Destroy.impl.%T2.as.Destroy.impl.Op (constants.%T2.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @T2.as.Destroy.impl.Op.%pattern_type (%pattern_type.8f6) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @T2.as.Destroy.impl.Op.%pattern_type (%pattern_type.8f6) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8_21.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @T2.as.Destroy.impl.Op.%ptr (%ptr.112) = value_param call_param0 +// CHECK:STDOUT: %.loc8_21.2: type = splice_block %Self.ref [symbolic = %T2 (constants.%T2)] { +// CHECK:STDOUT: %.loc8_21.3: type = specific_constant constants.%T2, @T2(constants.%G2) [symbolic = %T2 (constants.%T2)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc8_21.3 [symbolic = %T2 (constants.%T2)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @T2.as.Destroy.impl.Op.%ptr (%ptr.112) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %T2.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @T2.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @T1(%G1.loc4_15.2: type) { // CHECK:STDOUT: %G1.loc4_15.1: type = bind_symbolic_name G1, 0 [symbolic = %G1.loc4_15.1 (constants.%G1)] // CHECK:STDOUT: @@ -5262,6 +7432,9 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %self: @T1.F.%T1 (%T1.18aea2.1) = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @T1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T1.as.Destroy.impl.%T1.as.Destroy.impl.Op.decl), @T1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @T1.as.Destroy.impl(constants.%G1) [symbolic = @T1.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.fdd)] // CHECK:STDOUT: %T1.F.specific_fn.loc6_1.1: = specific_function %T1.F.decl, @T1.F(constants.%G1) [symbolic = %T1.F.specific_fn.loc6_1.2 (constants.%T1.F.specific_fn.1e2a8c.1)] // CHECK:STDOUT: %vtable_ptr.loc6_1.1: ref %ptr.454 = vtable_ptr @T1.vtable, @T1(constants.%G1) [symbolic = %vtable_ptr.loc6_1.2 (constants.%T1.vtable_ptr.b5fc91.1)] // CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete = constants.%struct_type.vptr] @@ -5283,6 +7456,9 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: %T3.decl: type = class_decl @T3 [symbolic = @T2.%T3 (constants.%T3)] {} {} +// CHECK:STDOUT: impl_decl @T2.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T2.as.Destroy.impl.%T2.as.Destroy.impl.Op.decl), @T2.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @T2.as.Destroy.impl(constants.%G2) [symbolic = @T2.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.fb2)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -5314,6 +7490,9 @@ class T2(G2:! type) { // CHECK:STDOUT: %G2.ref: type = name_ref G2, @T2.%G2.loc8_10.2 [symbolic = %G2 (constants.%G2)] // CHECK:STDOUT: %T1.loc10_24.1: type = class_type @T1, @T1(constants.%G2) [symbolic = %T1.loc10_24.2 (constants.%T1.18aea2.2)] // CHECK:STDOUT: %.loc10: @T3.%T3.elem (%T3.elem) = base_decl %T1.loc10_24.1, element0 [concrete] +// CHECK:STDOUT: impl_decl @T3.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@T3.as.Destroy.impl.%T3.as.Destroy.impl.Op.decl), @T3.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @T3.as.Destroy.impl(constants.%G2) [symbolic = @T3.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.7f3)] // CHECK:STDOUT: %T1.F.specific_fn.loc11_3.1: = specific_function constants.%T1.F.0df085.2, @T1.F(constants.%G2) [symbolic = %T1.F.specific_fn.loc11_3.2 (constants.%T1.F.specific_fn.1e2a8c.2)] // CHECK:STDOUT: %vtable_ptr.loc11_3.1: ref %ptr.454 = vtable_ptr @T3.vtable, @T3(constants.%G2) [symbolic = %vtable_ptr.loc11_3.2 (constants.%T3.vtable_ptr)] // CHECK:STDOUT: %struct_type.base.loc11_3.1: type = struct_type {.base: %T1.18aea2.2} [symbolic = %struct_type.base.loc11_3.2 (constants.%struct_type.base)] @@ -5352,6 +7531,39 @@ class T2(G2:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @T1.as.Destroy.impl.Op(@T1.%G1.loc4_15.2: type) { +// CHECK:STDOUT: %G1: type = bind_symbolic_name G1, 0 [symbolic = %G1 (constants.%G1)] +// CHECK:STDOUT: %T1: type = class_type @T1, @T1(%G1) [symbolic = %T1 (constants.%T1.18aea2.1)] +// CHECK:STDOUT: %ptr: type = ptr_type %T1 [symbolic = %ptr (constants.%ptr.997)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.f06)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @T1.as.Destroy.impl.Op.%ptr (%ptr.997)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @T3.as.Destroy.impl.Op(@T2.%G2.loc8_10.2: type) { +// CHECK:STDOUT: %G2: type = bind_symbolic_name G2, 0 [symbolic = %G2 (constants.%G2)] +// CHECK:STDOUT: %T3: type = class_type @T3, @T3(%G2) [symbolic = %T3 (constants.%T3)] +// CHECK:STDOUT: %ptr: type = ptr_type %T3 [symbolic = %ptr (constants.%ptr.625)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.753)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @T3.as.Destroy.impl.Op.%ptr (%ptr.625)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @T2.as.Destroy.impl.Op(@T2.%G2.loc8_10.2: type) { +// CHECK:STDOUT: %G2: type = bind_symbolic_name G2, 0 [symbolic = %G2 (constants.%G2)] +// CHECK:STDOUT: %T2: type = class_type @T2, @T2(%G2) [symbolic = %T2 (constants.%T2)] +// CHECK:STDOUT: %ptr: type = ptr_type %T2 [symbolic = %ptr (constants.%ptr.112)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.8f6)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @T2.as.Destroy.impl.Op.%ptr (%ptr.112)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @T1(constants.%G1) { // CHECK:STDOUT: %G1.loc4_15.1 => constants.%G1 // CHECK:STDOUT: @@ -5371,6 +7583,18 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete => constants.%require_complete.86d019.1 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @T1.as.Destroy.impl(constants.%G1) { +// CHECK:STDOUT: %G1 => constants.%G1 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.fdd +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @T1.as.Destroy.impl.Op(constants.%G1) { +// CHECK:STDOUT: %G1 => constants.%G1 +// CHECK:STDOUT: %T1 => constants.%T1.18aea2.1 +// CHECK:STDOUT: %ptr => constants.%ptr.997 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.f06 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @T2(constants.%G2) { // CHECK:STDOUT: %G2.loc8_10.1 => constants.%G2 // CHECK:STDOUT: } @@ -5396,3 +7620,27 @@ class T2(G2:! type) { // CHECK:STDOUT: %require_complete => constants.%require_complete.86d019.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @T3.as.Destroy.impl(constants.%G2) { +// CHECK:STDOUT: %G2 => constants.%G2 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.7f3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @T3.as.Destroy.impl.Op(constants.%G2) { +// CHECK:STDOUT: %G2 => constants.%G2 +// CHECK:STDOUT: %T3 => constants.%T3 +// CHECK:STDOUT: %ptr => constants.%ptr.625 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.753 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @T2.as.Destroy.impl(constants.%G2) { +// CHECK:STDOUT: %G2 => constants.%G2 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.fb2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @T2.as.Destroy.impl.Op(constants.%G2) { +// CHECK:STDOUT: %G2 => constants.%G2 +// CHECK:STDOUT: %T2 => constants.%T2 +// CHECK:STDOUT: %ptr => constants.%ptr.112 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.8f6 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/deduce/array.carbon b/toolchain/check/testdata/deduce/array.carbon index 4dd44426c375..ec547a7e5120 100644 --- a/toolchain/check/testdata/deduce/array.carbon +++ b/toolchain/check/testdata/deduce/array.carbon @@ -129,6 +129,14 @@ fn G() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] @@ -138,7 +146,6 @@ fn G() -> i32 { // CHECK:STDOUT: %pattern_type.58b: type = pattern_type %array_type.743 [symbolic] // CHECK:STDOUT: %pattern_type.7dcd0a.1: type = pattern_type %T [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %require_complete.06f: = require_complete_type %array_type.743 [symbolic] @@ -175,30 +182,25 @@ fn G() -> i32 { // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: %array: %array_type.002 = tuple_value (%C.val, %C.val, %C.val) [concrete] // CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%C) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.6eb: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.85d: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%array_type.002) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.1f9: %T.as.Destroy.impl.Op.type.85d = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.f55: = specific_function %T.as.Destroy.impl.Op.1f9, @T.as.Destroy.impl.Op(%array_type.002) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.1f9, @T.as.Destroy.impl.Op(%array_type.002) [concrete] // CHECK:STDOUT: %complete_type.dd1: = complete_type_witness %array_type.002 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs -// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -239,7 +241,26 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -248,6 +269,8 @@ fn G() -> i32 { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc6_6.2: type) { // CHECK:STDOUT: %T.loc6_6.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.1 (constants.%T)] // CHECK:STDOUT: %array_type.loc6_29.1: type = array_type constants.%int_3, %T.loc6_6.1 [symbolic = %array_type.loc6_29.1 (constants.%array_type.743)] @@ -316,16 +339,14 @@ fn G() -> i32 { // CHECK:STDOUT: %.loc8: ref %C = splice_block %return {} // CHECK:STDOUT: %.loc10: %array_type.002 = bind_value %a.ref // CHECK:STDOUT: %F.call: init %C = call %F.specific_fn(%.loc10) to %.loc8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8: = bound_method %.loc8, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6eb] -// CHECK:STDOUT: %bound_method.loc8: = bound_method %.loc8, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc8, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc8: %ptr.019 = addr_of %.loc8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8: init %empty_tuple.type = call %bound_method.loc8(%addr.loc8) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9: = bound_method %a.var, constants.%T.as.Destroy.impl.Op.1f9 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.1f9, @T.as.Destroy.impl.Op(constants.%array_type.002) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.f55] -// CHECK:STDOUT: %bound_method.loc9: = bound_method %a.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr.loc8) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %a.var, constants.%T.as.Destroy.impl.Op.1f9 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.1f9, @T.as.Destroy.impl.Op(constants.%array_type.002) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method: = bound_method %a.var, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr.loc9: %ptr.301 = addr_of %a.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9: init %empty_tuple.type = call %bound_method.loc9(%addr.loc9) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc9) // CHECK:STDOUT: return %F.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -351,6 +372,14 @@ fn G() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %IntLiteral.type: type = fn_type @IntLiteral [concrete] @@ -361,7 +390,6 @@ fn G() -> i32 { // CHECK:STDOUT: %pattern_type.9ee: type = pattern_type %array_type.6a2 [symbolic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] @@ -397,7 +425,6 @@ fn G() -> i32 { // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: %array: %array_type.002 = tuple_value (%C.val, %C.val, %C.val) [concrete] // CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%int_3.1ba) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.85d: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%array_type.002) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.1f9: %T.as.Destroy.impl.Op.type.85d = struct_value () [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.1f9, @T.as.Destroy.impl.Op(%array_type.002) [concrete] @@ -409,19 +436,19 @@ fn G() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .IntLiteral = %Core.IntLiteral // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs -// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.IntLiteral: %IntLiteral.type = import_ref Core//prelude/parts/int_literal, IntLiteral, loaded [concrete = constants.%IntLiteral] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -471,7 +498,26 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -480,6 +526,8 @@ fn G() -> i32 { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%N.loc6_6.2: Core.IntLiteral) { // CHECK:STDOUT: %N.loc6_6.1: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N.loc6_6.1 (constants.%N)] // CHECK:STDOUT: %array_type.loc6_42.1: type = array_type %N.loc6_6.1, constants.%C [symbolic = %array_type.loc6_42.1 (constants.%array_type.6a2)] @@ -574,6 +622,14 @@ fn G() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] @@ -585,7 +641,6 @@ fn G() -> i32 { // CHECK:STDOUT: %array_type.bb5: type = array_type %N, %T [symbolic] // CHECK:STDOUT: %pattern_type.261: type = pattern_type %array_type.bb5 [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.ec9: = require_complete_type %array_type.bb5 [symbolic] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] @@ -601,7 +656,6 @@ fn G() -> i32 { // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: %array: %array_type.002 = tuple_value (%C.val, %C.val, %C.val) [concrete] // CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%C, %int_3) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.85d: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%array_type.002) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.1f9: %T.as.Destroy.impl.Op.type.85d = struct_value () [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.1f9, @T.as.Destroy.impl.Op(%array_type.002) [concrete] @@ -610,13 +664,13 @@ fn G() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { -// CHECK:STDOUT: .IntLiteral = %Core.IntLiteral // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .IntLiteral = %Core.IntLiteral // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Core.IntLiteral: %IntLiteral.type = import_ref Core//prelude/parts/int_literal, IntLiteral, loaded [concrete = constants.%IntLiteral] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Core.IntLiteral: %IntLiteral.type = import_ref Core//prelude/parts/int_literal, IntLiteral, loaded [concrete = constants.%IntLiteral] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -654,7 +708,26 @@ fn G() -> i32 { // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -663,6 +736,8 @@ fn G() -> i32 { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc6_6.2: type, %N.loc6_16.2: Core.IntLiteral) { // CHECK:STDOUT: %T.loc6_6.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.1 (constants.%T)] // CHECK:STDOUT: %N.loc6_16.1: Core.IntLiteral = bind_symbolic_name N, 1 [symbolic = %N.loc6_16.1 (constants.%N)] @@ -744,6 +819,14 @@ fn G() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] @@ -753,7 +836,6 @@ fn G() -> i32 { // CHECK:STDOUT: %pattern_type.a4c: type = pattern_type %array_type.9d4 [symbolic] // CHECK:STDOUT: %pattern_type.7dcd0a.1: type = pattern_type %T [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %require_complete.d11: = require_complete_type %array_type.9d4 [symbolic] @@ -792,30 +874,25 @@ fn G() -> i32 { // CHECK:STDOUT: %array_type.15a: type = array_type %int_2, %C [concrete] // CHECK:STDOUT: %pattern_type.114: type = pattern_type %array_type.15a [concrete] // CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%C) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.6eb: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.85d: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%array_type.002) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.1f9: %T.as.Destroy.impl.Op.type.85d = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.f55: = specific_function %T.as.Destroy.impl.Op.1f9, @T.as.Destroy.impl.Op(%array_type.002) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.1f9, @T.as.Destroy.impl.Op(%array_type.002) [concrete] // CHECK:STDOUT: %complete_type.8eb: = complete_type_witness %array_type.15a [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs -// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -856,7 +933,26 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -865,6 +961,8 @@ fn G() -> i32 { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc6_6.2: type) { // CHECK:STDOUT: %T.loc6_6.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.1 (constants.%T)] // CHECK:STDOUT: %array_type.loc6_29.1: type = array_type constants.%int_2, %T.loc6_6.1 [symbolic = %array_type.loc6_29.1 (constants.%array_type.9d4)] @@ -933,16 +1031,14 @@ fn G() -> i32 { // CHECK:STDOUT: %.loc8: ref %C = splice_block %return {} // CHECK:STDOUT: %.loc21: %array_type.15a = converted %a.ref, [concrete = ] // CHECK:STDOUT: %F.call: init %C = call %F.specific_fn() to %.loc8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8: = bound_method %.loc8, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6eb] -// CHECK:STDOUT: %bound_method.loc8: = bound_method %.loc8, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc8, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc8: %ptr.019 = addr_of %.loc8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8: init %empty_tuple.type = call %bound_method.loc8(%addr.loc8) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10: = bound_method %a.var, constants.%T.as.Destroy.impl.Op.1f9 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.1f9, @T.as.Destroy.impl.Op(constants.%array_type.002) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.f55] -// CHECK:STDOUT: %bound_method.loc10: = bound_method %a.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr.loc8) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %a.var, constants.%T.as.Destroy.impl.Op.1f9 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.1f9, @T.as.Destroy.impl.Op(constants.%array_type.002) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method: = bound_method %a.var, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr.loc10: %ptr.301 = addr_of %a.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10: init %empty_tuple.type = call %bound_method.loc10(%addr.loc10) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc10) // CHECK:STDOUT: return %F.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -968,9 +1064,22 @@ fn G() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %IntLiteral.type: type = fn_type @IntLiteral [concrete] // CHECK:STDOUT: %IntLiteral: %IntLiteral.type = struct_value () [concrete] // CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic] @@ -979,7 +1088,6 @@ fn G() -> i32 { // CHECK:STDOUT: %pattern_type.9ee: type = pattern_type %array_type.6a2 [symbolic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] @@ -1017,7 +1125,6 @@ fn G() -> i32 { // CHECK:STDOUT: %array_type.002: type = array_type %int_3.1ba, %C [concrete] // CHECK:STDOUT: %pattern_type.a63: type = pattern_type %array_type.002 [concrete] // CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%int_3.1ba) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.419: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%array_type.fe4) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.11a: %T.as.Destroy.impl.Op.type.419 = struct_value () [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.11a, @T.as.Destroy.impl.Op(%array_type.fe4) [concrete] @@ -1029,19 +1136,19 @@ fn G() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .IntLiteral = %Core.IntLiteral // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs -// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.IntLiteral: %IntLiteral.type = import_ref Core//prelude/parts/int_literal, IntLiteral, loaded [concrete = constants.%IntLiteral] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1093,7 +1200,42 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1103,6 +1245,9 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1111,6 +1256,10 @@ fn G() -> i32 { // CHECK:STDOUT: .Self = constants.%D // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%N.loc7_6.2: Core.IntLiteral) { // CHECK:STDOUT: %N.loc7_6.1: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N.loc7_6.1 (constants.%N)] // CHECK:STDOUT: %array_type.loc7_42.1: type = array_type %N.loc7_6.1, constants.%C [symbolic = %array_type.loc7_42.1 (constants.%array_type.6a2)] @@ -1205,11 +1354,18 @@ fn G() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %N.51e: %i32 = bind_symbolic_name N, 0 [symbolic] @@ -1247,7 +1403,6 @@ fn G() -> i32 { // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: %array: %array_type.002 = tuple_value (%C.val, %C.val, %C.val) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.85d: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%array_type.002) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.1f9: %T.as.Destroy.impl.Op.type.85d = struct_value () [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.1f9, @T.as.Destroy.impl.Op(%array_type.002) [concrete] @@ -1255,17 +1410,17 @@ fn G() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs -// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.85c: @Int.as.ImplicitAs.impl.%Int.as.ImplicitAs.impl.Convert.type (%Int.as.ImplicitAs.impl.Convert.type.708) = import_ref Core//prelude/parts/int, loc20_44, loaded [symbolic = @Int.as.ImplicitAs.impl.%Int.as.ImplicitAs.impl.Convert (constants.%Int.as.ImplicitAs.impl.Convert.c68)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.1d9 = impl_witness_table (%Core.import_ref.85c), @Int.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1319,7 +1474,26 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1328,6 +1502,8 @@ fn G() -> i32 { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%N.loc6_6.2: %i32) { // CHECK:STDOUT: %N.loc6_6.1: %i32 = bind_symbolic_name N, 0 [symbolic = %N.loc6_6.1 (constants.%N.51e)] // CHECK:STDOUT: %Int.as.ImplicitAs.impl.Convert.bound: = bound_method %N.loc6_6.1, constants.%Int.as.ImplicitAs.impl.Convert.960 [symbolic = %Int.as.ImplicitAs.impl.Convert.bound (constants.%Int.as.ImplicitAs.impl.Convert.bound)] diff --git a/toolchain/check/testdata/deduce/binding_pattern.carbon b/toolchain/check/testdata/deduce/binding_pattern.carbon index fe0f2773697e..664e1c5cd1ee 100644 --- a/toolchain/check/testdata/deduce/binding_pattern.carbon +++ b/toolchain/check/testdata/deduce/binding_pattern.carbon @@ -69,6 +69,13 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: %pattern_type.7dcd0a.1: type = pattern_type %T [symbolic] // CHECK:STDOUT: %C.Create.type.f31: type = fn_type @C.Create, @C(%T) [symbolic] // CHECK:STDOUT: %C.Create.cc8: %C.Create.type.f31 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] @@ -98,10 +105,12 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.492: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.ca0) = import_ref Core//prelude/parts/as, loc12_35, loaded [symbolic = @ImplicitAs.%assoc0 (constants.%assoc0.dc0)] // CHECK:STDOUT: %Core.import_ref.1c7: @ImplicitAs.%ImplicitAs.Convert.type (%ImplicitAs.Convert.type.275) = import_ref Core//prelude/parts/as, loc12_35, loaded [symbolic = @ImplicitAs.%ImplicitAs.Convert (constants.%ImplicitAs.Convert.42e)] @@ -129,6 +138,34 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f2e as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc4_19.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.f2e)] { +// CHECK:STDOUT: %.loc4_19.3: type = specific_constant constants.%C.f2e, @C(constants.%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_19.3 [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%T.loc4_9.2: type) { // CHECK:STDOUT: %T.loc4_9.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: @@ -145,6 +182,9 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: %T.ref: type = name_ref T, @C.%T.loc4_9.2 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %value: @C.Create.%T (%T) = bind_name value, %value.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -169,6 +209,17 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%U.loc8_6.2: type, %V.loc8_16.2: type) { // CHECK:STDOUT: %U.loc8_6.1: type = bind_symbolic_name U, 0 [symbolic = %U.loc8_6.1 (constants.%U)] // CHECK:STDOUT: %V.loc8_16.1: type = bind_symbolic_name V, 1 [symbolic = %V.loc8_16.1 (constants.%V)] @@ -216,6 +267,18 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.7dcd0a.1 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.f2e +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%U, constants.%V) { // CHECK:STDOUT: %U.loc8_6.1 => constants.%U // CHECK:STDOUT: %V.loc8_16.1 => constants.%V @@ -249,6 +312,13 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: %pattern_type.7dcd0a.1: type = pattern_type %T [symbolic] // CHECK:STDOUT: %C.Create.type.f31: type = fn_type @C.Create, @C(%T) [symbolic] // CHECK:STDOUT: %C.Create.cc8: %C.Create.type.f31 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] @@ -283,10 +353,12 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.492: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.ca0) = import_ref Core//prelude/parts/as, loc12_35, loaded [symbolic = @ImplicitAs.%assoc0 (constants.%assoc0.dc0)] // CHECK:STDOUT: %Core.import_ref.1c7: @ImplicitAs.%ImplicitAs.Convert.type (%ImplicitAs.Convert.type.275) = import_ref Core//prelude/parts/as, loc12_35, loaded [symbolic = @ImplicitAs.%ImplicitAs.Convert (constants.%ImplicitAs.Convert.42e)] @@ -326,6 +398,34 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f2e as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc4_19.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.f2e)] { +// CHECK:STDOUT: %.loc4_19.3: type = specific_constant constants.%C.f2e, @C(constants.%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_19.3 [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%T.loc4_9.2: type) { // CHECK:STDOUT: %T.loc4_9.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: @@ -342,6 +442,9 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: %T.ref: type = name_ref T, @C.%T.loc4_9.2 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %value: @C.Create.%T (%T) = bind_name value, %value.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -366,6 +469,17 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%U.loc9_6.2: type, %V.loc9_16.2: %type_where) { // CHECK:STDOUT: %U.loc9_6.1: type = bind_symbolic_name U, 0 [symbolic = %U.loc9_6.1 (constants.%U)] // CHECK:STDOUT: %V.loc9_16.1: %type_where = bind_symbolic_name V, 1 [symbolic = %V.loc9_16.1 (constants.%V)] @@ -416,6 +530,18 @@ fn F(U:! type, V:! type where {} impls Core.ImplicitAs(.Self)) { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.7dcd0a.1 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.f2e +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%U, constants.%V) { // CHECK:STDOUT: %U.loc9_6.1 => constants.%U // CHECK:STDOUT: %V.loc9_16.1 => constants.%V diff --git a/toolchain/check/testdata/deduce/generic_type.carbon b/toolchain/check/testdata/deduce/generic_type.carbon index 0e7d312987ee..5224ae873b23 100644 --- a/toolchain/check/testdata/deduce/generic_type.carbon +++ b/toolchain/check/testdata/deduce/generic_type.carbon @@ -78,9 +78,21 @@ fn G() -> i32 { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.f2e: type = class_type @C, @C(%T) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.a08: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.e5e: type = pattern_type %C.f2e [symbolic] // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] @@ -94,11 +106,6 @@ fn G() -> i32 { // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %F.specific_fn.c4a: = specific_function %F, @F(%D) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.548: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%D) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.2d4: %T.as.Destroy.impl.Op.type.548 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(%D) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -163,14 +170,61 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f2e as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc4_19.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.f2e)] { +// CHECK:STDOUT: %.loc4_19.3: type = specific_constant constants.%C.f2e, @C(constants.%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_19.3 [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%T.loc4_9.2: type) { // CHECK:STDOUT: %T.loc4_9.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -179,14 +233,30 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%D // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc7_6.2: type) { // CHECK:STDOUT: %T.loc7_6.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc7_6.1 (constants.%T)] // CHECK:STDOUT: %C.loc7_22.1: type = class_type @C, @C(%T.loc7_6.1) [symbolic = %C.loc7_22.1 (constants.%C.f2e)] @@ -217,11 +287,9 @@ fn G() -> i32 { // CHECK:STDOUT: %F.specific_fn: = specific_function %F.ref, @F(constants.%D) [concrete = constants.%F.specific_fn.c4a] // CHECK:STDOUT: %.loc9_15: ref %D = splice_block %return {} // CHECK:STDOUT: %F.call: init %D = call %F.specific_fn(%p.ref) to %.loc9_15 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc9_15, constants.%T.as.Destroy.impl.Op.2d4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc9_15, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound: = bound_method %.loc9_15, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.19c = addr_of %.loc9_15 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %F.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -231,6 +299,18 @@ fn G() -> i32 { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a08 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.f2e +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%T) { // CHECK:STDOUT: %T.loc7_6.1 => constants.%T // CHECK:STDOUT: %C.loc7_22.1 => constants.%C.f2e @@ -256,8 +336,8 @@ fn G() -> i32 { // CHECK:STDOUT: %pattern_type.loc7_25 => constants.%pattern_type.510 // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete.loc7_25 => constants.%complete_type.357 -// CHECK:STDOUT: %require_complete.loc7_17 => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete.loc7_25 => constants.%complete_type +// CHECK:STDOUT: %require_complete.loc7_17 => constants.%complete_type // CHECK:STDOUT: %F.specific_fn.loc7_39.2 => constants.%F.specific_fn.c4a // CHECK:STDOUT: } // CHECK:STDOUT: @@ -270,20 +350,27 @@ fn G() -> i32 { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %I.generic: %I.type = struct_value () [concrete] // CHECK:STDOUT: %I.ff1: type = class_type @I, @I(%T) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.f61: = impl_witness @I.%Destroy.impl_witness_table, @I.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.22f: type = ptr_type %I.ff1 [symbolic] +// CHECK:STDOUT: %pattern_type.b10: type = pattern_type %ptr.22f [symbolic] +// CHECK:STDOUT: %I.as.Destroy.impl.Op.type: type = fn_type @I.as.Destroy.impl.Op, @I.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %I.as.Destroy.impl.Op: %I.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.576: type = pattern_type %I.ff1 [symbolic] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.1c8: = require_complete_type %I.ff1 [symbolic] // CHECK:STDOUT: %F.specific_fn.ef1: = specific_function %F, @F(%T) [symbolic] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: %I.ed8: type = class_type @I, @I(%C) [concrete] // CHECK:STDOUT: %pattern_type.917: type = pattern_type %I.ed8 [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] @@ -353,14 +440,61 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @I.as.Destroy.impl(@I.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @I.%Destroy.impl_witness_table, @I.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.f61)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %I.as.Destroy.impl.Op.type: type = fn_type @I.as.Destroy.impl.Op, @I.as.Destroy.impl(%T) [symbolic = %I.as.Destroy.impl.Op.type (constants.%I.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %I.as.Destroy.impl.Op: @I.as.Destroy.impl.%I.as.Destroy.impl.Op.type (%I.as.Destroy.impl.Op.type) = struct_value () [symbolic = %I.as.Destroy.impl.Op (constants.%I.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%I.ff1 as constants.%Destroy.type { +// CHECK:STDOUT: %I.as.Destroy.impl.Op.decl: @I.as.Destroy.impl.%I.as.Destroy.impl.Op.type (%I.as.Destroy.impl.Op.type) = fn_decl @I.as.Destroy.impl.Op [symbolic = @I.as.Destroy.impl.%I.as.Destroy.impl.Op (constants.%I.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @I.as.Destroy.impl.Op.%pattern_type (%pattern_type.b10) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @I.as.Destroy.impl.Op.%pattern_type (%pattern_type.b10) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @I.as.Destroy.impl.Op.%ptr (%ptr.22f) = value_param call_param0 +// CHECK:STDOUT: %.loc4_19.2: type = splice_block %Self.ref [symbolic = %I (constants.%I.ff1)] { +// CHECK:STDOUT: %.loc4_19.3: type = specific_constant constants.%I.ff1, @I(constants.%T) [symbolic = %I (constants.%I.ff1)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_19.3 [symbolic = %I (constants.%I.ff1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @I.as.Destroy.impl.Op.%ptr (%ptr.22f) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %I.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @I.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @I(%T.loc4_9.2: type) { // CHECK:STDOUT: %T.loc4_9.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_9.1 (constants.%T)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @I.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@I.as.Destroy.impl.%I.as.Destroy.impl.Op.decl), @I.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @I.as.Destroy.impl(constants.%T) [symbolic = @I.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.f61)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -369,14 +503,30 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @I.as.Destroy.impl.Op(@I.%T.loc4_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %I: type = class_type @I, @I(%T) [symbolic = %I (constants.%I.ff1)] +// CHECK:STDOUT: %ptr: type = ptr_type %I [symbolic = %ptr (constants.%ptr.22f)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.b10)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @I.as.Destroy.impl.Op.%ptr (%ptr.22f)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc7_6.2: type) { // CHECK:STDOUT: %T.loc7_6.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc7_6.1 (constants.%T)] // CHECK:STDOUT: %I.loc7_22.1: type = class_type @I, @I(%T.loc7_6.1) [symbolic = %I.loc7_22.1 (constants.%I.ff1)] @@ -393,11 +543,9 @@ fn G() -> i32 { // CHECK:STDOUT: %F.specific_fn.loc7_39.1: = specific_function %F.ref, @F(constants.%T) [symbolic = %F.specific_fn.loc7_39.2 (constants.%F.specific_fn.ef1)] // CHECK:STDOUT: %.loc7_25: ref %C = splice_block %return {} // CHECK:STDOUT: %F.call: init %C = call %F.specific_fn.loc7_39.1(%p.ref) to %.loc7_25 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc7_25, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc7_25, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc7_25, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.019 = addr_of %.loc7_25 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %F.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -409,11 +557,9 @@ fn G() -> i32 { // CHECK:STDOUT: %F.specific_fn: = specific_function %F.ref, @F(constants.%C) [concrete = constants.%F.specific_fn.04a] // CHECK:STDOUT: %.loc9_15: ref %C = splice_block %return {} // CHECK:STDOUT: %F.call: init %C = call %F.specific_fn(%p.ref) to %.loc9_15 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc9_15, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc9_15, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc9_15, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.019 = addr_of %.loc9_15 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %F.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -423,6 +569,18 @@ fn G() -> i32 { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @I.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.f61 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %I => constants.%I.ff1 +// CHECK:STDOUT: %ptr => constants.%ptr.22f +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.b10 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%T) { // CHECK:STDOUT: %T.loc7_6.1 => constants.%T // CHECK:STDOUT: %I.loc7_22.1 => constants.%I.ff1 @@ -445,7 +603,7 @@ fn G() -> i32 { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.917 // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete => constants.%complete_type // CHECK:STDOUT: %F.specific_fn.loc7_39.2 => constants.%F.specific_fn.04a // CHECK:STDOUT: } // CHECK:STDOUT: @@ -462,10 +620,33 @@ fn G() -> i32 { // CHECK:STDOUT: %Inner.type.eae: type = generic_class_type @Inner, @Outer(%T) [symbolic] // CHECK:STDOUT: %Inner.generic.137: %Inner.type.eae = struct_value () [symbolic] // CHECK:STDOUT: %Inner.c71: type = class_type @Inner, @Inner(%T, %U) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.de8: = impl_witness @Inner.%Destroy.impl_witness_table, @Inner.as.Destroy.impl(%T, %U) [symbolic] +// CHECK:STDOUT: %ptr.276: type = ptr_type %Inner.c71 [symbolic] +// CHECK:STDOUT: %pattern_type.01f: type = pattern_type %ptr.276 [symbolic] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.type: type = fn_type @Inner.as.Destroy.impl.Op, @Inner.as.Destroy.impl(%T, %U) [symbolic] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op: %Inner.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.a35: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.6ff: type = ptr_type %Outer.9d6 [symbolic] +// CHECK:STDOUT: %pattern_type.07e: type = pattern_type %ptr.6ff [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: %Outer.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.127: = require_complete_type %Outer.9d6 [symbolic] // CHECK:STDOUT: %pattern_type.372: type = pattern_type %Inner.c71 [symbolic] // CHECK:STDOUT: %tuple.type.24b: type = tuple_type (type, type) [concrete] @@ -477,8 +658,6 @@ fn G() -> i32 { // CHECK:STDOUT: %require_complete.fe1: = require_complete_type %tuple.type.30b [symbolic] // CHECK:STDOUT: %require_complete.e7e: = require_complete_type %Inner.c71 [symbolic] // CHECK:STDOUT: %F.specific_fn.dd9: = specific_function %F, @F(%T, %U) [symbolic] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.bc9: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%T) [symbolic] // CHECK:STDOUT: %T.as.Destroy.impl.Op.46f: %T.as.Destroy.impl.Op.type.bc9 = struct_value () [symbolic] // CHECK:STDOUT: %require_complete.8fa: = require_complete_type %ptr.937 [symbolic] @@ -590,6 +769,95 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Inner.as.Destroy.impl(@Outer.%T.loc4_13.2: type, @Inner.%U.loc5_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 1 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Inner.%Destroy.impl_witness_table, @Inner.as.Destroy.impl(%T, %U) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.de8)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.type: type = fn_type @Inner.as.Destroy.impl.Op, @Inner.as.Destroy.impl(%T, %U) [symbolic = %Inner.as.Destroy.impl.Op.type (constants.%Inner.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op: @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.type (%Inner.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Inner.as.Destroy.impl.Op (constants.%Inner.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Inner.c71 as constants.%Destroy.type { +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.decl: @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.type (%Inner.as.Destroy.impl.Op.type) = fn_decl @Inner.as.Destroy.impl.Op [symbolic = @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op (constants.%Inner.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Inner.as.Destroy.impl.Op.%pattern_type (%pattern_type.01f) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Inner.as.Destroy.impl.Op.%pattern_type (%pattern_type.01f) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5_25.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Inner.as.Destroy.impl.Op.%ptr (%ptr.276) = value_param call_param0 +// CHECK:STDOUT: %.loc5_25.2: type = splice_block %Self.ref [symbolic = %Inner (constants.%Inner.c71)] { +// CHECK:STDOUT: %.loc5_25.3: type = specific_constant constants.%Inner.c71, @Inner(constants.%T, constants.%U) [symbolic = %Inner (constants.%Inner.c71)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc5_25.3 [symbolic = %Inner (constants.%Inner.c71)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Inner.as.Destroy.impl.Op.%ptr (%ptr.276) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Inner.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Inner.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Outer.as.Destroy.impl(@Outer.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.a35)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%T) [symbolic = %Outer.as.Destroy.impl.Op.type (constants.%Outer.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Outer.9d6 as constants.%Destroy.type { +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.decl: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = fn_decl @Outer.as.Destroy.impl.Op [symbolic = @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.07e) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.07e) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff) = value_param call_param0 +// CHECK:STDOUT: %.loc4_23.2: type = splice_block %Self.ref [symbolic = %Outer (constants.%Outer.9d6)] { +// CHECK:STDOUT: %.loc4_23.3: type = specific_constant constants.%Outer.9d6, @Outer(constants.%T) [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_23.3 [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Outer.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Outer.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Outer(%T.loc4_13.2: type) { // CHECK:STDOUT: %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: @@ -603,6 +871,9 @@ fn G() -> i32 { // CHECK:STDOUT: } { // CHECK:STDOUT: %U.loc5_15.2: type = bind_symbolic_name U, 1 [symbolic = %U.loc5_15.1 (constants.%U)] // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Outer.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.decl), @Outer.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Outer.as.Destroy.impl(constants.%T) [symbolic = @Outer.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a35)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -619,6 +890,9 @@ fn G() -> i32 { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @Inner.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.decl), @Inner.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Inner.as.Destroy.impl(constants.%T, constants.%U) [symbolic = @Inner.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.de8)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -629,6 +903,9 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -638,6 +915,9 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -646,6 +926,33 @@ fn G() -> i32 { // CHECK:STDOUT: .Self = constants.%D // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Inner.as.Destroy.impl.Op(@Outer.%T.loc4_13.2: type, @Inner.%U.loc5_15.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 1 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Inner: type = class_type @Inner, @Inner(%T, %U) [symbolic = %Inner (constants.%Inner.c71)] +// CHECK:STDOUT: %ptr: type = ptr_type %Inner [symbolic = %ptr (constants.%ptr.276)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.01f)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Inner.as.Destroy.impl.Op.%ptr (%ptr.276)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Outer.as.Destroy.impl.Op(@Outer.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Outer: type = class_type @Outer, @Outer(%T) [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: %ptr: type = ptr_type %Outer [symbolic = %ptr (constants.%ptr.6ff)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.07e)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc13_6.2: type, %U.loc13_16.2: type) { // CHECK:STDOUT: %T.loc13_6.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc13_6.1 (constants.%T)] // CHECK:STDOUT: %U.loc13_16.1: type = bind_symbolic_name U, 1 [symbolic = %U.loc13_16.1 (constants.%U)] @@ -716,6 +1023,32 @@ fn G() -> i32 { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Inner.as.Destroy.impl(constants.%T, constants.%U) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.de8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Inner.as.Destroy.impl.Op(constants.%T, constants.%U) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Inner => constants.%Inner.c71 +// CHECK:STDOUT: %ptr => constants.%ptr.276 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.01f +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a35 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Outer => constants.%Outer.9d6 +// CHECK:STDOUT: %ptr => constants.%ptr.6ff +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.07e +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%T, constants.%U) { // CHECK:STDOUT: %T.loc13_6.1 => constants.%T // CHECK:STDOUT: %U.loc13_16.1 => constants.%U @@ -793,6 +1126,13 @@ fn G() -> i32 { // CHECK:STDOUT: %WithNontype.type: type = generic_class_type @WithNontype [concrete] // CHECK:STDOUT: %WithNontype.generic: %WithNontype.type = struct_value () [concrete] // CHECK:STDOUT: %WithNontype.8a6: type = class_type @WithNontype, @WithNontype(%N.51e) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.743: = impl_witness @WithNontype.%Destroy.impl_witness_table, @WithNontype.as.Destroy.impl(%N.51e) [symbolic] +// CHECK:STDOUT: %ptr.95c: type = ptr_type %WithNontype.8a6 [symbolic] +// CHECK:STDOUT: %pattern_type.c81: type = pattern_type %ptr.95c [symbolic] +// CHECK:STDOUT: %WithNontype.as.Destroy.impl.Op.type: type = fn_type @WithNontype.as.Destroy.impl.Op, @WithNontype.as.Destroy.impl(%N.51e) [symbolic] +// CHECK:STDOUT: %WithNontype.as.Destroy.impl.Op: %WithNontype.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.48f: type = pattern_type %WithNontype.8a6 [symbolic] @@ -822,7 +1162,7 @@ fn G() -> i32 { // CHECK:STDOUT: %WithNontype.val: %WithNontype.b82 = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.b66: type = pattern_type %WithNontype.b82 [concrete] // CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%int_0.6a9) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e99: = impl_witness @WithNontype.%Destroy.impl_witness_table, @WithNontype.as.Destroy.impl(%int_0.6a9) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.68d: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%WithNontype.b82) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.6ee: %T.as.Destroy.impl.Op.type.68d = struct_value () [concrete] // CHECK:STDOUT: %ptr.791: type = ptr_type %WithNontype.b82 [concrete] @@ -832,16 +1172,16 @@ fn G() -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -896,12 +1236,43 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @WithNontype.as.Destroy.impl(@WithNontype.%N.loc4_19.2: %i32) { +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.51e)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @WithNontype.%Destroy.impl_witness_table, @WithNontype.as.Destroy.impl(%N) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.743)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %WithNontype.as.Destroy.impl.Op.type: type = fn_type @WithNontype.as.Destroy.impl.Op, @WithNontype.as.Destroy.impl(%N) [symbolic = %WithNontype.as.Destroy.impl.Op.type (constants.%WithNontype.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %WithNontype.as.Destroy.impl.Op: @WithNontype.as.Destroy.impl.%WithNontype.as.Destroy.impl.Op.type (%WithNontype.as.Destroy.impl.Op.type) = struct_value () [symbolic = %WithNontype.as.Destroy.impl.Op (constants.%WithNontype.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%WithNontype.8a6 as constants.%Destroy.type { +// CHECK:STDOUT: %WithNontype.as.Destroy.impl.Op.decl: @WithNontype.as.Destroy.impl.%WithNontype.as.Destroy.impl.Op.type (%WithNontype.as.Destroy.impl.Op.type) = fn_decl @WithNontype.as.Destroy.impl.Op [symbolic = @WithNontype.as.Destroy.impl.%WithNontype.as.Destroy.impl.Op (constants.%WithNontype.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @WithNontype.as.Destroy.impl.Op.%pattern_type (%pattern_type.c81) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @WithNontype.as.Destroy.impl.Op.%pattern_type (%pattern_type.c81) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_28.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @WithNontype.as.Destroy.impl.Op.%ptr (%ptr.95c) = value_param call_param0 +// CHECK:STDOUT: %.loc4_28.2: type = splice_block %Self.ref [symbolic = %WithNontype (constants.%WithNontype.8a6)] { +// CHECK:STDOUT: %.loc4_28.3: type = specific_constant constants.%WithNontype.8a6, @WithNontype(constants.%N.51e) [symbolic = %WithNontype (constants.%WithNontype.8a6)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_28.3 [symbolic = %WithNontype (constants.%WithNontype.8a6)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @WithNontype.as.Destroy.impl.Op.%ptr (%ptr.95c) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %WithNontype.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @WithNontype.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @WithNontype(%N.loc4_19.2: %i32) { // CHECK:STDOUT: %N.loc4_19.1: %i32 = bind_symbolic_name N, 0 [symbolic = %N.loc4_19.1 (constants.%N.51e)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @WithNontype.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@WithNontype.as.Destroy.impl.%WithNontype.as.Destroy.impl.Op.decl), @WithNontype.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @WithNontype.as.Destroy.impl(constants.%N.51e) [symbolic = @WithNontype.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.743)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -911,6 +1282,17 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @WithNontype.as.Destroy.impl.Op(@WithNontype.%N.loc4_19.2: %i32) { +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.51e)] +// CHECK:STDOUT: %WithNontype: type = class_type @WithNontype, @WithNontype(%N) [symbolic = %WithNontype (constants.%WithNontype.8a6)] +// CHECK:STDOUT: %ptr: type = ptr_type %WithNontype [symbolic = %ptr (constants.%ptr.95c)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.c81)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @WithNontype.as.Destroy.impl.Op.%ptr (%ptr.95c)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%N.loc6_6.2: %i32) { // CHECK:STDOUT: %N.loc6_6.1: %i32 = bind_symbolic_name N, 0 [symbolic = %N.loc6_6.1 (constants.%N.51e)] // CHECK:STDOUT: %WithNontype.loc6_31.1: type = class_type @WithNontype, @WithNontype(%N.loc6_6.1) [symbolic = %WithNontype.loc6_31.1 (constants.%WithNontype.8a6)] @@ -963,6 +1345,18 @@ fn G() -> i32 { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @WithNontype.as.Destroy.impl(constants.%N.51e) { +// CHECK:STDOUT: %N => constants.%N.51e +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.743 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @WithNontype.as.Destroy.impl.Op(constants.%N.51e) { +// CHECK:STDOUT: %N => constants.%N.51e +// CHECK:STDOUT: %WithNontype => constants.%WithNontype.8a6 +// CHECK:STDOUT: %ptr => constants.%ptr.95c +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.c81 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%N.51e) { // CHECK:STDOUT: %N.loc6_6.1 => constants.%N.51e // CHECK:STDOUT: %WithNontype.loc6_31.1 => constants.%WithNontype.8a6 @@ -984,3 +1378,8 @@ fn G() -> i32 { // CHECK:STDOUT: %require_complete => constants.%complete_type.357 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @WithNontype.as.Destroy.impl(constants.%int_0.6a9) { +// CHECK:STDOUT: %N => constants.%int_0.6a9 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.e99 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/deduce/tuple.carbon b/toolchain/check/testdata/deduce/tuple.carbon index 7ad0108a56a5..48d9d83b619a 100644 --- a/toolchain/check/testdata/deduce/tuple.carbon +++ b/toolchain/check/testdata/deduce/tuple.carbon @@ -61,9 +61,22 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %U: type = bind_symbolic_name U, 1 [symbolic] @@ -72,7 +85,6 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: %pattern_type.65c: type = pattern_type %tuple.type.30b [symbolic] // CHECK:STDOUT: %pattern_type.a32: type = pattern_type %U [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.b54: = require_complete_type %U [symbolic] // CHECK:STDOUT: %require_complete.fe1: = require_complete_type %tuple.type.30b [symbolic] @@ -83,11 +95,6 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %F.specific_fn.4a7: = specific_function %F, @F(%C, %D) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.548: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%D) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.2d4: %T.as.Destroy.impl.Op.type.548 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(%D) [concrete] // CHECK:STDOUT: %complete_type.53b: = complete_type_witness %tuple.type.e8a [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -153,7 +160,42 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -163,6 +205,9 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -171,6 +216,10 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: .Self = constants.%D // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc7_6.2: type, %U.loc7_16.2: type) { // CHECK:STDOUT: %T.loc7_6.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc7_6.1 (constants.%T)] // CHECK:STDOUT: %U.loc7_16.1: type = bind_symbolic_name U, 1 [symbolic = %U.loc7_16.1 (constants.%U)] @@ -202,11 +251,9 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: %F.specific_fn: = specific_function %F.ref, @F(constants.%C, constants.%D) [concrete = constants.%F.specific_fn.4a7] // CHECK:STDOUT: %.loc9_20: ref %D = splice_block %return {} // CHECK:STDOUT: %F.call: init %D = call %F.specific_fn(%pair.ref) to %.loc9_20 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc9_20, constants.%T.as.Destroy.impl.Op.2d4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc9_20, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound: = bound_method %.loc9_20, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.19c = addr_of %.loc9_20 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %F.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -250,6 +297,13 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: %HasPair.type: type = generic_class_type @HasPair [concrete] // CHECK:STDOUT: %HasPair.generic: %HasPair.type = struct_value () [concrete] // CHECK:STDOUT: %HasPair.920: type = class_type @HasPair, @HasPair(%Pair) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.347: = impl_witness @HasPair.%Destroy.impl_witness_table, @HasPair.as.Destroy.impl(%Pair) [symbolic] +// CHECK:STDOUT: %ptr.c3d: type = ptr_type %HasPair.920 [symbolic] +// CHECK:STDOUT: %pattern_type.ba5: type = pattern_type %ptr.c3d [symbolic] +// CHECK:STDOUT: %HasPair.as.Destroy.impl.Op.type: type = fn_type @HasPair.as.Destroy.impl.Op, @HasPair.as.Destroy.impl(%Pair) [symbolic] +// CHECK:STDOUT: %HasPair.as.Destroy.impl.Op: %HasPair.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %A: %i32 = bind_symbolic_name A, 0 [symbolic] @@ -294,11 +348,13 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -397,12 +453,43 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @HasPair.as.Destroy.impl(@HasPair.%Pair.loc4_15.2: %tuple.type.d07) { +// CHECK:STDOUT: %Pair: %tuple.type.d07 = bind_symbolic_name Pair, 0 [symbolic = %Pair (constants.%Pair)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @HasPair.%Destroy.impl_witness_table, @HasPair.as.Destroy.impl(%Pair) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.347)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %HasPair.as.Destroy.impl.Op.type: type = fn_type @HasPair.as.Destroy.impl.Op, @HasPair.as.Destroy.impl(%Pair) [symbolic = %HasPair.as.Destroy.impl.Op.type (constants.%HasPair.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %HasPair.as.Destroy.impl.Op: @HasPair.as.Destroy.impl.%HasPair.as.Destroy.impl.Op.type (%HasPair.as.Destroy.impl.Op.type) = struct_value () [symbolic = %HasPair.as.Destroy.impl.Op (constants.%HasPair.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%HasPair.920 as constants.%Destroy.type { +// CHECK:STDOUT: %HasPair.as.Destroy.impl.Op.decl: @HasPair.as.Destroy.impl.%HasPair.as.Destroy.impl.Op.type (%HasPair.as.Destroy.impl.Op.type) = fn_decl @HasPair.as.Destroy.impl.Op [symbolic = @HasPair.as.Destroy.impl.%HasPair.as.Destroy.impl.Op (constants.%HasPair.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @HasPair.as.Destroy.impl.Op.%pattern_type (%pattern_type.ba5) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @HasPair.as.Destroy.impl.Op.%pattern_type (%pattern_type.ba5) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_34.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @HasPair.as.Destroy.impl.Op.%ptr (%ptr.c3d) = value_param call_param0 +// CHECK:STDOUT: %.loc4_34.2: type = splice_block %Self.ref [symbolic = %HasPair (constants.%HasPair.920)] { +// CHECK:STDOUT: %.loc4_34.3: type = specific_constant constants.%HasPair.920, @HasPair(constants.%Pair) [symbolic = %HasPair (constants.%HasPair.920)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_34.3 [symbolic = %HasPair (constants.%HasPair.920)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @HasPair.as.Destroy.impl.Op.%ptr (%ptr.c3d) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %HasPair.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @HasPair.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @HasPair(%Pair.loc4_15.2: %tuple.type.d07) { // CHECK:STDOUT: %Pair.loc4_15.1: %tuple.type.d07 = bind_symbolic_name Pair, 0 [symbolic = %Pair.loc4_15.1 (constants.%Pair)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @HasPair.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@HasPair.as.Destroy.impl.%HasPair.as.Destroy.impl.Op.decl), @HasPair.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @HasPair.as.Destroy.impl(constants.%Pair) [symbolic = @HasPair.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.347)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -412,6 +499,17 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @HasPair.as.Destroy.impl.Op(@HasPair.%Pair.loc4_15.2: %tuple.type.d07) { +// CHECK:STDOUT: %Pair: %tuple.type.d07 = bind_symbolic_name Pair, 0 [symbolic = %Pair (constants.%Pair)] +// CHECK:STDOUT: %HasPair: type = class_type @HasPair, @HasPair(%Pair) [symbolic = %HasPair (constants.%HasPair.920)] +// CHECK:STDOUT: %ptr: type = ptr_type %HasPair [symbolic = %ptr (constants.%ptr.c3d)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.ba5)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @HasPair.as.Destroy.impl.Op.%ptr (%ptr.c3d)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%A.loc6_6.2: %i32, %B.loc6_15.2: %i32) { // CHECK:STDOUT: %A.loc6_6.1: %i32 = bind_symbolic_name A, 0 [symbolic = %A.loc6_6.1 (constants.%A)] // CHECK:STDOUT: %B.loc6_15.1: %i32 = bind_symbolic_name B, 1 [symbolic = %B.loc6_15.1 (constants.%B)] @@ -444,6 +542,18 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: %Pair.loc4_15.1 => constants.%Pair // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @HasPair.as.Destroy.impl(constants.%Pair) { +// CHECK:STDOUT: %Pair => constants.%Pair +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.347 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @HasPair.as.Destroy.impl.Op(constants.%Pair) { +// CHECK:STDOUT: %Pair => constants.%Pair +// CHECK:STDOUT: %HasPair => constants.%HasPair.920 +// CHECK:STDOUT: %ptr => constants.%ptr.c3d +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.ba5 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @HasPair(constants.%tuple.159) { // CHECK:STDOUT: %Pair.loc4_15.1 => constants.%tuple.159 // CHECK:STDOUT: @@ -479,9 +589,21 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %tuple.type.24b: type = tuple_type (type, type) [concrete] @@ -499,9 +621,11 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -555,7 +679,42 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -565,6 +724,9 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -573,6 +735,10 @@ fn G(pair: (C, D)) -> D { // CHECK:STDOUT: .Self = constants.%D // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc7_6.2: type) { // CHECK:STDOUT: %T.loc7_6.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc7_6.1 (constants.%T)] // CHECK:STDOUT: %tuple.type: type = tuple_type (%T.loc7_6.1, %T.loc7_6.1) [symbolic = %tuple.type (constants.%tuple.type.d00)] diff --git a/toolchain/check/testdata/deduce/type_operator.carbon b/toolchain/check/testdata/deduce/type_operator.carbon index 2d989f0b6dd9..2188e765f5d9 100644 --- a/toolchain/check/testdata/deduce/type_operator.carbon +++ b/toolchain/check/testdata/deduce/type_operator.carbon @@ -71,6 +71,14 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] @@ -79,22 +87,15 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: %pattern_type.afe: type = pattern_type %ptr.79f [symbolic] // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %require_complete.6e5: = require_complete_type %ptr.79f [symbolic] // CHECK:STDOUT: %F.specific_fn.ef1: = specific_function %F, @F(%T) [symbolic] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %F.specific_fn.04a: = specific_function %F, @F(%C) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] // CHECK:STDOUT: %complete_type.d05: = complete_type_witness %ptr.019 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -151,7 +152,26 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -160,6 +180,8 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc6_6.2: type) { // CHECK:STDOUT: %T.loc6_6.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.1 (constants.%T)] // CHECK:STDOUT: %ptr.loc6_20.1: type = ptr_type %T.loc6_6.1 [symbolic = %ptr.loc6_20.1 (constants.%ptr.79f)] @@ -190,11 +212,9 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: %F.specific_fn: = specific_function %F.ref, @F(constants.%C) [concrete = constants.%F.specific_fn.04a] // CHECK:STDOUT: %.loc8_13: ref %C = splice_block %return {} // CHECK:STDOUT: %F.call: init %C = call %F.specific_fn(%p.ref) to %.loc8_13 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc8_13, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc8_13, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc8_13, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.019 = addr_of %.loc8_13 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %F.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -226,6 +246,14 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] @@ -235,7 +263,6 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: %pattern_type.fa5: type = pattern_type %ptr.6d4 [symbolic] // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %require_complete.20b: = require_complete_type %ptr.6d4 [symbolic] @@ -247,11 +274,6 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %F.specific_fn.04a: = specific_function %F, @F(%C) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: %complete_type.247: = complete_type_witness %ptr.801 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -311,7 +333,26 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -320,6 +361,8 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc6_6.2: type) { // CHECK:STDOUT: %T.loc6_6.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.1 (constants.%T)] // CHECK:STDOUT: %const.loc6_19.1: type = const_type %T.loc6_6.1 [symbolic = %const.loc6_19.1 (constants.%const.a1a)] @@ -351,11 +394,9 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: %F.specific_fn: = specific_function %F.ref, @F(constants.%C) [concrete = constants.%F.specific_fn.04a] // CHECK:STDOUT: %.loc8_19: ref %C = splice_block %return {} // CHECK:STDOUT: %F.call: init %C = call %F.specific_fn(%p.ref) to %.loc8_19 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc8_19, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc8_19, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc8_19, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.019 = addr_of %.loc8_19 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %F.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -389,6 +430,14 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] @@ -397,7 +446,6 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: %pattern_type.afe: type = pattern_type %ptr.79f [symbolic] // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %require_complete.6e5: = require_complete_type %ptr.79f [symbolic] @@ -409,7 +457,6 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %F.specific_fn.486: = specific_function %F, @F(%const) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.dff: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%const) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.206: %T.as.Destroy.impl.Op.type.dff = struct_value () [concrete] // CHECK:STDOUT: %complete_type.247: = complete_type_witness %ptr.801 [concrete] @@ -472,7 +519,26 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -481,6 +547,8 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc6_6.2: type) { // CHECK:STDOUT: %T.loc6_6.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.1 (constants.%T)] // CHECK:STDOUT: %ptr.loc6_20.1: type = ptr_type %T.loc6_6.1 [symbolic = %ptr.loc6_20.1 (constants.%ptr.79f)] @@ -547,6 +615,13 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] @@ -560,8 +635,6 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %require_complete.20b: = require_complete_type %ptr.6d4 [symbolic] // CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%T) [symbolic] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] // CHECK:STDOUT: %const.668: type = const_type %C [concrete] // CHECK:STDOUT: %pattern_type.6af: type = pattern_type %const.668 [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] @@ -570,9 +643,11 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -622,7 +697,26 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -631,6 +725,8 @@ fn G(p: C*) -> const C { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc6_6.2: type) { // CHECK:STDOUT: %T.loc6_6.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.1 (constants.%T)] // CHECK:STDOUT: %const.loc6_19.1: type = const_type %T.loc6_6.1 [symbolic = %const.loc6_19.1 (constants.%const.a1a)] diff --git a/toolchain/check/testdata/deduce/value_with_type_through_access.carbon b/toolchain/check/testdata/deduce/value_with_type_through_access.carbon index 4a71d989949c..7cd511c2e82d 100644 --- a/toolchain/check/testdata/deduce/value_with_type_through_access.carbon +++ b/toolchain/check/testdata/deduce/value_with_type_through_access.carbon @@ -112,6 +112,13 @@ fn G() { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %HoldsType.generic: %HoldsType.type = struct_value () [concrete] // CHECK:STDOUT: %HoldsType.cc9: type = class_type @HoldsType, @HoldsType(%T.6eb) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d43: = impl_witness @HoldsType.%Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(%T.6eb) [symbolic] +// CHECK:STDOUT: %ptr.47e: type = ptr_type %HoldsType.cc9 [symbolic] +// CHECK:STDOUT: %pattern_type.c39: type = pattern_type %ptr.47e [symbolic] +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op.type: type = fn_type @HoldsType.as.Destroy.impl.Op, @HoldsType.as.Destroy.impl(%T.6eb) [symbolic] +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op: %HoldsType.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.ec6: type = pattern_type %HoldsType.cc9 [symbolic] @@ -123,6 +130,11 @@ fn G() { // CHECK:STDOUT: %require_complete.514: = require_complete_type %HoldsType.cc9 [symbolic] // CHECK:STDOUT: %require_complete.fec: = require_complete_type %tuple.elem0 [symbolic] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %tuple: %tuple.type = tuple_value (%C) [concrete] @@ -132,15 +144,11 @@ fn G() { // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%tuple) [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.6eb: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.7a6: = impl_witness @HoldsType.%Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(%tuple) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.431: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%HoldsType.c09) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.f20: %T.as.Destroy.impl.Op.type.431 = struct_value () [concrete] // CHECK:STDOUT: %ptr.79a: type = ptr_type %HoldsType.c09 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.58d: = specific_function %T.as.Destroy.impl.Op.f20, @T.as.Destroy.impl.Op(%HoldsType.c09) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.f20, @T.as.Destroy.impl.Op(%HoldsType.c09) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -201,12 +209,59 @@ fn G() { // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @HoldsType.as.Destroy.impl(@HoldsType.%T.loc4_17.2: %tuple.type) { +// CHECK:STDOUT: %T: %tuple.type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.6eb)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @HoldsType.%Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.d43)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op.type: type = fn_type @HoldsType.as.Destroy.impl.Op, @HoldsType.as.Destroy.impl(%T) [symbolic = %HoldsType.as.Destroy.impl.Op.type (constants.%HoldsType.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op: @HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op.type (%HoldsType.as.Destroy.impl.Op.type) = struct_value () [symbolic = %HoldsType.as.Destroy.impl.Op (constants.%HoldsType.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%HoldsType.cc9 as constants.%Destroy.type { +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op.decl: @HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op.type (%HoldsType.as.Destroy.impl.Op.type) = fn_decl @HoldsType.as.Destroy.impl.Op [symbolic = @HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op (constants.%HoldsType.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @HoldsType.as.Destroy.impl.Op.%pattern_type (%pattern_type.c39) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @HoldsType.as.Destroy.impl.Op.%pattern_type (%pattern_type.c39) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_31.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @HoldsType.as.Destroy.impl.Op.%ptr (%ptr.47e) = value_param call_param0 +// CHECK:STDOUT: %.loc4_31.2: type = splice_block %Self.ref [symbolic = %HoldsType (constants.%HoldsType.cc9)] { +// CHECK:STDOUT: %.loc4_31.3: type = specific_constant constants.%HoldsType.cc9, @HoldsType(constants.%T.6eb) [symbolic = %HoldsType (constants.%HoldsType.cc9)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_31.3 [symbolic = %HoldsType (constants.%HoldsType.cc9)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @HoldsType.as.Destroy.impl.Op.%ptr (%ptr.47e) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %HoldsType.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @HoldsType.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc10: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @HoldsType(%T.loc4_17.2: %tuple.type) { // CHECK:STDOUT: %T.loc4_17.1: %tuple.type = bind_symbolic_name T, 0 [symbolic = %T.loc4_17.1 (constants.%T.6eb)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @HoldsType.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op.decl), @HoldsType.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(constants.%T.6eb) [symbolic = @HoldsType.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.d43)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -217,6 +272,9 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -225,6 +283,17 @@ fn G() { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @HoldsType.as.Destroy.impl.Op(@HoldsType.%T.loc4_17.2: %tuple.type) { +// CHECK:STDOUT: %T: %tuple.type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.6eb)] +// CHECK:STDOUT: %HoldsType: type = class_type @HoldsType, @HoldsType(%T) [symbolic = %HoldsType (constants.%HoldsType.cc9)] +// CHECK:STDOUT: %ptr: type = ptr_type %HoldsType [symbolic = %ptr (constants.%ptr.47e)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.c39)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @HoldsType.as.Destroy.impl.Op.%ptr (%ptr.47e)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc8_6.2: %tuple.type) { // CHECK:STDOUT: %T.loc8_6.1: %tuple.type = bind_symbolic_name T, 0 [symbolic = %T.loc8_6.1 (constants.%T.6eb)] // CHECK:STDOUT: %HoldsType.loc8_34.1: type = class_type @HoldsType, @HoldsType(%T.loc8_6.1) [symbolic = %HoldsType.loc8_34.1 (constants.%HoldsType.cc9)] @@ -242,6 +311,8 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @G() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] @@ -265,16 +336,14 @@ fn G() { // CHECK:STDOUT: %.loc13_30.5: ref %C = converted %.loc13_30.1, %.loc13_30.4 // CHECK:STDOUT: %.loc13_30.6: %C = bind_value %.loc13_30.5 // CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.specific_fn(%.loc13_8.2, %.loc13_30.6) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13_30: = bound_method %.loc13_30.2, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6eb] -// CHECK:STDOUT: %bound_method.loc13_30: = bound_method %.loc13_30.2, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc13_30.2, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc13_30: %ptr.019 = addr_of %.loc13_30.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc13_30: init %empty_tuple.type = call %bound_method.loc13_30(%addr.loc13_30) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13_6: = bound_method %.loc13_6.2, constants.%T.as.Destroy.impl.Op.f20 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.f20, @T.as.Destroy.impl.Op(constants.%HoldsType.c09) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.58d] -// CHECK:STDOUT: %bound_method.loc13_6: = bound_method %.loc13_6.2, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr.loc13_30) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc13_6.2, constants.%T.as.Destroy.impl.Op.f20 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.f20, @T.as.Destroy.impl.Op(constants.%HoldsType.c09) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method: = bound_method %.loc13_6.2, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr.loc13_6: %ptr.79a = addr_of %.loc13_6.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc13_6: init %empty_tuple.type = call %bound_method.loc13_6(%addr.loc13_6) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc13_6) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -284,6 +353,18 @@ fn G() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @HoldsType.as.Destroy.impl(constants.%T.6eb) { +// CHECK:STDOUT: %T => constants.%T.6eb +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.d43 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @HoldsType.as.Destroy.impl.Op(constants.%T.6eb) { +// CHECK:STDOUT: %T => constants.%T.6eb +// CHECK:STDOUT: %HoldsType => constants.%HoldsType.cc9 +// CHECK:STDOUT: %ptr => constants.%ptr.47e +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.c39 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%T.6eb) { // CHECK:STDOUT: %T.loc8_6.1 => constants.%T.6eb // CHECK:STDOUT: %HoldsType.loc8_34.1 => constants.%HoldsType.cc9 @@ -310,6 +391,11 @@ fn G() { // CHECK:STDOUT: %require_complete.loc8_38 => constants.%complete_type.357 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @HoldsType.as.Destroy.impl(constants.%tuple) { +// CHECK:STDOUT: %T => constants.%tuple +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.7a6 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- struct_access.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -320,6 +406,13 @@ fn G() { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %HoldsType.generic: %HoldsType.type = struct_value () [concrete] // CHECK:STDOUT: %HoldsType.843: type = class_type @HoldsType, @HoldsType(%T.08d) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.715: = impl_witness @HoldsType.%Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(%T.08d) [symbolic] +// CHECK:STDOUT: %ptr.ca6: type = ptr_type %HoldsType.843 [symbolic] +// CHECK:STDOUT: %pattern_type.051: type = pattern_type %ptr.ca6 [symbolic] +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op.type: type = fn_type @HoldsType.as.Destroy.impl.Op, @HoldsType.as.Destroy.impl(%T.08d) [symbolic] +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op: %HoldsType.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.aa4: type = pattern_type %HoldsType.843 [symbolic] @@ -330,6 +423,11 @@ fn G() { // CHECK:STDOUT: %require_complete.b19: = require_complete_type %HoldsType.843 [symbolic] // CHECK:STDOUT: %require_complete.1b9: = require_complete_type %.20a [symbolic] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %struct: %struct_type.t = struct_value (%C) [concrete] @@ -339,15 +437,11 @@ fn G() { // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%struct) [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.6eb: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.131: = impl_witness @HoldsType.%Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(%struct) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.8ea: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%HoldsType.705) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.180: %T.as.Destroy.impl.Op.type.8ea = struct_value () [concrete] // CHECK:STDOUT: %ptr.5d1: type = ptr_type %HoldsType.705 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.fde: = specific_function %T.as.Destroy.impl.Op.180, @T.as.Destroy.impl.Op(%HoldsType.705) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.180, @T.as.Destroy.impl.Op(%HoldsType.705) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -401,12 +495,59 @@ fn G() { // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @HoldsType.as.Destroy.impl(@HoldsType.%T.loc4_17.2: %struct_type.t) { +// CHECK:STDOUT: %T: %struct_type.t = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.08d)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @HoldsType.%Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.715)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op.type: type = fn_type @HoldsType.as.Destroy.impl.Op, @HoldsType.as.Destroy.impl(%T) [symbolic = %HoldsType.as.Destroy.impl.Op.type (constants.%HoldsType.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op: @HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op.type (%HoldsType.as.Destroy.impl.Op.type) = struct_value () [symbolic = %HoldsType.as.Destroy.impl.Op (constants.%HoldsType.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%HoldsType.843 as constants.%Destroy.type { +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op.decl: @HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op.type (%HoldsType.as.Destroy.impl.Op.type) = fn_decl @HoldsType.as.Destroy.impl.Op [symbolic = @HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op (constants.%HoldsType.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @HoldsType.as.Destroy.impl.Op.%pattern_type (%pattern_type.051) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @HoldsType.as.Destroy.impl.Op.%pattern_type (%pattern_type.051) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_33.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @HoldsType.as.Destroy.impl.Op.%ptr (%ptr.ca6) = value_param call_param0 +// CHECK:STDOUT: %.loc4_33.2: type = splice_block %Self.ref [symbolic = %HoldsType (constants.%HoldsType.843)] { +// CHECK:STDOUT: %.loc4_33.3: type = specific_constant constants.%HoldsType.843, @HoldsType(constants.%T.08d) [symbolic = %HoldsType (constants.%HoldsType.843)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_33.3 [symbolic = %HoldsType (constants.%HoldsType.843)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @HoldsType.as.Destroy.impl.Op.%ptr (%ptr.ca6) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %HoldsType.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @HoldsType.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc10: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @HoldsType(%T.loc4_17.2: %struct_type.t) { // CHECK:STDOUT: %T.loc4_17.1: %struct_type.t = bind_symbolic_name T, 0 [symbolic = %T.loc4_17.1 (constants.%T.08d)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @HoldsType.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op.decl), @HoldsType.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(constants.%T.08d) [symbolic = @HoldsType.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.715)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -417,6 +558,9 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -425,6 +569,17 @@ fn G() { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @HoldsType.as.Destroy.impl.Op(@HoldsType.%T.loc4_17.2: %struct_type.t) { +// CHECK:STDOUT: %T: %struct_type.t = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.08d)] +// CHECK:STDOUT: %HoldsType: type = class_type @HoldsType, @HoldsType(%T) [symbolic = %HoldsType (constants.%HoldsType.843)] +// CHECK:STDOUT: %ptr: type = ptr_type %HoldsType [symbolic = %ptr (constants.%ptr.ca6)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.051)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @HoldsType.as.Destroy.impl.Op.%ptr (%ptr.ca6)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc8_6.2: %struct_type.t) { // CHECK:STDOUT: %T.loc8_6.1: %struct_type.t = bind_symbolic_name T, 0 [symbolic = %T.loc8_6.1 (constants.%T.08d)] // CHECK:STDOUT: %HoldsType.loc8_36.1: type = class_type @HoldsType, @HoldsType(%T.loc8_6.1) [symbolic = %HoldsType.loc8_36.1 (constants.%HoldsType.843)] @@ -442,6 +597,8 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @G() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] @@ -465,16 +622,14 @@ fn G() { // CHECK:STDOUT: %.loc13_33.5: ref %C = converted %.loc13_33.1, %.loc13_33.4 // CHECK:STDOUT: %.loc13_33.6: %C = bind_value %.loc13_33.5 // CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.specific_fn(%.loc13_8.2, %.loc13_33.6) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13_33: = bound_method %.loc13_33.2, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6eb] -// CHECK:STDOUT: %bound_method.loc13_33: = bound_method %.loc13_33.2, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc13_33.2, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc13_33: %ptr.019 = addr_of %.loc13_33.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc13_33: init %empty_tuple.type = call %bound_method.loc13_33(%addr.loc13_33) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13_6: = bound_method %.loc13_6.2, constants.%T.as.Destroy.impl.Op.180 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.180, @T.as.Destroy.impl.Op(constants.%HoldsType.705) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.fde] -// CHECK:STDOUT: %bound_method.loc13_6: = bound_method %.loc13_6.2, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr.loc13_33) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc13_6.2, constants.%T.as.Destroy.impl.Op.180 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.180, @T.as.Destroy.impl.Op(constants.%HoldsType.705) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method: = bound_method %.loc13_6.2, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr.loc13_6: %ptr.5d1 = addr_of %.loc13_6.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc13_6: init %empty_tuple.type = call %bound_method.loc13_6(%addr.loc13_6) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc13_6) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -484,6 +639,18 @@ fn G() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @HoldsType.as.Destroy.impl(constants.%T.08d) { +// CHECK:STDOUT: %T => constants.%T.08d +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.715 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @HoldsType.as.Destroy.impl.Op(constants.%T.08d) { +// CHECK:STDOUT: %T => constants.%T.08d +// CHECK:STDOUT: %HoldsType => constants.%HoldsType.843 +// CHECK:STDOUT: %ptr => constants.%ptr.ca6 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.051 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%T.08d) { // CHECK:STDOUT: %T.loc8_6.1 => constants.%T.08d // CHECK:STDOUT: %HoldsType.loc8_36.1 => constants.%HoldsType.843 @@ -510,19 +677,37 @@ fn G() { // CHECK:STDOUT: %require_complete.loc8_40 => constants.%complete_type.357 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @HoldsType.as.Destroy.impl(constants.%struct) { +// CHECK:STDOUT: %T => constants.%struct +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.131 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_todo_class_access.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Class: type = class_type @Class [concrete] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, type [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b40: = impl_witness @Class.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.t: type = struct_type {.t: type} [concrete] // CHECK:STDOUT: %complete_type.509: = complete_type_witness %struct_type.t [concrete] // CHECK:STDOUT: %T.0de: %Class = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %pattern_type.761: type = pattern_type %Class [concrete] // CHECK:STDOUT: %HoldsType.type: type = generic_class_type @HoldsType [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %HoldsType.generic: %HoldsType.type = struct_value () [concrete] // CHECK:STDOUT: %HoldsType.f95cf2.1: type = class_type @HoldsType, @HoldsType(%T.0de) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.2b4af8.1: = impl_witness @HoldsType.%Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(%T.0de) [symbolic] +// CHECK:STDOUT: %ptr.deb697.1: type = ptr_type %HoldsType.f95cf2.1 [symbolic] +// CHECK:STDOUT: %pattern_type.dc9093.1: type = pattern_type %ptr.deb697.1 [symbolic] +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op.type: type = fn_type @HoldsType.as.Destroy.impl.Op, @HoldsType.as.Destroy.impl(%T.0de) [symbolic] +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op: %HoldsType.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.937: type = pattern_type %HoldsType.f95cf2.1 [symbolic] @@ -531,24 +716,24 @@ fn G() { // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.8fa644.1: = require_complete_type %HoldsType.f95cf2.1 [symbolic] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %c: %Class = bind_symbolic_name c, 0 [symbolic] // CHECK:STDOUT: %Class.val: %Class = struct_value (%C) [concrete] // CHECK:STDOUT: %HoldsType.f95cf2.2: type = class_type @HoldsType, @HoldsType(%c) [symbolic] // CHECK:STDOUT: %HoldsType.val: %HoldsType.f95cf2.2 = struct_value () [symbolic] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] -// CHECK:STDOUT: %ptr.deb: type = ptr_type %HoldsType.f95cf2.2 [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.2b4af8.2: = impl_witness @HoldsType.%Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(%c) [symbolic] +// CHECK:STDOUT: %ptr.deb697.2: type = ptr_type %HoldsType.f95cf2.2 [symbolic] // CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %HoldsType.f95cf2.2, @Destroy [symbolic] // CHECK:STDOUT: %Destroy.facet.088: %Destroy.type = facet_value %HoldsType.f95cf2.2, (%Destroy.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %.da6: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.088 [symbolic] // CHECK:STDOUT: %impl.elem0: %.da6 = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic] // CHECK:STDOUT: %specific_impl_fn: = specific_impl_function %impl.elem0, @Destroy.Op(%Destroy.facet.088) [symbolic] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.7de: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Class) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d64: %T.as.Destroy.impl.Op.type.7de = struct_value () [concrete] -// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(%Class) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -606,8 +791,71 @@ fn G() { // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Class.as.Destroy.impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: %Class.as.Destroy.impl.Op.type = fn_decl @Class.as.Destroy.impl.Op [concrete = constants.%Class.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %ptr.e71 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @HoldsType.as.Destroy.impl(@HoldsType.%T.loc8_17.2: %Class) { +// CHECK:STDOUT: %T: %Class = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.0de)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @HoldsType.%Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.2b4af8.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op.type: type = fn_type @HoldsType.as.Destroy.impl.Op, @HoldsType.as.Destroy.impl(%T) [symbolic = %HoldsType.as.Destroy.impl.Op.type (constants.%HoldsType.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op: @HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op.type (%HoldsType.as.Destroy.impl.Op.type) = struct_value () [symbolic = %HoldsType.as.Destroy.impl.Op (constants.%HoldsType.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%HoldsType.f95cf2.1 as constants.%Destroy.type { +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op.decl: @HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op.type (%HoldsType.as.Destroy.impl.Op.type) = fn_decl @HoldsType.as.Destroy.impl.Op [symbolic = @HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op (constants.%HoldsType.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @HoldsType.as.Destroy.impl.Op.%pattern_type (%pattern_type.dc9093.1) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @HoldsType.as.Destroy.impl.Op.%pattern_type (%pattern_type.dc9093.1) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8_28.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @HoldsType.as.Destroy.impl.Op.%ptr (%ptr.deb697.1) = value_param call_param0 +// CHECK:STDOUT: %.loc8_28.2: type = splice_block %Self.ref [symbolic = %HoldsType (constants.%HoldsType.f95cf2.1)] { +// CHECK:STDOUT: %.loc8_28.3: type = specific_constant constants.%HoldsType.f95cf2.1, @HoldsType(constants.%T.0de) [symbolic = %HoldsType (constants.%HoldsType.f95cf2.1)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc8_28.3 [symbolic = %HoldsType (constants.%HoldsType.f95cf2.1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @HoldsType.as.Destroy.impl.Op.%ptr (%ptr.deb697.1) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %HoldsType.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @HoldsType.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc23: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %.loc5: %Class.elem = field_decl t, element0 [concrete] +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b40] // CHECK:STDOUT: %struct_type.t: type = struct_type {.t: type} [concrete = constants.%struct_type.t] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.t [concrete = constants.%complete_type.509] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -623,6 +871,9 @@ fn G() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @HoldsType.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op.decl), @HoldsType.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(constants.%T.0de) [symbolic = @HoldsType.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.2b4af8.1)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -633,6 +884,9 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -641,6 +895,19 @@ fn G() { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.as.Destroy.impl.Op(%self.param: %ptr.e71) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @HoldsType.as.Destroy.impl.Op(@HoldsType.%T.loc8_17.2: %Class) { +// CHECK:STDOUT: %T: %Class = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.0de)] +// CHECK:STDOUT: %HoldsType: type = class_type @HoldsType, @HoldsType(%T) [symbolic = %HoldsType (constants.%HoldsType.f95cf2.1)] +// CHECK:STDOUT: %ptr: type = ptr_type %HoldsType [symbolic = %ptr (constants.%ptr.deb697.1)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.dc9093.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @HoldsType.as.Destroy.impl.Op.%ptr (%ptr.deb697.1)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc21_6.2: %Class) { // CHECK:STDOUT: %T.loc21_6.1: %Class = bind_symbolic_name T, 0 [symbolic = %T.loc21_6.1 (constants.%T.0de)] // CHECK:STDOUT: %HoldsType.loc21_31.1: type = class_type @HoldsType, @HoldsType(%T.loc21_6.1) [symbolic = %HoldsType.loc21_31.1 (constants.%HoldsType.f95cf2.1)] @@ -656,6 +923,8 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @G() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -687,13 +956,11 @@ fn G() { // CHECK:STDOUT: %bound_method.loc27_6.1: = bound_method %.loc27_6.2, %impl.elem0 // CHECK:STDOUT: %specific_impl_fn: = specific_impl_function %impl.elem0, @Destroy.Op(constants.%Destroy.facet.088) [symbolic = constants.%specific_impl_fn] // CHECK:STDOUT: %bound_method.loc27_6.2: = bound_method %.loc27_6.2, %specific_impl_fn -// CHECK:STDOUT: %addr.loc27: %ptr.deb = addr_of %.loc27_6.2 +// CHECK:STDOUT: %addr.loc27: %ptr.deb697.2 = addr_of %.loc27_6.2 // CHECK:STDOUT: %.loc27_6.5: init %empty_tuple.type = call %bound_method.loc27_6.2(%addr.loc27) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc26_26.2, constants.%T.as.Destroy.impl.Op.d64 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d64, @T.as.Destroy.impl.Op(constants.%Class) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc26: = bound_method %.loc26_26.2, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.bound: = bound_method %.loc26_26.2, constants.%Class.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc26: %ptr.e71 = addr_of %.loc26_26.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc26(%addr.loc26) +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Class.as.Destroy.impl.Op.bound(%addr.loc26) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -703,6 +970,18 @@ fn G() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @HoldsType.as.Destroy.impl(constants.%T.0de) { +// CHECK:STDOUT: %T => constants.%T.0de +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.2b4af8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @HoldsType.as.Destroy.impl.Op(constants.%T.0de) { +// CHECK:STDOUT: %T => constants.%T.0de +// CHECK:STDOUT: %HoldsType => constants.%HoldsType.f95cf2.1 +// CHECK:STDOUT: %ptr => constants.%ptr.deb697.1 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.dc9093.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%T.0de) { // CHECK:STDOUT: %T.loc21_6.1 => constants.%T.0de // CHECK:STDOUT: %HoldsType.loc21_31.1 => constants.%HoldsType.f95cf2.1 @@ -716,6 +995,11 @@ fn G() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @HoldsType.as.Destroy.impl(constants.%c) { +// CHECK:STDOUT: %T => constants.%c +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.2b4af8.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_todo_array_index.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -727,9 +1011,16 @@ fn G() { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %HoldsType.generic: %HoldsType.type = struct_value () [concrete] // CHECK:STDOUT: %HoldsType: type = class_type @HoldsType, @HoldsType(%T.eb6) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.139: = impl_witness @HoldsType.%Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(%T.eb6) [symbolic] +// CHECK:STDOUT: %ptr.ea3: type = ptr_type %array_type [concrete] +// CHECK:STDOUT: %ptr.998: type = ptr_type %HoldsType [symbolic] +// CHECK:STDOUT: %pattern_type.34f: type = pattern_type %ptr.998 [symbolic] +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op.type: type = fn_type @HoldsType.as.Destroy.impl.Op, @HoldsType.as.Destroy.impl(%T.eb6) [symbolic] +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op: %HoldsType.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %ptr.ea3: type = ptr_type %array_type [concrete] // CHECK:STDOUT: %pattern_type.142: type = pattern_type %HoldsType [symbolic] // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] @@ -756,11 +1047,15 @@ fn G() { // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.640: = require_complete_type %HoldsType [symbolic] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %tuple.type: type = tuple_type (type) [concrete] // CHECK:STDOUT: %array: %array_type = tuple_value (%C) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.8a7: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%array_type) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.246: %T.as.Destroy.impl.Op.type.8a7 = struct_value () [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.246, @T.as.Destroy.impl.Op(%array_type) [concrete] @@ -768,17 +1063,17 @@ fn G() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs -// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -841,12 +1136,59 @@ fn G() { // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @HoldsType.as.Destroy.impl(@HoldsType.%T.loc4_17.2: %array_type) { +// CHECK:STDOUT: %T: %array_type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.eb6)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @HoldsType.%Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.139)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op.type: type = fn_type @HoldsType.as.Destroy.impl.Op, @HoldsType.as.Destroy.impl(%T) [symbolic = %HoldsType.as.Destroy.impl.Op.type (constants.%HoldsType.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op: @HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op.type (%HoldsType.as.Destroy.impl.Op.type) = struct_value () [symbolic = %HoldsType.as.Destroy.impl.Op (constants.%HoldsType.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%HoldsType as constants.%Destroy.type { +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op.decl: @HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op.type (%HoldsType.as.Destroy.impl.Op.type) = fn_decl @HoldsType.as.Destroy.impl.Op [symbolic = @HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op (constants.%HoldsType.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @HoldsType.as.Destroy.impl.Op.%pattern_type (%pattern_type.34f) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @HoldsType.as.Destroy.impl.Op.%pattern_type (%pattern_type.34f) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_37.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @HoldsType.as.Destroy.impl.Op.%ptr (%ptr.998) = value_param call_param0 +// CHECK:STDOUT: %.loc4_37.2: type = splice_block %Self.ref [symbolic = %HoldsType (constants.%HoldsType)] { +// CHECK:STDOUT: %.loc4_37.3: type = specific_constant constants.%HoldsType, @HoldsType(constants.%T.eb6) [symbolic = %HoldsType (constants.%HoldsType)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_37.3 [symbolic = %HoldsType (constants.%HoldsType)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @HoldsType.as.Destroy.impl.Op.%ptr (%ptr.998) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %HoldsType.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @HoldsType.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc14: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @HoldsType(%T.loc4_17.2: %array_type) { // CHECK:STDOUT: %T.loc4_17.1: %array_type = bind_symbolic_name T, 0 [symbolic = %T.loc4_17.1 (constants.%T.eb6)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @HoldsType.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op.decl), @HoldsType.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(constants.%T.eb6) [symbolic = @HoldsType.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.139)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -857,6 +1199,9 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -865,6 +1210,17 @@ fn G() { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @HoldsType.as.Destroy.impl.Op(@HoldsType.%T.loc4_17.2: %array_type) { +// CHECK:STDOUT: %T: %array_type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.eb6)] +// CHECK:STDOUT: %HoldsType: type = class_type @HoldsType, @HoldsType(%T) [symbolic = %HoldsType (constants.%HoldsType)] +// CHECK:STDOUT: %ptr: type = ptr_type %HoldsType [symbolic = %ptr (constants.%ptr.998)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.34f)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @HoldsType.as.Destroy.impl.Op.%ptr (%ptr.998)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc12_6.2: %array_type) { // CHECK:STDOUT: %T.loc12_6.1: %array_type = bind_symbolic_name T, 0 [symbolic = %T.loc12_6.1 (constants.%T.eb6)] // CHECK:STDOUT: %HoldsType.loc12_40.1: type = class_type @HoldsType, @HoldsType(%T.loc12_6.1) [symbolic = %HoldsType.loc12_40.1 (constants.%HoldsType)] @@ -879,6 +1235,8 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @G() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] @@ -911,6 +1269,18 @@ fn G() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @HoldsType.as.Destroy.impl(constants.%T.eb6) { +// CHECK:STDOUT: %T => constants.%T.eb6 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.139 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @HoldsType.as.Destroy.impl.Op(constants.%T.eb6) { +// CHECK:STDOUT: %T => constants.%T.eb6 +// CHECK:STDOUT: %HoldsType => constants.%HoldsType +// CHECK:STDOUT: %ptr => constants.%ptr.998 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.34f +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%T.eb6) { // CHECK:STDOUT: %T.loc12_6.1 => constants.%T.eb6 // CHECK:STDOUT: %HoldsType.loc12_40.1 => constants.%HoldsType diff --git a/toolchain/check/testdata/facet/call_combined_impl_witness.carbon b/toolchain/check/testdata/facet/call_combined_impl_witness.carbon index 2356757dda3b..45c75a32b632 100644 --- a/toolchain/check/testdata/facet/call_combined_impl_witness.carbon +++ b/toolchain/check/testdata/facet/call_combined_impl_witness.carbon @@ -64,8 +64,15 @@ fn F() { // CHECK:STDOUT: %B.assoc_type: type = assoc_entity_type @B [concrete] // CHECK:STDOUT: %assoc0.a29: %B.assoc_type = assoc_entity element0, @B.%B.BB.decl [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Empty.impl_witness: = impl_witness file.%Empty.impl_witness_table [concrete] // CHECK:STDOUT: %A.impl_witness: = impl_witness file.%A.impl_witness_table [concrete] // CHECK:STDOUT: %C.as.A.impl.AA.type: type = fn_type @C.as.A.impl.AA [concrete] @@ -111,26 +118,21 @@ fn F() { // CHECK:STDOUT: %facet_value: %facet_type.242 = facet_value %C, (%Empty.impl_witness, %A.impl_witness, %B.impl_witness) [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %G.specific_fn: = specific_function %G, @G(%facet_value) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: %.7ab: type = fn_type_with_self_type %A.AA.type, %A.facet.66c [concrete] // CHECK:STDOUT: %.b43: type = fn_type_with_self_type %B.BB.type, %B.facet.82f [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { -// CHECK:STDOUT: .BitAndWith = %Core.BitAndWith // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .BitAndWith = %Core.BitAndWith // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.BitAndWith: %BitAndWith.type.f2e = import_ref Core//prelude, BitAndWith, loaded [concrete = constants.%BitAndWith.generic] // CHECK:STDOUT: %Core.import_ref.012: %type.as.BitAndWith.impl.Op.type = import_ref Core//prelude, loc13_42, loaded [concrete = constants.%type.as.BitAndWith.impl.Op] // CHECK:STDOUT: %BitAndWith.impl_witness_table = impl_witness_table (%Core.import_ref.012), @type.as.BitAndWith.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -232,6 +234,22 @@ fn F() { // CHECK:STDOUT: witness = (%B.BB.decl) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc24: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.Empty.impl: %C.ref as %Empty.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%Empty.impl_witness @@ -254,8 +272,11 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -270,6 +291,8 @@ fn F() { // CHECK:STDOUT: fn(); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.A.impl.AA() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return @@ -366,11 +389,9 @@ fn F() { // CHECK:STDOUT: %G.specific_fn: = specific_function %G.ref, @G(constants.%facet_value) [concrete = constants.%G.specific_fn] // CHECK:STDOUT: %.loc45_8.2: %C = bind_value %.loc45_8.1 // CHECK:STDOUT: %G.call: init %empty_tuple.type = call %G.specific_fn(%.loc45_8.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc45_6.2, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc45_6.2, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc45_6.2, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.019 = addr_of %.loc45_6.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -398,7 +419,7 @@ fn F() { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.c48 // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete => constants.%complete_type // CHECK:STDOUT: %A.lookup_impl_witness => constants.%A.impl_witness // CHECK:STDOUT: %A.facet.loc34 => constants.%A.facet.66c // CHECK:STDOUT: %.loc34_4.2 => constants.%.7ab diff --git a/toolchain/check/testdata/facet/convert_class_type_to_facet_type.carbon b/toolchain/check/testdata/facet/convert_class_type_to_facet_type.carbon index 0b0ee09f6b9d..39cfc3fe2f5c 100644 --- a/toolchain/check/testdata/facet/convert_class_type_to_facet_type.carbon +++ b/toolchain/check/testdata/facet/convert_class_type_to_facet_type.carbon @@ -27,15 +27,22 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Animal.type: type = facet_type <@Animal> [concrete] -// CHECK:STDOUT: %Self: %Animal.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.fd4: %Animal.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %Goat: type = class_type @Goat [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Goat.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.940: type = ptr_type %Goat [concrete] +// CHECK:STDOUT: %pattern_type.396: type = pattern_type %ptr.940 [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.type: type = fn_type @Goat.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op: %Goat.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Animal.impl_witness: = impl_witness file.%Animal.impl_witness_table [concrete] // CHECK:STDOUT: %A: %Animal.type = bind_symbolic_name A, 0 [symbolic] -// CHECK:STDOUT: %pattern_type: type = pattern_type %Animal.type [concrete] +// CHECK:STDOUT: %pattern_type.3b0: type = pattern_type %Animal.type [concrete] // CHECK:STDOUT: %WalkAnimal.type: type = fn_type @WalkAnimal [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %WalkAnimal: %WalkAnimal.type = struct_value () [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] @@ -45,9 +52,11 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -68,7 +77,7 @@ fn F() { // CHECK:STDOUT: %Animal.impl_witness_table = impl_witness_table (), @Goat.as.Animal.impl [concrete] // CHECK:STDOUT: %Animal.impl_witness: = impl_witness %Animal.impl_witness_table [concrete = constants.%Animal.impl_witness] // CHECK:STDOUT: %WalkAnimal.decl: %WalkAnimal.type = fn_decl @WalkAnimal [concrete = constants.%WalkAnimal] { -// CHECK:STDOUT: %A.patt: %pattern_type = symbolic_binding_pattern A, 0 [concrete] +// CHECK:STDOUT: %A.patt: %pattern_type.3b0 = symbolic_binding_pattern A, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %Animal.ref: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] // CHECK:STDOUT: %A.loc20_15.2: %Animal.type = bind_symbolic_name A, 0 [symbolic = %A.loc20_15.1 (constants.%A)] @@ -77,19 +86,38 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @Animal { -// CHECK:STDOUT: %Self: %Animal.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %Animal.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.fd4] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = %Self // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Goat.as.Destroy.impl: constants.%Goat as constants.%Destroy.type { +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.decl: %Goat.as.Destroy.impl.Op.type = fn_decl @Goat.as.Destroy.impl.Op [concrete = constants.%Goat.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.396 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.396 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc17: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.940 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Goat [concrete = constants.%Goat] +// CHECK:STDOUT: %self: %ptr.940 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Goat.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Goat.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @Goat.as.Animal.impl: %Goat.ref as %Animal.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%Animal.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Goat { +// CHECK:STDOUT: impl_decl @Goat.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Goat.as.Destroy.impl.%Goat.as.Destroy.impl.Op.decl), @Goat.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -98,6 +126,8 @@ fn F() { // CHECK:STDOUT: .Self = constants.%Goat // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Goat.as.Destroy.impl.Op(%self.param: %ptr.940) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @WalkAnimal(%A.loc20_15.2: %Animal.type) { // CHECK:STDOUT: %A.loc20_15.1: %Animal.type = bind_symbolic_name A, 0 [symbolic = %A.loc20_15.1 (constants.%A)] // CHECK:STDOUT: diff --git a/toolchain/check/testdata/facet/convert_class_type_to_generic_facet_value.carbon b/toolchain/check/testdata/facet/convert_class_type_to_generic_facet_value.carbon index 418e5af5bdbf..5c5691a47dbb 100644 --- a/toolchain/check/testdata/facet/convert_class_type_to_generic_facet_value.carbon +++ b/toolchain/check/testdata/facet/convert_class_type_to_generic_facet_value.carbon @@ -77,9 +77,21 @@ fn G() { // CHECK:STDOUT: %Generic.assoc_type.0fd: type = assoc_entity_type @Generic, @Generic(%Scalar) [symbolic] // CHECK:STDOUT: %assoc0.296: %Generic.assoc_type.0fd = assoc_entity element0, @Generic.%Generic.F.decl [symbolic] // CHECK:STDOUT: %GenericParam: type = class_type @GenericParam [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.884: = impl_witness @GenericParam.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.f73: type = ptr_type %GenericParam [concrete] +// CHECK:STDOUT: %pattern_type.7c3: type = pattern_type %ptr.f73 [concrete] +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op.type: type = fn_type @GenericParam.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op: %GenericParam.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %ImplsGeneric: type = class_type @ImplsGeneric [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9ca: = impl_witness @ImplsGeneric.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.011: type = ptr_type %ImplsGeneric [concrete] +// CHECK:STDOUT: %pattern_type.2db: type = pattern_type %ptr.011 [concrete] +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op.type: type = fn_type @ImplsGeneric.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op: %ImplsGeneric.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Generic.type.769: type = facet_type <@Generic, @Generic(%GenericParam)> [concrete] // CHECK:STDOUT: %Self.f84: %Generic.type.769 = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %Generic.F.type.4cf: type = fn_type @Generic.F, @Generic(%GenericParam) [concrete] @@ -110,9 +122,11 @@ fn G() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -193,6 +207,38 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @GenericParam.as.Destroy.impl: constants.%GenericParam as constants.%Destroy.type { +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op.decl: %GenericParam.as.Destroy.impl.Op.type = fn_decl @GenericParam.as.Destroy.impl.Op [concrete = constants.%GenericParam.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.7c3 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.7c3 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.f73 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%GenericParam [concrete = constants.%GenericParam] +// CHECK:STDOUT: %self: %ptr.f73 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %GenericParam.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @GenericParam.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @ImplsGeneric.as.Destroy.impl: constants.%ImplsGeneric as constants.%Destroy.type { +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op.decl: %ImplsGeneric.as.Destroy.impl.Op.type = fn_decl @ImplsGeneric.as.Destroy.impl.Op [concrete = constants.%ImplsGeneric.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.2db = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.2db = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc10: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.011 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%ImplsGeneric [concrete = constants.%ImplsGeneric] +// CHECK:STDOUT: %self: %ptr.011 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %ImplsGeneric.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @ImplsGeneric.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @ImplsGeneric.as.Generic.impl: %ImplsGeneric.ref as %Generic.type { // CHECK:STDOUT: %ImplsGeneric.as.Generic.impl.F.decl: %ImplsGeneric.as.Generic.impl.F.type = fn_decl @ImplsGeneric.as.Generic.impl.F [concrete = constants.%ImplsGeneric.as.Generic.impl.F] {} {} // CHECK:STDOUT: @@ -202,6 +248,9 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @GenericParam { +// CHECK:STDOUT: impl_decl @GenericParam.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@GenericParam.as.Destroy.impl.%GenericParam.as.Destroy.impl.Op.decl), @GenericParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.884] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -211,6 +260,9 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @ImplsGeneric { +// CHECK:STDOUT: impl_decl @ImplsGeneric.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@ImplsGeneric.as.Destroy.impl.%ImplsGeneric.as.Destroy.impl.Op.decl), @ImplsGeneric.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.9ca] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -223,6 +275,10 @@ fn G() { // CHECK:STDOUT: fn(); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @GenericParam.as.Destroy.impl.Op(%self.param: %ptr.f73) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ImplsGeneric.as.Destroy.impl.Op(%self.param: %ptr.011) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @ImplsGeneric.as.Generic.impl.F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return @@ -360,9 +416,21 @@ fn G() { // CHECK:STDOUT: %Generic.assoc_type.0fd: type = assoc_entity_type @Generic, @Generic(%Scalar) [symbolic] // CHECK:STDOUT: %assoc0.296: %Generic.assoc_type.0fd = assoc_entity element0, @Generic.%Generic.F.decl [symbolic] // CHECK:STDOUT: %GenericParam: type = class_type @GenericParam [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.884: = impl_witness @GenericParam.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.f73: type = ptr_type %GenericParam [concrete] +// CHECK:STDOUT: %pattern_type.7c3: type = pattern_type %ptr.f73 [concrete] +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op.type: type = fn_type @GenericParam.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op: %GenericParam.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %ImplsGeneric: type = class_type @ImplsGeneric [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9ca: = impl_witness @ImplsGeneric.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.011: type = ptr_type %ImplsGeneric [concrete] +// CHECK:STDOUT: %pattern_type.2db: type = pattern_type %ptr.011 [concrete] +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op.type: type = fn_type @ImplsGeneric.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op: %ImplsGeneric.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Generic.type.769: type = facet_type <@Generic, @Generic(%GenericParam)> [concrete] // CHECK:STDOUT: %Self.f84: %Generic.type.769 = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %Generic.F.type.4cf: type = fn_type @Generic.F, @Generic(%GenericParam) [concrete] @@ -387,11 +455,6 @@ fn G() { // CHECK:STDOUT: %pattern_type.ded: type = pattern_type %Generic.type.769 [concrete] // CHECK:STDOUT: %pattern_type.589: type = pattern_type %GenericParam [concrete] // CHECK:STDOUT: %CallGenericMethod.specific_fn: = specific_function %CallGenericMethod, @CallGenericMethod(%GenericParam, %Generic.facet) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.ae1: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%GenericParam) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.0cc: %T.as.Destroy.impl.Op.type.ae1 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.f73: type = ptr_type %GenericParam [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.0cc, @T.as.Destroy.impl.Op(%GenericParam) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -471,6 +534,38 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @GenericParam.as.Destroy.impl: constants.%GenericParam as constants.%Destroy.type { +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op.decl: %GenericParam.as.Destroy.impl.Op.type = fn_decl @GenericParam.as.Destroy.impl.Op [concrete = constants.%GenericParam.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.7c3 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.7c3 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.f73 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%GenericParam [concrete = constants.%GenericParam] +// CHECK:STDOUT: %self: %ptr.f73 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %GenericParam.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @GenericParam.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @ImplsGeneric.as.Destroy.impl: constants.%ImplsGeneric as constants.%Destroy.type { +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op.decl: %ImplsGeneric.as.Destroy.impl.Op.type = fn_decl @ImplsGeneric.as.Destroy.impl.Op [concrete = constants.%ImplsGeneric.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.2db = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.2db = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc10: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.011 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%ImplsGeneric [concrete = constants.%ImplsGeneric] +// CHECK:STDOUT: %self: %ptr.011 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %ImplsGeneric.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @ImplsGeneric.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @ImplsGeneric.as.Generic.impl: %ImplsGeneric.ref as %Generic.type { // CHECK:STDOUT: %ImplsGeneric.as.Generic.impl.F.decl: %ImplsGeneric.as.Generic.impl.F.type = fn_decl @ImplsGeneric.as.Generic.impl.F [concrete = constants.%ImplsGeneric.as.Generic.impl.F] {} {} // CHECK:STDOUT: @@ -480,8 +575,11 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @GenericParam { +// CHECK:STDOUT: impl_decl @GenericParam.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@GenericParam.as.Destroy.impl.%GenericParam.as.Destroy.impl.Op.decl), @GenericParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.884] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -489,8 +587,11 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @ImplsGeneric { +// CHECK:STDOUT: impl_decl @ImplsGeneric.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@ImplsGeneric.as.Destroy.impl.%ImplsGeneric.as.Destroy.impl.Op.decl), @ImplsGeneric.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.9ca] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -501,6 +602,10 @@ fn G() { // CHECK:STDOUT: fn(); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @GenericParam.as.Destroy.impl.Op(%self.param: %ptr.f73) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ImplsGeneric.as.Destroy.impl.Op(%self.param: %ptr.011) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @ImplsGeneric.as.Generic.impl.F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return @@ -537,11 +642,9 @@ fn G() { // CHECK:STDOUT: %CallGenericMethod.specific_fn: = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet) [concrete = constants.%CallGenericMethod.specific_fn] // CHECK:STDOUT: %.loc18_38.2: %GenericParam = bind_value %.loc18_38.1 // CHECK:STDOUT: %CallGenericMethod.call: init %empty_tuple.type = call %CallGenericMethod.specific_fn(%.loc18_38.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc18_36.2, constants.%T.as.Destroy.impl.Op.0cc -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.0cc, @T.as.Destroy.impl.Op(constants.%GenericParam) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc18_36.2, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op.bound: = bound_method %.loc18_36.2, constants.%GenericParam.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.f73 = addr_of %.loc18_36.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op.call: init %empty_tuple.type = call %GenericParam.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -585,6 +688,6 @@ fn G() { // CHECK:STDOUT: %pattern_type.loc15_48 => constants.%pattern_type.589 // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete => constants.%complete_type // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/facet/convert_class_value_to_facet_value_value.carbon b/toolchain/check/testdata/facet/convert_class_value_to_facet_value_value.carbon index 14442ec857ce..a1970cf70453 100644 --- a/toolchain/check/testdata/facet/convert_class_value_to_facet_value_value.carbon +++ b/toolchain/check/testdata/facet/convert_class_value_to_facet_value_value.carbon @@ -37,8 +37,15 @@ fn F() { // CHECK:STDOUT: %WalkAnimal: %WalkAnimal.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.234: = require_complete_type %T.as_type [symbolic] // CHECK:STDOUT: %Goat: type = class_type @Goat [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.943: = impl_witness @Goat.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.940: type = ptr_type %Goat [concrete] +// CHECK:STDOUT: %pattern_type.396: type = pattern_type %ptr.940 [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.type: type = fn_type @Goat.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op: %Goat.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Animal.impl_witness: = impl_witness file.%Animal.impl_witness_table [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] @@ -46,11 +53,6 @@ fn F() { // CHECK:STDOUT: %Animal.facet: %Animal.type = facet_value %Goat, (%Animal.impl_witness) [concrete] // CHECK:STDOUT: %pattern_type.ab7: type = pattern_type %Goat [concrete] // CHECK:STDOUT: %WalkAnimal.specific_fn: = specific_function %WalkAnimal, @WalkAnimal(%Animal.facet) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.e7a: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Goat) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.55a: %T.as.Destroy.impl.Op.type.e7a = struct_value () [concrete] -// CHECK:STDOUT: %ptr.940: type = ptr_type %Goat [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.55a, @T.as.Destroy.impl.Op(%Goat) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -105,14 +107,33 @@ fn F() { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Goat.as.Destroy.impl: constants.%Goat as constants.%Destroy.type { +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.decl: %Goat.as.Destroy.impl.Op.type = fn_decl @Goat.as.Destroy.impl.Op [concrete = constants.%Goat.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.396 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.396 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc19: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.940 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Goat [concrete = constants.%Goat] +// CHECK:STDOUT: %self: %ptr.940 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Goat.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Goat.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @Goat.as.Animal.impl: %Goat.ref as %Animal.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%Animal.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Goat { +// CHECK:STDOUT: impl_decl @Goat.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Goat.as.Destroy.impl.%Goat.as.Destroy.impl.Op.decl), @Goat.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.943] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -133,6 +154,8 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Goat.as.Destroy.impl.Op(%self.param: %ptr.940) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %WalkAnimal.ref: %WalkAnimal.type = name_ref WalkAnimal, file.%WalkAnimal.decl [concrete = constants.%WalkAnimal] @@ -149,11 +172,9 @@ fn F() { // CHECK:STDOUT: %WalkAnimal.specific_fn: = specific_function %WalkAnimal.ref, @WalkAnimal(constants.%Animal.facet) [concrete = constants.%WalkAnimal.specific_fn] // CHECK:STDOUT: %.loc23_17.2: %Goat = bind_value %.loc23_17.1 // CHECK:STDOUT: %WalkAnimal.call: init %empty_tuple.type = call %WalkAnimal.specific_fn(%.loc23_17.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc23_15.2, constants.%T.as.Destroy.impl.Op.55a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.55a, @T.as.Destroy.impl.Op(constants.%Goat) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc23_15.2, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.bound: = bound_method %.loc23_15.2, constants.%Goat.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.940 = addr_of %.loc23_15.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Goat.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -169,6 +190,6 @@ fn F() { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.ab7 // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete => constants.%complete_type // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/facet/convert_class_value_to_generic_facet_value_value.carbon b/toolchain/check/testdata/facet/convert_class_value_to_generic_facet_value_value.carbon index 855f09d68a4d..e3136a78a25c 100644 --- a/toolchain/check/testdata/facet/convert_class_value_to_generic_facet_value_value.carbon +++ b/toolchain/check/testdata/facet/convert_class_value_to_generic_facet_value_value.carbon @@ -109,9 +109,21 @@ fn B() { // CHECK:STDOUT: %Generic.assoc_type.0fd877.1: type = assoc_entity_type @Generic, @Generic(%Scalar) [symbolic] // CHECK:STDOUT: %assoc0.2966cb.1: %Generic.assoc_type.0fd877.1 = assoc_entity element0, @Generic.%Generic.F.decl [symbolic] // CHECK:STDOUT: %GenericParam: type = class_type @GenericParam [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.884: = impl_witness @GenericParam.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.f73: type = ptr_type %GenericParam [concrete] +// CHECK:STDOUT: %pattern_type.7c3: type = pattern_type %ptr.f73 [concrete] +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op.type: type = fn_type @GenericParam.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op: %GenericParam.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %ImplsGeneric: type = class_type @ImplsGeneric [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9ca: = impl_witness @ImplsGeneric.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.011: type = ptr_type %ImplsGeneric [concrete] +// CHECK:STDOUT: %pattern_type.2db: type = pattern_type %ptr.011 [concrete] +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op.type: type = fn_type @ImplsGeneric.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op: %ImplsGeneric.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Generic.type.769: type = facet_type <@Generic, @Generic(%GenericParam)> [concrete] // CHECK:STDOUT: %Self.f84: %Generic.type.769 = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %Generic.F.type.4cf: type = fn_type @Generic.F, @Generic(%GenericParam) [concrete] @@ -152,15 +164,6 @@ fn B() { // CHECK:STDOUT: %pattern_type.c8d: type = pattern_type %ImplsGeneric [concrete] // CHECK:STDOUT: %pattern_type.589: type = pattern_type %GenericParam [concrete] // CHECK:STDOUT: %CallGenericMethod.specific_fn: = specific_function %CallGenericMethod, @CallGenericMethod(%GenericParam, %Generic.facet.8ff) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.ae1: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%GenericParam) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.0cc: %T.as.Destroy.impl.Op.type.ae1 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.f73: type = ptr_type %GenericParam [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.934: = specific_function %T.as.Destroy.impl.Op.0cc, @T.as.Destroy.impl.Op(%GenericParam) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.e98: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%ImplsGeneric) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.51a: %T.as.Destroy.impl.Op.type.e98 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.011: type = ptr_type %ImplsGeneric [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.7b0: = specific_function %T.as.Destroy.impl.Op.51a, @T.as.Destroy.impl.Op(%ImplsGeneric) [concrete] // CHECK:STDOUT: %complete_type.997: = complete_type_witness %Generic.type.769 [concrete] // CHECK:STDOUT: %.3e6: type = fn_type_with_self_type %Generic.F.type.4cf, %Generic.facet.8ff [concrete] // CHECK:STDOUT: } @@ -251,6 +254,38 @@ fn B() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @GenericParam.as.Destroy.impl: constants.%GenericParam as constants.%Destroy.type { +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op.decl: %GenericParam.as.Destroy.impl.Op.type = fn_decl @GenericParam.as.Destroy.impl.Op [concrete = constants.%GenericParam.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.7c3 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.7c3 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.f73 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%GenericParam [concrete = constants.%GenericParam] +// CHECK:STDOUT: %self: %ptr.f73 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %GenericParam.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @GenericParam.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @ImplsGeneric.as.Destroy.impl: constants.%ImplsGeneric as constants.%Destroy.type { +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op.decl: %ImplsGeneric.as.Destroy.impl.Op.type = fn_decl @ImplsGeneric.as.Destroy.impl.Op [concrete = constants.%ImplsGeneric.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.2db = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.2db = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc10: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.011 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%ImplsGeneric [concrete = constants.%ImplsGeneric] +// CHECK:STDOUT: %self: %ptr.011 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %ImplsGeneric.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @ImplsGeneric.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @ImplsGeneric.as.Generic.impl: %ImplsGeneric.ref as %Generic.type { // CHECK:STDOUT: %ImplsGeneric.as.Generic.impl.F.decl: %ImplsGeneric.as.Generic.impl.F.type = fn_decl @ImplsGeneric.as.Generic.impl.F [concrete = constants.%ImplsGeneric.as.Generic.impl.F] {} {} // CHECK:STDOUT: @@ -260,6 +295,9 @@ fn B() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @GenericParam { +// CHECK:STDOUT: impl_decl @GenericParam.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@GenericParam.as.Destroy.impl.%GenericParam.as.Destroy.impl.Op.decl), @GenericParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.884] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -269,6 +307,9 @@ fn B() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @ImplsGeneric { +// CHECK:STDOUT: impl_decl @ImplsGeneric.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@ImplsGeneric.as.Destroy.impl.%ImplsGeneric.as.Destroy.impl.Op.decl), @ImplsGeneric.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.9ca] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -281,6 +322,10 @@ fn B() { // CHECK:STDOUT: fn(); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @GenericParam.as.Destroy.impl.Op(%self.param: %ptr.f73) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ImplsGeneric.as.Destroy.impl.Op(%self.param: %ptr.011) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @ImplsGeneric.as.Generic.impl.F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return @@ -343,16 +388,12 @@ fn B() { // CHECK:STDOUT: %.loc20_24.2: %ImplsGeneric = bind_value %.loc20_24.1 // CHECK:STDOUT: %.loc20_44.2: %GenericParam = bind_value %.loc20_44.1 // CHECK:STDOUT: %CallGenericMethod.call: init %empty_tuple.type = call %CallGenericMethod.specific_fn(%.loc20_24.2, %.loc20_44.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc20_42: = bound_method %.loc20_42.2, constants.%T.as.Destroy.impl.Op.0cc -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.0cc, @T.as.Destroy.impl.Op(constants.%GenericParam) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.934] -// CHECK:STDOUT: %bound_method.loc20_42: = bound_method %.loc20_42.2, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op.bound: = bound_method %.loc20_42.2, constants.%GenericParam.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc20_42: %ptr.f73 = addr_of %.loc20_42.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc20_42: init %empty_tuple.type = call %bound_method.loc20_42(%addr.loc20_42) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc20_22: = bound_method %.loc20_22.2, constants.%T.as.Destroy.impl.Op.51a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.51a, @T.as.Destroy.impl.Op(constants.%ImplsGeneric) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.7b0] -// CHECK:STDOUT: %bound_method.loc20_22: = bound_method %.loc20_22.2, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op.call: init %empty_tuple.type = call %GenericParam.as.Destroy.impl.Op.bound(%addr.loc20_42) +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op.bound: = bound_method %.loc20_22.2, constants.%ImplsGeneric.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc20_22: %ptr.011 = addr_of %.loc20_22.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc20_22: init %empty_tuple.type = call %bound_method.loc20_22(%addr.loc20_22) +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op.call: init %empty_tuple.type = call %ImplsGeneric.as.Destroy.impl.Op.bound(%addr.loc20_22) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -435,6 +476,13 @@ fn B() { // CHECK:STDOUT: %I.type.f76: type = facet_type <@I, @I(%V, %W)> [symbolic] // CHECK:STDOUT: %Self.770: %I.type.f76 = bind_symbolic_name Self, 2 [symbolic] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T.8b3: type = bind_symbolic_name T, 0 [symbolic] @@ -459,11 +507,6 @@ fn B() { // CHECK:STDOUT: %I.facet: %I.type.202 = facet_value %C, (%I.impl_witness.806) [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %A.specific_fn: = specific_function %A, @A(%I.facet) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -547,6 +590,22 @@ fn B() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl @C.as.I.impl(%T.loc7_14.1: type) { // CHECK:STDOUT: %T.loc7_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc7_14.2 (constants.%T.8b3)] // CHECK:STDOUT: %I.type.loc7_36.2: type = facet_type <@I, @I(%T.loc7_14.2, constants.%empty_tuple.type)> [symbolic = %I.type.loc7_36.2 (constants.%I.type.bea)] @@ -562,6 +621,9 @@ fn B() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -570,6 +632,8 @@ fn B() { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @A(%T.loc9_6.2: %I.type.202) { // CHECK:STDOUT: %T.loc9_6.1: %I.type.202 = bind_symbolic_name T, 0 [symbolic = %T.loc9_6.1 (constants.%T.e96)] // CHECK:STDOUT: %T.as_type.loc9_24.1: type = facet_access_type %T.loc9_6.1 [symbolic = %T.as_type.loc9_24.1 (constants.%T.as_type)] @@ -600,11 +664,9 @@ fn B() { // CHECK:STDOUT: %A.specific_fn: = specific_function %A.ref, @A(constants.%I.facet) [concrete = constants.%A.specific_fn] // CHECK:STDOUT: %.loc12_8.2: %C = bind_value %.loc12_8.1 // CHECK:STDOUT: %A.call: init %empty_tuple.type = call %A.specific_fn(%.loc12_8.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc12_6.2, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc12_6.2, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc12_6.2, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.019 = addr_of %.loc12_6.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -674,8 +736,15 @@ fn B() { // CHECK:STDOUT: %I.type.f76: type = facet_type <@I, @I(%V, %W)> [symbolic] // CHECK:STDOUT: %Self.770: %I.type.f76 = bind_symbolic_name Self, 2 [symbolic] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T.8b3: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %I.type.bea: type = facet_type <@I, @I(%T.8b3, %empty_tuple.type)> [symbolic] // CHECK:STDOUT: %Self.ec5: %I.type.bea = bind_symbolic_name Self, 2 [symbolic] @@ -692,11 +761,6 @@ fn B() { // CHECK:STDOUT: %B.type: type = fn_type @B [concrete] // CHECK:STDOUT: %B: %B.type = struct_value () [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -780,6 +844,22 @@ fn B() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl @C.as.I.impl(%T.loc7_14.1: type) { // CHECK:STDOUT: %T.loc7_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc7_14.2 (constants.%T.8b3)] // CHECK:STDOUT: %I.type.loc7_36.2: type = facet_type <@I, @I(%T.loc7_14.2, constants.%empty_tuple.type)> [symbolic = %I.type.loc7_36.2 (constants.%I.type.bea)] @@ -795,14 +875,19 @@ fn B() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @A(%T.loc9_6.2: %I.type.906) { // CHECK:STDOUT: %T.loc9_6.1: %I.type.906 = bind_symbolic_name T, 0 [symbolic = %T.loc9_6.1 (constants.%T.4b2)] // CHECK:STDOUT: %T.as_type.loc9_24.1: type = facet_access_type %T.loc9_6.1 [symbolic = %T.as_type.loc9_24.1 (constants.%T.as_type)] @@ -826,11 +911,9 @@ fn B() { // CHECK:STDOUT: %.loc19_6.3: init %C = class_init (), %.loc19_6.2 [concrete = constants.%C.val] // CHECK:STDOUT: %.loc19_6.4: ref %C = temporary %.loc19_6.2, %.loc19_6.3 // CHECK:STDOUT: %.loc19_8: ref %C = converted %.loc19_6.1, %.loc19_6.4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc19_6.2, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc19_6.2, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc19_6.2, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.019 = addr_of %.loc19_6.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -878,6 +961,13 @@ fn B() { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.c6b: type = class_type @C, @C(%V, %W) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.4f9: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%V, %W) [symbolic] +// CHECK:STDOUT: %ptr.1cf: type = ptr_type %C.c6b [symbolic] +// CHECK:STDOUT: %pattern_type.b68: type = pattern_type %ptr.1cf [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%V, %W) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T.8b3: type = bind_symbolic_name T, 0 [symbolic] @@ -894,7 +984,7 @@ fn B() { // CHECK:STDOUT: %B: %B.type = struct_value () [concrete] // CHECK:STDOUT: %C.c74: type = class_type @C, @C(%empty_struct_type, %empty_struct_type) [concrete] // CHECK:STDOUT: %C.val: %C.c74 = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e53: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%empty_struct_type, %empty_struct_type) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.53e: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.c74) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.2b8: %T.as.Destroy.impl.Op.type.53e = struct_value () [concrete] // CHECK:STDOUT: %ptr.128: type = ptr_type %C.c74 [concrete] @@ -966,6 +1056,35 @@ fn B() { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%V.loc5_9.2: type, @C.%W.loc5_19.2: type) { +// CHECK:STDOUT: %V: type = bind_symbolic_name V, 0 [symbolic = %V (constants.%V)] +// CHECK:STDOUT: %W: type = bind_symbolic_name W, 1 [symbolic = %W (constants.%W)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%V, %W) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.4f9)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%V, %W) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.c6b as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.b68) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.b68) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5_29.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.1cf) = value_param call_param0 +// CHECK:STDOUT: %.loc5_29.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.c6b)] { +// CHECK:STDOUT: %.loc5_29.3: type = specific_constant constants.%C.c6b, @C(constants.%V, constants.%W) [symbolic = %C (constants.%C.c6b)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc5_29.3 [symbolic = %C (constants.%C.c6b)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.1cf) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl @C.as.I.impl(%T.loc7_14.1: type) { // CHECK:STDOUT: %T.loc7_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc7_14.2 (constants.%T.8b3)] // CHECK:STDOUT: %C.loc7_31.2: type = class_type @C, @C(%T.loc7_14.2, constants.%empty_tuple.type) [symbolic = %C.loc7_31.2 (constants.%C.463)] @@ -986,6 +1105,9 @@ fn B() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%V, constants.%W) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.4f9)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -995,6 +1117,18 @@ fn B() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%V.loc5_9.2: type, @C.%W.loc5_19.2: type) { +// CHECK:STDOUT: %V: type = bind_symbolic_name V, 0 [symbolic = %V (constants.%V)] +// CHECK:STDOUT: %W: type = bind_symbolic_name W, 1 [symbolic = %W (constants.%W)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%V, %W) [symbolic = %C (constants.%C.c6b)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.1cf)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.b68)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.1cf)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @A(%T.loc9_6.2: %I.type) { // CHECK:STDOUT: %T.loc9_6.1: %I.type = bind_symbolic_name T, 0 [symbolic = %T.loc9_6.1 (constants.%T.826)] // CHECK:STDOUT: %T.as_type.loc9_16.1: type = facet_access_type %T.loc9_6.1 [symbolic = %T.as_type.loc9_16.1 (constants.%T.as_type)] @@ -1036,6 +1170,20 @@ fn B() { // CHECK:STDOUT: %W.loc5_19.1 => constants.%W // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%V, constants.%W) { +// CHECK:STDOUT: %V => constants.%V +// CHECK:STDOUT: %W => constants.%W +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.4f9 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%V, constants.%W) { +// CHECK:STDOUT: %V => constants.%V +// CHECK:STDOUT: %W => constants.%W +// CHECK:STDOUT: %C => constants.%C.c6b +// CHECK:STDOUT: %ptr => constants.%ptr.1cf +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.b68 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%T.8b3, constants.%empty_tuple.type) { // CHECK:STDOUT: %V.loc5_9.1 => constants.%T.8b3 // CHECK:STDOUT: %W.loc5_19.1 => constants.%empty_tuple.type @@ -1060,3 +1208,9 @@ fn B() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%empty_struct_type, constants.%empty_struct_type) { +// CHECK:STDOUT: %V => constants.%empty_struct_type +// CHECK:STDOUT: %W => constants.%empty_struct_type +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.e53 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/facet/convert_facet_value_as_type_knows_original_type.carbon b/toolchain/check/testdata/facet/convert_facet_value_as_type_knows_original_type.carbon index 41c3044041bd..c17c85a94f5a 100644 --- a/toolchain/check/testdata/facet/convert_facet_value_as_type_knows_original_type.carbon +++ b/toolchain/check/testdata/facet/convert_facet_value_as_type_knows_original_type.carbon @@ -67,14 +67,21 @@ fn F() { // CHECK:STDOUT: %Animal.type: type = facet_type <@Animal> [concrete] // CHECK:STDOUT: %Self.fd4: %Animal.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %Goat: type = class_type @Goat [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Goat.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.940: type = ptr_type %Goat [concrete] +// CHECK:STDOUT: %pattern_type.396: type = pattern_type %ptr.940 [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.type: type = fn_type @Goat.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op: %Goat.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Animal.impl_witness: = impl_witness file.%Animal.impl_witness_table [concrete] // CHECK:STDOUT: %Eats.impl_witness: = impl_witness file.%Eats.impl_witness_table [concrete] // CHECK:STDOUT: %e: %Eats.type = bind_symbolic_name e, 0 [symbolic] -// CHECK:STDOUT: %pattern_type: type = pattern_type %Eats.type [concrete] +// CHECK:STDOUT: %pattern_type.a05: type = pattern_type %Eats.type [concrete] // CHECK:STDOUT: %Feed.type: type = fn_type @Feed [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Feed: %Feed.type = struct_value () [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] @@ -85,9 +92,11 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -116,7 +125,7 @@ fn F() { // CHECK:STDOUT: %Eats.impl_witness_table = impl_witness_table (), @Goat.as.Eats.impl [concrete] // CHECK:STDOUT: %Eats.impl_witness: = impl_witness %Eats.impl_witness_table [concrete = constants.%Eats.impl_witness] // CHECK:STDOUT: %Feed.decl: %Feed.type = fn_decl @Feed [concrete = constants.%Feed] { -// CHECK:STDOUT: %e.patt: %pattern_type = symbolic_binding_pattern e, 0 [concrete] +// CHECK:STDOUT: %e.patt: %pattern_type.a05 = symbolic_binding_pattern e, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %Eats.ref: type = name_ref Eats, file.%Eats.decl [concrete = constants.%Eats.type] // CHECK:STDOUT: %e.loc11_9.2: %Eats.type = bind_symbolic_name e, 0 [symbolic = %e.loc11_9.1 (constants.%e)] @@ -140,6 +149,22 @@ fn F() { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Goat.as.Destroy.impl: constants.%Goat as constants.%Destroy.type { +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.decl: %Goat.as.Destroy.impl.Op.type = fn_decl @Goat.as.Destroy.impl.Op [concrete = constants.%Goat.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.396 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.396 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.940 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Goat [concrete = constants.%Goat] +// CHECK:STDOUT: %self: %ptr.940 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Goat.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Goat.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @Goat.as.Animal.impl: %Goat.ref as %Animal.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%Animal.impl_witness @@ -151,6 +176,9 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Goat { +// CHECK:STDOUT: impl_decl @Goat.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Goat.as.Destroy.impl.%Goat.as.Destroy.impl.Op.decl), @Goat.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -159,6 +187,8 @@ fn F() { // CHECK:STDOUT: .Self = constants.%Goat // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Goat.as.Destroy.impl.Op(%self.param: %ptr.940) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @Feed(%e.loc11_9.2: %Eats.type) { // CHECK:STDOUT: %e.loc11_9.1: %Eats.type = bind_symbolic_name e, 0 [symbolic = %e.loc11_9.1 (constants.%e)] // CHECK:STDOUT: @@ -216,19 +246,21 @@ fn F() { // CHECK:STDOUT: %Goat.as.Eats.impl.Eat.type: type = fn_type @Goat.as.Eats.impl.Eat [concrete] // CHECK:STDOUT: %Goat.as.Eats.impl.Eat: %Goat.as.Eats.impl.Eat.type = struct_value () [concrete] // CHECK:STDOUT: %Eats.facet: %Eats.type = facet_value %Goat, (%Eats.impl_witness) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.943: = impl_witness @Goat.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.940: type = ptr_type %Goat [concrete] +// CHECK:STDOUT: %pattern_type.396: type = pattern_type %ptr.940 [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.type: type = fn_type @Goat.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op: %Goat.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %Animal.facet: %Animal.type = facet_value %Goat, (%Animal.impl_witness) [concrete] // CHECK:STDOUT: %pattern_type.ab7: type = pattern_type %Goat [concrete] // CHECK:STDOUT: %Goat.val: %Goat = struct_value () [concrete] // CHECK:STDOUT: %.f6e: type = fn_type_with_self_type %Eats.Eat.type, %Eats.facet [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.e7a: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Goat) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.55a: %T.as.Destroy.impl.Op.type.e7a = struct_value () [concrete] -// CHECK:STDOUT: %ptr.940: type = ptr_type %Goat [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.55a, @T.as.Destroy.impl.Op(%Goat) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -287,6 +319,22 @@ fn F() { // CHECK:STDOUT: witness = @Goat.%Eats.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Goat.as.Destroy.impl: constants.%Goat as constants.%Destroy.type { +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.decl: %Goat.as.Destroy.impl.Op.type = fn_decl @Goat.as.Destroy.impl.Op [concrete = constants.%Goat.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.396 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.396 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.940 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Goat [concrete = constants.%Goat] +// CHECK:STDOUT: %self: %ptr.940 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Goat.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Goat.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Goat { // CHECK:STDOUT: %Goat.Bleet.decl: %Goat.Bleet.type = fn_decl @Goat.Bleet [concrete = constants.%Goat.Bleet] {} {} // CHECK:STDOUT: impl_decl @Goat.as.Animal.impl [concrete] {} { @@ -301,8 +349,11 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: %Eats.impl_witness_table = impl_witness_table (@Goat.as.Eats.impl.%Goat.as.Eats.impl.Eat.decl), @Goat.as.Eats.impl [concrete] // CHECK:STDOUT: %Eats.impl_witness: = impl_witness %Eats.impl_witness_table [concrete = constants.%Eats.impl_witness] +// CHECK:STDOUT: impl_decl @Goat.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Goat.as.Destroy.impl.%Goat.as.Destroy.impl.Op.decl), @Goat.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.943] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -328,6 +379,8 @@ fn F() { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Goat.as.Destroy.impl.Op(%self.param: %ptr.940) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -385,21 +438,15 @@ fn F() { // CHECK:STDOUT: %Eat.ref.loc27: %Eats.assoc_type = name_ref Eat, @Eats.%assoc0 [concrete = constants.%assoc0.e43] // CHECK:STDOUT: %impl.elem0.loc27: %.f6e = impl_witness_access constants.%Eats.impl_witness, element0 [concrete = constants.%Goat.as.Eats.impl.Eat] // CHECK:STDOUT: %Goat.as.Eats.impl.Eat.call.loc27: init %empty_tuple.type = call %impl.elem0.loc27() -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc27: = bound_method %.loc27_6.2, constants.%T.as.Destroy.impl.Op.55a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.55a, @T.as.Destroy.impl.Op(constants.%Goat) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc27: = bound_method %.loc27_6.2, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.bound.loc27: = bound_method %.loc27_6.2, constants.%Goat.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc27: %ptr.940 = addr_of %.loc27_6.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc27: init %empty_tuple.type = call %bound_method.loc27(%addr.loc27) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc26: = bound_method %.loc26_6.2, constants.%T.as.Destroy.impl.Op.55a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.55a, @T.as.Destroy.impl.Op(constants.%Goat) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc26: = bound_method %.loc26_6.2, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.call.loc27: init %empty_tuple.type = call %Goat.as.Destroy.impl.Op.bound.loc27(%addr.loc27) +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.bound.loc26: = bound_method %.loc26_6.2, constants.%Goat.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc26: %ptr.940 = addr_of %.loc26_6.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc26: init %empty_tuple.type = call %bound_method.loc26(%addr.loc26) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc22: = bound_method %.loc22_28.2, constants.%T.as.Destroy.impl.Op.55a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.55a, @T.as.Destroy.impl.Op(constants.%Goat) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc22: = bound_method %.loc22_28.2, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.call.loc26: init %empty_tuple.type = call %Goat.as.Destroy.impl.Op.bound.loc26(%addr.loc26) +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.bound.loc22: = bound_method %.loc22_28.2, constants.%Goat.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc22: %ptr.940 = addr_of %.loc22_28.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc22: init %empty_tuple.type = call %bound_method.loc22(%addr.loc22) +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.call.loc22: init %empty_tuple.type = call %Goat.as.Destroy.impl.Op.bound.loc22(%addr.loc22) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/facet/convert_facet_value_to_itself.carbon b/toolchain/check/testdata/facet/convert_facet_value_to_itself.carbon index 5c344f64721e..583d2bd96908 100644 --- a/toolchain/check/testdata/facet/convert_facet_value_to_itself.carbon +++ b/toolchain/check/testdata/facet/convert_facet_value_to_itself.carbon @@ -29,9 +29,9 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Animal.type: type = facet_type <@Animal> [concrete] -// CHECK:STDOUT: %Self: %Animal.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.fd4: %Animal.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %T: %Animal.type = bind_symbolic_name T, 0 [symbolic] -// CHECK:STDOUT: %pattern_type: type = pattern_type %Animal.type [concrete] +// CHECK:STDOUT: %pattern_type.3b0: type = pattern_type %Animal.type [concrete] // CHECK:STDOUT: %FeedAnimal.type: type = fn_type @FeedAnimal [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %FeedAnimal: %FeedAnimal.type = struct_value () [concrete] @@ -39,6 +39,13 @@ fn F() { // CHECK:STDOUT: %HandleAnimal: %HandleAnimal.type = struct_value () [concrete] // CHECK:STDOUT: %FeedAnimal.specific_fn.ec8: = specific_function %FeedAnimal, @FeedAnimal(%T) [symbolic] // CHECK:STDOUT: %Goat: type = class_type @Goat [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Goat.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.940: type = ptr_type %Goat [concrete] +// CHECK:STDOUT: %pattern_type.396: type = pattern_type %ptr.940 [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.type: type = fn_type @Goat.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op: %Goat.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Animal.impl_witness: = impl_witness file.%Animal.impl_witness_table [concrete] @@ -51,9 +58,11 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -68,13 +77,13 @@ fn F() { // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %Animal.decl: type = interface_decl @Animal [concrete = constants.%Animal.type] {} {} // CHECK:STDOUT: %FeedAnimal.decl: %FeedAnimal.type = fn_decl @FeedAnimal [concrete = constants.%FeedAnimal] { -// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %T.patt: %pattern_type.3b0 = symbolic_binding_pattern T, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %Animal.ref: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] // CHECK:STDOUT: %T.loc17_15.2: %Animal.type = bind_symbolic_name T, 0 [symbolic = %T.loc17_15.1 (constants.%T)] // CHECK:STDOUT: } // CHECK:STDOUT: %HandleAnimal.decl: %HandleAnimal.type = fn_decl @HandleAnimal [concrete = constants.%HandleAnimal] { -// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %T.patt: %pattern_type.3b0 = symbolic_binding_pattern T, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %Animal.ref: type = name_ref Animal, file.%Animal.decl [concrete = constants.%Animal.type] // CHECK:STDOUT: %T.loc19_17.2: %Animal.type = bind_symbolic_name T, 0 [symbolic = %T.loc19_17.1 (constants.%T)] @@ -90,19 +99,38 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @Animal { -// CHECK:STDOUT: %Self: %Animal.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %Animal.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.fd4] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = %Self // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Goat.as.Destroy.impl: constants.%Goat as constants.%Destroy.type { +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.decl: %Goat.as.Destroy.impl.Op.type = fn_decl @Goat.as.Destroy.impl.Op [concrete = constants.%Goat.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.396 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.396 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc21: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.940 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Goat [concrete = constants.%Goat] +// CHECK:STDOUT: %self: %ptr.940 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Goat.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Goat.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @Goat.as.Animal.impl: %Goat.ref as %Animal.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%Animal.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Goat { +// CHECK:STDOUT: impl_decl @Goat.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Goat.as.Destroy.impl.%Goat.as.Destroy.impl.Op.decl), @Goat.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -138,6 +166,8 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Goat.as.Destroy.impl.Op(%self.param: %ptr.940) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %HandleAnimal.ref: %HandleAnimal.type = name_ref HandleAnimal, file.%HandleAnimal.decl [concrete = constants.%HandleAnimal] diff --git a/toolchain/check/testdata/facet/convert_facet_value_value_to_generic_facet_value_value.carbon b/toolchain/check/testdata/facet/convert_facet_value_value_to_generic_facet_value_value.carbon index 8ee2e0b1b988..7df41af848fb 100644 --- a/toolchain/check/testdata/facet/convert_facet_value_value_to_generic_facet_value_value.carbon +++ b/toolchain/check/testdata/facet/convert_facet_value_value_to_generic_facet_value_value.carbon @@ -41,6 +41,14 @@ fn F() { // CHECK:STDOUT: %Edible.type: type = facet_type <@Edible> [concrete] // CHECK:STDOUT: %Self.9af: %Edible.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %Grass: type = class_type @Grass [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.826: = impl_witness @Grass.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.2bd: type = ptr_type %Grass [concrete] +// CHECK:STDOUT: %pattern_type.4f0: type = pattern_type %ptr.2bd [concrete] +// CHECK:STDOUT: %Grass.as.Destroy.impl.Op.type: type = fn_type @Grass.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Grass.as.Destroy.impl.Op: %Grass.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Edible.impl_witness: = impl_witness file.%Edible.impl_witness_table [concrete] @@ -49,7 +57,6 @@ fn F() { // CHECK:STDOUT: %Food.8b3: type = bind_symbolic_name Food, 0 [symbolic] // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %Eats.type.ba2: type = generic_interface_type @Eats [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Eats.generic: %Eats.type.ba2 = struct_value () [concrete] // CHECK:STDOUT: %Eats.type.6c0: type = facet_type <@Eats, @Eats(%Food.8b3)> [symbolic] // CHECK:STDOUT: %Self.4eb: %Eats.type.6c0 = bind_symbolic_name Self, 1 [symbolic] @@ -64,6 +71,11 @@ fn F() { // CHECK:STDOUT: %require_complete.42532a.1: = require_complete_type %Eats.type.f54c3d.1 [symbolic] // CHECK:STDOUT: %Eats.impl_witness.fabf92.1: = impl_witness file.%Eats.impl_witness_table, @T.as_type.as.Eats.impl(%T.fd4, %U) [symbolic] // CHECK:STDOUT: %Goat: type = class_type @Goat [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.943: = impl_witness @Goat.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.940: type = ptr_type %Goat [concrete] +// CHECK:STDOUT: %pattern_type.396: type = pattern_type %ptr.940 [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.type: type = fn_type @Goat.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op: %Goat.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Animal.impl_witness: = impl_witness file.%Animal.impl_witness_table [concrete] // CHECK:STDOUT: %Food.9af: %Edible.type = bind_symbolic_name Food, 0 [symbolic] // CHECK:STDOUT: %Food.as_type.952: type = facet_access_type %Food.9af [symbolic] @@ -101,15 +113,6 @@ fn F() { // CHECK:STDOUT: %pattern_type.ab7: type = pattern_type %Goat [concrete] // CHECK:STDOUT: %pattern_type.aff: type = pattern_type %Grass [concrete] // CHECK:STDOUT: %HandleAnimal.specific_fn: = specific_function %HandleAnimal, @HandleAnimal(%Animal.facet, %Edible.facet) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.7fb: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Grass) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d66: %T.as.Destroy.impl.Op.type.7fb = struct_value () [concrete] -// CHECK:STDOUT: %ptr.2bd: type = ptr_type %Grass [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.9e2: = specific_function %T.as.Destroy.impl.Op.d66, @T.as.Destroy.impl.Op(%Grass) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.e7a: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Goat) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.55a: %T.as.Destroy.impl.Op.type.e7a = struct_value () [concrete] -// CHECK:STDOUT: %ptr.940: type = ptr_type %Goat [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.d9f: = specific_function %T.as.Destroy.impl.Op.55a, @T.as.Destroy.impl.Op(%Goat) [concrete] // CHECK:STDOUT: %Eats.type.1ae: type = facet_type <@Eats, @Eats(%Grass)> [concrete] // CHECK:STDOUT: %Self.016: %Eats.type.1ae = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %complete_type.004: = complete_type_witness %Eats.type.1ae [concrete] @@ -280,6 +283,22 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Grass.as.Destroy.impl: constants.%Grass as constants.%Destroy.type { +// CHECK:STDOUT: %Grass.as.Destroy.impl.Op.decl: %Grass.as.Destroy.impl.Op.type = fn_decl @Grass.as.Destroy.impl.Op [concrete = constants.%Grass.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.4f0 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.4f0 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc17: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.2bd = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Grass [concrete = constants.%Grass] +// CHECK:STDOUT: %self: %ptr.2bd = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Grass.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Grass.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @Grass.as.Edible.impl: %Grass.ref as %Edible.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%Edible.impl_witness @@ -302,12 +321,31 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Goat.as.Destroy.impl: constants.%Goat as constants.%Destroy.type { +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.decl: %Goat.as.Destroy.impl.Op.type = fn_decl @Goat.as.Destroy.impl.Op [concrete = constants.%Goat.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.396 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.396 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc28: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.940 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Goat [concrete = constants.%Goat] +// CHECK:STDOUT: %self: %ptr.940 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Goat.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Goat.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @Goat.as.Animal.impl: %Goat.ref as %Animal.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%Animal.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Grass { +// CHECK:STDOUT: impl_decl @Grass.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Grass.as.Destroy.impl.%Grass.as.Destroy.impl.Op.decl), @Grass.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.826] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -317,6 +355,9 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Goat { +// CHECK:STDOUT: impl_decl @Goat.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Goat.as.Destroy.impl.%Goat.as.Destroy.impl.Op.decl), @Goat.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.943] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -325,6 +366,10 @@ fn F() { // CHECK:STDOUT: .Self = constants.%Goat // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Grass.as.Destroy.impl.Op(%self.param: %ptr.2bd) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Goat.as.Destroy.impl.Op(%self.param: %ptr.940) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @Feed(%Food.loc31_9.2: %Edible.type, %T.loc31_24.2: @Feed.%Eats.type.loc31_37.1 (%Eats.type.b39)) { // CHECK:STDOUT: %Food.loc31_9.1: %Edible.type = bind_symbolic_name Food, 0 [symbolic = %Food.loc31_9.1 (constants.%Food.9af)] // CHECK:STDOUT: %Food.as_type.loc31_37.1: type = facet_access_type %Food.loc31_9.1 [symbolic = %Food.as_type.loc31_37.1 (constants.%Food.as_type.952)] @@ -407,16 +452,12 @@ fn F() { // CHECK:STDOUT: %.loc35_19.2: %Goat = bind_value %.loc35_19.1 // CHECK:STDOUT: %.loc35_31.2: %Grass = bind_value %.loc35_31.1 // CHECK:STDOUT: %HandleAnimal.call: init %empty_tuple.type = call %HandleAnimal.specific_fn(%.loc35_19.2, %.loc35_31.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc35_29: = bound_method %.loc35_29.2, constants.%T.as.Destroy.impl.Op.d66 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.d66, @T.as.Destroy.impl.Op(constants.%Grass) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.9e2] -// CHECK:STDOUT: %bound_method.loc35_29: = bound_method %.loc35_29.2, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %Grass.as.Destroy.impl.Op.bound: = bound_method %.loc35_29.2, constants.%Grass.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc35_29: %ptr.2bd = addr_of %.loc35_29.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc35_29: init %empty_tuple.type = call %bound_method.loc35_29(%addr.loc35_29) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc35_17: = bound_method %.loc35_17.2, constants.%T.as.Destroy.impl.Op.55a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.55a, @T.as.Destroy.impl.Op(constants.%Goat) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.d9f] -// CHECK:STDOUT: %bound_method.loc35_17: = bound_method %.loc35_17.2, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %Grass.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Grass.as.Destroy.impl.Op.bound(%addr.loc35_29) +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.bound: = bound_method %.loc35_17.2, constants.%Goat.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc35_17: %ptr.940 = addr_of %.loc35_17.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc35_17: init %empty_tuple.type = call %bound_method.loc35_17(%addr.loc35_17) +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Goat.as.Destroy.impl.Op.bound(%addr.loc35_17) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/facet/convert_facet_value_value_to_itself.carbon b/toolchain/check/testdata/facet/convert_facet_value_value_to_itself.carbon index fee596180a16..5d4eedac4da0 100644 --- a/toolchain/check/testdata/facet/convert_facet_value_value_to_itself.carbon +++ b/toolchain/check/testdata/facet/convert_facet_value_value_to_itself.carbon @@ -42,8 +42,15 @@ fn F() { // CHECK:STDOUT: %HandleAnimal: %HandleAnimal.type = struct_value () [concrete] // CHECK:STDOUT: %FeedAnimal.specific_fn.ec8: = specific_function %FeedAnimal, @FeedAnimal(%T.fd4) [symbolic] // CHECK:STDOUT: %Goat: type = class_type @Goat [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.943: = impl_witness @Goat.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.940: type = ptr_type %Goat [concrete] +// CHECK:STDOUT: %pattern_type.396: type = pattern_type %ptr.940 [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.type: type = fn_type @Goat.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op: %Goat.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Animal.impl_witness: = impl_witness file.%Animal.impl_witness_table [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] @@ -51,11 +58,6 @@ fn F() { // CHECK:STDOUT: %Animal.facet: %Animal.type = facet_value %Goat, (%Animal.impl_witness) [concrete] // CHECK:STDOUT: %pattern_type.ab7: type = pattern_type %Goat [concrete] // CHECK:STDOUT: %HandleAnimal.specific_fn: = specific_function %HandleAnimal, @HandleAnimal(%Animal.facet) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.e7a: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Goat) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.55a: %T.as.Destroy.impl.Op.type.e7a = struct_value () [concrete] -// CHECK:STDOUT: %ptr.940: type = ptr_type %Goat [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.55a, @T.as.Destroy.impl.Op(%Goat) [concrete] // CHECK:STDOUT: %FeedAnimal.specific_fn.82e: = specific_function %FeedAnimal, @FeedAnimal(%Animal.facet) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -127,14 +129,33 @@ fn F() { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Goat.as.Destroy.impl: constants.%Goat as constants.%Destroy.type { +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.decl: %Goat.as.Destroy.impl.Op.type = fn_decl @Goat.as.Destroy.impl.Op [concrete = constants.%Goat.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.396 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.396 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc21: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.940 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Goat [concrete = constants.%Goat] +// CHECK:STDOUT: %self: %ptr.940 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Goat.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Goat.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @Goat.as.Animal.impl: %Goat.ref as %Animal.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%Animal.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Goat { +// CHECK:STDOUT: impl_decl @Goat.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Goat.as.Destroy.impl.%Goat.as.Destroy.impl.Op.decl), @Goat.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.943] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -176,6 +197,8 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Goat.as.Destroy.impl.Op(%self.param: %ptr.940) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %HandleAnimal.ref: %HandleAnimal.type = name_ref HandleAnimal, file.%HandleAnimal.decl [concrete = constants.%HandleAnimal] @@ -192,11 +215,9 @@ fn F() { // CHECK:STDOUT: %HandleAnimal.specific_fn: = specific_function %HandleAnimal.ref, @HandleAnimal(constants.%Animal.facet) [concrete = constants.%HandleAnimal.specific_fn] // CHECK:STDOUT: %.loc25_19.2: %Goat = bind_value %.loc25_19.1 // CHECK:STDOUT: %HandleAnimal.call: init %empty_tuple.type = call %HandleAnimal.specific_fn(%.loc25_19.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc25_17.2, constants.%T.as.Destroy.impl.Op.55a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.55a, @T.as.Destroy.impl.Op(constants.%Goat) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc25_17.2, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.bound: = bound_method %.loc25_17.2, constants.%Goat.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.940 = addr_of %.loc25_17.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Goat.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -221,7 +242,7 @@ fn F() { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.ab7 // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete => constants.%complete_type // CHECK:STDOUT: %FeedAnimal.specific_fn.loc19_37.2 => constants.%FeedAnimal.specific_fn.82e // CHECK:STDOUT: } // CHECK:STDOUT: @@ -231,6 +252,6 @@ fn F() { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.ab7 // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete => constants.%complete_type // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/facet/fail_convert_class_type_to_generic_facet_value.carbon b/toolchain/check/testdata/facet/fail_convert_class_type_to_generic_facet_value.carbon index 8e9dd743757d..150fc4f3a7fc 100644 --- a/toolchain/check/testdata/facet/fail_convert_class_type_to_generic_facet_value.carbon +++ b/toolchain/check/testdata/facet/fail_convert_class_type_to_generic_facet_value.carbon @@ -51,10 +51,27 @@ fn G() { // CHECK:STDOUT: %Generic.assoc_type.0fd: type = assoc_entity_type @Generic, @Generic(%Scalar) [symbolic] // CHECK:STDOUT: %assoc0.296: %Generic.assoc_type.0fd = assoc_entity element0, @Generic.%Generic.F.decl [symbolic] // CHECK:STDOUT: %GenericParam: type = class_type @GenericParam [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.884: = impl_witness @GenericParam.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.f73: type = ptr_type %GenericParam [concrete] +// CHECK:STDOUT: %pattern_type.7c3: type = pattern_type %ptr.f73 [concrete] +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op.type: type = fn_type @GenericParam.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op: %GenericParam.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %WrongGenericParam: type = class_type @WrongGenericParam [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.01c: = impl_witness @WrongGenericParam.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.397: type = ptr_type %WrongGenericParam [concrete] +// CHECK:STDOUT: %pattern_type.396: type = pattern_type %ptr.397 [concrete] +// CHECK:STDOUT: %WrongGenericParam.as.Destroy.impl.Op.type: type = fn_type @WrongGenericParam.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %WrongGenericParam.as.Destroy.impl.Op: %WrongGenericParam.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ImplsGeneric: type = class_type @ImplsGeneric [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9ca: = impl_witness @ImplsGeneric.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.011: type = ptr_type %ImplsGeneric [concrete] +// CHECK:STDOUT: %pattern_type.2db: type = pattern_type %ptr.011 [concrete] +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op.type: type = fn_type @ImplsGeneric.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op: %ImplsGeneric.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Generic.type.769: type = facet_type <@Generic, @Generic(%GenericParam)> [concrete] // CHECK:STDOUT: %Self.f84: %Generic.type.769 = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %Generic.F.type.4cf: type = fn_type @Generic.F, @Generic(%GenericParam) [concrete] @@ -77,9 +94,11 @@ fn G() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -147,6 +166,54 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @GenericParam.as.Destroy.impl: constants.%GenericParam as constants.%Destroy.type { +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op.decl: %GenericParam.as.Destroy.impl.Op.type = fn_decl @GenericParam.as.Destroy.impl.Op [concrete = constants.%GenericParam.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.7c3 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.7c3 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc19: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.f73 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%GenericParam [concrete = constants.%GenericParam] +// CHECK:STDOUT: %self: %ptr.f73 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %GenericParam.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @GenericParam.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @WrongGenericParam.as.Destroy.impl: constants.%WrongGenericParam as constants.%Destroy.type { +// CHECK:STDOUT: %WrongGenericParam.as.Destroy.impl.Op.decl: %WrongGenericParam.as.Destroy.impl.Op.type = fn_decl @WrongGenericParam.as.Destroy.impl.Op [concrete = constants.%WrongGenericParam.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.396 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.396 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc20: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.397 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%WrongGenericParam [concrete = constants.%WrongGenericParam] +// CHECK:STDOUT: %self: %ptr.397 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %WrongGenericParam.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @WrongGenericParam.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @ImplsGeneric.as.Destroy.impl: constants.%ImplsGeneric as constants.%Destroy.type { +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op.decl: %ImplsGeneric.as.Destroy.impl.Op.type = fn_decl @ImplsGeneric.as.Destroy.impl.Op [concrete = constants.%ImplsGeneric.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.2db = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.2db = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc22: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.011 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%ImplsGeneric [concrete = constants.%ImplsGeneric] +// CHECK:STDOUT: %self: %ptr.011 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %ImplsGeneric.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @ImplsGeneric.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @ImplsGeneric.as.Generic.impl: %ImplsGeneric.ref as %Generic.type { // CHECK:STDOUT: %ImplsGeneric.as.Generic.impl.F.decl: %ImplsGeneric.as.Generic.impl.F.type = fn_decl @ImplsGeneric.as.Generic.impl.F [concrete = constants.%ImplsGeneric.as.Generic.impl.F] {} {} // CHECK:STDOUT: @@ -156,6 +223,9 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @GenericParam { +// CHECK:STDOUT: impl_decl @GenericParam.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@GenericParam.as.Destroy.impl.%GenericParam.as.Destroy.impl.Op.decl), @GenericParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.884] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -165,6 +235,9 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @WrongGenericParam { +// CHECK:STDOUT: impl_decl @WrongGenericParam.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@WrongGenericParam.as.Destroy.impl.%WrongGenericParam.as.Destroy.impl.Op.decl), @WrongGenericParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.01c] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -174,6 +247,9 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @ImplsGeneric { +// CHECK:STDOUT: impl_decl @ImplsGeneric.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@ImplsGeneric.as.Destroy.impl.%ImplsGeneric.as.Destroy.impl.Op.decl), @ImplsGeneric.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.9ca] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -186,6 +262,12 @@ fn G() { // CHECK:STDOUT: fn(); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @GenericParam.as.Destroy.impl.Op(%self.param: %ptr.f73) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @WrongGenericParam.as.Destroy.impl.Op(%self.param: %ptr.397) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ImplsGeneric.as.Destroy.impl.Op(%self.param: %ptr.011) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @ImplsGeneric.as.Generic.impl.F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return diff --git a/toolchain/check/testdata/facet/fail_convert_type_erased_type_to_facet.carbon b/toolchain/check/testdata/facet/fail_convert_type_erased_type_to_facet.carbon index 11209cfda9e2..17a33d6df567 100644 --- a/toolchain/check/testdata/facet/fail_convert_type_erased_type_to_facet.carbon +++ b/toolchain/check/testdata/facet/fail_convert_type_erased_type_to_facet.carbon @@ -35,8 +35,15 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Animal.type: type = facet_type <@Animal> [concrete] -// CHECK:STDOUT: %Self: %Animal.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.fd4: %Animal.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %Goat: type = class_type @Goat [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Goat.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.940: type = ptr_type %Goat [concrete] +// CHECK:STDOUT: %pattern_type.396: type = pattern_type %ptr.940 [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.type: type = fn_type @Goat.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op: %Goat.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Animal.impl_witness: = impl_witness file.%Animal.impl_witness_table [concrete] @@ -52,9 +59,11 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -84,19 +93,38 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @Animal { -// CHECK:STDOUT: %Self: %Animal.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %Animal.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.fd4] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = %Self // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Goat.as.Destroy.impl: constants.%Goat as constants.%Destroy.type { +// CHECK:STDOUT: %Goat.as.Destroy.impl.Op.decl: %Goat.as.Destroy.impl.Op.type = fn_decl @Goat.as.Destroy.impl.Op [concrete = constants.%Goat.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.396 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.396 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc17: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.940 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Goat [concrete = constants.%Goat] +// CHECK:STDOUT: %self: %ptr.940 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Goat.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Goat.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @Goat.as.Animal.impl: %Goat.ref as %Animal.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%Animal.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Goat { +// CHECK:STDOUT: impl_decl @Goat.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Goat.as.Destroy.impl.%Goat.as.Destroy.impl.Op.decl), @Goat.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -105,6 +133,8 @@ fn F() { // CHECK:STDOUT: .Self = constants.%Goat // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Goat.as.Destroy.impl.Op(%self.param: %ptr.940) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @WalkAnimal(%a.loc20_15.2: %Animal.type) { // CHECK:STDOUT: %a.loc20_15.1: %Animal.type = bind_symbolic_name a, 0 [symbolic = %a.loc20_15.1 (constants.%a)] // CHECK:STDOUT: diff --git a/toolchain/check/testdata/facet/fail_deduction_uses_runtime_type_conversion.carbon b/toolchain/check/testdata/facet/fail_deduction_uses_runtime_type_conversion.carbon index bbbf54478e9e..0e3b91463a54 100644 --- a/toolchain/check/testdata/facet/fail_deduction_uses_runtime_type_conversion.carbon +++ b/toolchain/check/testdata/facet/fail_deduction_uses_runtime_type_conversion.carbon @@ -51,10 +51,27 @@ fn G(holds_to: HoldsType((RuntimeConvertTo, ))) { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %HoldsType.generic: %HoldsType.type = struct_value () [concrete] // CHECK:STDOUT: %HoldsType.cc9: type = class_type @HoldsType, @HoldsType(%T.6eb) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d43: = impl_witness @HoldsType.%Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(%T.6eb) [symbolic] +// CHECK:STDOUT: %ptr.47e: type = ptr_type %HoldsType.cc9 [symbolic] +// CHECK:STDOUT: %pattern_type.c39: type = pattern_type %ptr.47e [symbolic] +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op.type: type = fn_type @HoldsType.as.Destroy.impl.Op, @HoldsType.as.Destroy.impl(%T.6eb) [symbolic] +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op: %HoldsType.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %RuntimeConvertFrom: type = class_type @RuntimeConvertFrom [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.99d: = impl_witness @RuntimeConvertFrom.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.415: type = ptr_type %RuntimeConvertFrom [concrete] +// CHECK:STDOUT: %pattern_type.b92: type = pattern_type %ptr.415 [concrete] +// CHECK:STDOUT: %RuntimeConvertFrom.as.Destroy.impl.Op.type: type = fn_type @RuntimeConvertFrom.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %RuntimeConvertFrom.as.Destroy.impl.Op: %RuntimeConvertFrom.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %RuntimeConvertTo: type = class_type @RuntimeConvertTo [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.8af: = impl_witness @RuntimeConvertTo.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.339: type = ptr_type %RuntimeConvertTo [concrete] +// CHECK:STDOUT: %pattern_type.a4a: type = pattern_type %ptr.339 [concrete] +// CHECK:STDOUT: %RuntimeConvertTo.as.Destroy.impl.Op.type: type = fn_type @RuntimeConvertTo.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %RuntimeConvertTo.as.Destroy.impl.Op: %RuntimeConvertTo.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.580: type = facet_type <@ImplicitAs, @ImplicitAs(%RuntimeConvertTo)> [concrete] @@ -83,26 +100,17 @@ fn G(holds_to: HoldsType((RuntimeConvertTo, ))) { // CHECK:STDOUT: %RuntimeConvertFrom.val: %RuntimeConvertFrom = struct_value () [concrete] // CHECK:STDOUT: %.f4e: type = fn_type_with_self_type %ImplicitAs.Convert.type.50a, %ImplicitAs.facet [concrete] // CHECK:STDOUT: %RuntimeConvertFrom.as.ImplicitAs.impl.Convert.bound: = bound_method %from, %RuntimeConvertFrom.as.ImplicitAs.impl.Convert [symbolic] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.139: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%RuntimeConvertTo) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d2d: %T.as.Destroy.impl.Op.type.139 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.339: type = ptr_type %RuntimeConvertTo [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.373: = specific_function %T.as.Destroy.impl.Op.d2d, @T.as.Destroy.impl.Op(%RuntimeConvertTo) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.147: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%RuntimeConvertFrom) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.3f3: %T.as.Destroy.impl.Op.type.147 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.415: type = ptr_type %RuntimeConvertFrom [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.5db: = specific_function %T.as.Destroy.impl.Op.3f3, @T.as.Destroy.impl.Op(%RuntimeConvertFrom) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -177,6 +185,66 @@ fn G(holds_to: HoldsType((RuntimeConvertTo, ))) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @HoldsType.as.Destroy.impl(@HoldsType.%T.loc17_17.2: %tuple.type) { +// CHECK:STDOUT: %T: %tuple.type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.6eb)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @HoldsType.%Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.d43)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op.type: type = fn_type @HoldsType.as.Destroy.impl.Op, @HoldsType.as.Destroy.impl(%T) [symbolic = %HoldsType.as.Destroy.impl.Op.type (constants.%HoldsType.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op: @HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op.type (%HoldsType.as.Destroy.impl.Op.type) = struct_value () [symbolic = %HoldsType.as.Destroy.impl.Op (constants.%HoldsType.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%HoldsType.cc9 as constants.%Destroy.type { +// CHECK:STDOUT: %HoldsType.as.Destroy.impl.Op.decl: @HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op.type (%HoldsType.as.Destroy.impl.Op.type) = fn_decl @HoldsType.as.Destroy.impl.Op [symbolic = @HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op (constants.%HoldsType.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @HoldsType.as.Destroy.impl.Op.%pattern_type (%pattern_type.c39) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @HoldsType.as.Destroy.impl.Op.%pattern_type (%pattern_type.c39) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc17_31.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @HoldsType.as.Destroy.impl.Op.%ptr (%ptr.47e) = value_param call_param0 +// CHECK:STDOUT: %.loc17_31.2: type = splice_block %Self.ref [symbolic = %HoldsType (constants.%HoldsType.cc9)] { +// CHECK:STDOUT: %.loc17_31.3: type = specific_constant constants.%HoldsType.cc9, @HoldsType(constants.%T.6eb) [symbolic = %HoldsType (constants.%HoldsType.cc9)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc17_31.3 [symbolic = %HoldsType (constants.%HoldsType.cc9)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @HoldsType.as.Destroy.impl.Op.%ptr (%ptr.47e) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %HoldsType.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @HoldsType.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @RuntimeConvertFrom.as.Destroy.impl: constants.%RuntimeConvertFrom as constants.%Destroy.type { +// CHECK:STDOUT: %RuntimeConvertFrom.as.Destroy.impl.Op.decl: %RuntimeConvertFrom.as.Destroy.impl.Op.type = fn_decl @RuntimeConvertFrom.as.Destroy.impl.Op [concrete = constants.%RuntimeConvertFrom.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.b92 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.b92 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc19: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.415 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%RuntimeConvertFrom [concrete = constants.%RuntimeConvertFrom] +// CHECK:STDOUT: %self: %ptr.415 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %RuntimeConvertFrom.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @RuntimeConvertFrom.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @RuntimeConvertTo.as.Destroy.impl: constants.%RuntimeConvertTo as constants.%Destroy.type { +// CHECK:STDOUT: %RuntimeConvertTo.as.Destroy.impl.Op.decl: %RuntimeConvertTo.as.Destroy.impl.Op.type = fn_decl @RuntimeConvertTo.as.Destroy.impl.Op [concrete = constants.%RuntimeConvertTo.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a4a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a4a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc20: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.339 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%RuntimeConvertTo [concrete = constants.%RuntimeConvertTo] +// CHECK:STDOUT: %self: %ptr.339 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %RuntimeConvertTo.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @RuntimeConvertTo.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @RuntimeConvertFrom.as.ImplicitAs.impl: %RuntimeConvertFrom.ref as %ImplicitAs.type { // CHECK:STDOUT: %RuntimeConvertFrom.as.ImplicitAs.impl.Convert.decl: %RuntimeConvertFrom.as.ImplicitAs.impl.Convert.type = fn_decl @RuntimeConvertFrom.as.ImplicitAs.impl.Convert [concrete = constants.%RuntimeConvertFrom.as.ImplicitAs.impl.Convert] { // CHECK:STDOUT: %self.patt: %pattern_type.f64 = binding_pattern self [concrete] @@ -204,8 +272,11 @@ fn G(holds_to: HoldsType((RuntimeConvertTo, ))) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @HoldsType.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@HoldsType.as.Destroy.impl.%HoldsType.as.Destroy.impl.Op.decl), @HoldsType.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @HoldsType.as.Destroy.impl(constants.%T.6eb) [symbolic = @HoldsType.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.d43)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -214,8 +285,11 @@ fn G(holds_to: HoldsType((RuntimeConvertTo, ))) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @RuntimeConvertFrom { +// CHECK:STDOUT: impl_decl @RuntimeConvertFrom.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@RuntimeConvertFrom.as.Destroy.impl.%RuntimeConvertFrom.as.Destroy.impl.Op.decl), @RuntimeConvertFrom.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.99d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -223,14 +297,32 @@ fn G(holds_to: HoldsType((RuntimeConvertTo, ))) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @RuntimeConvertTo { +// CHECK:STDOUT: impl_decl @RuntimeConvertTo.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@RuntimeConvertTo.as.Destroy.impl.%RuntimeConvertTo.as.Destroy.impl.Op.decl), @RuntimeConvertTo.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.8af] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%RuntimeConvertTo // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @HoldsType.as.Destroy.impl.Op(@HoldsType.%T.loc17_17.2: %tuple.type) { +// CHECK:STDOUT: %T: %tuple.type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T.6eb)] +// CHECK:STDOUT: %HoldsType: type = class_type @HoldsType, @HoldsType(%T) [symbolic = %HoldsType (constants.%HoldsType.cc9)] +// CHECK:STDOUT: %ptr: type = ptr_type %HoldsType [symbolic = %ptr (constants.%ptr.47e)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.c39)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @HoldsType.as.Destroy.impl.Op.%ptr (%ptr.47e)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @RuntimeConvertFrom.as.Destroy.impl.Op(%self.param: %ptr.415) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @RuntimeConvertTo.as.Destroy.impl.Op(%self.param: %ptr.339) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @RuntimeConvertFrom.as.ImplicitAs.impl.Convert(%self.param: %RuntimeConvertFrom) -> %return.param: %RuntimeConvertTo { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc24_58.1: %empty_struct_type = struct_literal () @@ -274,24 +366,20 @@ fn G(holds_to: HoldsType((RuntimeConvertTo, ))) { // CHECK:STDOUT: %from.ref: %RuntimeConvertFrom = name_ref from, %from [symbolic = constants.%from] // CHECK:STDOUT: %holds_to.ref: %HoldsType.066 = name_ref holds_to, %holds_to // CHECK:STDOUT: %impl.elem0: %.f4e = impl_witness_access constants.%ImplicitAs.impl_witness, element0 [concrete = constants.%RuntimeConvertFrom.as.ImplicitAs.impl.Convert] -// CHECK:STDOUT: %bound_method.loc41_19.1: = bound_method constants.%from, %impl.elem0 [symbolic = constants.%RuntimeConvertFrom.as.ImplicitAs.impl.Convert.bound] +// CHECK:STDOUT: %bound_method: = bound_method constants.%from, %impl.elem0 [symbolic = constants.%RuntimeConvertFrom.as.ImplicitAs.impl.Convert.bound] // CHECK:STDOUT: %.loc41_19.1: ref %RuntimeConvertTo = temporary_storage -// CHECK:STDOUT: %RuntimeConvertFrom.as.ImplicitAs.impl.Convert.call: init %RuntimeConvertTo = call %bound_method.loc41_19.1(constants.%from) to %.loc41_19.1 +// CHECK:STDOUT: %RuntimeConvertFrom.as.ImplicitAs.impl.Convert.call: init %RuntimeConvertTo = call %bound_method(constants.%from) to %.loc41_19.1 // CHECK:STDOUT: %.loc41_19.2: init %RuntimeConvertTo = converted constants.%from, %RuntimeConvertFrom.as.ImplicitAs.impl.Convert.call // CHECK:STDOUT: %.loc41_19.3: ref %RuntimeConvertTo = temporary %.loc41_19.1, %.loc41_19.2 // CHECK:STDOUT: %.loc41_19.4: %RuntimeConvertTo = bind_value %.loc41_19.3 // CHECK:STDOUT: %F.specific_fn: = specific_function %F.ref, @F(constants.%tuple, ) [concrete = ] // CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.specific_fn(%holds_to.ref) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc41: = bound_method %.loc41_19.1, constants.%T.as.Destroy.impl.Op.d2d -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.d2d, @T.as.Destroy.impl.Op(constants.%RuntimeConvertTo) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.373] -// CHECK:STDOUT: %bound_method.loc41_19.2: = bound_method %.loc41_19.1, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %RuntimeConvertTo.as.Destroy.impl.Op.bound: = bound_method %.loc41_19.1, constants.%RuntimeConvertTo.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc41: %ptr.339 = addr_of %.loc41_19.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc41: init %empty_tuple.type = call %bound_method.loc41_19.2(%addr.loc41) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc30: = bound_method %.loc30_36.2, constants.%T.as.Destroy.impl.Op.3f3 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.3f3, @T.as.Destroy.impl.Op(constants.%RuntimeConvertFrom) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.5db] -// CHECK:STDOUT: %bound_method.loc30: = bound_method %.loc30_36.2, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %RuntimeConvertTo.as.Destroy.impl.Op.call: init %empty_tuple.type = call %RuntimeConvertTo.as.Destroy.impl.Op.bound(%addr.loc41) +// CHECK:STDOUT: %RuntimeConvertFrom.as.Destroy.impl.Op.bound: = bound_method %.loc30_36.2, constants.%RuntimeConvertFrom.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc30: %ptr.415 = addr_of %.loc30_36.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc30: init %empty_tuple.type = call %bound_method.loc30(%addr.loc30) +// CHECK:STDOUT: %RuntimeConvertFrom.as.Destroy.impl.Op.call: init %empty_tuple.type = call %RuntimeConvertFrom.as.Destroy.impl.Op.bound(%addr.loc30) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -301,6 +389,18 @@ fn G(holds_to: HoldsType((RuntimeConvertTo, ))) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @HoldsType.as.Destroy.impl(constants.%T.6eb) { +// CHECK:STDOUT: %T => constants.%T.6eb +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.d43 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @HoldsType.as.Destroy.impl.Op(constants.%T.6eb) { +// CHECK:STDOUT: %T => constants.%T.6eb +// CHECK:STDOUT: %HoldsType => constants.%HoldsType.cc9 +// CHECK:STDOUT: %ptr => constants.%ptr.47e +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.c39 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%T.6eb, constants.%A) { // CHECK:STDOUT: %T.loc27_6.1 => constants.%T.6eb // CHECK:STDOUT: %tuple.elem0.loc27_25.1 => constants.%tuple.elem0 diff --git a/toolchain/check/testdata/for/actual.carbon b/toolchain/check/testdata/for/actual.carbon index e3c39c91059d..ab55c2e6dcd6 100644 --- a/toolchain/check/testdata/for/actual.carbon +++ b/toolchain/check/testdata/for/actual.carbon @@ -97,11 +97,17 @@ fn Read() { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.956, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.impl_witness.1fb: = impl_witness imports.%ImplicitAs.impl_witness_table.2b9, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] // CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete] // CHECK:STDOUT: %complete_type.f8a: = complete_type_witness %i32.builtin [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.3a2: = impl_witness imports.%Destroy.impl_witness_table.1b4, @Int.as.Destroy.impl(%N.c80) [symbolic] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.type: type = fn_type @Int.as.Destroy.impl.Op, @Int.as.Destroy.impl(%N.c80) [symbolic] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op: %Int.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.784: type = ptr_type %Int.49d0e6.1 [symbolic] +// CHECK:STDOUT: %pattern_type.4dc: type = pattern_type %ptr.784 [symbolic] // CHECK:STDOUT: %M: Core.IntLiteral = bind_symbolic_name M, 1 [symbolic] // CHECK:STDOUT: %Other: type = bind_symbolic_name Other, 0 [symbolic] // CHECK:STDOUT: %require_complete.b4f426.3: = require_complete_type %Int.49d0e6.1 [symbolic] @@ -117,8 +123,6 @@ fn Read() { // CHECK:STDOUT: %OrderedWith.Less.type.8fe: type = fn_type @OrderedWith.Less, @OrderedWith(%Int.49d0e6.1) [symbolic] // CHECK:STDOUT: %OrderedWith.assoc_type.d92: type = assoc_entity_type @OrderedWith, @OrderedWith(%Int.49d0e6.1) [symbolic] // CHECK:STDOUT: %assoc0.8dc: %OrderedWith.assoc_type.d92 = assoc_entity element0, imports.%Core.import_ref.13d [symbolic] -// CHECK:STDOUT: %ptr.784: type = ptr_type %Int.49d0e6.1 [symbolic] -// CHECK:STDOUT: %pattern_type.4dc: type = pattern_type %ptr.784 [symbolic] // CHECK:STDOUT: %require_complete.0f5: = require_complete_type %ptr.784 [symbolic] // CHECK:STDOUT: %Inc.type: type = facet_type <@Inc> [concrete] // CHECK:STDOUT: %Iterate.facet.7f1: %Iterate.type = facet_value %.Self.as_type.935, (%Iterate.lookup_impl_witness.65a) [symbolic_self] @@ -133,6 +137,11 @@ fn Read() { // CHECK:STDOUT: %IntRange.as.Iterate.impl.Next.type: type = fn_type @IntRange.as.Iterate.impl.Next, @IntRange.as.Iterate.impl(%N.c80) [symbolic] // CHECK:STDOUT: %IntRange.as.Iterate.impl.Next: %IntRange.as.Iterate.impl.Next.type = struct_value () [symbolic] // CHECK:STDOUT: %IntRange.elem.e7c: type = unbound_element_type %IntRange.349, %Int.49d0e6.1 [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.0ef: = impl_witness @IntRange.%Destroy.impl_witness_table, @IntRange.as.Destroy.impl(%N.c80) [symbolic] +// CHECK:STDOUT: %ptr.710: type = ptr_type %IntRange.349 [symbolic] +// CHECK:STDOUT: %pattern_type.99f: type = pattern_type %ptr.710 [symbolic] +// CHECK:STDOUT: %IntRange.as.Destroy.impl.Op.type: type = fn_type @IntRange.as.Destroy.impl.Op, @IntRange.as.Destroy.impl(%N.c80) [symbolic] +// CHECK:STDOUT: %IntRange.as.Destroy.impl.Op: %IntRange.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.start.end.78d: type = struct_type {.start: %Int.49d0e6.1, .end: %Int.49d0e6.1} [symbolic] // CHECK:STDOUT: %complete_type.9d5: = complete_type_witness %struct_type.start.end.78d [symbolic] // CHECK:STDOUT: %require_complete.524: = require_complete_type %IntRange.349 [symbolic] @@ -157,16 +166,14 @@ fn Read() { // CHECK:STDOUT: %Optional.Some.specific_fn.6f1: = specific_function %Optional.Some.58a, @Optional.Some(%Int.49d0e6.1) [symbolic] // CHECK:STDOUT: %ptr.2aa: type = ptr_type %Optional.708 [symbolic] // CHECK:STDOUT: %require_complete.a5e: = require_complete_type %ptr.2aa [symbolic] -// CHECK:STDOUT: %Destroy.lookup_impl_witness.f9d: = lookup_impl_witness %Optional.708, @Destroy [symbolic] -// CHECK:STDOUT: %Destroy.facet.be9: %Destroy.type = facet_value %Optional.708, (%Destroy.lookup_impl_witness.f9d) [symbolic] +// CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %Optional.708, @Destroy [symbolic] +// CHECK:STDOUT: %Destroy.facet.be9: %Destroy.type = facet_value %Optional.708, (%Destroy.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %.1ee: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.be9 [symbolic] -// CHECK:STDOUT: %impl.elem0.5fd: %.1ee = impl_witness_access %Destroy.lookup_impl_witness.f9d, element0 [symbolic] +// CHECK:STDOUT: %impl.elem0.5fd: %.1ee = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic] // CHECK:STDOUT: %specific_impl_fn.79e: = specific_impl_function %impl.elem0.5fd, @Destroy.Op(%Destroy.facet.be9) [symbolic] -// CHECK:STDOUT: %Destroy.lookup_impl_witness.34a: = lookup_impl_witness %Int.49d0e6.1, @Destroy [symbolic] -// CHECK:STDOUT: %Destroy.facet.13d: %Destroy.type = facet_value %Int.49d0e6.1, (%Destroy.lookup_impl_witness.34a) [symbolic] -// CHECK:STDOUT: %.bbc: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.13d [symbolic] -// CHECK:STDOUT: %impl.elem0.fe8: %.bbc = impl_witness_access %Destroy.lookup_impl_witness.34a, element0 [symbolic] -// CHECK:STDOUT: %specific_impl_fn.f4e: = specific_impl_function %impl.elem0.fe8, @Destroy.Op(%Destroy.facet.13d) [symbolic] +// CHECK:STDOUT: %Destroy.facet.d3b: %Destroy.type = facet_value %Int.49d0e6.1, (%Destroy.impl_witness.3a2) [symbolic] +// CHECK:STDOUT: %.ffb: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.d3b [symbolic] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.specific_fn: = specific_function %Int.as.Destroy.impl.Op, @Int.as.Destroy.impl.Op(%N.c80) [symbolic] // CHECK:STDOUT: %Optional.None.specific_fn.82b: = specific_function %Optional.None.83e, @Optional.None(%Int.49d0e6.1) [symbolic] // CHECK:STDOUT: %IntRange.365: type = class_type @IntRange, @IntRange(%int_32) [concrete] // CHECK:STDOUT: %pattern_type.d16: type = pattern_type %IntRange.365 [concrete] @@ -184,6 +191,7 @@ fn Read() { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.d04: = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.b6e: = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.378: = impl_witness @IntRange.%Destroy.impl_witness_table, @IntRange.as.Destroy.impl(%int_32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.2d1: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%IntRange.365) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.fa8: %T.as.Destroy.impl.Op.type.2d1 = struct_value () [concrete] // CHECK:STDOUT: %ptr.049: type = ptr_type %IntRange.365 [concrete] @@ -196,9 +204,9 @@ fn Read() { // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .Iterate = %Core.Iterate // CHECK:STDOUT: .Optional = %Core.Optional +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .OrderedWith = %Core.OrderedWith // CHECK:STDOUT: .Inc = %Core.Inc -// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... @@ -211,23 +219,25 @@ fn Read() { // CHECK:STDOUT: %Core.import_ref.9e6: type = import_ref Core//prelude/iterate, loc13_17, loaded [concrete = %CursorType] // CHECK:STDOUT: %Core.import_ref.f49c: @Optional.%Optional.None.type (%Optional.None.type.ef2) = import_ref Core//prelude/iterate, inst131 [indirect], loaded [symbolic = @Optional.%Optional.None (constants.%Optional.None.fd6)] // CHECK:STDOUT: %Core.import_ref.1a8: @Optional.%Optional.Some.type (%Optional.Some.type.b2c) = import_ref Core//prelude/iterate, inst132 [indirect], loaded [symbolic = @Optional.%Optional.Some (constants.%Optional.Some.d0d)] -// CHECK:STDOUT: %Core.import_ref.cf4: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/iterate, inst439 [indirect], loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] +// CHECK:STDOUT: %Core.import_ref.cf4: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/iterate, inst471 [indirect], loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.2b9 = impl_witness_table (%Core.import_ref.cf4), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.import_ref.19a: @OrderedWith.%OrderedWith.assoc_type (%OrderedWith.assoc_type.03c) = import_ref Core//prelude/iterate, inst819 [indirect], loaded [symbolic = @OrderedWith.%assoc0 (constants.%assoc0.5db)] -// CHECK:STDOUT: %Core.import_ref.b2b: @Int.as.OrderedWith.impl.db3.%Int.as.OrderedWith.impl.Less.type (%Int.as.OrderedWith.impl.Less.type.2c7) = import_ref Core//prelude/iterate, inst908 [indirect], loaded [symbolic = @Int.as.OrderedWith.impl.db3.%Int.as.OrderedWith.impl.Less (constants.%Int.as.OrderedWith.impl.Less.a5a)] -// CHECK:STDOUT: %Core.import_ref.ab6 = import_ref Core//prelude/iterate, inst909 [indirect], unloaded -// CHECK:STDOUT: %Core.import_ref.875 = import_ref Core//prelude/iterate, inst910 [indirect], unloaded -// CHECK:STDOUT: %Core.import_ref.82b = import_ref Core//prelude/iterate, inst911 [indirect], unloaded +// CHECK:STDOUT: %Core.import_ref.741: @Int.as.Destroy.impl.%Int.as.Destroy.impl.Op.type (%Int.as.Destroy.impl.Op.type) = import_ref Core//prelude/iterate, inst440 [indirect], loaded [symbolic = @Int.as.Destroy.impl.%Int.as.Destroy.impl.Op (constants.%Int.as.Destroy.impl.Op)] +// CHECK:STDOUT: %Destroy.impl_witness_table.1b4 = impl_witness_table (%Core.import_ref.741), @Int.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Core.import_ref.19a: @OrderedWith.%OrderedWith.assoc_type (%OrderedWith.assoc_type.03c) = import_ref Core//prelude/iterate, inst851 [indirect], loaded [symbolic = @OrderedWith.%assoc0 (constants.%assoc0.5db)] +// CHECK:STDOUT: %Core.import_ref.b2b: @Int.as.OrderedWith.impl.db3.%Int.as.OrderedWith.impl.Less.type (%Int.as.OrderedWith.impl.Less.type.2c7) = import_ref Core//prelude/iterate, inst940 [indirect], loaded [symbolic = @Int.as.OrderedWith.impl.db3.%Int.as.OrderedWith.impl.Less (constants.%Int.as.OrderedWith.impl.Less.a5a)] +// CHECK:STDOUT: %Core.import_ref.ab6 = import_ref Core//prelude/iterate, inst941 [indirect], unloaded +// CHECK:STDOUT: %Core.import_ref.875 = import_ref Core//prelude/iterate, inst942 [indirect], unloaded +// CHECK:STDOUT: %Core.import_ref.82b = import_ref Core//prelude/iterate, inst943 [indirect], unloaded // CHECK:STDOUT: %OrderedWith.impl_witness_table.476 = impl_witness_table (%Core.import_ref.b2b, %Core.import_ref.ab6, %Core.import_ref.875, %Core.import_ref.82b), @Int.as.OrderedWith.impl.db3 [concrete] -// CHECK:STDOUT: %Core.import_ref.13d: @OrderedWith.%OrderedWith.Less.type (%OrderedWith.Less.type.f19) = import_ref Core//prelude/iterate, inst1883 [indirect], loaded [symbolic = @OrderedWith.%OrderedWith.Less (constants.%OrderedWith.Less.02e)] +// CHECK:STDOUT: %Core.import_ref.13d: @OrderedWith.%OrderedWith.Less.type (%OrderedWith.Less.type.f19) = import_ref Core//prelude/iterate, inst1915 [indirect], loaded [symbolic = @OrderedWith.%OrderedWith.Less (constants.%OrderedWith.Less.02e)] // CHECK:STDOUT: %CursorType: type = assoc_const_decl @CursorType [concrete] {} // CHECK:STDOUT: %Core.import_ref.4f9: type = import_ref Core//prelude/iterate, loc12_18, loaded [concrete = %ElementType] // CHECK:STDOUT: %ElementType: type = assoc_const_decl @ElementType [concrete] {} // CHECK:STDOUT: %Core.Optional: %Optional.type = import_ref Core//prelude/types/optional, Optional, loaded [concrete = constants.%Optional.generic] -// CHECK:STDOUT: %Core.OrderedWith: %OrderedWith.type.270 = import_ref Core//prelude/operators/comparison, OrderedWith, loaded [concrete = constants.%OrderedWith.generic] -// CHECK:STDOUT: %Core.import_ref.d49 = import_ref Core//prelude/iterate, inst6604 [indirect], unloaded -// CHECK:STDOUT: %Core.Inc: type = import_ref Core//prelude/operators/arithmetic, Inc, loaded [concrete = constants.%Inc.type] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Core.OrderedWith: %OrderedWith.type.270 = import_ref Core//prelude/operators/comparison, OrderedWith, loaded [concrete = constants.%OrderedWith.generic] +// CHECK:STDOUT: %Core.import_ref.d49 = import_ref Core//prelude/iterate, inst6633 [indirect], unloaded +// CHECK:STDOUT: %Core.Inc: type = import_ref Core//prelude/operators/arithmetic, Inc, loaded [concrete = constants.%Inc.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/operators/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -346,6 +356,34 @@ fn Read() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @IntRange.as.Destroy.impl(@IntRange.%N.loc4_16.2: Core.IntLiteral) { +// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.c80)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @IntRange.%Destroy.impl_witness_table, @IntRange.as.Destroy.impl(%N) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.0ef)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %IntRange.as.Destroy.impl.Op.type: type = fn_type @IntRange.as.Destroy.impl.Op, @IntRange.as.Destroy.impl(%N) [symbolic = %IntRange.as.Destroy.impl.Op.type (constants.%IntRange.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %IntRange.as.Destroy.impl.Op: @IntRange.as.Destroy.impl.%IntRange.as.Destroy.impl.Op.type (%IntRange.as.Destroy.impl.Op.type) = struct_value () [symbolic = %IntRange.as.Destroy.impl.Op (constants.%IntRange.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%IntRange.349 as constants.%Destroy.type { +// CHECK:STDOUT: %IntRange.as.Destroy.impl.Op.decl: @IntRange.as.Destroy.impl.%IntRange.as.Destroy.impl.Op.type (%IntRange.as.Destroy.impl.Op.type) = fn_decl @IntRange.as.Destroy.impl.Op [symbolic = @IntRange.as.Destroy.impl.%IntRange.as.Destroy.impl.Op (constants.%IntRange.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @IntRange.as.Destroy.impl.Op.%pattern_type (%pattern_type.99f) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @IntRange.as.Destroy.impl.Op.%pattern_type (%pattern_type.99f) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_39.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @IntRange.as.Destroy.impl.Op.%ptr (%ptr.710) = value_param call_param0 +// CHECK:STDOUT: %.loc4_39.2: type = splice_block %Self.ref [symbolic = %IntRange (constants.%IntRange.349)] { +// CHECK:STDOUT: %.loc4_39.3: type = specific_constant constants.%IntRange.349, @IntRange(constants.%N.c80) [symbolic = %IntRange (constants.%IntRange.349)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_39.3 [symbolic = %IntRange (constants.%IntRange.349)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @IntRange.as.Destroy.impl.Op.%ptr (%ptr.710) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %IntRange.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @IntRange.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @IntRange(%N.loc4_16.2: Core.IntLiteral) { // CHECK:STDOUT: %N.loc4_16.1: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N.loc4_16.1 (constants.%N.c80)] // CHECK:STDOUT: @@ -431,6 +469,9 @@ fn Read() { // CHECK:STDOUT: %N.ref.loc23: Core.IntLiteral = name_ref N, %N.loc4_16.2 [symbolic = %N.loc4_16.1 (constants.%N.c80)] // CHECK:STDOUT: %Int.loc23: type = class_type @Int, @Int(constants.%N.c80) [symbolic = %Int.loc22_32.2 (constants.%Int.49d0e6.1)] // CHECK:STDOUT: %.loc23: @IntRange.%IntRange.elem (%IntRange.elem.e7c) = field_decl end, element1 [concrete] +// CHECK:STDOUT: impl_decl @IntRange.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@IntRange.as.Destroy.impl.%IntRange.as.Destroy.impl.Op.decl), @IntRange.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @IntRange.as.Destroy.impl(constants.%N.c80) [symbolic = @IntRange.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.0ef)] // CHECK:STDOUT: %struct_type.start.end.loc24_1.1: type = struct_type {.start: %Int.49d0e6.1, .end: %Int.49d0e6.1} [symbolic = %struct_type.start.end.loc24_1.2 (constants.%struct_type.start.end.78d)] // CHECK:STDOUT: %complete_type.loc24_1.1: = complete_type_witness %struct_type.start.end.loc24_1.1 [symbolic = %complete_type.loc24_1.2 (constants.%complete_type.9d5)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc24_1.1 @@ -529,18 +570,19 @@ fn Read() { // CHECK:STDOUT: %Optional.Some.type: type = fn_type @Optional.Some, @Optional(%Int.loc11_43.1) [symbolic = %Optional.Some.type (constants.%Optional.Some.type.185)] // CHECK:STDOUT: %Optional.Some: @IntRange.as.Iterate.impl.Next.%Optional.Some.type (%Optional.Some.type.185) = struct_value () [symbolic = %Optional.Some (constants.%Optional.Some.58a)] // CHECK:STDOUT: %Optional.Some.specific_fn.loc15_42.2: = specific_function %Optional.Some, @Optional.Some(%Int.loc11_43.1) [symbolic = %Optional.Some.specific_fn.loc15_42.2 (constants.%Optional.Some.specific_fn.6f1)] -// CHECK:STDOUT: %Destroy.lookup_impl_witness.loc11: = lookup_impl_witness %Optional.loc11_75.1, @Destroy [symbolic = %Destroy.lookup_impl_witness.loc11 (constants.%Destroy.lookup_impl_witness.f9d)] -// CHECK:STDOUT: %Destroy.facet.loc11: %Destroy.type = facet_value %Optional.loc11_75.1, (%Destroy.lookup_impl_witness.loc11) [symbolic = %Destroy.facet.loc11 (constants.%Destroy.facet.be9)] +// CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %Optional.loc11_75.1, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)] +// CHECK:STDOUT: %Destroy.facet.loc11: %Destroy.type = facet_value %Optional.loc11_75.1, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet.loc11 (constants.%Destroy.facet.be9)] // CHECK:STDOUT: %.loc11_47.6: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet.loc11 [symbolic = %.loc11_47.6 (constants.%.1ee)] -// CHECK:STDOUT: %impl.elem0.loc11_47.4: @IntRange.as.Iterate.impl.Next.%.loc11_47.6 (%.1ee) = impl_witness_access %Destroy.lookup_impl_witness.loc11, element0 [symbolic = %impl.elem0.loc11_47.4 (constants.%impl.elem0.5fd)] +// CHECK:STDOUT: %impl.elem0.loc11_47.4: @IntRange.as.Iterate.impl.Next.%.loc11_47.6 (%.1ee) = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc11_47.4 (constants.%impl.elem0.5fd)] // CHECK:STDOUT: %specific_impl_fn.loc11_47.4: = specific_impl_function %impl.elem0.loc11_47.4, @Destroy.Op(%Destroy.facet.loc11) [symbolic = %specific_impl_fn.loc11_47.4 (constants.%specific_impl_fn.79e)] // CHECK:STDOUT: %ptr.loc11_47: type = ptr_type %Optional.loc11_75.1 [symbolic = %ptr.loc11_47 (constants.%ptr.2aa)] // CHECK:STDOUT: %require_complete.loc11_47.2: = require_complete_type %ptr.loc11_47 [symbolic = %require_complete.loc11_47.2 (constants.%require_complete.a5e)] -// CHECK:STDOUT: %Destroy.lookup_impl_witness.loc12: = lookup_impl_witness %Int.loc11_43.1, @Destroy [symbolic = %Destroy.lookup_impl_witness.loc12 (constants.%Destroy.lookup_impl_witness.34a)] -// CHECK:STDOUT: %Destroy.facet.loc12: %Destroy.type = facet_value %Int.loc11_43.1, (%Destroy.lookup_impl_witness.loc12) [symbolic = %Destroy.facet.loc12 (constants.%Destroy.facet.13d)] -// CHECK:STDOUT: %.loc12_7.3: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet.loc12 [symbolic = %.loc12_7.3 (constants.%.bbc)] -// CHECK:STDOUT: %impl.elem0.loc12_7.3: @IntRange.as.Iterate.impl.Next.%.loc12_7.3 (%.bbc) = impl_witness_access %Destroy.lookup_impl_witness.loc12, element0 [symbolic = %impl.elem0.loc12_7.3 (constants.%impl.elem0.fe8)] -// CHECK:STDOUT: %specific_impl_fn.loc12_7.3: = specific_impl_function %impl.elem0.loc12_7.3, @Destroy.Op(%Destroy.facet.loc12) [symbolic = %specific_impl_fn.loc12_7.3 (constants.%specific_impl_fn.f4e)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.1b4, @Int.as.Destroy.impl(%N) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.3a2)] +// CHECK:STDOUT: %Destroy.facet.loc12: %Destroy.type = facet_value %Int.loc11_43.1, (%Destroy.impl_witness) [symbolic = %Destroy.facet.loc12 (constants.%Destroy.facet.d3b)] +// CHECK:STDOUT: %.loc12_7: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet.loc12 [symbolic = %.loc12_7 (constants.%.ffb)] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.type: type = fn_type @Int.as.Destroy.impl.Op, @Int.as.Destroy.impl(%N) [symbolic = %Int.as.Destroy.impl.Op.type (constants.%Int.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op: @IntRange.as.Iterate.impl.Next.%Int.as.Destroy.impl.Op.type (%Int.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Int.as.Destroy.impl.Op (constants.%Int.as.Destroy.impl.Op)] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.specific_fn: = specific_function %Int.as.Destroy.impl.Op, @Int.as.Destroy.impl.Op(%N) [symbolic = %Int.as.Destroy.impl.Op.specific_fn (constants.%Int.as.Destroy.impl.Op.specific_fn)] // CHECK:STDOUT: %Optional.None.type: type = fn_type @Optional.None, @Optional(%Int.loc11_43.1) [symbolic = %Optional.None.type (constants.%Optional.None.type.73a)] // CHECK:STDOUT: %Optional.None: @IntRange.as.Iterate.impl.Next.%Optional.None.type (%Optional.None.type.73a) = struct_value () [symbolic = %Optional.None (constants.%Optional.None.83e)] // CHECK:STDOUT: %Optional.None.specific_fn.loc17_42.2: = specific_function %Optional.None, @Optional.None(%Int.loc11_43.1) [symbolic = %Optional.None.specific_fn.loc17_42.2 (constants.%Optional.None.specific_fn.82b)] @@ -573,8 +615,8 @@ fn Read() { // CHECK:STDOUT: %Less.ref: @IntRange.as.Iterate.impl.Next.%OrderedWith.assoc_type (%OrderedWith.assoc_type.d92) = name_ref Less, %.loc13_17.1 [symbolic = %assoc0 (constants.%assoc0.8dc)] // CHECK:STDOUT: %impl.elem0.loc13: @IntRange.as.Iterate.impl.Next.%.loc13_17.2 (%.64e) = impl_witness_access constants.%OrderedWith.impl_witness.bea, element0 [symbolic = %Int.as.OrderedWith.impl.Less (constants.%Int.as.OrderedWith.impl.Less.4be)] // CHECK:STDOUT: %bound_method.loc13_17.1: = bound_method %value.ref.loc13, %impl.elem0.loc13 -// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0.loc13, @Int.as.OrderedWith.impl.Less.1(constants.%N.c80, constants.%N.c80) [symbolic = %Int.as.OrderedWith.impl.Less.specific_fn (constants.%Int.as.OrderedWith.impl.Less.specific_fn.bb3)] -// CHECK:STDOUT: %bound_method.loc13_17.2: = bound_method %value.ref.loc13, %specific_fn +// CHECK:STDOUT: %specific_fn.loc13: = specific_function %impl.elem0.loc13, @Int.as.OrderedWith.impl.Less.1(constants.%N.c80, constants.%N.c80) [symbolic = %Int.as.OrderedWith.impl.Less.specific_fn (constants.%Int.as.OrderedWith.impl.Less.specific_fn.bb3)] +// CHECK:STDOUT: %bound_method.loc13_17.2: = bound_method %value.ref.loc13, %specific_fn.loc13 // CHECK:STDOUT: %.loc13_11: @IntRange.as.Iterate.impl.Next.%Int.loc11_43.1 (%Int.49d0e6.1) = bind_value %value.ref.loc13 // CHECK:STDOUT: %Int.as.OrderedWith.impl.Less.call: init bool = call %bound_method.loc13_17.2(%.loc13_11, %.loc13_23.2) // CHECK:STDOUT: %.loc13_27.1: bool = value_of_initializer %Int.as.OrderedWith.impl.Less.call @@ -604,18 +646,18 @@ fn Read() { // CHECK:STDOUT: %.loc11_47.1: ref @IntRange.as.Iterate.impl.Next.%Optional.loc11_75.1 (%Optional.708) = splice_block %return {} // CHECK:STDOUT: %.loc15_48: @IntRange.as.Iterate.impl.Next.%Int.loc11_43.1 (%Int.49d0e6.1) = bind_value %value.ref.loc15 // CHECK:STDOUT: %Optional.Some.call: init @IntRange.as.Iterate.impl.Next.%Optional.loc11_75.1 (%Optional.708) = call %Optional.Some.specific_fn.loc15_42.1(%.loc15_48) to %.loc11_47.1 -// CHECK:STDOUT: %impl.elem0.loc11_47.1: @IntRange.as.Iterate.impl.Next.%.loc11_47.6 (%.1ee) = impl_witness_access constants.%Destroy.lookup_impl_witness.f9d, element0 [symbolic = %impl.elem0.loc11_47.4 (constants.%impl.elem0.5fd)] +// CHECK:STDOUT: %impl.elem0.loc11_47.1: @IntRange.as.Iterate.impl.Next.%.loc11_47.6 (%.1ee) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc11_47.4 (constants.%impl.elem0.5fd)] // CHECK:STDOUT: %bound_method.loc11_47.1: = bound_method %.loc11_47.1, %impl.elem0.loc11_47.1 // CHECK:STDOUT: %specific_impl_fn.loc11_47.1: = specific_impl_function %impl.elem0.loc11_47.1, @Destroy.Op(constants.%Destroy.facet.be9) [symbolic = %specific_impl_fn.loc11_47.4 (constants.%specific_impl_fn.79e)] // CHECK:STDOUT: %bound_method.loc11_47.2: = bound_method %.loc11_47.1, %specific_impl_fn.loc11_47.1 // CHECK:STDOUT: %addr.loc11_47.1: @IntRange.as.Iterate.impl.Next.%ptr.loc11_47 (%ptr.2aa) = addr_of %.loc11_47.1 // CHECK:STDOUT: %.loc11_47.2: init %empty_tuple.type = call %bound_method.loc11_47.2(%addr.loc11_47.1) -// CHECK:STDOUT: %impl.elem0.loc12_7.1: @IntRange.as.Iterate.impl.Next.%.loc12_7.3 (%.bbc) = impl_witness_access constants.%Destroy.lookup_impl_witness.34a, element0 [symbolic = %impl.elem0.loc12_7.3 (constants.%impl.elem0.fe8)] +// CHECK:STDOUT: %impl.elem0.loc12_7.1: @IntRange.as.Iterate.impl.Next.%.loc12_7 (%.ffb) = impl_witness_access constants.%Destroy.impl_witness.3a2, element0 [symbolic = %Int.as.Destroy.impl.Op (constants.%Int.as.Destroy.impl.Op)] // CHECK:STDOUT: %bound_method.loc12_7.1: = bound_method %value.var, %impl.elem0.loc12_7.1 -// CHECK:STDOUT: %specific_impl_fn.loc12_7.1: = specific_impl_function %impl.elem0.loc12_7.1, @Destroy.Op(constants.%Destroy.facet.13d) [symbolic = %specific_impl_fn.loc12_7.3 (constants.%specific_impl_fn.f4e)] -// CHECK:STDOUT: %bound_method.loc12_7.2: = bound_method %value.var, %specific_impl_fn.loc12_7.1 +// CHECK:STDOUT: %specific_fn.loc12_7.1: = specific_function %impl.elem0.loc12_7.1, @Int.as.Destroy.impl.Op(constants.%N.c80) [symbolic = %Int.as.Destroy.impl.Op.specific_fn (constants.%Int.as.Destroy.impl.Op.specific_fn)] +// CHECK:STDOUT: %bound_method.loc12_7.2: = bound_method %value.var, %specific_fn.loc12_7.1 // CHECK:STDOUT: %addr.loc12_7.1: @IntRange.as.Iterate.impl.Next.%ptr.loc11_44.1 (%ptr.784) = addr_of %value.var -// CHECK:STDOUT: %.loc12_7.1: init %empty_tuple.type = call %bound_method.loc12_7.2(%addr.loc12_7.1) +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.call.loc12_7.1: init %empty_tuple.type = call %bound_method.loc12_7.2(%addr.loc12_7.1) // CHECK:STDOUT: return %Optional.Some.call to %return // CHECK:STDOUT: // CHECK:STDOUT: !if.else: @@ -631,28 +673,39 @@ fn Read() { // CHECK:STDOUT: %Optional.None.specific_fn.loc17_42.1: = specific_function %None.ref, @Optional.None(constants.%Int.49d0e6.1) [symbolic = %Optional.None.specific_fn.loc17_42.2 (constants.%Optional.None.specific_fn.82b)] // CHECK:STDOUT: %.loc11_47.3: ref @IntRange.as.Iterate.impl.Next.%Optional.loc11_75.1 (%Optional.708) = splice_block %return {} // CHECK:STDOUT: %Optional.None.call: init @IntRange.as.Iterate.impl.Next.%Optional.loc11_75.1 (%Optional.708) = call %Optional.None.specific_fn.loc17_42.1() to %.loc11_47.3 -// CHECK:STDOUT: %impl.elem0.loc11_47.2: @IntRange.as.Iterate.impl.Next.%.loc11_47.6 (%.1ee) = impl_witness_access constants.%Destroy.lookup_impl_witness.f9d, element0 [symbolic = %impl.elem0.loc11_47.4 (constants.%impl.elem0.5fd)] +// CHECK:STDOUT: %impl.elem0.loc11_47.2: @IntRange.as.Iterate.impl.Next.%.loc11_47.6 (%.1ee) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc11_47.4 (constants.%impl.elem0.5fd)] // CHECK:STDOUT: %bound_method.loc11_47.3: = bound_method %.loc11_47.3, %impl.elem0.loc11_47.2 // CHECK:STDOUT: %specific_impl_fn.loc11_47.2: = specific_impl_function %impl.elem0.loc11_47.2, @Destroy.Op(constants.%Destroy.facet.be9) [symbolic = %specific_impl_fn.loc11_47.4 (constants.%specific_impl_fn.79e)] // CHECK:STDOUT: %bound_method.loc11_47.4: = bound_method %.loc11_47.3, %specific_impl_fn.loc11_47.2 // CHECK:STDOUT: %addr.loc11_47.2: @IntRange.as.Iterate.impl.Next.%ptr.loc11_47 (%ptr.2aa) = addr_of %.loc11_47.3 // CHECK:STDOUT: %.loc11_47.4: init %empty_tuple.type = call %bound_method.loc11_47.4(%addr.loc11_47.2) -// CHECK:STDOUT: %impl.elem0.loc11_47.3: @IntRange.as.Iterate.impl.Next.%.loc11_47.6 (%.1ee) = impl_witness_access constants.%Destroy.lookup_impl_witness.f9d, element0 [symbolic = %impl.elem0.loc11_47.4 (constants.%impl.elem0.5fd)] +// CHECK:STDOUT: %impl.elem0.loc11_47.3: @IntRange.as.Iterate.impl.Next.%.loc11_47.6 (%.1ee) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc11_47.4 (constants.%impl.elem0.5fd)] // CHECK:STDOUT: %bound_method.loc11_47.5: = bound_method %.loc11_47.1, %impl.elem0.loc11_47.3 // CHECK:STDOUT: %specific_impl_fn.loc11_47.3: = specific_impl_function %impl.elem0.loc11_47.3, @Destroy.Op(constants.%Destroy.facet.be9) [symbolic = %specific_impl_fn.loc11_47.4 (constants.%specific_impl_fn.79e)] // CHECK:STDOUT: %bound_method.loc11_47.6: = bound_method %.loc11_47.1, %specific_impl_fn.loc11_47.3 // CHECK:STDOUT: %addr.loc11_47.3: @IntRange.as.Iterate.impl.Next.%ptr.loc11_47 (%ptr.2aa) = addr_of %.loc11_47.1 // CHECK:STDOUT: %.loc11_47.5: init %empty_tuple.type = call %bound_method.loc11_47.6(%addr.loc11_47.3) -// CHECK:STDOUT: %impl.elem0.loc12_7.2: @IntRange.as.Iterate.impl.Next.%.loc12_7.3 (%.bbc) = impl_witness_access constants.%Destroy.lookup_impl_witness.34a, element0 [symbolic = %impl.elem0.loc12_7.3 (constants.%impl.elem0.fe8)] +// CHECK:STDOUT: %impl.elem0.loc12_7.2: @IntRange.as.Iterate.impl.Next.%.loc12_7 (%.ffb) = impl_witness_access constants.%Destroy.impl_witness.3a2, element0 [symbolic = %Int.as.Destroy.impl.Op (constants.%Int.as.Destroy.impl.Op)] // CHECK:STDOUT: %bound_method.loc12_7.3: = bound_method %value.var, %impl.elem0.loc12_7.2 -// CHECK:STDOUT: %specific_impl_fn.loc12_7.2: = specific_impl_function %impl.elem0.loc12_7.2, @Destroy.Op(constants.%Destroy.facet.13d) [symbolic = %specific_impl_fn.loc12_7.3 (constants.%specific_impl_fn.f4e)] -// CHECK:STDOUT: %bound_method.loc12_7.4: = bound_method %value.var, %specific_impl_fn.loc12_7.2 +// CHECK:STDOUT: %specific_fn.loc12_7.2: = specific_function %impl.elem0.loc12_7.2, @Int.as.Destroy.impl.Op(constants.%N.c80) [symbolic = %Int.as.Destroy.impl.Op.specific_fn (constants.%Int.as.Destroy.impl.Op.specific_fn)] +// CHECK:STDOUT: %bound_method.loc12_7.4: = bound_method %value.var, %specific_fn.loc12_7.2 // CHECK:STDOUT: %addr.loc12_7.2: @IntRange.as.Iterate.impl.Next.%ptr.loc11_44.1 (%ptr.784) = addr_of %value.var -// CHECK:STDOUT: %.loc12_7.2: init %empty_tuple.type = call %bound_method.loc12_7.4(%addr.loc12_7.2) +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.call.loc12_7.2: init %empty_tuple.type = call %bound_method.loc12_7.4(%addr.loc12_7.2) // CHECK:STDOUT: return %Optional.None.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @IntRange.as.Destroy.impl.Op(@IntRange.%N.loc4_16.2: Core.IntLiteral) { +// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.c80)] +// CHECK:STDOUT: %IntRange: type = class_type @IntRange, @IntRange(%N) [symbolic = %IntRange (constants.%IntRange.349)] +// CHECK:STDOUT: %ptr: type = ptr_type %IntRange [symbolic = %ptr (constants.%ptr.710)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.99f)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @IntRange.as.Destroy.impl.Op.%ptr (%ptr.710)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @Range(%end.param: %i32) -> %return.param: %IntRange.365 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %IntRange.ref.loc27: %IntRange.type = name_ref IntRange, file.%IntRange.decl [concrete = constants.%IntRange.generic] @@ -740,6 +793,18 @@ fn Read() { // CHECK:STDOUT: %pattern_type.loc11_47 => constants.%pattern_type.4b1 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @IntRange.as.Destroy.impl(constants.%N.c80) { +// CHECK:STDOUT: %N => constants.%N.c80 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.0ef +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @IntRange.as.Destroy.impl.Op(constants.%N.c80) { +// CHECK:STDOUT: %N => constants.%N.c80 +// CHECK:STDOUT: %IntRange => constants.%IntRange.349 +// CHECK:STDOUT: %ptr => constants.%ptr.710 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.99f +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @IntRange(constants.%int_32) { // CHECK:STDOUT: %N.loc4_16.1 => constants.%int_32 // CHECK:STDOUT: @@ -767,6 +832,11 @@ fn Read() { // CHECK:STDOUT: %struct_type.start.end => constants.%struct_type.start.end.d0a // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @IntRange.as.Destroy.impl(constants.%int_32) { +// CHECK:STDOUT: %N => constants.%int_32 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.378 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- trivial.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -809,6 +879,12 @@ fn Read() { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.9ba: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.6da: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.382: = impl_witness imports.%Destroy.impl_witness_table.14b, @Int.as.Destroy.impl(%N.c80) [symbolic] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.type: type = fn_type @Int.as.Destroy.impl.Op, @Int.as.Destroy.impl(%N.c80) [symbolic] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op: %Int.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.58a: type = ptr_type %Int.7ff11f.1 [symbolic] +// CHECK:STDOUT: %pattern_type.6d0: type = pattern_type %ptr.58a [symbolic] // CHECK:STDOUT: %To.c80: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To.c80) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.6d7: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2 = struct_value () [symbolic] @@ -816,8 +892,6 @@ fn Read() { // CHECK:STDOUT: %require_complete.10b: = require_complete_type %OrderedWith.type.256 [symbolic] // CHECK:STDOUT: %OrderedWith.Less.type.016: type = fn_type @OrderedWith.Less, @OrderedWith(%Int.7ff11f.1) [symbolic] // CHECK:STDOUT: %OrderedWith.assoc_type.e53: type = assoc_entity_type @OrderedWith, @OrderedWith(%Int.7ff11f.1) [symbolic] -// CHECK:STDOUT: %ptr.58a: type = ptr_type %Int.7ff11f.1 [symbolic] -// CHECK:STDOUT: %pattern_type.6d0: type = pattern_type %ptr.58a [symbolic] // CHECK:STDOUT: %require_complete.656: = require_complete_type %ptr.58a [symbolic] // CHECK:STDOUT: %Inc.type: type = facet_type <@Inc> [concrete] // CHECK:STDOUT: %ImplicitAs.impl_witness.e34: = impl_witness imports.%ImplicitAs.impl_witness_table.e36, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] @@ -829,7 +903,6 @@ fn Read() { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.16d, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] // CHECK:STDOUT: %bound_method.d68: = bound_method %y, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.58b: init %i32 = call %bound_method.d68(%y) [symbolic] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] // CHECK:STDOUT: %Iterate.type: type = facet_type <@Iterate> [concrete] // CHECK:STDOUT: %.Self.36d: %Iterate.type = bind_symbolic_name .Self [symbolic_self] @@ -862,21 +935,25 @@ fn Read() { // CHECK:STDOUT: %Optional.Some.type.fe1: type = fn_type @Optional.Some, @Optional(%Int.7ff11f.1) [symbolic] // CHECK:STDOUT: %Optional.Some.aae: %Optional.Some.type.fe1 = struct_value () [symbolic] // CHECK:STDOUT: %Optional.Some.specific_fn.b8a: = specific_function %Optional.Some.aae, @Optional.Some(%Int.7ff11f.1) [symbolic] -// CHECK:STDOUT: %Destroy.lookup_impl_witness.f0d: = lookup_impl_witness %Optional.e9f, @Destroy [symbolic] -// CHECK:STDOUT: %Destroy.facet.82c: %Destroy.type = facet_value %Optional.e9f, (%Destroy.lookup_impl_witness.f0d) [symbolic] +// CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %Optional.e9f, @Destroy [symbolic] +// CHECK:STDOUT: %Destroy.facet.82c: %Destroy.type = facet_value %Optional.e9f, (%Destroy.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %.485: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.82c [symbolic] -// CHECK:STDOUT: %impl.elem0.c7c: %.485 = impl_witness_access %Destroy.lookup_impl_witness.f0d, element0 [symbolic] +// CHECK:STDOUT: %impl.elem0.c7c: %.485 = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic] // CHECK:STDOUT: %specific_impl_fn.ebe: = specific_impl_function %impl.elem0.c7c, @Destroy.Op(%Destroy.facet.82c) [symbolic] // CHECK:STDOUT: %ptr.d1d: type = ptr_type %Optional.e9f [symbolic] // CHECK:STDOUT: %require_complete.c68: = require_complete_type %ptr.d1d [symbolic] -// CHECK:STDOUT: %Destroy.lookup_impl_witness.f03: = lookup_impl_witness %Int.7ff11f.1, @Destroy [symbolic] -// CHECK:STDOUT: %Destroy.facet.96a: %Destroy.type = facet_value %Int.7ff11f.1, (%Destroy.lookup_impl_witness.f03) [symbolic] -// CHECK:STDOUT: %.f67: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.96a [symbolic] -// CHECK:STDOUT: %impl.elem0.4dc: %.f67 = impl_witness_access %Destroy.lookup_impl_witness.f03, element0 [symbolic] -// CHECK:STDOUT: %specific_impl_fn.f8f: = specific_impl_function %impl.elem0.4dc, @Destroy.Op(%Destroy.facet.96a) [symbolic] +// CHECK:STDOUT: %Destroy.facet.168: %Destroy.type = facet_value %Int.7ff11f.1, (%Destroy.impl_witness.382) [symbolic] +// CHECK:STDOUT: %.a07: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.168 [symbolic] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.specific_fn: = specific_function %Int.as.Destroy.impl.Op, @Int.as.Destroy.impl.Op(%N.c80) [symbolic] // CHECK:STDOUT: %Optional.None.type.8c4: type = fn_type @Optional.None, @Optional(%Int.7ff11f.1) [symbolic] // CHECK:STDOUT: %Optional.None.7a7: %Optional.None.type.8c4 = struct_value () [symbolic] // CHECK:STDOUT: %Optional.None.specific_fn.9e7: = specific_function %Optional.None.7a7, @Optional.None(%Int.7ff11f.1) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.881: = impl_witness imports.%Destroy.impl_witness_table.901, @IntRange.as.Destroy.impl(%N.c80) [symbolic] +// CHECK:STDOUT: %IntRange.as.Destroy.impl.Op.type: type = fn_type @IntRange.as.Destroy.impl.Op, @IntRange.as.Destroy.impl(%N.c80) [symbolic] +// CHECK:STDOUT: %IntRange.as.Destroy.impl.Op: %IntRange.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.710: type = ptr_type %IntRange.349 [symbolic] +// CHECK:STDOUT: %pattern_type.99f: type = pattern_type %ptr.710 [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.bb5: = impl_witness imports.%Destroy.impl_witness_table.901, @IntRange.as.Destroy.impl(%int_32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.2d1: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%IntRange.365) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.fa8: %T.as.Destroy.impl.Op.type.2d1 = struct_value () [concrete] // CHECK:STDOUT: %ptr.049: type = ptr_type %IntRange.365 [concrete] @@ -902,8 +979,10 @@ fn Read() { // CHECK:STDOUT: %Main.import_ref.261 = import_ref Main//lib, loc23_18, unloaded // CHECK:STDOUT: %Main.import_ref.f1e294.2: Core.IntLiteral = import_ref Main//lib, loc4_16, loaded [symbolic = @IntRange.%N (constants.%N.c80)] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/operators/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] -// CHECK:STDOUT: %Core.import_ref.a86: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2) = import_ref Core//prelude/types/int, loc20_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.6d7)] -// CHECK:STDOUT: %ImplicitAs.impl_witness_table.e36 = impl_witness_table (%Core.import_ref.a86), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %Core.import_ref.45b = import_ref Core//prelude/types/int, loc13_29, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.14b = impl_witness_table (%Core.import_ref.45b), @Int.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Core.import_ref.a86c: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2) = import_ref Core//prelude/types/int, loc20_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.6d7)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table.e36 = impl_witness_table (%Core.import_ref.a86c), @Core.IntLiteral.as.ImplicitAs.impl [concrete] // CHECK:STDOUT: %Core.import_ref.e33 = import_ref Core//prelude/types/int, loc52_46, unloaded // CHECK:STDOUT: %Core.import_ref.a58 = import_ref Core//prelude/types/int, loc53_58, unloaded // CHECK:STDOUT: %Core.import_ref.a39 = import_ref Core//prelude/types/int, loc54_49, unloaded @@ -921,7 +1000,14 @@ fn Read() { // CHECK:STDOUT: %Iterate.impl_witness_table.b32 = impl_witness_table (%Main.import_ref.e3faa9.1, %Main.import_ref.e3faa9.2, %Main.import_ref.11c, %Main.import_ref.f97), @IntRange.as.Iterate.impl [concrete] // CHECK:STDOUT: %Main.import_ref.f1e294.4: Core.IntLiteral = import_ref Main//lib, loc4_16, loaded [symbolic = @IntRange.%N (constants.%N.c80)] // CHECK:STDOUT: %Main.import_ref.f1e294.5: Core.IntLiteral = import_ref Main//lib, loc4_16, loaded [symbolic = @IntRange.%N (constants.%N.c80)] -// CHECK:STDOUT: %Main.import_ref.026 = import_ref Main//lib, inst1842 [indirect], unloaded +// CHECK:STDOUT: %Main.import_ref.026 = import_ref Main//lib, inst1890 [indirect], unloaded +// CHECK:STDOUT: %Main.import_ref.921 = import_ref Main//lib, loc4_39, unloaded +// CHECK:STDOUT: %Main.import_ref.f1e294.6: Core.IntLiteral = import_ref Main//lib, loc4_16, loaded [symbolic = @IntRange.%N (constants.%N.c80)] +// CHECK:STDOUT: %Main.import_ref.e9a: type = import_ref Main//lib, inst39 [no loc], loaded [symbolic = constants.%IntRange.349] +// CHECK:STDOUT: %Main.import_ref.cb9: type = import_ref Main//lib, inst297 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.b63 = import_ref Main//lib, loc4_39, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.901 = impl_witness_table (%Main.import_ref.b63), @IntRange.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.f1e294.7: Core.IntLiteral = import_ref Main//lib, loc4_16, loaded [symbolic = @IntRange.%N (constants.%N.c80)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -956,6 +1042,20 @@ fn Read() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @IntRange.as.Destroy.impl(imports.%Main.import_ref.f1e294.6: Core.IntLiteral) [from "lib.carbon"] { +// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.c80)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.901, @IntRange.as.Destroy.impl(%N) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.881)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %IntRange.as.Destroy.impl.Op.type: type = fn_type @IntRange.as.Destroy.impl.Op, @IntRange.as.Destroy.impl(%N) [symbolic = %IntRange.as.Destroy.impl.Op.type (constants.%IntRange.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %IntRange.as.Destroy.impl.Op: @IntRange.as.Destroy.impl.%IntRange.as.Destroy.impl.Op.type (%IntRange.as.Destroy.impl.Op.type) = struct_value () [symbolic = %IntRange.as.Destroy.impl.Op (constants.%IntRange.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%Main.import_ref.e9a as imports.%Main.import_ref.cb9 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.921 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @IntRange(imports.%Main.import_ref.f1e294.1: Core.IntLiteral) [from "lib.carbon"] { // CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.c80)] // CHECK:STDOUT: @@ -1098,18 +1198,19 @@ fn Read() { // CHECK:STDOUT: %Optional.Some.type: type = fn_type @Optional.Some, @Optional(%Int) [symbolic = %Optional.Some.type (constants.%Optional.Some.type.fe1)] // CHECK:STDOUT: %Optional.Some: @IntRange.as.Iterate.impl.Next.%Optional.Some.type (%Optional.Some.type.fe1) = struct_value () [symbolic = %Optional.Some (constants.%Optional.Some.aae)] // CHECK:STDOUT: %Optional.Some.specific_fn: = specific_function %Optional.Some, @Optional.Some(%Int) [symbolic = %Optional.Some.specific_fn (constants.%Optional.Some.specific_fn.b8a)] -// CHECK:STDOUT: %Destroy.lookup_impl_witness.1: = lookup_impl_witness %Optional, @Destroy [symbolic = %Destroy.lookup_impl_witness.1 (constants.%Destroy.lookup_impl_witness.f0d)] -// CHECK:STDOUT: %Destroy.facet.1: %Destroy.type = facet_value %Optional, (%Destroy.lookup_impl_witness.1) [symbolic = %Destroy.facet.1 (constants.%Destroy.facet.82c)] +// CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %Optional, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)] +// CHECK:STDOUT: %Destroy.facet.1: %Destroy.type = facet_value %Optional, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet.1 (constants.%Destroy.facet.82c)] // CHECK:STDOUT: %.3: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet.1 [symbolic = %.3 (constants.%.485)] -// CHECK:STDOUT: %impl.elem0.2: @IntRange.as.Iterate.impl.Next.%.3 (%.485) = impl_witness_access %Destroy.lookup_impl_witness.1, element0 [symbolic = %impl.elem0.2 (constants.%impl.elem0.c7c)] +// CHECK:STDOUT: %impl.elem0.2: @IntRange.as.Iterate.impl.Next.%.3 (%.485) = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.2 (constants.%impl.elem0.c7c)] // CHECK:STDOUT: %specific_impl_fn.2: = specific_impl_function %impl.elem0.2, @Destroy.Op(%Destroy.facet.1) [symbolic = %specific_impl_fn.2 (constants.%specific_impl_fn.ebe)] // CHECK:STDOUT: %ptr.2: type = ptr_type %Optional [symbolic = %ptr.2 (constants.%ptr.d1d)] // CHECK:STDOUT: %require_complete.6: = require_complete_type %ptr.2 [symbolic = %require_complete.6 (constants.%require_complete.c68)] -// CHECK:STDOUT: %Destroy.lookup_impl_witness.2: = lookup_impl_witness %Int, @Destroy [symbolic = %Destroy.lookup_impl_witness.2 (constants.%Destroy.lookup_impl_witness.f03)] -// CHECK:STDOUT: %Destroy.facet.2: %Destroy.type = facet_value %Int, (%Destroy.lookup_impl_witness.2) [symbolic = %Destroy.facet.2 (constants.%Destroy.facet.96a)] -// CHECK:STDOUT: %.4: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet.2 [symbolic = %.4 (constants.%.f67)] -// CHECK:STDOUT: %impl.elem0.3: @IntRange.as.Iterate.impl.Next.%.4 (%.f67) = impl_witness_access %Destroy.lookup_impl_witness.2, element0 [symbolic = %impl.elem0.3 (constants.%impl.elem0.4dc)] -// CHECK:STDOUT: %specific_impl_fn.3: = specific_impl_function %impl.elem0.3, @Destroy.Op(%Destroy.facet.2) [symbolic = %specific_impl_fn.3 (constants.%specific_impl_fn.f8f)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.14b, @Int.as.Destroy.impl(%N) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.382)] +// CHECK:STDOUT: %Destroy.facet.2: %Destroy.type = facet_value %Int, (%Destroy.impl_witness) [symbolic = %Destroy.facet.2 (constants.%Destroy.facet.168)] +// CHECK:STDOUT: %.4: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet.2 [symbolic = %.4 (constants.%.a07)] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.type: type = fn_type @Int.as.Destroy.impl.Op, @Int.as.Destroy.impl(%N) [symbolic = %Int.as.Destroy.impl.Op.type (constants.%Int.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op: @IntRange.as.Iterate.impl.Next.%Int.as.Destroy.impl.Op.type (%Int.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Int.as.Destroy.impl.Op (constants.%Int.as.Destroy.impl.Op)] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.specific_fn: = specific_function %Int.as.Destroy.impl.Op, @Int.as.Destroy.impl.Op(%N) [symbolic = %Int.as.Destroy.impl.Op.specific_fn (constants.%Int.as.Destroy.impl.Op.specific_fn)] // CHECK:STDOUT: %Optional.None.type: type = fn_type @Optional.None, @Optional(%Int) [symbolic = %Optional.None.type (constants.%Optional.None.type.8c4)] // CHECK:STDOUT: %Optional.None: @IntRange.as.Iterate.impl.Next.%Optional.None.type (%Optional.None.type.8c4) = struct_value () [symbolic = %Optional.None (constants.%Optional.None.7a7)] // CHECK:STDOUT: %Optional.None.specific_fn: = specific_function %Optional.None, @Optional.None(%Int) [symbolic = %Optional.None.specific_fn (constants.%Optional.None.specific_fn.9e7)] @@ -1117,6 +1218,17 @@ fn Read() { // CHECK:STDOUT: fn; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @IntRange.as.Destroy.impl.Op(imports.%Main.import_ref.f1e294.7: Core.IntLiteral) [from "lib.carbon"] { +// CHECK:STDOUT: %N: Core.IntLiteral = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.c80)] +// CHECK:STDOUT: %IntRange: type = class_type @IntRange, @IntRange(%N) [symbolic = %IntRange (constants.%IntRange.349)] +// CHECK:STDOUT: %ptr: type = ptr_type %IntRange [symbolic = %ptr (constants.%ptr.710)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.99f)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @IntRange(constants.%N.c80) { // CHECK:STDOUT: %N => constants.%N.c80 // CHECK:STDOUT: @@ -1187,3 +1299,20 @@ fn Read() { // CHECK:STDOUT: %pattern_type.3 => constants.%pattern_type.fd8 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @IntRange.as.Destroy.impl(constants.%N.c80) { +// CHECK:STDOUT: %N => constants.%N.c80 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.881 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @IntRange.as.Destroy.impl.Op(constants.%N.c80) { +// CHECK:STDOUT: %N => constants.%N.c80 +// CHECK:STDOUT: %IntRange => constants.%IntRange.349 +// CHECK:STDOUT: %ptr => constants.%ptr.710 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.99f +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @IntRange.as.Destroy.impl(constants.%int_32) { +// CHECK:STDOUT: %N => constants.%int_32 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.bb5 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/for/basic.carbon b/toolchain/check/testdata/for/basic.carbon index e6c96831f191..48f9f24c0e69 100644 --- a/toolchain/check/testdata/for/basic.carbon +++ b/toolchain/check/testdata/for/basic.carbon @@ -77,6 +77,9 @@ fn Run() { // CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete] // CHECK:STDOUT: %TrivialRange.as.Iterate.impl.NewCursor.type.bd2331.2: type = fn_type @TrivialRange.as.Iterate.impl.NewCursor.loc6_32.2 [concrete] // CHECK:STDOUT: %TrivialRange.as.Iterate.impl.NewCursor.c20a1c.2: %TrivialRange.as.Iterate.impl.NewCursor.type.bd2331.2 = struct_value () [concrete] +// CHECK:STDOUT: %ptr.41d: type = ptr_type %TrivialRange [concrete] +// CHECK:STDOUT: %TrivialRange.as.Destroy.impl.Op.type: type = fn_type @TrivialRange.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %TrivialRange.as.Destroy.impl.Op: %TrivialRange.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %Optional.HasValue.type.b7a: type = fn_type @Optional.HasValue, @Optional(%empty_tuple.type) [concrete] // CHECK:STDOUT: %Optional.HasValue.ada: %Optional.HasValue.type.b7a = struct_value () [concrete] @@ -97,9 +100,6 @@ fn Run() { // CHECK:STDOUT: %.708: type = fn_type_with_self_type %Iterate.Next.type, %Iterate.facet.d50 [concrete] // CHECK:STDOUT: %Optional.HasValue.specific_fn: = specific_function %Optional.HasValue.ada, @Optional.HasValue(%empty_tuple.type) [concrete] // CHECK:STDOUT: %Optional.Get.specific_fn: = specific_function %Optional.Get.6e8, @Optional.Get(%empty_tuple.type) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.8d6: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%TrivialRange) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.90d: %T.as.Destroy.impl.Op.type.8d6 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.41d: type = ptr_type %TrivialRange [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -186,11 +186,9 @@ fn Run() { // CHECK:STDOUT: %bound_method.loc18_35.7: = bound_method %var, %T.as.Destroy.impl.Op.specific_fn.3 // CHECK:STDOUT: %addr.loc18_35.4: %ptr.843 = addr_of %var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc18_35.3: init %empty_tuple.type = call %bound_method.loc18_35.7(%addr.loc18_35.4) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc18_18: = bound_method %.loc18_18.2, constants.%T.as.Destroy.impl.Op.90d -// CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc18_18: = bound_method %.loc18_18.2, %T.as.Destroy.impl.Op.specific_fn.4 +// CHECK:STDOUT: %TrivialRange.as.Destroy.impl.Op.bound: = bound_method %.loc18_18.2, constants.%TrivialRange.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc18_18: %ptr.41d = addr_of %.loc18_18.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc18_18: init %empty_tuple.type = call %bound_method.loc18_18(%addr.loc18_18) +// CHECK:STDOUT: %TrivialRange.as.Destroy.impl.Op.call: init %empty_tuple.type = call %TrivialRange.as.Destroy.impl.Op.bound(%addr.loc18_18) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/for/pattern.carbon b/toolchain/check/testdata/for/pattern.carbon index 8b1dc0ab716e..f4d4ce52e4df 100644 --- a/toolchain/check/testdata/for/pattern.carbon +++ b/toolchain/check/testdata/for/pattern.carbon @@ -122,10 +122,13 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %Body.type: type = fn_type @Body [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Body: %Body.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.c28: type = ptr_type %empty_struct_type [concrete] // CHECK:STDOUT: %EmptyRange.type: type = generic_class_type @EmptyRange [concrete] @@ -165,16 +168,13 @@ fn Run() { // CHECK:STDOUT: %Optional.Get.9c1: %Optional.Get.type.115 = struct_value () [concrete] // CHECK:STDOUT: %Optional.HasValue.specific_fn: = specific_function %Optional.HasValue.513, @Optional.HasValue(%C) [concrete] // CHECK:STDOUT: %Optional.Get.specific_fn: = specific_function %Optional.Get.9c1, @Optional.Get(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.f77: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.01c: %T.as.Destroy.impl.Op.type.f77 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.e93: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Optional.cf0) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.a97: %T.as.Destroy.impl.Op.type.e93 = struct_value () [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.867: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Optional.cf0) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.3e8: %T.as.Destroy.impl.Op.type.867 = struct_value () [concrete] // CHECK:STDOUT: %ptr.8e6: type = ptr_type %Optional.cf0 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.8b2: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%empty_struct_type) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.ca6: %T.as.Destroy.impl.Op.type.8b2 = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.699: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%EmptyRange.cc8) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d12: %T.as.Destroy.impl.Op.type.699 = struct_value () [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.069: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%empty_struct_type) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.d5a: %T.as.Destroy.impl.Op.type.069 = struct_value () [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.88d: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%EmptyRange.cc8) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.929: %T.as.Destroy.impl.Op.type.88d = struct_value () [concrete] // CHECK:STDOUT: %ptr.35d: type = ptr_type %EmptyRange.cc8 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -254,24 +254,22 @@ fn Run() { // CHECK:STDOUT: br !for.next // CHECK:STDOUT: // CHECK:STDOUT: !for.done: -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_36.1: = bound_method %.loc12_36.8, constants.%T.as.Destroy.impl.Op.01c -// CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc12_36.7: = bound_method %.loc12_36.8, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc12_36.8, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc12_36.2: %ptr.019 = addr_of %.loc12_36.8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_36.1: init %empty_tuple.type = call %bound_method.loc12_36.7(%addr.loc12_36.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_36.2: = bound_method %.loc12_36.1, constants.%T.as.Destroy.impl.Op.a97 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr.loc12_36.2) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_36.1: = bound_method %.loc12_36.1, constants.%T.as.Destroy.impl.Op.3e8 // CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc12_36.8: = bound_method %.loc12_36.1, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %bound_method.loc12_36.7: = bound_method %.loc12_36.1, %T.as.Destroy.impl.Op.specific_fn.1 // CHECK:STDOUT: %addr.loc12_36.3: %ptr.8e6 = addr_of %.loc12_36.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_36.2: init %empty_tuple.type = call %bound_method.loc12_36.8(%addr.loc12_36.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_36.3: = bound_method %var, constants.%T.as.Destroy.impl.Op.ca6 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_36.1: init %empty_tuple.type = call %bound_method.loc12_36.7(%addr.loc12_36.3) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_36.2: = bound_method %var, constants.%T.as.Destroy.impl.Op.d5a // CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc12_36.9: = bound_method %var, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %bound_method.loc12_36.8: = bound_method %var, %T.as.Destroy.impl.Op.specific_fn.2 // CHECK:STDOUT: %addr.loc12_36.4: %ptr.c28 = addr_of %var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_36.3: init %empty_tuple.type = call %bound_method.loc12_36.9(%addr.loc12_36.4) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_35: = bound_method %.loc12_35.1, constants.%T.as.Destroy.impl.Op.d12 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_36.2: init %empty_tuple.type = call %bound_method.loc12_36.8(%addr.loc12_36.4) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_35: = bound_method %.loc12_35.1, constants.%T.as.Destroy.impl.Op.929 // CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc12_35: = bound_method %.loc12_35.1, %T.as.Destroy.impl.Op.specific_fn.4 +// CHECK:STDOUT: %bound_method.loc12_35: = bound_method %.loc12_35.1, %T.as.Destroy.impl.Op.specific_fn.3 // CHECK:STDOUT: %addr.loc12_35: %ptr.35d = addr_of %.loc12_35.1 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_35: init %empty_tuple.type = call %bound_method.loc12_35(%addr.loc12_35) // CHECK:STDOUT: @@ -281,10 +279,12 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %Body.type: type = fn_type @Body [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %Body.type: type = fn_type @Body [concrete] // CHECK:STDOUT: %Body: %Body.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.c28: type = ptr_type %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] @@ -325,15 +325,13 @@ fn Run() { // CHECK:STDOUT: %Optional.Get.9c1: %Optional.Get.type.115 = struct_value () [concrete] // CHECK:STDOUT: %Optional.HasValue.specific_fn: = specific_function %Optional.HasValue.513, @Optional.HasValue(%C) [concrete] // CHECK:STDOUT: %Optional.Get.specific_fn: = specific_function %Optional.Get.9c1, @Optional.Get(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.f77: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.01c: %T.as.Destroy.impl.Op.type.f77 = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.e93: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Optional.cf0) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.a97: %T.as.Destroy.impl.Op.type.e93 = struct_value () [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.867: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Optional.cf0) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.3e8: %T.as.Destroy.impl.Op.type.867 = struct_value () [concrete] // CHECK:STDOUT: %ptr.8e6: type = ptr_type %Optional.cf0 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.8b2: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%empty_struct_type) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.ca6: %T.as.Destroy.impl.Op.type.8b2 = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.699: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%EmptyRange.cc8) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d12: %T.as.Destroy.impl.Op.type.699 = struct_value () [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.069: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%empty_struct_type) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.d5a: %T.as.Destroy.impl.Op.type.069 = struct_value () [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.88d: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%EmptyRange.cc8) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.929: %T.as.Destroy.impl.Op.type.88d = struct_value () [concrete] // CHECK:STDOUT: %ptr.35d: type = ptr_type %EmptyRange.cc8 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -415,29 +413,25 @@ fn Run() { // CHECK:STDOUT: br !for.next // CHECK:STDOUT: // CHECK:STDOUT: !for.done: -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_8.1: = bound_method %.loc12_8, constants.%T.as.Destroy.impl.Op.01c -// CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc12_8.1: = bound_method %.loc12_8, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound.loc12_8.1: = bound_method %.loc12_8, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc12_8.1: %ptr.019 = addr_of %.loc12_8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_8.1: init %empty_tuple.type = call %bound_method.loc12_8.1(%addr.loc12_8.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_8.2: = bound_method %c.var, constants.%T.as.Destroy.impl.Op.01c -// CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc12_8.2: = bound_method %c.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call.loc12_8.1: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound.loc12_8.1(%addr.loc12_8.1) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound.loc12_8.2: = bound_method %c.var, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc12_8.2: %ptr.019 = addr_of %c.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_8.2: init %empty_tuple.type = call %bound_method.loc12_8.2(%addr.loc12_8.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_40.1: = bound_method %.loc12_40.1, constants.%T.as.Destroy.impl.Op.a97 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call.loc12_8.2: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound.loc12_8.2(%addr.loc12_8.2) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_40.1: = bound_method %.loc12_40.1, constants.%T.as.Destroy.impl.Op.3e8 // CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc12_40.7: = bound_method %.loc12_40.1, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %bound_method.loc12_40.7: = bound_method %.loc12_40.1, %T.as.Destroy.impl.Op.specific_fn.1 // CHECK:STDOUT: %addr.loc12_40.2: %ptr.8e6 = addr_of %.loc12_40.1 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_40.1: init %empty_tuple.type = call %bound_method.loc12_40.7(%addr.loc12_40.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_40.2: = bound_method %var, constants.%T.as.Destroy.impl.Op.ca6 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_40.2: = bound_method %var, constants.%T.as.Destroy.impl.Op.d5a // CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc12_40.8: = bound_method %var, %T.as.Destroy.impl.Op.specific_fn.4 +// CHECK:STDOUT: %bound_method.loc12_40.8: = bound_method %var, %T.as.Destroy.impl.Op.specific_fn.2 // CHECK:STDOUT: %addr.loc12_40.3: %ptr.c28 = addr_of %var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_40.2: init %empty_tuple.type = call %bound_method.loc12_40.8(%addr.loc12_40.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_39: = bound_method %.loc12_39.1, constants.%T.as.Destroy.impl.Op.d12 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_39: = bound_method %.loc12_39.1, constants.%T.as.Destroy.impl.Op.929 // CHECK:STDOUT: -// CHECK:STDOUT: %bound_method.loc12_39: = bound_method %.loc12_39.1, %T.as.Destroy.impl.Op.specific_fn.5 +// CHECK:STDOUT: %bound_method.loc12_39: = bound_method %.loc12_39.1, %T.as.Destroy.impl.Op.specific_fn.3 // CHECK:STDOUT: %addr.loc12_39: %ptr.35d = addr_of %.loc12_39.1 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_39: init %empty_tuple.type = call %bound_method.loc12_39(%addr.loc12_39) // CHECK:STDOUT: @@ -633,10 +627,10 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %Body.type: type = fn_type @Body [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Body: %Body.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.c28: type = ptr_type %empty_struct_type [concrete] // CHECK:STDOUT: %tuple.type.56b: type = tuple_type (%C, %C) [concrete] @@ -679,16 +673,16 @@ fn Run() { // CHECK:STDOUT: %Optional.Get.8a7: %Optional.Get.type.4a4 = struct_value () [concrete] // CHECK:STDOUT: %Optional.HasValue.specific_fn: = specific_function %Optional.HasValue.bef, @Optional.HasValue(%tuple.type.56b) [concrete] // CHECK:STDOUT: %Optional.Get.specific_fn: = specific_function %Optional.Get.8a7, @Optional.Get(%tuple.type.56b) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.65e: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%tuple.type.56b) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.587: %T.as.Destroy.impl.Op.type.65e = struct_value () [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.12e: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%tuple.type.56b) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.34b: %T.as.Destroy.impl.Op.type.12e = struct_value () [concrete] // CHECK:STDOUT: %ptr.9f0: type = ptr_type %tuple.type.56b [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.400: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Optional.657) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5ec: %T.as.Destroy.impl.Op.type.400 = struct_value () [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.e9f: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Optional.657) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.5c4: %T.as.Destroy.impl.Op.type.e9f = struct_value () [concrete] // CHECK:STDOUT: %ptr.036: type = ptr_type %Optional.657 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.8b2: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%empty_struct_type) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.ca6: %T.as.Destroy.impl.Op.type.8b2 = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.cee: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%EmptyRange.90a) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.323: %T.as.Destroy.impl.Op.type.cee = struct_value () [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.069: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%empty_struct_type) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.d5a: %T.as.Destroy.impl.Op.type.069 = struct_value () [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.8c3: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%EmptyRange.90a) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.85b: %T.as.Destroy.impl.Op.type.8c3 = struct_value () [concrete] // CHECK:STDOUT: %ptr.f9b: type = ptr_type %EmptyRange.90a [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -779,22 +773,22 @@ fn Run() { // CHECK:STDOUT: br !for.next // CHECK:STDOUT: // CHECK:STDOUT: !for.done: -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_49.1: = bound_method %.loc12_49.8, constants.%T.as.Destroy.impl.Op.587 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_49.1: = bound_method %.loc12_49.8, constants.%T.as.Destroy.impl.Op.34b // CHECK:STDOUT: // CHECK:STDOUT: %bound_method.loc12_49.7: = bound_method %.loc12_49.8, %T.as.Destroy.impl.Op.specific_fn.1 // CHECK:STDOUT: %addr.loc12_49.2: %ptr.9f0 = addr_of %.loc12_49.8 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_49.1: init %empty_tuple.type = call %bound_method.loc12_49.7(%addr.loc12_49.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_49.2: = bound_method %.loc12_49.1, constants.%T.as.Destroy.impl.Op.5ec +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_49.2: = bound_method %.loc12_49.1, constants.%T.as.Destroy.impl.Op.5c4 // CHECK:STDOUT: // CHECK:STDOUT: %bound_method.loc12_49.8: = bound_method %.loc12_49.1, %T.as.Destroy.impl.Op.specific_fn.2 // CHECK:STDOUT: %addr.loc12_49.3: %ptr.036 = addr_of %.loc12_49.1 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_49.2: init %empty_tuple.type = call %bound_method.loc12_49.8(%addr.loc12_49.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_49.3: = bound_method %var, constants.%T.as.Destroy.impl.Op.ca6 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_49.3: = bound_method %var, constants.%T.as.Destroy.impl.Op.d5a // CHECK:STDOUT: // CHECK:STDOUT: %bound_method.loc12_49.9: = bound_method %var, %T.as.Destroy.impl.Op.specific_fn.3 // CHECK:STDOUT: %addr.loc12_49.4: %ptr.c28 = addr_of %var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_49.3: init %empty_tuple.type = call %bound_method.loc12_49.9(%addr.loc12_49.4) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_48: = bound_method %.loc12_48.1, constants.%T.as.Destroy.impl.Op.323 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_48: = bound_method %.loc12_48.1, constants.%T.as.Destroy.impl.Op.85b // CHECK:STDOUT: // CHECK:STDOUT: %bound_method.loc12_48: = bound_method %.loc12_48.1, %T.as.Destroy.impl.Op.specific_fn.4 // CHECK:STDOUT: %addr.loc12_48: %ptr.f9b = addr_of %.loc12_48.1 diff --git a/toolchain/check/testdata/function/call/i32.carbon b/toolchain/check/testdata/function/call/i32.carbon index c2301f4584ca..5fb96d299b9c 100644 --- a/toolchain/check/testdata/function/call/i32.carbon +++ b/toolchain/check/testdata/function/call/i32.carbon @@ -38,6 +38,7 @@ fn Main() { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -50,7 +51,6 @@ fn Main() { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.956, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] // CHECK:STDOUT: %bound_method: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] diff --git a/toolchain/check/testdata/function/call/more_param_ir.carbon b/toolchain/check/testdata/function/call/more_param_ir.carbon index f1f41aade1c8..5a2ae9013219 100644 --- a/toolchain/check/testdata/function/call/more_param_ir.carbon +++ b/toolchain/check/testdata/function/call/more_param_ir.carbon @@ -42,6 +42,7 @@ fn Main() { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -60,7 +61,6 @@ fn Main() { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.ce9: = bound_method %int_6.462, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.efa: = bound_method %int_6.462, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_6.e56: %i32 = int_value 6 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.438: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%tuple.type.a1c) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.c8e: %T.as.Destroy.impl.Op.type.438 = struct_value () [concrete] // CHECK:STDOUT: %ptr.0b7: type = ptr_type %tuple.type.a1c [concrete] diff --git a/toolchain/check/testdata/function/call/prefer_unqualified_lookup.carbon b/toolchain/check/testdata/function/call/prefer_unqualified_lookup.carbon index 99cf892f0a93..828250d84494 100644 --- a/toolchain/check/testdata/function/call/prefer_unqualified_lookup.carbon +++ b/toolchain/check/testdata/function/call/prefer_unqualified_lookup.carbon @@ -45,8 +45,20 @@ fn Class(F:! type).Inner.G() -> i32 { return F(); } // CHECK:STDOUT: %Inner.F: %Inner.F.type = struct_value () [symbolic] // CHECK:STDOUT: %Inner.G.type: type = fn_type @Inner.G, @Inner(%F) [symbolic] // CHECK:STDOUT: %Inner.G: %Inner.G.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.3a7: = impl_witness @Inner.%Destroy.impl_witness_table, @Inner.as.Destroy.impl(%F) [symbolic] +// CHECK:STDOUT: %ptr.2b5: type = ptr_type %Inner [symbolic] +// CHECK:STDOUT: %pattern_type.2df: type = pattern_type %ptr.2b5 [symbolic] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.type: type = fn_type @Inner.as.Destroy.impl.Op, @Inner.as.Destroy.impl(%F) [symbolic] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op: %Inner.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.95a: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%F) [symbolic] +// CHECK:STDOUT: %ptr.955: type = ptr_type %Class [symbolic] +// CHECK:STDOUT: %pattern_type.9e0: type = pattern_type %ptr.955 [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%F) [symbolic] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: %Class.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] @@ -70,11 +82,13 @@ fn Class(F:! type).Inner.G() -> i32 { return F(); } // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -103,6 +117,62 @@ fn Class(F:! type).Inner.G() -> i32 { return F(); } // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Inner.as.Destroy.impl(@Class.%F.loc5_13.2: type) { +// CHECK:STDOUT: %F: type = bind_symbolic_name F, 0 [symbolic = %F (constants.%F)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Inner.%Destroy.impl_witness_table, @Inner.as.Destroy.impl(%F) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.3a7)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.type: type = fn_type @Inner.as.Destroy.impl.Op, @Inner.as.Destroy.impl(%F) [symbolic = %Inner.as.Destroy.impl.Op.type (constants.%Inner.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op: @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.type (%Inner.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Inner.as.Destroy.impl.Op (constants.%Inner.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Inner as constants.%Destroy.type { +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.decl: @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.type (%Inner.as.Destroy.impl.Op.type) = fn_decl @Inner.as.Destroy.impl.Op [symbolic = @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op (constants.%Inner.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Inner.as.Destroy.impl.Op.%pattern_type (%pattern_type.2df) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Inner.as.Destroy.impl.Op.%pattern_type (%pattern_type.2df) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6_15.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Inner.as.Destroy.impl.Op.%ptr (%ptr.2b5) = value_param call_param0 +// CHECK:STDOUT: %.loc6_15.2: type = splice_block %Self.ref [symbolic = %Inner (constants.%Inner)] { +// CHECK:STDOUT: %.loc6_15.3: type = specific_constant constants.%Inner, @Inner(constants.%F) [symbolic = %Inner (constants.%Inner)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc6_15.3 [symbolic = %Inner (constants.%Inner)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Inner.as.Destroy.impl.Op.%ptr (%ptr.2b5) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Inner.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Inner.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Class.as.Destroy.impl(@Class.%F.loc5_13.2: type) { +// CHECK:STDOUT: %F: type = bind_symbolic_name F, 0 [symbolic = %F (constants.%F)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Class.%Destroy.impl_witness_table, @Class.as.Destroy.impl(%F) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.95a)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.type: type = fn_type @Class.as.Destroy.impl.Op, @Class.as.Destroy.impl(%F) [symbolic = %Class.as.Destroy.impl.Op.type (constants.%Class.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Class.as.Destroy.impl.Op: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Class as constants.%Destroy.type { +// CHECK:STDOUT: %Class.as.Destroy.impl.Op.decl: @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.type (%Class.as.Destroy.impl.Op.type) = fn_decl @Class.as.Destroy.impl.Op [symbolic = @Class.as.Destroy.impl.%Class.as.Destroy.impl.Op (constants.%Class.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.as.Destroy.impl.Op.%pattern_type (%pattern_type.9e0) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = value_param call_param0 +// CHECK:STDOUT: %.loc5_23.2: type = splice_block %Self.ref [symbolic = %Class (constants.%Class)] { +// CHECK:STDOUT: %.loc5_23.3: type = specific_constant constants.%Class, @Class(constants.%F) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc5_23.3 [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.as.Destroy.impl.Op.%ptr (%ptr.955) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Class.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Class.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Class(%F.loc5_13.2: type) { // CHECK:STDOUT: %F.loc5_13.1: type = bind_symbolic_name F, 0 [symbolic = %F.loc5_13.1 (constants.%F)] // CHECK:STDOUT: @@ -111,6 +181,9 @@ fn Class(F:! type).Inner.G() -> i32 { return F(); } // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: %Inner.decl: type = class_decl @Inner [symbolic = @Class.%Inner (constants.%Inner)] {} {} +// CHECK:STDOUT: impl_decl @Class.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Class.as.Destroy.impl.%Class.as.Destroy.impl.Op.decl), @Class.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Class.as.Destroy.impl(constants.%F) [symbolic = @Class.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.95a)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -148,6 +221,9 @@ fn Class(F:! type).Inner.G() -> i32 { return F(); } // CHECK:STDOUT: %return.param.loc9: ref %i32 = out_param call_param0 // CHECK:STDOUT: %return.loc9: ref %i32 = return_slot %return.param.loc9 // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Inner.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.decl), @Inner.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Inner.as.Destroy.impl(constants.%F) [symbolic = @Inner.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.3a7)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -195,6 +271,28 @@ fn Class(F:! type).Inner.G() -> i32 { return F(); } // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Inner.as.Destroy.impl.Op(@Class.%F.loc5_13.2: type) { +// CHECK:STDOUT: %F: type = bind_symbolic_name F, 0 [symbolic = %F (constants.%F)] +// CHECK:STDOUT: %Inner: type = class_type @Inner, @Inner(%F) [symbolic = %Inner (constants.%Inner)] +// CHECK:STDOUT: %ptr: type = ptr_type %Inner [symbolic = %ptr (constants.%ptr.2b5)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.2df)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Inner.as.Destroy.impl.Op.%ptr (%ptr.2b5)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.as.Destroy.impl.Op(@Class.%F.loc5_13.2: type) { +// CHECK:STDOUT: %F: type = bind_symbolic_name F, 0 [symbolic = %F (constants.%F)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%F) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %ptr: type = ptr_type %Class [symbolic = %ptr (constants.%ptr.955)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.9e0)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.as.Destroy.impl.Op.%ptr (%ptr.955)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Class(constants.%F) { // CHECK:STDOUT: %F.loc5_13.1 => constants.%F // CHECK:STDOUT: @@ -217,3 +315,27 @@ fn Class(F:! type).Inner.G() -> i32 { return F(); } // CHECK:STDOUT: // CHECK:STDOUT: specific @Inner.G(constants.%F) {} // CHECK:STDOUT: +// CHECK:STDOUT: specific @Inner.as.Destroy.impl(constants.%F) { +// CHECK:STDOUT: %F => constants.%F +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.3a7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Inner.as.Destroy.impl.Op(constants.%F) { +// CHECK:STDOUT: %F => constants.%F +// CHECK:STDOUT: %Inner => constants.%Inner +// CHECK:STDOUT: %ptr => constants.%ptr.2b5 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.2df +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl(constants.%F) { +// CHECK:STDOUT: %F => constants.%F +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.95a +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.as.Destroy.impl.Op(constants.%F) { +// CHECK:STDOUT: %F => constants.%F +// CHECK:STDOUT: %Class => constants.%Class +// CHECK:STDOUT: %ptr => constants.%ptr.955 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.9e0 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/function/declaration/fail_import_incomplete_return.carbon b/toolchain/check/testdata/function/declaration/fail_import_incomplete_return.carbon index 8e05d81db893..bf2984e38e7a 100644 --- a/toolchain/check/testdata/function/declaration/fail_import_incomplete_return.carbon +++ b/toolchain/check/testdata/function/declaration/fail_import_incomplete_return.carbon @@ -105,15 +105,24 @@ fn CallFAndGIncomplete() { // CHECK:STDOUT: %ReturnDUsed: %ReturnDUsed.type = struct_value () [concrete] // CHECK:STDOUT: %Call.type: type = fn_type @Call [concrete] // CHECK:STDOUT: %Call: %Call.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -166,9 +175,28 @@ fn CallFAndGIncomplete() { // CHECK:STDOUT: %D.decl.loc37: type = class_decl @D [concrete = constants.%D] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc37: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C; // CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -194,6 +222,8 @@ fn CallFAndGIncomplete() { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_use_imported.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -206,16 +236,16 @@ fn CallFAndGIncomplete() { // CHECK:STDOUT: %ReturnCUsed: %ReturnCUsed.type = struct_value () [concrete] // CHECK:STDOUT: %ReturnDUnused.type: type = fn_type @ReturnDUnused [concrete] // CHECK:STDOUT: %ReturnDUnused: %ReturnDUnused.type = struct_value () [concrete] -// CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %D.b3dde2.1: type = class_type @D.1 [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %ReturnDUsed.type: type = fn_type @ReturnDUsed [concrete] // CHECK:STDOUT: %ReturnDUsed: %ReturnDUsed.type = struct_value () [concrete] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.548: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%D) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.2d4: %T.as.Destroy.impl.Op.type.548 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(%D) [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b6f: = impl_witness imports.%Destroy.impl_witness_table.cd7 [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D.b3dde2.1 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -231,9 +261,16 @@ fn CallFAndGIncomplete() { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Main.import_ref.8f2: = import_ref Main//incomplete_return, loc37_10, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Main.import_ref.cab = import_ref Main//incomplete_return, inst20 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//incomplete_return, loc37_10, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.cabe25.1 = import_ref Main//incomplete_return, inst20 [no loc], unloaded // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.7ba: = import_ref Main//incomplete_return, loc37_9, loaded [concrete = constants.%Destroy.impl_witness.b6f] +// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//incomplete_return, loc37_10, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.cabe25.2 = import_ref Main//incomplete_return, inst20 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.4aa: type = import_ref Main//incomplete_return, inst20 [no loc], loaded [concrete = constants.%D.b3dde2.1] +// CHECK:STDOUT: %Main.import_ref.cb9: type = import_ref Main//incomplete_return, inst67 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.283: %D.as.Destroy.impl.Op.type = import_ref Main//incomplete_return, loc37_9, loaded [concrete = constants.%D.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.cd7 = impl_witness_table (%Main.import_ref.283), @D.as.Destroy.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -253,13 +290,25 @@ fn CallFAndGIncomplete() { // CHECK:STDOUT: %CallFAndGIncomplete.decl: %CallFAndGIncomplete.type = fn_decl @CallFAndGIncomplete [concrete = constants.%CallFAndGIncomplete] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: imports.%Main.import_ref.4aa as imports.%Main.import_ref.cb9 [from "fail_incomplete_return.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.7ba +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C [from "fail_incomplete_return.carbon"]; // CHECK:STDOUT: -// CHECK:STDOUT: class @D [from "fail_incomplete_return.carbon"] { -// CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f2 +// CHECK:STDOUT: class @D.1 [from "fail_incomplete_return.carbon"] { +// CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.1 // CHECK:STDOUT: // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = imports.%Main.import_ref.cab +// CHECK:STDOUT: .Self = imports.%Main.import_ref.cabe25.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @D.2 [from "fail_incomplete_return.carbon"] { +// CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.2 +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Main.import_ref.cabe25.2 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @CallFAndGIncomplete() { @@ -269,23 +318,19 @@ fn CallFAndGIncomplete() { // CHECK:STDOUT: %ReturnCUsed.ref: %ReturnCUsed.type = name_ref ReturnCUsed, imports.%Main.ReturnCUsed [concrete = constants.%ReturnCUsed] // CHECK:STDOUT: %ReturnCUsed.call: init = call %ReturnCUsed.ref() // CHECK:STDOUT: %ReturnDUnused.ref: %ReturnDUnused.type = name_ref ReturnDUnused, imports.%Main.ReturnDUnused [concrete = constants.%ReturnDUnused] -// CHECK:STDOUT: %.loc33_17.1: ref %D = temporary_storage -// CHECK:STDOUT: %ReturnDUnused.call: init %D = call %ReturnDUnused.ref() to %.loc33_17.1 -// CHECK:STDOUT: %.loc33_17.2: ref %D = temporary %.loc33_17.1, %ReturnDUnused.call +// CHECK:STDOUT: %.loc33_17.1: ref %D.b3dde2.1 = temporary_storage +// CHECK:STDOUT: %ReturnDUnused.call: init %D.b3dde2.1 = call %ReturnDUnused.ref() to %.loc33_17.1 +// CHECK:STDOUT: %.loc33_17.2: ref %D.b3dde2.1 = temporary %.loc33_17.1, %ReturnDUnused.call // CHECK:STDOUT: %ReturnDUsed.ref: %ReturnDUsed.type = name_ref ReturnDUsed, imports.%Main.ReturnDUsed [concrete = constants.%ReturnDUsed] -// CHECK:STDOUT: %.loc34_15.1: ref %D = temporary_storage -// CHECK:STDOUT: %ReturnDUsed.call: init %D = call %ReturnDUsed.ref() to %.loc34_15.1 -// CHECK:STDOUT: %.loc34_15.2: ref %D = temporary %.loc34_15.1, %ReturnDUsed.call -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc34: = bound_method %.loc34_15.1, constants.%T.as.Destroy.impl.Op.2d4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc34: = bound_method %.loc34_15.1, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %.loc34_15.1: ref %D.b3dde2.1 = temporary_storage +// CHECK:STDOUT: %ReturnDUsed.call: init %D.b3dde2.1 = call %ReturnDUsed.ref() to %.loc34_15.1 +// CHECK:STDOUT: %.loc34_15.2: ref %D.b3dde2.1 = temporary %.loc34_15.1, %ReturnDUsed.call +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc34: = bound_method %.loc34_15.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc34: %ptr.19c = addr_of %.loc34_15.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc34: init %empty_tuple.type = call %bound_method.loc34(%addr.loc34) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc33: = bound_method %.loc33_17.1, constants.%T.as.Destroy.impl.Op.2d4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc33: = bound_method %.loc33_17.1, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc34: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc34(%addr.loc34) +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc33: = bound_method %.loc33_17.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc33: %ptr.19c = addr_of %.loc33_17.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc33: init %empty_tuple.type = call %bound_method.loc33(%addr.loc33) +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc33: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc33(%addr.loc33) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -297,3 +342,5 @@ fn CallFAndGIncomplete() { // CHECK:STDOUT: // CHECK:STDOUT: fn @ReturnDUsed [from "fail_incomplete_return.carbon"]; // CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op = "no_op" [from "fail_incomplete_return.carbon"]; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/function/declaration/import.carbon b/toolchain/check/testdata/function/declaration/import.carbon index d50e8b4bc127..9bedbfeefb83 100644 --- a/toolchain/check/testdata/function/declaration/import.carbon +++ b/toolchain/check/testdata/function/declaration/import.carbon @@ -912,8 +912,8 @@ import library "extern_api"; // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] -// CHECK:STDOUT: %Core.import_ref.a86: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.6d7)] -// CHECK:STDOUT: %ImplicitAs.impl_witness_table.e36 = impl_witness_table (%Core.import_ref.a86), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %Core.import_ref.a86c: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0b2) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.6d7)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table.e36 = impl_witness_table (%Core.import_ref.a86c), @Core.IntLiteral.as.ImplicitAs.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { diff --git a/toolchain/check/testdata/function/generic/call.carbon b/toolchain/check/testdata/function/generic/call.carbon index 27cf7248f9d8..eab0033fd4ed 100644 --- a/toolchain/check/testdata/function/generic/call.carbon +++ b/toolchain/check/testdata/function/generic/call.carbon @@ -76,17 +76,19 @@ fn CallSpecific(x: C) -> C { // CHECK:STDOUT: %require_complete.6e5: = require_complete_type %ptr.79f [symbolic] // CHECK:STDOUT: %Function.specific_fn.4d7: = specific_function %Function, @Function(%ptr.79f) [symbolic] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %CallSpecific.type: type = fn_type @CallSpecific [concrete] // CHECK:STDOUT: %CallSpecific: %CallSpecific.type = struct_value () [concrete] // CHECK:STDOUT: %Function.specific_fn.1b5: = specific_function %Function, @Function(%C) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -173,9 +175,28 @@ fn CallSpecific(x: C) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc16: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -240,6 +261,8 @@ fn CallSpecific(x: C) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @CallSpecific(%x.param: %C) -> %return.param: %C { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Function.ref: %Function.type = name_ref Function, file.%Function.decl [concrete = constants.%Function] @@ -248,11 +271,9 @@ fn CallSpecific(x: C) -> C { // CHECK:STDOUT: %Function.specific_fn: = specific_function %Function.ref, @Function(constants.%C) [concrete = constants.%Function.specific_fn.1b5] // CHECK:STDOUT: %.loc18: ref %C = splice_block %return {} // CHECK:STDOUT: %Function.call: init %C = call %Function.specific_fn(%x.ref) to %.loc18 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc18, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc18, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc18, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.019 = addr_of %.loc18 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %Function.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -288,7 +309,7 @@ fn CallSpecific(x: C) -> C { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.c48 // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete => constants.%complete_type // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: --- deduced.carbon @@ -311,17 +332,19 @@ fn CallSpecific(x: C) -> C { // CHECK:STDOUT: %require_complete.6e5: = require_complete_type %ptr.79f [symbolic] // CHECK:STDOUT: %Function.specific_fn.4d7: = specific_function %Function, @Function(%ptr.79f) [symbolic] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %CallSpecific.type: type = fn_type @CallSpecific [concrete] // CHECK:STDOUT: %CallSpecific: %CallSpecific.type = struct_value () [concrete] // CHECK:STDOUT: %Function.specific_fn.1b5: = specific_function %Function, @Function(%C) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -408,9 +431,28 @@ fn CallSpecific(x: C) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc16: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -472,6 +514,8 @@ fn CallSpecific(x: C) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @CallSpecific(%x.param: %C) -> %return.param: %C { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Function.ref: %Function.type = name_ref Function, file.%Function.decl [concrete = constants.%Function] @@ -479,11 +523,9 @@ fn CallSpecific(x: C) -> C { // CHECK:STDOUT: %Function.specific_fn: = specific_function %Function.ref, @Function(constants.%C) [concrete = constants.%Function.specific_fn.1b5] // CHECK:STDOUT: %.loc18: ref %C = splice_block %return {} // CHECK:STDOUT: %Function.call: init %C = call %Function.specific_fn(%x.ref) to %.loc18 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc18, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc18, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc18, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.019 = addr_of %.loc18 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %Function.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -519,6 +561,6 @@ fn CallSpecific(x: C) -> C { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.c48 // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete => constants.%complete_type // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/function/generic/call_method_on_generic_facet.carbon b/toolchain/check/testdata/function/generic/call_method_on_generic_facet.carbon index 48c0da036f3c..f89fb068bccc 100644 --- a/toolchain/check/testdata/function/generic/call_method_on_generic_facet.carbon +++ b/toolchain/check/testdata/function/generic/call_method_on_generic_facet.carbon @@ -53,9 +53,21 @@ fn G() { // CHECK:STDOUT: %Generic.assoc_type.0fd877.1: type = assoc_entity_type @Generic, @Generic(%Scalar) [symbolic] // CHECK:STDOUT: %assoc0.2966cb.1: %Generic.assoc_type.0fd877.1 = assoc_entity element0, @Generic.%Generic.F.decl [symbolic] // CHECK:STDOUT: %GenericParam: type = class_type @GenericParam [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.884: = impl_witness @GenericParam.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.f73: type = ptr_type %GenericParam [concrete] +// CHECK:STDOUT: %pattern_type.7c3: type = pattern_type %ptr.f73 [concrete] +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op.type: type = fn_type @GenericParam.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op: %GenericParam.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %ImplsGeneric: type = class_type @ImplsGeneric [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9ca: = impl_witness @ImplsGeneric.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.011: type = ptr_type %ImplsGeneric [concrete] +// CHECK:STDOUT: %pattern_type.2db: type = pattern_type %ptr.011 [concrete] +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op.type: type = fn_type @ImplsGeneric.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op: %ImplsGeneric.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Generic.type.769: type = facet_type <@Generic, @Generic(%GenericParam)> [concrete] // CHECK:STDOUT: %Self.f84: %Generic.type.769 = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %Generic.F.type.4cf: type = fn_type @Generic.F, @Generic(%GenericParam) [concrete] @@ -104,9 +116,11 @@ fn G() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -191,6 +205,38 @@ fn G() { // CHECK:STDOUT: witness = (%Other.G.decl) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @GenericParam.as.Destroy.impl: constants.%GenericParam as constants.%Destroy.type { +// CHECK:STDOUT: %GenericParam.as.Destroy.impl.Op.decl: %GenericParam.as.Destroy.impl.Op.type = fn_decl @GenericParam.as.Destroy.impl.Op [concrete = constants.%GenericParam.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.7c3 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.7c3 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc19: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.f73 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%GenericParam [concrete = constants.%GenericParam] +// CHECK:STDOUT: %self: %ptr.f73 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %GenericParam.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @GenericParam.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @ImplsGeneric.as.Destroy.impl: constants.%ImplsGeneric as constants.%Destroy.type { +// CHECK:STDOUT: %ImplsGeneric.as.Destroy.impl.Op.decl: %ImplsGeneric.as.Destroy.impl.Op.type = fn_decl @ImplsGeneric.as.Destroy.impl.Op [concrete = constants.%ImplsGeneric.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.2db = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.2db = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc21: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.011 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%ImplsGeneric [concrete = constants.%ImplsGeneric] +// CHECK:STDOUT: %self: %ptr.011 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %ImplsGeneric.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @ImplsGeneric.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @ImplsGeneric.as.Generic.impl: %ImplsGeneric.ref as %Generic.type { // CHECK:STDOUT: %ImplsGeneric.as.Generic.impl.F.decl: %ImplsGeneric.as.Generic.impl.F.type = fn_decl @ImplsGeneric.as.Generic.impl.F [concrete = constants.%ImplsGeneric.as.Generic.impl.F] {} {} // CHECK:STDOUT: @@ -208,6 +254,9 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @GenericParam { +// CHECK:STDOUT: impl_decl @GenericParam.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@GenericParam.as.Destroy.impl.%GenericParam.as.Destroy.impl.Op.decl), @GenericParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.884] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -217,6 +266,9 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @ImplsGeneric { +// CHECK:STDOUT: impl_decl @ImplsGeneric.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@ImplsGeneric.as.Destroy.impl.%ImplsGeneric.as.Destroy.impl.Op.decl), @ImplsGeneric.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.9ca] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -229,6 +281,10 @@ fn G() { // CHECK:STDOUT: fn(); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @GenericParam.as.Destroy.impl.Op(%self.param: %ptr.f73) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ImplsGeneric.as.Destroy.impl.Op(%self.param: %ptr.011) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @ImplsGeneric.as.Generic.impl.F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return diff --git a/toolchain/check/testdata/function/generic/deduce.carbon b/toolchain/check/testdata/function/generic/deduce.carbon index 29109cd77ebe..b1186139bcc1 100644 --- a/toolchain/check/testdata/function/generic/deduce.carbon +++ b/toolchain/check/testdata/function/generic/deduce.carbon @@ -509,6 +509,14 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %A: type = class_type @A [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] @@ -517,23 +525,16 @@ fn F() { // CHECK:STDOUT: %ptr.79f: type = ptr_type %T [symbolic] // CHECK:STDOUT: %pattern_type.afe: type = pattern_type %ptr.79f [symbolic] // CHECK:STDOUT: %ExplicitAndAlsoDeduced.type: type = fn_type @ExplicitAndAlsoDeduced [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %ExplicitAndAlsoDeduced: %ExplicitAndAlsoDeduced.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.6e5: = require_complete_type %ptr.79f [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %ExplicitAndAlsoDeduced.specific_fn.41d: = specific_function %ExplicitAndAlsoDeduced, @ExplicitAndAlsoDeduced(%T) [symbolic] -// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] -// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] // CHECK:STDOUT: %CallExplicitAndAlsoDeduced.type: type = fn_type @CallExplicitAndAlsoDeduced [concrete] // CHECK:STDOUT: %CallExplicitAndAlsoDeduced: %CallExplicitAndAlsoDeduced.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.c10: type = pattern_type %A [concrete] // CHECK:STDOUT: %ExplicitAndAlsoDeduced.specific_fn.720: = specific_function %ExplicitAndAlsoDeduced, @ExplicitAndAlsoDeduced(%A) [concrete] // CHECK:STDOUT: %A.val: %A = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.b96: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%A) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.885: %T.as.Destroy.impl.Op.type.b96 = struct_value () [concrete] // CHECK:STDOUT: %complete_type.7ea: = complete_type_witness %ptr.6db [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.885, @T.as.Destroy.impl.Op(%A) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -581,7 +582,26 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -590,6 +610,8 @@ fn F() { // CHECK:STDOUT: .Self = constants.%A // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @ExplicitAndAlsoDeduced(%T.loc6_27.2: type) { // CHECK:STDOUT: %T.loc6_27.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_27.1 (constants.%T)] // CHECK:STDOUT: %pattern_type.loc6_37: type = pattern_type %T.loc6_27.1 [symbolic = %pattern_type.loc6_37 (constants.%pattern_type.7dc)] @@ -628,11 +650,9 @@ fn F() { // CHECK:STDOUT: %ExplicitAndAlsoDeduced.call: init %ptr.6db = call %ExplicitAndAlsoDeduced.specific_fn(%.loc11_37.6) // CHECK:STDOUT: %.loc11_39.1: %ptr.6db = value_of_initializer %ExplicitAndAlsoDeduced.call // CHECK:STDOUT: %.loc11_39.2: %ptr.6db = converted %ExplicitAndAlsoDeduced.call, %.loc11_39.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc11_37.2, constants.%T.as.Destroy.impl.Op.885 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.885, @T.as.Destroy.impl.Op(constants.%A) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc11_37.2, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %A.as.Destroy.impl.Op.bound: = bound_method %.loc11_37.2, constants.%A.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.6db = addr_of %.loc11_37.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %A.as.Destroy.impl.Op.call: init %empty_tuple.type = call %A.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %.loc11_39.2 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -1549,8 +1569,15 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Z.type: type = facet_type <@Z> [concrete] -// CHECK:STDOUT: %Self: %Z.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.6e6: %Z.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %EE: type = class_type @EE [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.c99: = impl_witness @EE.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.7d7: type = ptr_type %EE [concrete] +// CHECK:STDOUT: %pattern_type.04a: type = pattern_type %ptr.7d7 [concrete] +// CHECK:STDOUT: %EE.as.Destroy.impl.Op.type: type = fn_type @EE.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %EE.as.Destroy.impl.Op: %EE.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Z.impl_witness.354: = impl_witness file.%Z.impl_witness_table.loc6 [concrete] @@ -1559,12 +1586,22 @@ fn F() { // CHECK:STDOUT: %DD.type: type = generic_class_type @DD [concrete] // CHECK:STDOUT: %DD.generic: %DD.type = struct_value () [concrete] // CHECK:STDOUT: %DD.296: type = class_type @DD, @DD(%E) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.63b: = impl_witness @DD.%Destroy.impl_witness_table, @DD.as.Destroy.impl(%E) [symbolic] +// CHECK:STDOUT: %ptr.964: type = ptr_type %DD.296 [symbolic] +// CHECK:STDOUT: %pattern_type.75a: type = pattern_type %ptr.964 [symbolic] +// CHECK:STDOUT: %DD.as.Destroy.impl.Op.type: type = fn_type @DD.as.Destroy.impl.Op, @DD.as.Destroy.impl(%E) [symbolic] +// CHECK:STDOUT: %DD.as.Destroy.impl.Op: %DD.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %Z.impl_witness.c98: = impl_witness file.%Z.impl_witness_table.loc9, @DD.as.Z.impl(%E) [symbolic] // CHECK:STDOUT: %D: %Z.type = bind_symbolic_name D, 0 [symbolic] // CHECK:STDOUT: %pattern_type.5af: type = pattern_type %Z.type [concrete] // CHECK:STDOUT: %CC.type: type = generic_class_type @CC [concrete] // CHECK:STDOUT: %CC.generic: %CC.type = struct_value () [concrete] // CHECK:STDOUT: %CC.a2f: type = class_type @CC, @CC(%D) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.e69: = impl_witness @CC.%Destroy.impl_witness_table, @CC.as.Destroy.impl(%D) [symbolic] +// CHECK:STDOUT: %ptr.019: type = ptr_type %CC.a2f [symbolic] +// CHECK:STDOUT: %pattern_type.d71: type = pattern_type %ptr.019 [symbolic] +// CHECK:STDOUT: %CC.as.Destroy.impl.Op.type: type = fn_type @CC.as.Destroy.impl.Op, @CC.as.Destroy.impl(%D) [symbolic] +// CHECK:STDOUT: %CC.as.Destroy.impl.Op: %CC.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %Z.lookup_impl_witness: = lookup_impl_witness %DD.296, @Z [symbolic] // CHECK:STDOUT: %Z.facet.aae: %Z.type = facet_value %DD.296, (%Z.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %CC.23e: type = class_type @CC, @CC(%Z.facet.aae) [symbolic] @@ -1581,9 +1618,11 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1645,18 +1684,62 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @Z { -// CHECK:STDOUT: %Self: %Z.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %Z.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.6e6] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = %Self // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @EE.as.Destroy.impl: constants.%EE as constants.%Destroy.type { +// CHECK:STDOUT: %EE.as.Destroy.impl.Op.decl: %EE.as.Destroy.impl.Op.type = fn_decl @EE.as.Destroy.impl.Op [concrete = constants.%EE.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.04a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.04a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.7d7 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%EE [concrete = constants.%EE] +// CHECK:STDOUT: %self: %ptr.7d7 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %EE.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @EE.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @EE.as.Z.impl: %EE.ref as %Z.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%Z.impl_witness.loc6 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @DD.as.Destroy.impl(@DD.%E.loc8_10.2: type) { +// CHECK:STDOUT: %E: type = bind_symbolic_name E, 0 [symbolic = %E (constants.%E)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @DD.%Destroy.impl_witness_table, @DD.as.Destroy.impl(%E) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.63b)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %DD.as.Destroy.impl.Op.type: type = fn_type @DD.as.Destroy.impl.Op, @DD.as.Destroy.impl(%E) [symbolic = %DD.as.Destroy.impl.Op.type (constants.%DD.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %DD.as.Destroy.impl.Op: @DD.as.Destroy.impl.%DD.as.Destroy.impl.Op.type (%DD.as.Destroy.impl.Op.type) = struct_value () [symbolic = %DD.as.Destroy.impl.Op (constants.%DD.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%DD.296 as constants.%Destroy.type { +// CHECK:STDOUT: %DD.as.Destroy.impl.Op.decl: @DD.as.Destroy.impl.%DD.as.Destroy.impl.Op.type (%DD.as.Destroy.impl.Op.type) = fn_decl @DD.as.Destroy.impl.Op [symbolic = @DD.as.Destroy.impl.%DD.as.Destroy.impl.Op (constants.%DD.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @DD.as.Destroy.impl.Op.%pattern_type (%pattern_type.75a) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @DD.as.Destroy.impl.Op.%pattern_type (%pattern_type.75a) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8_20.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @DD.as.Destroy.impl.Op.%ptr (%ptr.964) = value_param call_param0 +// CHECK:STDOUT: %.loc8_20.2: type = splice_block %Self.ref [symbolic = %DD (constants.%DD.296)] { +// CHECK:STDOUT: %.loc8_20.3: type = specific_constant constants.%DD.296, @DD(constants.%E) [symbolic = %DD (constants.%DD.296)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc8_20.3 [symbolic = %DD (constants.%DD.296)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @DD.as.Destroy.impl.Op.%ptr (%ptr.964) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %DD.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @DD.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl @DD.as.Z.impl(%E.loc9_14.1: type) { // CHECK:STDOUT: %E.loc9_14.2: type = bind_symbolic_name E, 0 [symbolic = %E.loc9_14.2 (constants.%E)] // CHECK:STDOUT: %DD.loc9_28.2: type = class_type @DD, @DD(%E.loc9_14.2) [symbolic = %DD.loc9_28.2 (constants.%DD.296)] @@ -1670,6 +1753,34 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @CC.as.Destroy.impl(@CC.%D.loc11_10.2: %Z.type) { +// CHECK:STDOUT: %D: %Z.type = bind_symbolic_name D, 0 [symbolic = %D (constants.%D)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @CC.%Destroy.impl_witness_table, @CC.as.Destroy.impl(%D) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.e69)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %CC.as.Destroy.impl.Op.type: type = fn_type @CC.as.Destroy.impl.Op, @CC.as.Destroy.impl(%D) [symbolic = %CC.as.Destroy.impl.Op.type (constants.%CC.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %CC.as.Destroy.impl.Op: @CC.as.Destroy.impl.%CC.as.Destroy.impl.Op.type (%CC.as.Destroy.impl.Op.type) = struct_value () [symbolic = %CC.as.Destroy.impl.Op (constants.%CC.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%CC.a2f as constants.%Destroy.type { +// CHECK:STDOUT: %CC.as.Destroy.impl.Op.decl: @CC.as.Destroy.impl.%CC.as.Destroy.impl.Op.type (%CC.as.Destroy.impl.Op.type) = fn_decl @CC.as.Destroy.impl.Op [symbolic = @CC.as.Destroy.impl.%CC.as.Destroy.impl.Op (constants.%CC.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @CC.as.Destroy.impl.Op.%pattern_type (%pattern_type.d71) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @CC.as.Destroy.impl.Op.%pattern_type (%pattern_type.d71) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc11_17.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @CC.as.Destroy.impl.Op.%ptr (%ptr.019) = value_param call_param0 +// CHECK:STDOUT: %.loc11_17.2: type = splice_block %Self.ref [symbolic = %CC (constants.%CC.a2f)] { +// CHECK:STDOUT: %.loc11_17.3: type = specific_constant constants.%CC.a2f, @CC(constants.%D) [symbolic = %CC (constants.%CC.a2f)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc11_17.3 [symbolic = %CC (constants.%CC.a2f)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @CC.as.Destroy.impl.Op.%ptr (%ptr.019) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %CC.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @CC.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl @CC.as.Z.impl(%E.loc12_14.1: type) { // CHECK:STDOUT: %E.loc12_14.2: type = bind_symbolic_name E, 0 [symbolic = %E.loc12_14.2 (constants.%E)] // CHECK:STDOUT: %DD.loc12_31.2: type = class_type @DD, @DD(%E.loc12_14.2) [symbolic = %DD.loc12_31.2 (constants.%DD.296)] @@ -1687,6 +1798,9 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @EE { +// CHECK:STDOUT: impl_decl @EE.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@EE.as.Destroy.impl.%EE.as.Destroy.impl.Op.decl), @EE.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.c99] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1701,6 +1815,9 @@ fn F() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @DD.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@DD.as.Destroy.impl.%DD.as.Destroy.impl.Op.decl), @DD.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @DD.as.Destroy.impl(constants.%E) [symbolic = @DD.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.63b)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1716,6 +1833,9 @@ fn F() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @CC.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@CC.as.Destroy.impl.%CC.as.Destroy.impl.Op.decl), @CC.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @CC.as.Destroy.impl(constants.%D) [symbolic = @CC.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.e69)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1725,6 +1845,30 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @EE.as.Destroy.impl.Op(%self.param: %ptr.7d7) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @DD.as.Destroy.impl.Op(@DD.%E.loc8_10.2: type) { +// CHECK:STDOUT: %E: type = bind_symbolic_name E, 0 [symbolic = %E (constants.%E)] +// CHECK:STDOUT: %DD: type = class_type @DD, @DD(%E) [symbolic = %DD (constants.%DD.296)] +// CHECK:STDOUT: %ptr: type = ptr_type %DD [symbolic = %ptr (constants.%ptr.964)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.75a)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @DD.as.Destroy.impl.Op.%ptr (%ptr.964)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @CC.as.Destroy.impl.Op(@CC.%D.loc11_10.2: %Z.type) { +// CHECK:STDOUT: %D: %Z.type = bind_symbolic_name D, 0 [symbolic = %D (constants.%D)] +// CHECK:STDOUT: %CC: type = class_type @CC, @CC(%D) [symbolic = %CC (constants.%CC.a2f)] +// CHECK:STDOUT: %ptr: type = ptr_type %CC [symbolic = %ptr (constants.%ptr.019)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.d71)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @CC.as.Destroy.impl.Op.%ptr (%ptr.019)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %CC.ref: %CC.type = name_ref CC, file.%CC.decl [concrete = constants.%CC.generic] @@ -1744,6 +1888,18 @@ fn F() { // CHECK:STDOUT: %E.loc8_10.1 => constants.%E // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @DD.as.Destroy.impl(constants.%E) { +// CHECK:STDOUT: %E => constants.%E +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.63b +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @DD.as.Destroy.impl.Op(constants.%E) { +// CHECK:STDOUT: %E => constants.%E +// CHECK:STDOUT: %DD => constants.%DD.296 +// CHECK:STDOUT: %ptr => constants.%ptr.964 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.75a +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @DD.as.Z.impl(constants.%E) { // CHECK:STDOUT: %E.loc9_14.2 => constants.%E // CHECK:STDOUT: %DD.loc9_28.2 => constants.%DD.296 @@ -1756,6 +1912,18 @@ fn F() { // CHECK:STDOUT: %D.loc11_10.1 => constants.%D // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @CC.as.Destroy.impl(constants.%D) { +// CHECK:STDOUT: %D => constants.%D +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.e69 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CC.as.Destroy.impl.Op(constants.%D) { +// CHECK:STDOUT: %D => constants.%D +// CHECK:STDOUT: %CC => constants.%CC.a2f +// CHECK:STDOUT: %ptr => constants.%ptr.019 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d71 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @CC(constants.%Z.facet.aae) { // CHECK:STDOUT: %D.loc11_10.1 => constants.%Z.facet.aae // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/function/generic/deduce_nested_facet_value.carbon b/toolchain/check/testdata/function/generic/deduce_nested_facet_value.carbon index b6af743a9c51..f19a1291e742 100644 --- a/toolchain/check/testdata/function/generic/deduce_nested_facet_value.carbon +++ b/toolchain/check/testdata/function/generic/deduce_nested_facet_value.carbon @@ -45,6 +45,13 @@ fn F() { // CHECK:STDOUT: %W.type: type = facet_type <@W> [concrete] // CHECK:STDOUT: %Self.f12: %W.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %DD: type = class_type @DD [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.147: = impl_witness @DD.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.3d1: type = ptr_type %DD [concrete] +// CHECK:STDOUT: %pattern_type.3fc: type = pattern_type %ptr.3d1 [concrete] +// CHECK:STDOUT: %DD.as.Destroy.impl.Op.type: type = fn_type @DD.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %DD.as.Destroy.impl.Op: %DD.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Y.impl_witness: = impl_witness file.%Y.impl_witness_table [concrete] @@ -54,6 +61,11 @@ fn F() { // CHECK:STDOUT: %CC.type: type = generic_class_type @CC [concrete] // CHECK:STDOUT: %CC.generic: %CC.type = struct_value () [concrete] // CHECK:STDOUT: %CC.3ba: type = class_type @CC, @CC(%D) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.a11: = impl_witness @CC.%Destroy.impl_witness_table, @CC.as.Destroy.impl(%D) [symbolic] +// CHECK:STDOUT: %ptr.423: type = ptr_type %CC.3ba [symbolic] +// CHECK:STDOUT: %pattern_type.1ed: type = pattern_type %ptr.423 [symbolic] +// CHECK:STDOUT: %CC.as.Destroy.impl.Op.type: type = fn_type @CC.as.Destroy.impl.Op, @CC.as.Destroy.impl(%D) [symbolic] +// CHECK:STDOUT: %CC.as.Destroy.impl.Op: %CC.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %Z.type: type = facet_type <@Z> [concrete] // CHECK:STDOUT: %Self.6e6: %Z.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %BitAndWith.type.f2e: type = generic_interface_type @BitAndWith [concrete] @@ -85,10 +97,12 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .BitAndWith = %Core.BitAndWith // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.BitAndWith: %BitAndWith.type.f2e = import_ref Core//prelude, BitAndWith, loaded [concrete = constants.%BitAndWith.generic] // CHECK:STDOUT: %Core.import_ref.012: %type.as.BitAndWith.impl.Op.type = import_ref Core//prelude, loc13_42, loaded [concrete = constants.%type.as.BitAndWith.impl.Op] // CHECK:STDOUT: %BitAndWith.impl_witness_table = impl_witness_table (%Core.import_ref.012), @type.as.BitAndWith.impl [concrete] @@ -177,6 +191,22 @@ fn F() { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @DD.as.Destroy.impl: constants.%DD as constants.%Destroy.type { +// CHECK:STDOUT: %DD.as.Destroy.impl.Op.decl: %DD.as.Destroy.impl.Op.type = fn_decl @DD.as.Destroy.impl.Op [concrete = constants.%DD.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.3fc = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.3fc = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.3d1 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%DD [concrete = constants.%DD] +// CHECK:STDOUT: %self: %ptr.3d1 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %DD.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @DD.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @DD.as.Y.impl: %DD.ref as %Y.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%Y.impl_witness @@ -187,6 +217,34 @@ fn F() { // CHECK:STDOUT: witness = file.%W.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @CC.as.Destroy.impl(@CC.%D.loc12_10.2: %Y.type) { +// CHECK:STDOUT: %D: %Y.type = bind_symbolic_name D, 0 [symbolic = %D (constants.%D)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @CC.%Destroy.impl_witness_table, @CC.as.Destroy.impl(%D) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.a11)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %CC.as.Destroy.impl.Op.type: type = fn_type @CC.as.Destroy.impl.Op, @CC.as.Destroy.impl(%D) [symbolic = %CC.as.Destroy.impl.Op.type (constants.%CC.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %CC.as.Destroy.impl.Op: @CC.as.Destroy.impl.%CC.as.Destroy.impl.Op.type (%CC.as.Destroy.impl.Op.type) = struct_value () [symbolic = %CC.as.Destroy.impl.Op (constants.%CC.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%CC.3ba as constants.%Destroy.type { +// CHECK:STDOUT: %CC.as.Destroy.impl.Op.decl: @CC.as.Destroy.impl.%CC.as.Destroy.impl.Op.type (%CC.as.Destroy.impl.Op.type) = fn_decl @CC.as.Destroy.impl.Op [symbolic = @CC.as.Destroy.impl.%CC.as.Destroy.impl.Op (constants.%CC.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @CC.as.Destroy.impl.Op.%pattern_type (%pattern_type.1ed) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @CC.as.Destroy.impl.Op.%pattern_type (%pattern_type.1ed) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12_17.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @CC.as.Destroy.impl.Op.%ptr (%ptr.423) = value_param call_param0 +// CHECK:STDOUT: %.loc12_17.2: type = splice_block %Self.ref [symbolic = %CC (constants.%CC.3ba)] { +// CHECK:STDOUT: %.loc12_17.3: type = specific_constant constants.%CC.3ba, @CC(constants.%D) [symbolic = %CC (constants.%CC.3ba)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc12_17.3 [symbolic = %CC (constants.%CC.3ba)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @CC.as.Destroy.impl.Op.%ptr (%ptr.423) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %CC.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @CC.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl @CC.as.Z.impl(%E.loc19_14.1: %facet_type) { // CHECK:STDOUT: %E.loc19_14.2: %facet_type = bind_symbolic_name E, 0 [symbolic = %E.loc19_14.2 (constants.%E)] // CHECK:STDOUT: %Y.lookup_impl_witness: = lookup_impl_witness %E.loc19_14.2, @Y [symbolic = %Y.lookup_impl_witness (constants.%Y.lookup_impl_witness)] @@ -204,6 +262,9 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @DD { +// CHECK:STDOUT: impl_decl @DD.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@DD.as.Destroy.impl.%DD.as.Destroy.impl.Op.decl), @DD.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.147] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -218,6 +279,9 @@ fn F() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @CC.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@CC.as.Destroy.impl.%CC.as.Destroy.impl.Op.decl), @CC.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @CC.as.Destroy.impl(constants.%D) [symbolic = @CC.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a11)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -227,6 +291,19 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @DD.as.Destroy.impl.Op(%self.param: %ptr.3d1) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @CC.as.Destroy.impl.Op(@CC.%D.loc12_10.2: %Y.type) { +// CHECK:STDOUT: %D: %Y.type = bind_symbolic_name D, 0 [symbolic = %D (constants.%D)] +// CHECK:STDOUT: %CC: type = class_type @CC, @CC(%D) [symbolic = %CC (constants.%CC.3ba)] +// CHECK:STDOUT: %ptr: type = ptr_type %CC [symbolic = %ptr (constants.%ptr.423)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1ed)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @CC.as.Destroy.impl.Op.%ptr (%ptr.423)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %CC.ref: %CC.type = name_ref CC, file.%CC.decl [concrete = constants.%CC.generic] @@ -246,6 +323,18 @@ fn F() { // CHECK:STDOUT: %D.loc12_10.1 => constants.%D // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @CC.as.Destroy.impl(constants.%D) { +// CHECK:STDOUT: %D => constants.%D +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a11 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CC.as.Destroy.impl.Op(constants.%D) { +// CHECK:STDOUT: %D => constants.%D +// CHECK:STDOUT: %CC => constants.%CC.3ba +// CHECK:STDOUT: %ptr => constants.%ptr.423 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1ed +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @CC(constants.%Y.facet.7ec) { // CHECK:STDOUT: %D.loc12_10.1 => constants.%Y.facet.7ec // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/function/generic/param_in_type.carbon b/toolchain/check/testdata/function/generic/param_in_type.carbon index 130a3d2039e5..d2423b2d45a8 100644 --- a/toolchain/check/testdata/function/generic/param_in_type.carbon +++ b/toolchain/check/testdata/function/generic/param_in_type.carbon @@ -40,8 +40,8 @@ fn F(N:! i32, a: array(i32, N)*); // CHECK:STDOUT: %bound_method: = bound_method %N.51e, %Int.as.ImplicitAs.impl.Convert.specific_fn [symbolic] // CHECK:STDOUT: %Int.as.ImplicitAs.impl.Convert.call: init Core.IntLiteral = call %bound_method(%N.51e) [symbolic] // CHECK:STDOUT: %array_type: type = array_type %Int.as.ImplicitAs.impl.Convert.call, %i32 [symbolic] -// CHECK:STDOUT: %ptr: type = ptr_type %array_type [symbolic] -// CHECK:STDOUT: %pattern_type.c7e: type = pattern_type %ptr [symbolic] +// CHECK:STDOUT: %ptr.0ad: type = ptr_type %array_type [symbolic] +// CHECK:STDOUT: %pattern_type.c7e: type = pattern_type %ptr.0ad [symbolic] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -75,8 +75,8 @@ fn F(N:! i32, a: array(i32, N)*); // CHECK:STDOUT: %i32.loc15_10: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } // CHECK:STDOUT: %N.loc15_6.2: %i32 = bind_symbolic_name N, 0 [symbolic = %N.loc15_6.1 (constants.%N.51e)] -// CHECK:STDOUT: %a.param: @F.%ptr.loc15_31.1 (%ptr) = value_param call_param0 -// CHECK:STDOUT: %.loc15_31: type = splice_block %ptr.loc15_31.2 [symbolic = %ptr.loc15_31.1 (constants.%ptr)] { +// CHECK:STDOUT: %a.param: @F.%ptr.loc15_31.1 (%ptr.0ad) = value_param call_param0 +// CHECK:STDOUT: %.loc15_31: type = splice_block %ptr.loc15_31.2 [symbolic = %ptr.loc15_31.1 (constants.%ptr.0ad)] { // CHECK:STDOUT: %int_32.loc15_24: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc15_24: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %N.ref: %i32 = name_ref N, %N.loc15_6.2 [symbolic = %N.loc15_6.1 (constants.%N.51e)] @@ -88,9 +88,9 @@ fn F(N:! i32, a: array(i32, N)*); // CHECK:STDOUT: %.loc15_29.1: Core.IntLiteral = value_of_initializer %Int.as.ImplicitAs.impl.Convert.call.loc15_29.2 [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc15_29.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)] // CHECK:STDOUT: %.loc15_29.2: Core.IntLiteral = converted %N.ref, %.loc15_29.1 [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc15_29.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)] // CHECK:STDOUT: %array_type.loc15_30.2: type = array_type %.loc15_29.2, %i32.loc15_24 [symbolic = %array_type.loc15_30.1 (constants.%array_type)] -// CHECK:STDOUT: %ptr.loc15_31.2: type = ptr_type %array_type.loc15_30.2 [symbolic = %ptr.loc15_31.1 (constants.%ptr)] +// CHECK:STDOUT: %ptr.loc15_31.2: type = ptr_type %array_type.loc15_30.2 [symbolic = %ptr.loc15_31.1 (constants.%ptr.0ad)] // CHECK:STDOUT: } -// CHECK:STDOUT: %a: @F.%ptr.loc15_31.1 (%ptr) = bind_name a, %a.param +// CHECK:STDOUT: %a: @F.%ptr.loc15_31.1 (%ptr.0ad) = bind_name a, %a.param // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -100,10 +100,10 @@ fn F(N:! i32, a: array(i32, N)*); // CHECK:STDOUT: %bound_method.loc15_29.1: = bound_method %N.loc15_6.1, constants.%Int.as.ImplicitAs.impl.Convert.specific_fn [symbolic = %bound_method.loc15_29.1 (constants.%bound_method)] // CHECK:STDOUT: %Int.as.ImplicitAs.impl.Convert.call.loc15_29.1: init Core.IntLiteral = call %bound_method.loc15_29.1(%N.loc15_6.1) [symbolic = %Int.as.ImplicitAs.impl.Convert.call.loc15_29.1 (constants.%Int.as.ImplicitAs.impl.Convert.call)] // CHECK:STDOUT: %array_type.loc15_30.1: type = array_type %Int.as.ImplicitAs.impl.Convert.call.loc15_29.1, constants.%i32 [symbolic = %array_type.loc15_30.1 (constants.%array_type)] -// CHECK:STDOUT: %ptr.loc15_31.1: type = ptr_type %array_type.loc15_30.1 [symbolic = %ptr.loc15_31.1 (constants.%ptr)] +// CHECK:STDOUT: %ptr.loc15_31.1: type = ptr_type %array_type.loc15_30.1 [symbolic = %ptr.loc15_31.1 (constants.%ptr.0ad)] // CHECK:STDOUT: %pattern_type: type = pattern_type %ptr.loc15_31.1 [symbolic = %pattern_type (constants.%pattern_type.c7e)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%a.param: @F.%ptr.loc15_31.1 (%ptr)); +// CHECK:STDOUT: fn(%a.param: @F.%ptr.loc15_31.1 (%ptr.0ad)); // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%N.51e) { @@ -112,7 +112,7 @@ fn F(N:! i32, a: array(i32, N)*); // CHECK:STDOUT: %bound_method.loc15_29.1 => constants.%bound_method // CHECK:STDOUT: %Int.as.ImplicitAs.impl.Convert.call.loc15_29.1 => constants.%Int.as.ImplicitAs.impl.Convert.call // CHECK:STDOUT: %array_type.loc15_30.1 => constants.%array_type -// CHECK:STDOUT: %ptr.loc15_31.1 => constants.%ptr +// CHECK:STDOUT: %ptr.loc15_31.1 => constants.%ptr.0ad // CHECK:STDOUT: %pattern_type => constants.%pattern_type.c7e // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/function/generic/resolve_used.carbon b/toolchain/check/testdata/function/generic/resolve_used.carbon index ef68178ae25c..129483f2a2ab 100644 --- a/toolchain/check/testdata/function/generic/resolve_used.carbon +++ b/toolchain/check/testdata/function/generic/resolve_used.carbon @@ -55,16 +55,14 @@ fn CallNegative() { // CHECK:STDOUT: %pattern_type.8963eb.1: type = pattern_type %Int.49d0e6.1 [symbolic] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] -// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.bc9: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%T) [symbolic] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.46f: %T.as.Destroy.impl.Op.type.bc9 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.543: = impl_witness imports.%Destroy.impl_witness_table.72b, @Int.as.Destroy.impl(%N) [symbolic] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.type.733: type = fn_type @Int.as.Destroy.impl.Op, @Int.as.Destroy.impl(%N) [symbolic] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.011: %Int.as.Destroy.impl.Op.type.733 = struct_value () [symbolic] // CHECK:STDOUT: %ptr.784: type = ptr_type %Int.49d0e6.1 [symbolic] +// CHECK:STDOUT: %Destroy.facet.abb: %Destroy.type = facet_value %Int.49d0e6.1, (%Destroy.impl_witness.543) [symbolic] +// CHECK:STDOUT: %.94a: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.abb [symbolic] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.specific_fn.1f5: = specific_function %Int.as.Destroy.impl.Op.011, @Int.as.Destroy.impl.Op(%N) [symbolic] // CHECK:STDOUT: %require_complete.0f5: = require_complete_type %ptr.784 [symbolic] -// CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %Int.49d0e6.1, @Destroy [symbolic] -// CHECK:STDOUT: %Destroy.facet.13d: %Destroy.type = facet_value %Int.49d0e6.1, (%Destroy.lookup_impl_witness) [symbolic] -// CHECK:STDOUT: %.bbc: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.13d [symbolic] -// CHECK:STDOUT: %impl.elem0.fe8: %.bbc = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic] -// CHECK:STDOUT: %specific_impl_fn: = specific_impl_function %impl.elem0.fe8, @Destroy.Op(%Destroy.facet.13d) [symbolic] // CHECK:STDOUT: %CallNegative.type: type = fn_type @CallNegative [concrete] // CHECK:STDOUT: %CallNegative: %CallNegative.type = struct_value () [concrete] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete] @@ -72,14 +70,14 @@ fn CallNegative() { // CHECK:STDOUT: %i0: type = class_type @Int, @Int(%int_0) [concrete] // CHECK:STDOUT: %complete_type.d94: = complete_type_witness [concrete] // CHECK:STDOUT: %pattern_type.47b: type = pattern_type %i0 [concrete] -// CHECK:STDOUT: %Destroy.impl_witness.404: = impl_witness imports.%Destroy.impl_witness_table, @T.as.Destroy.impl(%i0) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.1c2: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i0) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.912: %T.as.Destroy.impl.Op.type.1c2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.951: = impl_witness imports.%Destroy.impl_witness_table.72b, @Int.as.Destroy.impl(%int_0) [concrete] +// CHECK:STDOUT: %Destroy.facet.4e0: %Destroy.type = facet_value %i0, (%Destroy.impl_witness.951) [concrete] +// CHECK:STDOUT: %.53d: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.4e0 [concrete] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.type.be2: type = fn_type @Int.as.Destroy.impl.Op, @Int.as.Destroy.impl(%int_0) [concrete] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.a22: %Int.as.Destroy.impl.Op.type.be2 = struct_value () [concrete] // CHECK:STDOUT: %ptr.3f1: type = ptr_type %i0 [concrete] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.specific_fn.f1a: = specific_function %Int.as.Destroy.impl.Op.a22, @Int.as.Destroy.impl.Op(%int_0) [concrete] // CHECK:STDOUT: %complete_type.588: = complete_type_witness %ptr.3f1 [concrete] -// CHECK:STDOUT: %Destroy.facet.973: %Destroy.type = facet_value %i0, (%Destroy.impl_witness.404) [concrete] -// CHECK:STDOUT: %.9ab: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.973 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.912, @T.as.Destroy.impl.Op(%i0) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -93,8 +91,8 @@ fn CallNegative() { // CHECK:STDOUT: %Core.IntLiteral: %IntLiteral.type = import_ref Core//prelude/parts/int_literal, IntLiteral, loaded [concrete = constants.%IntLiteral] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] -// CHECK:STDOUT: %Core.import_ref.0b9: @T.as.Destroy.impl.%T.as.Destroy.impl.Op.type (%T.as.Destroy.impl.Op.type.bc9) = import_ref Core//prelude/parts/destroy, loc8_29, loaded [symbolic = @T.as.Destroy.impl.%T.as.Destroy.impl.Op (constants.%T.as.Destroy.impl.Op.46f)] -// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (%Core.import_ref.0b9), @T.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Core.import_ref.f64: @Int.as.Destroy.impl.%Int.as.Destroy.impl.Op.type (%Int.as.Destroy.impl.Op.type.733) = import_ref Core//prelude/parts/int, loc9_29, loaded [symbolic = @Int.as.Destroy.impl.%Int.as.Destroy.impl.Op (constants.%Int.as.Destroy.impl.Op.011)] +// CHECK:STDOUT: %Destroy.impl_witness_table.72b = impl_witness_table (%Core.import_ref.f64), @Int.as.Destroy.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -126,11 +124,12 @@ fn CallNegative() { // CHECK:STDOUT: %Int.loc12_20.2: type = class_type @Int, @Int(%N.loc4_19.1) [symbolic = %Int.loc12_20.2 (constants.%Int.49d0e6.1)] // CHECK:STDOUT: %require_complete.loc12_20: = require_complete_type %Int.loc12_20.2 [symbolic = %require_complete.loc12_20 (constants.%require_complete.b4f426.1)] // CHECK:STDOUT: %pattern_type: type = pattern_type %Int.loc12_20.2 [symbolic = %pattern_type (constants.%pattern_type.8963eb.1)] -// CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %Int.loc12_20.2, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)] -// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %Int.loc12_20.2, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet.13d)] -// CHECK:STDOUT: %.loc12_3.2: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [symbolic = %.loc12_3.2 (constants.%.bbc)] -// CHECK:STDOUT: %impl.elem0.loc12_3.2: @ErrorIfNIsZero.%.loc12_3.2 (%.bbc) = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc12_3.2 (constants.%impl.elem0.fe8)] -// CHECK:STDOUT: %specific_impl_fn.loc12_3.2: = specific_impl_function %impl.elem0.loc12_3.2, @Destroy.Op(%Destroy.facet) [symbolic = %specific_impl_fn.loc12_3.2 (constants.%specific_impl_fn)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.72b, @Int.as.Destroy.impl(%N.loc4_19.1) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.543)] +// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %Int.loc12_20.2, (%Destroy.impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet.abb)] +// CHECK:STDOUT: %.loc12_3: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [symbolic = %.loc12_3 (constants.%.94a)] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.type: type = fn_type @Int.as.Destroy.impl.Op, @Int.as.Destroy.impl(%N.loc4_19.1) [symbolic = %Int.as.Destroy.impl.Op.type (constants.%Int.as.Destroy.impl.Op.type.733)] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op: @ErrorIfNIsZero.%Int.as.Destroy.impl.Op.type (%Int.as.Destroy.impl.Op.type.733) = struct_value () [symbolic = %Int.as.Destroy.impl.Op (constants.%Int.as.Destroy.impl.Op.011)] +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.specific_fn: = specific_function %Int.as.Destroy.impl.Op, @Int.as.Destroy.impl.Op(%N.loc4_19.1) [symbolic = %Int.as.Destroy.impl.Op.specific_fn (constants.%Int.as.Destroy.impl.Op.specific_fn.1f5)] // CHECK:STDOUT: %ptr: type = ptr_type %Int.loc12_20.2 [symbolic = %ptr (constants.%ptr.784)] // CHECK:STDOUT: %require_complete.loc12_3: = require_complete_type %ptr [symbolic = %require_complete.loc12_3 (constants.%require_complete.0f5)] // CHECK:STDOUT: @@ -148,12 +147,12 @@ fn CallNegative() { // CHECK:STDOUT: %Int.loc12_20.1: type = class_type @Int, @Int(constants.%N) [symbolic = %Int.loc12_20.2 (constants.%Int.49d0e6.1)] // CHECK:STDOUT: } // CHECK:STDOUT: %v: ref @ErrorIfNIsZero.%Int.loc12_20.2 (%Int.49d0e6.1) = bind_name v, %v.var -// CHECK:STDOUT: %impl.elem0.loc12_3.1: @ErrorIfNIsZero.%.loc12_3.2 (%.bbc) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc12_3.2 (constants.%impl.elem0.fe8)] -// CHECK:STDOUT: %bound_method.loc12_3.1: = bound_method %v.var, %impl.elem0.loc12_3.1 -// CHECK:STDOUT: %specific_impl_fn.loc12_3.1: = specific_impl_function %impl.elem0.loc12_3.1, @Destroy.Op(constants.%Destroy.facet.13d) [symbolic = %specific_impl_fn.loc12_3.2 (constants.%specific_impl_fn)] -// CHECK:STDOUT: %bound_method.loc12_3.2: = bound_method %v.var, %specific_impl_fn.loc12_3.1 +// CHECK:STDOUT: %impl.elem0: @ErrorIfNIsZero.%.loc12_3 (%.94a) = impl_witness_access constants.%Destroy.impl_witness.543, element0 [symbolic = %Int.as.Destroy.impl.Op (constants.%Int.as.Destroy.impl.Op.011)] +// CHECK:STDOUT: %bound_method.loc12_3.1: = bound_method %v.var, %impl.elem0 +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Int.as.Destroy.impl.Op(constants.%N) [symbolic = %Int.as.Destroy.impl.Op.specific_fn (constants.%Int.as.Destroy.impl.Op.specific_fn.1f5)] +// CHECK:STDOUT: %bound_method.loc12_3.2: = bound_method %v.var, %specific_fn // CHECK:STDOUT: %addr: @ErrorIfNIsZero.%ptr (%ptr.784) = addr_of %v.var -// CHECK:STDOUT: %.loc12_3.1: init %empty_tuple.type = call %bound_method.loc12_3.2(%addr) +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc12_3.2(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -178,11 +177,12 @@ fn CallNegative() { // CHECK:STDOUT: %Int.loc12_20.2 => constants.%i0 // CHECK:STDOUT: %require_complete.loc12_20 => constants.%complete_type.d94 // CHECK:STDOUT: %pattern_type => constants.%pattern_type.47b -// CHECK:STDOUT: %Destroy.lookup_impl_witness => constants.%Destroy.impl_witness.404 -// CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.973 -// CHECK:STDOUT: %.loc12_3.2 => constants.%.9ab -// CHECK:STDOUT: %impl.elem0.loc12_3.2 => constants.%T.as.Destroy.impl.Op.912 -// CHECK:STDOUT: %specific_impl_fn.loc12_3.2 => constants.%T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.951 +// CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.4e0 +// CHECK:STDOUT: %.loc12_3 => constants.%.53d +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.type => constants.%Int.as.Destroy.impl.Op.type.be2 +// CHECK:STDOUT: %Int.as.Destroy.impl.Op => constants.%Int.as.Destroy.impl.Op.a22 +// CHECK:STDOUT: %Int.as.Destroy.impl.Op.specific_fn => constants.%Int.as.Destroy.impl.Op.specific_fn.f1a // CHECK:STDOUT: %ptr => constants.%ptr.3f1 // CHECK:STDOUT: %require_complete.loc12_3 => constants.%complete_type.588 // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/function/generic/return_slot.carbon b/toolchain/check/testdata/function/generic/return_slot.carbon index adb133f22a8f..7225b0c93252 100644 --- a/toolchain/check/testdata/function/generic/return_slot.carbon +++ b/toolchain/check/testdata/function/generic/return_slot.carbon @@ -36,6 +36,13 @@ fn G() { // CHECK:STDOUT: %pattern_type.7dcd0a.1: type = pattern_type %T [symbolic] // CHECK:STDOUT: %Wrap.Make.type.652: type = fn_type @Wrap.Make, @Wrap(%T) [symbolic] // CHECK:STDOUT: %Wrap.Make.eb2: %Wrap.Make.type.652 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.c6a: = impl_witness @Wrap.%Destroy.impl_witness_table, @Wrap.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.b45: type = ptr_type %Wrap.af6 [symbolic] +// CHECK:STDOUT: %pattern_type.3b2: type = pattern_type %ptr.b45 [symbolic] +// CHECK:STDOUT: %Wrap.as.Destroy.impl.Op.type: type = fn_type @Wrap.as.Destroy.impl.Op, @Wrap.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Wrap.as.Destroy.impl.Op: %Wrap.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] @@ -50,6 +57,11 @@ fn G() { // CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete] // CHECK:STDOUT: %complete_type.f8a: = complete_type_witness %i32.builtin [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %array_type [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.arr.5f2: type = struct_type {.arr: %array_type} [concrete] // CHECK:STDOUT: %complete_type.22a: = complete_type_witness %struct_type.arr.5f2 [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] @@ -69,11 +81,6 @@ fn G() { // CHECK:STDOUT: %Wrap.Make.type.708: type = fn_type @Wrap.Make, @Wrap(%C) [concrete] // CHECK:STDOUT: %Wrap.Make.e4b: %Wrap.Make.type.708 = struct_value () [concrete] // CHECK:STDOUT: %Wrap.Make.specific_fn.834: = specific_function %Wrap.Make.e4b, @Wrap.Make(%C) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.6eb: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a63: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%empty_tuple.type) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.ea3: %T.as.Destroy.impl.Op.type.a63 = struct_value () [concrete] // CHECK:STDOUT: %ptr.843: type = ptr_type %empty_tuple.type [concrete] @@ -87,13 +94,13 @@ fn G() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { -// CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -113,6 +120,50 @@ fn G() { // CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Wrap.as.Destroy.impl(@Wrap.%T.loc15_12.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Wrap.%Destroy.impl_witness_table, @Wrap.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.c6a)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Wrap.as.Destroy.impl.Op.type: type = fn_type @Wrap.as.Destroy.impl.Op, @Wrap.as.Destroy.impl(%T) [symbolic = %Wrap.as.Destroy.impl.Op.type (constants.%Wrap.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Wrap.as.Destroy.impl.Op: @Wrap.as.Destroy.impl.%Wrap.as.Destroy.impl.Op.type (%Wrap.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Wrap.as.Destroy.impl.Op (constants.%Wrap.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Wrap.af6 as constants.%Destroy.type { +// CHECK:STDOUT: %Wrap.as.Destroy.impl.Op.decl: @Wrap.as.Destroy.impl.%Wrap.as.Destroy.impl.Op.type (%Wrap.as.Destroy.impl.Op.type) = fn_decl @Wrap.as.Destroy.impl.Op [symbolic = @Wrap.as.Destroy.impl.%Wrap.as.Destroy.impl.Op (constants.%Wrap.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Wrap.as.Destroy.impl.Op.%pattern_type (%pattern_type.3b2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Wrap.as.Destroy.impl.Op.%pattern_type (%pattern_type.3b2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15_22.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Wrap.as.Destroy.impl.Op.%ptr (%ptr.b45) = value_param call_param0 +// CHECK:STDOUT: %.loc15_22.2: type = splice_block %Self.ref [symbolic = %Wrap (constants.%Wrap.af6)] { +// CHECK:STDOUT: %.loc15_22.3: type = specific_constant constants.%Wrap.af6, @Wrap(constants.%T) [symbolic = %Wrap (constants.%Wrap.af6)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc15_22.3 [symbolic = %Wrap (constants.%Wrap.af6)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Wrap.as.Destroy.impl.Op.%ptr (%ptr.b45) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Wrap.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Wrap.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc19: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Wrap(%T.loc15_12.2: type) { // CHECK:STDOUT: %T.loc15_12.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc15_12.1 (constants.%T)] // CHECK:STDOUT: @@ -129,6 +180,9 @@ fn G() { // CHECK:STDOUT: %return.param: ref @Wrap.Make.%T (%T) = out_param call_param0 // CHECK:STDOUT: %return: ref @Wrap.Make.%T (%T) = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Wrap.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Wrap.as.Destroy.impl.%Wrap.as.Destroy.impl.Op.decl), @Wrap.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Wrap.as.Destroy.impl(constants.%T) [symbolic = @Wrap.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.c6a)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -146,6 +200,9 @@ fn G() { // CHECK:STDOUT: %int_100: Core.IntLiteral = int_value 100 [concrete = constants.%int_100] // CHECK:STDOUT: %array_type: type = array_type %int_100, %i32 [concrete = constants.%array_type] // CHECK:STDOUT: %.loc19: %C.elem = field_decl arr, element0 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %struct_type.arr: type = struct_type {.arr: %array_type} [concrete = constants.%struct_type.arr.5f2] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.arr [concrete = constants.%complete_type.22a] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -177,6 +234,19 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Wrap.as.Destroy.impl.Op(@Wrap.%T.loc15_12.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Wrap: type = class_type @Wrap, @Wrap(%T) [symbolic = %Wrap (constants.%Wrap.af6)] +// CHECK:STDOUT: %ptr: type = ptr_type %Wrap [symbolic = %ptr (constants.%ptr.b45)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.3b2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Wrap.as.Destroy.impl.Op.%ptr (%ptr.b45)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @G() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -233,24 +303,20 @@ fn G() { // CHECK:STDOUT: assign %c.var, %Wrap.Make.call.loc24 // CHECK:STDOUT: %C.ref.loc24_10: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %c: ref %C = bind_name c, %c.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc24_3.1: = bound_method %.loc24_3, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6eb] -// CHECK:STDOUT: %bound_method.loc24_3.1: = bound_method %.loc24_3, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound.loc24_3.1: = bound_method %.loc24_3, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc24_3.1: %ptr.019 = addr_of %.loc24_3 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc24_3.1: init %empty_tuple.type = call %bound_method.loc24_3.1(%addr.loc24_3.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc24_3.2: = bound_method %c.var, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6eb] -// CHECK:STDOUT: %bound_method.loc24_3.2: = bound_method %c.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call.loc24_3.1: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound.loc24_3.1(%addr.loc24_3.1) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound.loc24_3.2: = bound_method %c.var, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc24_3.2: %ptr.019 = addr_of %c.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc24_3.2: init %empty_tuple.type = call %bound_method.loc24_3.2(%addr.loc24_3.2) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call.loc24_3.2: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound.loc24_3.2(%addr.loc24_3.2) // CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc23: = bound_method %b.var, constants.%T.as.Destroy.impl.Op.ea3 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.ea3, @T.as.Destroy.impl.Op(constants.%empty_tuple.type) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.393] -// CHECK:STDOUT: %bound_method.loc23: = bound_method %b.var, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.ea3, @T.as.Destroy.impl.Op(constants.%empty_tuple.type) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.393] +// CHECK:STDOUT: %bound_method.loc23: = bound_method %b.var, %T.as.Destroy.impl.Op.specific_fn.1 // CHECK:STDOUT: %addr.loc23: %ptr.843 = addr_of %b.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc23: init %empty_tuple.type = call %bound_method.loc23(%addr.loc23) // CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc22: = bound_method %a.var, constants.%T.as.Destroy.impl.Op.e6a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.4: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.014] -// CHECK:STDOUT: %bound_method.loc22: = bound_method %a.var, %T.as.Destroy.impl.Op.specific_fn.4 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.014] +// CHECK:STDOUT: %bound_method.loc22: = bound_method %a.var, %T.as.Destroy.impl.Op.specific_fn.2 // CHECK:STDOUT: %addr.loc22: %ptr.235 = addr_of %a.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc22: init %empty_tuple.type = call %bound_method.loc22(%addr.loc22) // CHECK:STDOUT: return @@ -275,6 +341,18 @@ fn G() { // CHECK:STDOUT: %Wrap.Make.specific_fn.loc16_27.2 => constants.%Wrap.Make.specific_fn.bf1 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Wrap.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.c6a +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Wrap.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Wrap => constants.%Wrap.af6 +// CHECK:STDOUT: %ptr => constants.%ptr.b45 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.3b2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Wrap(constants.%i32) { // CHECK:STDOUT: %T.loc15_12.1 => constants.%i32 // CHECK:STDOUT: diff --git a/toolchain/check/testdata/generic/call_basic_depth.carbon b/toolchain/check/testdata/generic/call_basic_depth.carbon index c11b5a94af04..ab13005d2f18 100644 --- a/toolchain/check/testdata/generic/call_basic_depth.carbon +++ b/toolchain/check/testdata/generic/call_basic_depth.carbon @@ -54,6 +54,13 @@ fn M() { // CHECK:STDOUT: %C.Cfn.type: type = fn_type @C.Cfn [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %C.Cfn: %C.Cfn.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] @@ -66,11 +73,6 @@ fn M() { // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %H.specific_fn.1ed: = specific_function %H, @H(%T) [symbolic] // CHECK:STDOUT: %C.Cfn.specific_fn.53f: = specific_function %C.Cfn, @C.Cfn(%T) [symbolic] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.6eb: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: %M.type: type = fn_type @M [concrete] // CHECK:STDOUT: %M: %M.type = struct_value () [concrete] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] @@ -102,7 +104,7 @@ fn M() { // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.014: = specific_function %T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(%i32) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(%i32) [concrete] // CHECK:STDOUT: %H.specific_fn.aac: = specific_function %H, @H(%i32) [concrete] // CHECK:STDOUT: %C.Cfn.specific_fn.7b2: = specific_function %C.Cfn, @C.Cfn(%i32) [concrete] // CHECK:STDOUT: } @@ -176,6 +178,22 @@ fn M() { // CHECK:STDOUT: %M.decl: %M.type = fn_decl @M [concrete = constants.%M] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %C.Cfn.decl: %C.Cfn.type = fn_decl @C.Cfn [concrete = constants.%C.Cfn] { // CHECK:STDOUT: %self.patt: %pattern_type.c48 = binding_pattern self [concrete] @@ -192,6 +210,9 @@ fn M() { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc16_22.2 [symbolic = %T.loc16_22.1 (constants.%T)] // CHECK:STDOUT: %x: @C.Cfn.%T.loc16_22.1 (%T) = bind_name x, %x.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -214,6 +235,8 @@ fn M() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc20_6.2: type) { // CHECK:STDOUT: %T.loc20_6.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc20_6.1 (constants.%T)] // CHECK:STDOUT: %pattern_type: type = pattern_type %T.loc20_6.1 [symbolic = %pattern_type (constants.%pattern_type.7dcd0a.1)] @@ -278,15 +301,13 @@ fn M() { // CHECK:STDOUT: %C.Cfn.bound: = bound_method %c.ref, %Cfn.ref // CHECK:STDOUT: %x.ref.loc34: @G.%T.loc29_6.1 (%T) = name_ref x, %x // CHECK:STDOUT: %C.Cfn.specific_fn.loc34_4.1: = specific_function %Cfn.ref, @C.Cfn(constants.%T) [symbolic = %C.Cfn.specific_fn.loc34_4.2 (constants.%C.Cfn.specific_fn.53f)] -// CHECK:STDOUT: %bound_method.loc34: = bound_method %c.ref, %C.Cfn.specific_fn.loc34_4.1 +// CHECK:STDOUT: %bound_method: = bound_method %c.ref, %C.Cfn.specific_fn.loc34_4.1 // CHECK:STDOUT: %.loc34: %C = bind_value %c.ref -// CHECK:STDOUT: %C.Cfn.call: init %empty_tuple.type = call %bound_method.loc34(%.loc34, %x.ref.loc34) +// CHECK:STDOUT: %C.Cfn.call: init %empty_tuple.type = call %bound_method(%.loc34, %x.ref.loc34) // CHECK:STDOUT: %x.ref.loc35: @G.%T.loc29_6.1 (%T) = name_ref x, %x -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6eb] -// CHECK:STDOUT: %bound_method.loc33: = bound_method %c.var, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.019 = addr_of %c.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc33(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %x.ref.loc35 // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -334,12 +355,12 @@ fn M() { // CHECK:STDOUT: %G.call: init %i32 = call %G.specific_fn(%.loc43) // CHECK:STDOUT: assign %m.ref, %G.call // CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc40: = bound_method %m.var, constants.%T.as.Destroy.impl.Op.e6a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.014] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method.loc40: = bound_method %m.var, %T.as.Destroy.impl.Op.specific_fn.1 // CHECK:STDOUT: %addr.loc40: %ptr.235 = addr_of %m.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc40: init %empty_tuple.type = call %bound_method.loc40(%addr.loc40) // CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc39: = bound_method %n.var, constants.%T.as.Destroy.impl.Op.e6a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.014] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method.loc39_3.3: = bound_method %n.var, %T.as.Destroy.impl.Op.specific_fn.2 // CHECK:STDOUT: %addr.loc39: %ptr.235 = addr_of %n.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc39: init %empty_tuple.type = call %bound_method.loc39_3.3(%addr.loc39) diff --git a/toolchain/check/testdata/generic/complete_type.carbon b/toolchain/check/testdata/generic/complete_type.carbon index 18607ea4c3c5..907ab9258b9c 100644 --- a/toolchain/check/testdata/generic/complete_type.carbon +++ b/toolchain/check/testdata/generic/complete_type.carbon @@ -91,6 +91,13 @@ fn G() { F(B); } // CHECK:STDOUT: %A.130: type = class_type @A, @A(%T) [symbolic] // CHECK:STDOUT: %require_complete: = require_complete_type %T [symbolic] // CHECK:STDOUT: %A.elem.1ce: type = unbound_element_type %A.130, %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d93: = impl_witness @A.%Destroy.impl_witness_table, @A.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.ca9: type = ptr_type %A.130 [symbolic] +// CHECK:STDOUT: %pattern_type.09b: type = pattern_type %ptr.ca9 [symbolic] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op, @A.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.v.ff1: type = struct_type {.v: %T} [symbolic] // CHECK:STDOUT: %complete_type.460: = complete_type_witness %struct_type.v.ff1 [symbolic] // CHECK:STDOUT: %A.1d4: type = class_type @A, @A(%B) [concrete] @@ -100,15 +107,22 @@ fn G() { F(B); } // CHECK:STDOUT: %A.elem.4ce: type = unbound_element_type %A.1d4, %B [concrete] // CHECK:STDOUT: %struct_type.v.d45: type = struct_type {.v: %B} [concrete] // CHECK:STDOUT: %complete_type.1df: = complete_type_witness %struct_type.v.d45 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -140,7 +154,54 @@ fn G() { F(B); } // CHECK:STDOUT: %B.decl.loc29: type = class_decl @B [concrete = constants.%B] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @A.as.Destroy.impl(@A.%T.loc6_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @A.%Destroy.impl_witness_table, @A.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.d93)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op, @A.as.Destroy.impl(%T) [symbolic = %A.as.Destroy.impl.Op.type (constants.%A.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: @A.as.Destroy.impl.%A.as.Destroy.impl.Op.type (%A.as.Destroy.impl.Op.type) = struct_value () [symbolic = %A.as.Destroy.impl.Op (constants.%A.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%A.130 as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: @A.as.Destroy.impl.%A.as.Destroy.impl.Op.type (%A.as.Destroy.impl.Op.type) = fn_decl @A.as.Destroy.impl.Op [symbolic = @A.as.Destroy.impl.%A.as.Destroy.impl.Op (constants.%A.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @A.as.Destroy.impl.Op.%pattern_type (%pattern_type.09b) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @A.as.Destroy.impl.Op.%pattern_type (%pattern_type.09b) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @A.as.Destroy.impl.Op.%ptr (%ptr.ca9) = value_param call_param0 +// CHECK:STDOUT: %.loc6_19.2: type = splice_block %Self.ref [symbolic = %A (constants.%A.130)] { +// CHECK:STDOUT: %.loc6_19.3: type = specific_constant constants.%A.130, @A(constants.%T) [symbolic = %A (constants.%A.130)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc6_19.3 [symbolic = %A (constants.%A.130)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @A.as.Destroy.impl.Op.%ptr (%ptr.ca9) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc29: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @B { +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -162,6 +223,9 @@ fn G() { F(B); } // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc6_9.2 [symbolic = %T.loc6_9.1 (constants.%T)] // CHECK:STDOUT: %.loc13: @A.%A.elem (%A.elem.1ce) = field_decl v, element0 [concrete] +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @A.as.Destroy.impl(constants.%T) [symbolic = @A.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.d93)] // CHECK:STDOUT: %struct_type.v.loc14_1.1: type = struct_type {.v: %T} [symbolic = %struct_type.v.loc14_1.2 (constants.%struct_type.v.ff1)] // CHECK:STDOUT: %complete_type.loc14_1.1: = complete_type_witness %struct_type.v.loc14_1.1 [symbolic = %complete_type.loc14_1.2 (constants.%complete_type.460)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc14_1.1 @@ -173,15 +237,40 @@ fn G() { F(B); } // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @A.as.Destroy.impl.Op(@A.%T.loc6_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %A: type = class_type @A, @A(%T) [symbolic = %A (constants.%A.130)] +// CHECK:STDOUT: %ptr: type = ptr_type %A [symbolic = %ptr (constants.%ptr.ca9)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.09b)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @A.as.Destroy.impl.Op.%ptr (%ptr.ca9)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%x.param: %A.1d4) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @A(constants.%T) { // CHECK:STDOUT: %T.loc6_9.1 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @A.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.d93 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %A => constants.%A.130 +// CHECK:STDOUT: %ptr => constants.%ptr.ca9 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.09b +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @A(constants.%B) { // CHECK:STDOUT: %T.loc6_9.1 => constants.%B // CHECK:STDOUT: @@ -206,8 +295,7 @@ fn G() { F(B); } // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.bc9: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%T) [symbolic] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.46f: %T.as.Destroy.impl.Op.type.bc9 = struct_value () [symbolic] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %ptr.79f: type = ptr_type %T [symbolic] // CHECK:STDOUT: %require_complete.6e5: = require_complete_type %ptr.79f [symbolic] // CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %T, @Destroy [symbolic] @@ -218,17 +306,17 @@ fn G() { F(B); } // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%B) [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.facet.d69: %Destroy.type = facet_value %B, (%Destroy.impl_witness.40d) [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.049: type = pattern_type %B [concrete] -// CHECK:STDOUT: %Destroy.impl_witness.39d: = impl_witness imports.%Destroy.impl_witness_table, @T.as.Destroy.impl(%B) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.1a6: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%B) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.3c2: %T.as.Destroy.impl.Op.type.1a6 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %.1d8: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.d69 [concrete] // CHECK:STDOUT: %complete_type.3bf: = complete_type_witness %ptr.e79 [concrete] -// CHECK:STDOUT: %Destroy.facet.331: %Destroy.type = facet_value %B, (%Destroy.impl_witness.39d) [concrete] -// CHECK:STDOUT: %.c16: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.331 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.3c2, @T.as.Destroy.impl.Op(%B) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -238,8 +326,6 @@ fn G() { F(B); } // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] -// CHECK:STDOUT: %Core.import_ref.0b9: @T.as.Destroy.impl.%T.as.Destroy.impl.Op.type (%T.as.Destroy.impl.Op.type.bc9) = import_ref Core//prelude/parts/destroy, loc8_29, loaded [symbolic = @T.as.Destroy.impl.%T.as.Destroy.impl.Op (constants.%T.as.Destroy.impl.Op.46f)] -// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (%Core.import_ref.0b9), @T.as.Destroy.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -260,7 +346,26 @@ fn G() { F(B); } // CHECK:STDOUT: %B.decl.loc13: type = class_decl @B [concrete = constants.%B] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc13: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @B { +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -311,6 +416,8 @@ fn G() { F(B); } // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @F(constants.%T) { // CHECK:STDOUT: %T.loc6_6.1 => constants.%T // CHECK:STDOUT: } @@ -321,11 +428,11 @@ fn G() { F(B); } // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete.loc7_10 => constants.%complete_type.357 // CHECK:STDOUT: %pattern_type => constants.%pattern_type.049 -// CHECK:STDOUT: %Destroy.lookup_impl_witness => constants.%Destroy.impl_witness.39d -// CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.331 -// CHECK:STDOUT: %.loc7_3.2 => constants.%.c16 -// CHECK:STDOUT: %impl.elem0.loc7_3.2 => constants.%T.as.Destroy.impl.Op.3c2 -// CHECK:STDOUT: %specific_impl_fn.loc7_3.2 => constants.%T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Destroy.lookup_impl_witness => constants.%Destroy.impl_witness.40d +// CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.d69 +// CHECK:STDOUT: %.loc7_3.2 => constants.%.1d8 +// CHECK:STDOUT: %impl.elem0.loc7_3.2 => constants.%B.as.Destroy.impl.Op +// CHECK:STDOUT: %specific_impl_fn.loc7_3.2 => constants.%B.as.Destroy.impl.Op // CHECK:STDOUT: %ptr => constants.%ptr.e79 // CHECK:STDOUT: %require_complete.loc7_3 => constants.%complete_type.3bf // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/generic/dependent_param.carbon b/toolchain/check/testdata/generic/dependent_param.carbon index 25842222b9e1..fd79cacc96f5 100644 --- a/toolchain/check/testdata/generic/dependent_param.carbon +++ b/toolchain/check/testdata/generic/dependent_param.carbon @@ -39,9 +39,21 @@ var n: i32 = Outer(i32).Inner(42).Get(); // CHECK:STDOUT: %Inner.879: type = class_type @Inner, @Inner(%T, %U) [symbolic] // CHECK:STDOUT: %Inner.Get.type.889: type = fn_type @Inner.Get, @Inner(%T, %U) [symbolic] // CHECK:STDOUT: %Inner.Get.118: %Inner.Get.type.889 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.8af: = impl_witness @Inner.%Destroy.impl_witness_table, @Inner.as.Destroy.impl(%T, %U) [symbolic] +// CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] +// CHECK:STDOUT: %ptr.59b: type = ptr_type %Inner.879 [symbolic] +// CHECK:STDOUT: %pattern_type.75d: type = pattern_type %ptr.59b [symbolic] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.type: type = fn_type @Inner.as.Destroy.impl.Op, @Inner.as.Destroy.impl(%T, %U) [symbolic] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op: %Inner.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.a35: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.6ff: type = ptr_type %Outer.9d6 [symbolic] +// CHECK:STDOUT: %pattern_type.07e: type = pattern_type %ptr.6ff [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: %Outer.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] @@ -77,11 +89,13 @@ var n: i32 = Outer(i32).Inner(42).Get(); // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] @@ -112,6 +126,63 @@ var n: i32 = Outer(i32).Inner(42).Get(); // CHECK:STDOUT: %n: ref %i32 = bind_name n, %n.var [concrete = %n.var] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Inner.as.Destroy.impl(@Outer.%T.loc4_13.2: type, @Inner.%U.loc5_15.2: @Inner.%T (%T)) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %U: @Inner.as.Destroy.impl.%T (%T) = bind_symbolic_name U, 1 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Inner.%Destroy.impl_witness_table, @Inner.as.Destroy.impl(%T, %U) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.8af)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.type: type = fn_type @Inner.as.Destroy.impl.Op, @Inner.as.Destroy.impl(%T, %U) [symbolic = %Inner.as.Destroy.impl.Op.type (constants.%Inner.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op: @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.type (%Inner.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Inner.as.Destroy.impl.Op (constants.%Inner.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Inner.879 as constants.%Destroy.type { +// CHECK:STDOUT: %Inner.as.Destroy.impl.Op.decl: @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.type (%Inner.as.Destroy.impl.Op.type) = fn_decl @Inner.as.Destroy.impl.Op [symbolic = @Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op (constants.%Inner.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Inner.as.Destroy.impl.Op.%pattern_type (%pattern_type.75d) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Inner.as.Destroy.impl.Op.%pattern_type (%pattern_type.75d) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5_22.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Inner.as.Destroy.impl.Op.%ptr (%ptr.59b) = value_param call_param0 +// CHECK:STDOUT: %.loc5_22.2: type = splice_block %Self.ref [symbolic = %Inner (constants.%Inner.879)] { +// CHECK:STDOUT: %.loc5_22.3: type = specific_constant constants.%Inner.879, @Inner(constants.%T, constants.%U) [symbolic = %Inner (constants.%Inner.879)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc5_22.3 [symbolic = %Inner (constants.%Inner.879)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Inner.as.Destroy.impl.Op.%ptr (%ptr.59b) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Inner.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Inner.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Outer.as.Destroy.impl(@Outer.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.a35)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%T) [symbolic = %Outer.as.Destroy.impl.Op.type (constants.%Outer.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Outer.9d6 as constants.%Destroy.type { +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.decl: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = fn_decl @Outer.as.Destroy.impl.Op [symbolic = @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.07e) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.07e) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_23.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff) = value_param call_param0 +// CHECK:STDOUT: %.loc4_23.2: type = splice_block %Self.ref [symbolic = %Outer (constants.%Outer.9d6)] { +// CHECK:STDOUT: %.loc4_23.3: type = specific_constant constants.%Outer.9d6, @Outer(constants.%T) [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_23.3 [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Outer.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Outer.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @Outer(%T.loc4_13.2: type) { // CHECK:STDOUT: %T.loc4_13.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)] // CHECK:STDOUT: @@ -126,6 +197,9 @@ var n: i32 = Outer(i32).Inner(42).Get(); // CHECK:STDOUT: %T.ref: type = name_ref T, @Outer.%T.loc4_13.2 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %U.loc5_15.2: @Inner.%T (%T) = bind_symbolic_name U, 1 [symbolic = %U.loc5_15.1 (constants.%U)] // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Outer.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.decl), @Outer.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Outer.as.Destroy.impl(constants.%T) [symbolic = @Outer.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a35)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -145,6 +219,7 @@ var n: i32 = Outer(i32).Inner(42).Get(); // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Inner.Get.type: type = fn_type @Inner.Get, @Inner(%T, %U.loc5_15.1) [symbolic = %Inner.Get.type (constants.%Inner.Get.type.889)] // CHECK:STDOUT: %Inner.Get: @Inner.%Inner.Get.type (%Inner.Get.type.889) = struct_value () [symbolic = %Inner.Get (constants.%Inner.Get.118)] +// CHECK:STDOUT: %require_complete: = require_complete_type %T [symbolic = %require_complete (constants.%require_complete.4ae)] // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: %Inner.Get.decl: @Inner.%Inner.Get.type (%Inner.Get.type.889) = fn_decl @Inner.Get [symbolic = @Inner.%Inner.Get (constants.%Inner.Get.118)] { @@ -155,6 +230,9 @@ var n: i32 = Outer(i32).Inner(42).Get(); // CHECK:STDOUT: %return.param: ref @Inner.Get.%T (%T) = out_param call_param0 // CHECK:STDOUT: %return: ref @Inner.Get.%T (%T) = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Inner.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Inner.as.Destroy.impl.%Inner.as.Destroy.impl.Op.decl), @Inner.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Inner.as.Destroy.impl(constants.%T, constants.%U) [symbolic = @Inner.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.8af)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -172,8 +250,8 @@ var n: i32 = Outer(i32).Inner(42).Get(); // CHECK:STDOUT: %pattern_type: type = pattern_type %T [symbolic = %pattern_type (constants.%pattern_type.7dcd0a.1)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete: = require_complete_type %T [symbolic = %require_complete (constants.%require_complete.4ae)] // CHECK:STDOUT: %U: @Inner.Get.%T (%T) = bind_symbolic_name U, 1 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %require_complete: = require_complete_type %T [symbolic = %require_complete (constants.%require_complete.4ae)] // CHECK:STDOUT: // CHECK:STDOUT: fn() -> @Inner.Get.%T (%T) { // CHECK:STDOUT: !entry: @@ -182,6 +260,29 @@ var n: i32 = Outer(i32).Inner(42).Get(); // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Inner.as.Destroy.impl.Op(@Outer.%T.loc4_13.2: type, @Inner.%U.loc5_15.2: @Inner.%T (%T)) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %U: @Inner.as.Destroy.impl.Op.%T (%T) = bind_symbolic_name U, 1 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Inner: type = class_type @Inner, @Inner(%T, %U) [symbolic = %Inner (constants.%Inner.879)] +// CHECK:STDOUT: %ptr: type = ptr_type %Inner [symbolic = %ptr (constants.%ptr.59b)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.75d)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Inner.as.Destroy.impl.Op.%ptr (%ptr.59b)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Outer.as.Destroy.impl.Op(@Outer.%T.loc4_13.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Outer: type = class_type @Outer, @Outer(%T) [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: %ptr: type = ptr_type %Outer [symbolic = %ptr (constants.%ptr.6ff)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.07e)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Outer.ref: %Outer.type = name_ref Outer, file.%Outer.decl [concrete = constants.%Outer.generic] @@ -223,6 +324,7 @@ var n: i32 = Outer(i32).Inner(42).Get(); // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Inner.Get.type => constants.%Inner.Get.type.889 // CHECK:STDOUT: %Inner.Get => constants.%Inner.Get.118 +// CHECK:STDOUT: %require_complete => constants.%require_complete.4ae // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @Inner.Get(constants.%T, constants.%U) { @@ -230,6 +332,32 @@ var n: i32 = Outer(i32).Inner(42).Get(); // CHECK:STDOUT: %pattern_type => constants.%pattern_type.7dcd0a.1 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Inner.as.Destroy.impl(constants.%T, constants.%U) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.8af +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Inner.as.Destroy.impl.Op(constants.%T, constants.%U) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Inner => constants.%Inner.879 +// CHECK:STDOUT: %ptr => constants.%ptr.59b +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.75d +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a35 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Outer => constants.%Outer.9d6 +// CHECK:STDOUT: %ptr => constants.%ptr.6ff +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.07e +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Outer(constants.%i32) { // CHECK:STDOUT: %T.loc4_13.1 => constants.%i32 // CHECK:STDOUT: @@ -246,6 +374,7 @@ var n: i32 = Outer(i32).Inner(42).Get(); // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Inner.Get.type => constants.%Inner.Get.type.512 // CHECK:STDOUT: %Inner.Get => constants.%Inner.Get.18c +// CHECK:STDOUT: %require_complete => constants.%complete_type.f8a // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @Inner.Get(constants.%i32, constants.%int_42.c68) { @@ -253,7 +382,7 @@ var n: i32 = Outer(i32).Inner(42).Get(); // CHECK:STDOUT: %pattern_type => constants.%pattern_type.7ce // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete => constants.%complete_type.f8a // CHECK:STDOUT: %U => constants.%int_42.c68 +// CHECK:STDOUT: %require_complete => constants.%complete_type.f8a // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/generic/local.carbon b/toolchain/check/testdata/generic/local.carbon index 904cf0bcf39a..2eb2d9251e11 100644 --- a/toolchain/check/testdata/generic/local.carbon +++ b/toolchain/check/testdata/generic/local.carbon @@ -60,6 +60,13 @@ class C(C:! type) { // CHECK:STDOUT: %C.f06: type = class_type @C, @C(%T) [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %C.elem.cca: type = unbound_element_type %C.f06, %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.c0e: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.18b: type = ptr_type %C.f06 [symbolic] +// CHECK:STDOUT: %pattern_type.468: type = pattern_type %ptr.18b [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.x.2ac: type = struct_type {.x: %T} [symbolic] // CHECK:STDOUT: %complete_type.4339: = complete_type_witness %struct_type.x.2ac [symbolic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] @@ -92,7 +99,7 @@ class C(C:! type) { // CHECK:STDOUT: %bound_method: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] // CHECK:STDOUT: %C.val: %C.d45 = struct_value (%int_1.5d2) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.13b: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.39b: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.d45) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.5e9: %T.as.Destroy.impl.Op.type.39b = struct_value () [concrete] // CHECK:STDOUT: %ptr.9c7: type = ptr_type %C.d45 [concrete] @@ -101,17 +108,17 @@ class C(C:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs -// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -123,6 +130,34 @@ class C(C:! type) { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc5_11.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.c0e)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f06 as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.468) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.468) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5_21.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.18b) = value_param call_param0 +// CHECK:STDOUT: %.loc5_21.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.f06)] { +// CHECK:STDOUT: %.loc5_21.3: type = specific_constant constants.%C.f06, @C(constants.%T) [symbolic = %C (constants.%C.f06)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc5_21.3 [symbolic = %C (constants.%C.f06)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.18b) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%T.loc5_11.2: type) { // CHECK:STDOUT: %T.loc5_11.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc5_11.1 (constants.%T)] // CHECK:STDOUT: @@ -136,6 +171,9 @@ class C(C:! type) { // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc5_11.2 [symbolic = %T.loc5_11.1 (constants.%T)] // CHECK:STDOUT: %.loc6: @C.%C.elem (%C.elem.cca) = field_decl x, element0 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.c0e)] // CHECK:STDOUT: %struct_type.x.loc7_3.1: type = struct_type {.x: %T} [symbolic = %struct_type.x.loc7_3.2 (constants.%struct_type.x.2ac)] // CHECK:STDOUT: %complete_type.loc7_3.1: = complete_type_witness %struct_type.x.loc7_3.1 [symbolic = %complete_type.loc7_3.2 (constants.%complete_type.4339)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc7_3.1 @@ -187,10 +225,33 @@ class C(C:! type) { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc5_11.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.f06)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.18b)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.468)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.18b)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%T) { // CHECK:STDOUT: %T.loc5_11.1 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.c0e +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.f06 +// CHECK:STDOUT: %ptr => constants.%ptr.18b +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.468 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%i32) { // CHECK:STDOUT: %T.loc5_11.1 => constants.%i32 // CHECK:STDOUT: @@ -202,25 +263,39 @@ class C(C:! type) { // CHECK:STDOUT: %complete_type.loc7_3.2 => constants.%complete_type.1ec // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%i32) { +// CHECK:STDOUT: %T => constants.%i32 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.13b +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_param_shadows_class.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %C.8b3: type = bind_symbolic_name C, 0 [symbolic] -// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete] +// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.f06: type = class_type @C, @C(%C.8b3) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%C.8b3) [symbolic] +// CHECK:STDOUT: %ptr.18b: type = ptr_type %C.f06 [symbolic] +// CHECK:STDOUT: %pattern_type.468: type = pattern_type %ptr.18b [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%C.8b3) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -232,12 +307,43 @@ class C(C:! type) { // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%C.loc13_11.2: type) { +// CHECK:STDOUT: %C: type = bind_symbolic_name C, 0 [symbolic = %C (constants.%C.8b3)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%C) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%C) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f06 as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.468) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.468) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc13_21.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.18b) = value_param call_param0 +// CHECK:STDOUT: %.loc13_21.2: type = splice_block %Self.ref [symbolic = %C.loc13_21.2 (constants.%C.f06)] { +// CHECK:STDOUT: %.loc13_21.3: type = specific_constant constants.%C.f06, @C(constants.%C.8b3) [symbolic = %C.loc13_21.2 (constants.%C.f06)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc13_21.3 [symbolic = %C.loc13_21.2 (constants.%C.f06)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.18b) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%C.loc13_11.2: type) { // CHECK:STDOUT: %C.loc13_11.1: type = bind_symbolic_name C, 0 [symbolic = %C.loc13_11.1 (constants.%C.8b3)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%C.8b3) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -250,34 +356,66 @@ class C(C:! type) { // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %C.decl: %C.type = class_decl @C [concrete = constants.%C.generic] { -// CHECK:STDOUT: %C.patt: %pattern_type = symbolic_binding_pattern C, 0 [concrete] +// CHECK:STDOUT: %C.patt: %pattern_type.98f = symbolic_binding_pattern C, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %C.loc13_11.2: type = bind_symbolic_name C, 0 [symbolic = %C.loc13_11.1 (constants.%C.8b3)] // CHECK:STDOUT: } // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%C.loc13_11.2: type) { +// CHECK:STDOUT: %C.loc13_21.1: type = bind_symbolic_name C, 0 [symbolic = %C.loc13_21.1 (constants.%C.8b3)] +// CHECK:STDOUT: %C.loc13_21.2: type = class_type @C, @C(%C.loc13_21.1) [symbolic = %C.loc13_21.2 (constants.%C.f06)] +// CHECK:STDOUT: %ptr: type = ptr_type %C.loc13_21.2 [symbolic = %ptr (constants.%ptr.18b)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.468)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.18b)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%C.8b3) { // CHECK:STDOUT: %C.loc13_11.1 => constants.%C.8b3 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%C.8b3) { +// CHECK:STDOUT: %C => constants.%C.8b3 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%C.8b3) { +// CHECK:STDOUT: %C.loc13_21.1 => constants.%C.8b3 +// CHECK:STDOUT: %C.loc13_21.2 => constants.%C.f06 +// CHECK:STDOUT: %ptr => constants.%ptr.18b +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.468 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- nonlocal_param_shadows_class.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C.8b3: type = bind_symbolic_name C, 0 [symbolic] -// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete] +// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.f2e: type = class_type @C, @C(%C.8b3) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%C.8b3) [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%C.8b3) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -287,18 +425,49 @@ class C(C:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: %C.type = class_decl @C [concrete = constants.%C.generic] { -// CHECK:STDOUT: %C.patt: %pattern_type = symbolic_binding_pattern C, 0 [concrete] +// CHECK:STDOUT: %C.patt: %pattern_type.98f = symbolic_binding_pattern C, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %C.loc4_9.2: type = bind_symbolic_name C, 0 [symbolic = %C.loc4_9.1 (constants.%C.8b3)] // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%C.loc4_9.2: type) { +// CHECK:STDOUT: %C: type = bind_symbolic_name C, 0 [symbolic = %C (constants.%C.8b3)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%C) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%C) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f2e as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc4_19.2: type = splice_block %Self.ref [symbolic = %C.loc4_19.2 (constants.%C.f2e)] { +// CHECK:STDOUT: %.loc4_19.3: type = specific_constant constants.%C.f2e, @C(constants.%C.8b3) [symbolic = %C.loc4_19.2 (constants.%C.f2e)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_19.3 [symbolic = %C.loc4_19.2 (constants.%C.f2e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%C.loc4_9.2: type) { // CHECK:STDOUT: %C.loc4_9.1: type = bind_symbolic_name C, 0 [symbolic = %C.loc4_9.1 (constants.%C.8b3)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%C.8b3) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -308,7 +477,30 @@ class C(C:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%C.loc4_9.2: type) { +// CHECK:STDOUT: %C.loc4_19.1: type = bind_symbolic_name C, 0 [symbolic = %C.loc4_19.1 (constants.%C.8b3)] +// CHECK:STDOUT: %C.loc4_19.2: type = class_type @C, @C(%C.loc4_19.1) [symbolic = %C.loc4_19.2 (constants.%C.f2e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C.loc4_19.2 [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%C.8b3) { // CHECK:STDOUT: %C.loc4_9.1 => constants.%C.8b3 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%C.8b3) { +// CHECK:STDOUT: %C => constants.%C.8b3 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%C.8b3) { +// CHECK:STDOUT: %C.loc4_19.1 => constants.%C.8b3 +// CHECK:STDOUT: %C.loc4_19.2 => constants.%C.f2e +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/generic/template/convert.carbon b/toolchain/check/testdata/generic/template/convert.carbon index b14b91cd36b1..8e1439310482 100644 --- a/toolchain/check/testdata/generic/template/convert.carbon +++ b/toolchain/check/testdata/generic/template/convert.carbon @@ -89,6 +89,13 @@ fn Test(d: D) -> i32 { // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.type: type = fn_type @C.as.ImplicitAs.impl.Convert [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert: %C.as.ImplicitAs.impl.Convert.type = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value %C, (%ImplicitAs.impl_witness.96d) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete] // CHECK:STDOUT: %complete_type.54b: = complete_type_witness %struct_type.n [concrete] // CHECK:STDOUT: %Test2.type: type = fn_type @Test2 [concrete] @@ -119,11 +126,13 @@ fn Test(d: D) -> i32 { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -206,6 +215,22 @@ fn Test(d: D) -> i32 { // CHECK:STDOUT: witness = @C.%ImplicitAs.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -220,6 +245,9 @@ fn Test(d: D) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: %ImplicitAs.impl_witness_table = impl_witness_table (@C.as.ImplicitAs.impl.%C.as.ImplicitAs.impl.Convert.decl), @C.as.ImplicitAs.impl [concrete] // CHECK:STDOUT: %ImplicitAs.impl_witness: = impl_witness %ImplicitAs.impl_witness_table [concrete = constants.%ImplicitAs.impl_witness.96d] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete = constants.%struct_type.n] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n [concrete = constants.%complete_type.54b] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -267,6 +295,8 @@ fn Test(d: D) -> i32 { // CHECK:STDOUT: return %.loc15_50.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Test2(%c.param: %C) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] @@ -318,6 +348,13 @@ fn Test(d: D) -> i32 { // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [template] // CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.510: type = pattern_type %D [concrete] @@ -339,11 +376,13 @@ fn Test(d: D) -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -388,7 +427,26 @@ fn Test(d: D) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc14: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -415,6 +473,8 @@ fn Test(d: D) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Test(%d.param: %D) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] diff --git a/toolchain/check/testdata/generic/template/member_access.carbon b/toolchain/check/testdata/generic/template/member_access.carbon index 0d34eca8c2c8..008e21dc99f0 100644 --- a/toolchain/check/testdata/generic/template/member_access.carbon +++ b/toolchain/check/testdata/generic/template/member_access.carbon @@ -98,6 +98,13 @@ fn Test(e: E) { // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [template] // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete] // CHECK:STDOUT: %complete_type.54b: = complete_type_witness %struct_type.n [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] @@ -137,10 +144,12 @@ fn Test(e: E) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -193,10 +202,29 @@ fn Test(e: E) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc9: %C.elem = field_decl n, element0 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete = constants.%struct_type.n] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n [concrete = constants.%complete_type.54b] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -227,6 +255,8 @@ fn Test(e: E) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Test1(%c.param: %C) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] @@ -290,6 +320,13 @@ fn Test(e: E) { // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [template] // CHECK:STDOUT: %D: type = class_type @D [concrete] // CHECK:STDOUT: %D.elem: type = unbound_element_type %D, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.m: type = struct_type {.m: %i32} [concrete] // CHECK:STDOUT: %complete_type.218: = complete_type_witness %struct_type.m [concrete] // CHECK:STDOUT: %pattern_type.510: type = pattern_type %D [concrete] @@ -310,10 +347,12 @@ fn Test(e: E) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -351,10 +390,29 @@ fn Test(e: E) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @D { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc12: %D.elem = field_decl m, element0 [concrete] +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %struct_type.m: type = struct_type {.m: %i32} [concrete = constants.%struct_type.m] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.m [concrete = constants.%complete_type.218] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -386,6 +444,8 @@ fn Test(e: E) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Test(%d.param: %D) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] @@ -428,9 +488,21 @@ fn Test(e: E) { // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [template] // CHECK:STDOUT: %E: type = class_type @E [concrete] // CHECK:STDOUT: %F.a8a: type = class_type @F.loc15 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.51a: = impl_witness @F.loc15.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.01c: type = ptr_type %F.a8a [concrete] +// CHECK:STDOUT: %pattern_type.463: type = pattern_type %ptr.01c [concrete] +// CHECK:STDOUT: %F.as.Destroy.impl.Op.type: type = fn_type @F.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %F.as.Destroy.impl.Op: %F.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %E.elem: type = unbound_element_type %E, %F.a8a [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.c1f: = impl_witness @E.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.742: type = ptr_type %E [concrete] +// CHECK:STDOUT: %pattern_type.88c: type = pattern_type %ptr.742 [concrete] +// CHECK:STDOUT: %E.as.Destroy.impl.Op.type: type = fn_type @E.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %E.as.Destroy.impl.Op: %E.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.n.e4c: type = struct_type {.n: %F.a8a} [concrete] // CHECK:STDOUT: %complete_type.5ba: = complete_type_witness %struct_type.n.e4c [concrete] // CHECK:STDOUT: %pattern_type.a4a: type = pattern_type %E [concrete] @@ -459,11 +531,13 @@ fn Test(e: E) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -502,10 +576,45 @@ fn Test(e: E) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @F.as.Destroy.impl: constants.%F.a8a as constants.%Destroy.type { +// CHECK:STDOUT: %F.as.Destroy.impl.Op.decl: %F.as.Destroy.impl.Op.type = fn_decl @F.as.Destroy.impl.Op [concrete = constants.%F.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.463 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.463 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.01c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%F.a8a [concrete = constants.%F.a8a] +// CHECK:STDOUT: %self: %ptr.01c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %F.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @F.loc15.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @E.as.Destroy.impl: constants.%E as constants.%Destroy.type { +// CHECK:STDOUT: %E.as.Destroy.impl.Op.decl: %E.as.Destroy.impl.Op.type = fn_decl @E.as.Destroy.impl.Op [concrete = constants.%E.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.88c = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.88c = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc14: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.742 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%E [concrete = constants.%E] +// CHECK:STDOUT: %self: %ptr.742 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %E.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @E.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @E { // CHECK:STDOUT: %F.decl: type = class_decl @F.loc15 [concrete = constants.%F.a8a] {} {} // CHECK:STDOUT: %F.ref: type = name_ref F, %F.decl [concrete = constants.%F.a8a] // CHECK:STDOUT: %.loc16: %E.elem = field_decl n, element0 [concrete] +// CHECK:STDOUT: impl_decl @E.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@E.as.Destroy.impl.%E.as.Destroy.impl.Op.decl), @E.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.c1f] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %F.a8a} [concrete = constants.%struct_type.n.e4c] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n [concrete = constants.%complete_type.5ba] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -517,6 +626,9 @@ fn Test(e: E) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @F.loc15 { +// CHECK:STDOUT: impl_decl @F.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@F.as.Destroy.impl.%F.as.Destroy.impl.Op.decl), @F.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.51a] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -546,6 +658,10 @@ fn Test(e: E) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @F.as.Destroy.impl.Op(%self.param: %ptr.01c) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @E.as.Destroy.impl.Op(%self.param: %ptr.742) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Test(%e.param: %E) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F.c41] diff --git a/toolchain/check/testdata/generic/template/unimplemented.carbon b/toolchain/check/testdata/generic/template/unimplemented.carbon index 709327032435..0cafc8d29126 100644 --- a/toolchain/check/testdata/generic/template/unimplemented.carbon +++ b/toolchain/check/testdata/generic/template/unimplemented.carbon @@ -158,6 +158,13 @@ fn F[template T:! type](x: T) { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete] // CHECK:STDOUT: %complete_type.54b: = complete_type_witness %struct_type.n [concrete] // CHECK:STDOUT: %c: %C = bind_symbolic_name c, 0, template [template] @@ -173,11 +180,13 @@ fn F[template T:! type](x: T) { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .MulWith = %Core.MulWith // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/types/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.MulWith: %MulWith.type.8b4 = import_ref Core//prelude/operators/arithmetic, MulWith, loaded [concrete = constants.%MulWith.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -203,10 +212,29 @@ fn F[template T:! type](x: T) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc5: %C.elem = field_decl n, element0 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete = constants.%struct_type.n] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n [concrete = constants.%complete_type.54b] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -216,6 +244,8 @@ fn F[template T:! type](x: T) { // CHECK:STDOUT: .n = %.loc5 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%c.loc11_15.2: %C) { // CHECK:STDOUT: %c.loc11_15.1: %C = bind_symbolic_name c, 0, template [template = %c.loc11_15.1 (constants.%c)] // CHECK:STDOUT: diff --git a/toolchain/check/testdata/if_expr/basic.carbon b/toolchain/check/testdata/if_expr/basic.carbon index 898b008febb5..70fce21d1146 100644 --- a/toolchain/check/testdata/if_expr/basic.carbon +++ b/toolchain/check/testdata/if_expr/basic.carbon @@ -41,6 +41,7 @@ fn F(b: bool, n: i32, m: i32) -> i32 { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -54,7 +55,6 @@ fn F(b: bool, n: i32, m: i32) -> i32 { // CHECK:STDOUT: %bound_method: = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete] // CHECK:STDOUT: %array: %array_type = tuple_value (%int_0.6a9) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.fa9: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%array_type) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.606: %T.as.Destroy.impl.Op.type.fa9 = struct_value () [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.606, @T.as.Destroy.impl.Op(%array_type) [concrete] diff --git a/toolchain/check/testdata/if_expr/constant_condition.carbon b/toolchain/check/testdata/if_expr/constant_condition.carbon index e708ef858aa0..b97297ff46e7 100644 --- a/toolchain/check/testdata/if_expr/constant_condition.carbon +++ b/toolchain/check/testdata/if_expr/constant_condition.carbon @@ -52,6 +52,7 @@ fn PartiallyConstant(t: type) -> i32 { // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -80,7 +81,6 @@ fn PartiallyConstant(t: type) -> i32 { // CHECK:STDOUT: %Constant: %Constant.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] // CHECK:STDOUT: %pattern_type.fe8: type = pattern_type %ptr.235 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.ba2: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%ptr.235) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.649: %T.as.Destroy.impl.Op.type.ba2 = struct_value () [concrete] // CHECK:STDOUT: %ptr.5d5: type = ptr_type %ptr.235 [concrete] diff --git a/toolchain/check/testdata/if_expr/fail_not_in_function.carbon b/toolchain/check/testdata/if_expr/fail_not_in_function.carbon index 1bb8e93026ab..e74bcf1f60a5 100644 --- a/toolchain/check/testdata/if_expr/fail_not_in_function.carbon +++ b/toolchain/check/testdata/if_expr/fail_not_in_function.carbon @@ -124,18 +124,56 @@ fn F() { // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %true: bool = bool_literal true [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(.inst17.loc4_14: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_24.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc4_24.2: type = splice_block %Self.ref [symbolic = %C (constants.%C)] { +// CHECK:STDOUT: %.loc4_24.3: type = specific_constant constants.%C, @C(constants.%T) [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_24.3 [symbolic = %C (constants.%C)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(.inst17.loc4_14: type) { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -156,9 +194,32 @@ fn F() { // CHECK:STDOUT: .C = // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(.inst17.loc4_14: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(); // CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%T) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/if_expr/struct.carbon b/toolchain/check/testdata/if_expr/struct.carbon index 56db5e3fa075..9d063f6e5d78 100644 --- a/toolchain/check/testdata/if_expr/struct.carbon +++ b/toolchain/check/testdata/if_expr/struct.carbon @@ -44,6 +44,7 @@ fn F(cond: bool) { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -60,7 +61,6 @@ fn F(cond: bool) { // CHECK:STDOUT: %bound_method.b92: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_2.ef8: %i32 = int_value 2 [concrete] // CHECK:STDOUT: %struct: %struct_type.a.b.501 = struct_value (%int_1.5d2, %int_2.ef8) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.da3: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%struct_type.a.b.501) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.9db: %T.as.Destroy.impl.Op.type.da3 = struct_value () [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.9db, @T.as.Destroy.impl.Op(%struct_type.a.b.501) [concrete] diff --git a/toolchain/check/testdata/impl/assoc_const_self.carbon b/toolchain/check/testdata/impl/assoc_const_self.carbon index 54bcbd70a9cc..45659fcbd7eb 100644 --- a/toolchain/check/testdata/impl/assoc_const_self.carbon +++ b/toolchain/check/testdata/impl/assoc_const_self.carbon @@ -385,9 +385,16 @@ fn CallF() { // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] // CHECK:STDOUT: %assoc0.45f: %I.assoc_type = assoc_entity element0, @I.%V [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.15e: type = facet_type <@ImplicitAs, @ImplicitAs(%C)> [concrete] @@ -415,10 +422,12 @@ fn CallF() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -489,6 +498,22 @@ fn CallF() { // CHECK:STDOUT: assoc_const V:! @V.%Self.as_type (%Self.as_type.b70); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @empty_tuple.type.as.ImplicitAs.impl: %.loc10_7.2 as %ImplicitAs.type { // CHECK:STDOUT: %empty_tuple.type.as.ImplicitAs.impl.Convert.decl: %empty_tuple.type.as.ImplicitAs.impl.Convert.type = fn_decl @empty_tuple.type.as.ImplicitAs.impl.Convert [concrete = constants.%empty_tuple.type.as.ImplicitAs.impl.Convert] { // CHECK:STDOUT: %self.patt: %pattern_type.cb1 = binding_pattern self [concrete] @@ -519,6 +544,9 @@ fn CallF() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -527,6 +555,8 @@ fn CallF() { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @empty_tuple.type.as.ImplicitAs.impl.Convert(%self.param: %empty_tuple.type) -> %return.param: %C { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc11_41.1: %empty_struct_type = struct_literal () diff --git a/toolchain/check/testdata/impl/extend_impl_generic.carbon b/toolchain/check/testdata/impl/extend_impl_generic.carbon index e2766865f4f6..3f779b8350be 100644 --- a/toolchain/check/testdata/impl/extend_impl_generic.carbon +++ b/toolchain/check/testdata/impl/extend_impl_generic.carbon @@ -72,6 +72,13 @@ class X(U:! type) { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Param.elem: type = unbound_element_type %Param, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.2b9: = impl_witness @Param.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.756: type = ptr_type %Param [concrete] +// CHECK:STDOUT: %pattern_type.fae: type = pattern_type %ptr.756 [concrete] +// CHECK:STDOUT: %Param.as.Destroy.impl.Op.type: type = fn_type @Param.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Param.as.Destroy.impl.Op: %Param.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.x.ed6: type = struct_type {.x: %i32} [concrete] // CHECK:STDOUT: %complete_type.1ec: = complete_type_witness %struct_type.x.ed6 [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] @@ -86,6 +93,11 @@ class X(U:! type) { // CHECK:STDOUT: %C.as.HasF.impl.F.type: type = fn_type @C.as.HasF.impl.F [concrete] // CHECK:STDOUT: %C.as.HasF.impl.F: %C.as.HasF.impl.F.type = struct_value () [concrete] // CHECK:STDOUT: %HasF.facet: %HasF.type.b18 = facet_value %C, (%HasF.impl_witness) [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] @@ -112,30 +124,25 @@ class X(U:! type) { // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] // CHECK:STDOUT: %.22c: type = fn_type_with_self_type %HasF.F.type.7f1, %HasF.facet [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.70d: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Param) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.e46: %T.as.Destroy.impl.Op.type.70d = struct_value () [concrete] -// CHECK:STDOUT: %ptr.756: type = ptr_type %Param [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.022: = specific_function %T.as.Destroy.impl.Op.e46, @T.as.Destroy.impl.Op(%Param) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.014: = specific_function %T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(%i32) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(%i32) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -196,6 +203,22 @@ class X(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Param.as.Destroy.impl: constants.%Param as constants.%Destroy.type { +// CHECK:STDOUT: %Param.as.Destroy.impl.Op.decl: %Param.as.Destroy.impl.Op.type = fn_decl @Param.as.Destroy.impl.Op [concrete = constants.%Param.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.fae = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.fae = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.756 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Param [concrete = constants.%Param] +// CHECK:STDOUT: %self: %ptr.756 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Param.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Param.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.HasF.impl: %Self.ref as %HasF.type { // CHECK:STDOUT: %C.as.HasF.impl.F.decl: %C.as.HasF.impl.F.type = fn_decl @C.as.HasF.impl.F [concrete = constants.%C.as.HasF.impl.F] { // CHECK:STDOUT: %return.patt: %pattern_type.b01 = return_slot_pattern [concrete] @@ -212,10 +235,29 @@ class X(U:! type) { // CHECK:STDOUT: witness = @C.%HasF.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Param { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc9: %Param.elem = field_decl x, element0 [concrete] +// CHECK:STDOUT: impl_decl @Param.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Param.as.Destroy.impl.%Param.as.Destroy.impl.Op.decl), @Param.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.2b9] // CHECK:STDOUT: %struct_type.x: type = struct_type {.x: %i32} [concrete = constants.%struct_type.x.ed6] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.x [concrete = constants.%complete_type.1ec] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -234,6 +276,9 @@ class X(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: %HasF.impl_witness_table = impl_witness_table (@C.as.HasF.impl.%C.as.HasF.impl.F.decl), @C.as.HasF.impl [concrete] // CHECK:STDOUT: %HasF.impl_witness: = impl_witness %HasF.impl_witness_table [concrete = constants.%HasF.impl_witness] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -253,6 +298,8 @@ class X(U:! type) { // CHECK:STDOUT: fn() -> @HasF.F.%T (%T); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Param.as.Destroy.impl.Op(%self.param: %ptr.756) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.HasF.impl.F() -> %return.param: %Param { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] @@ -270,6 +317,8 @@ class X(U:! type) { // CHECK:STDOUT: return %.loc15_22 to %return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @G(%c.param: %C) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -311,21 +360,17 @@ class X(U:! type) { // CHECK:STDOUT: %i32.loc22: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } // CHECK:STDOUT: %b: ref %i32 = bind_name b, %b.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc22_20: = bound_method %.loc22_20.1, constants.%T.as.Destroy.impl.Op.e46 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.e46, @T.as.Destroy.impl.Op(constants.%Param) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.022] -// CHECK:STDOUT: %bound_method.loc22_20: = bound_method %.loc22_20.1, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %Param.as.Destroy.impl.Op.bound.loc22: = bound_method %.loc22_20.1, constants.%Param.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc22_20: %ptr.756 = addr_of %.loc22_20.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc22_20: init %empty_tuple.type = call %bound_method.loc22_20(%addr.loc22_20) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc22_3: = bound_method %b.var, constants.%T.as.Destroy.impl.Op.e6a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.014] -// CHECK:STDOUT: %bound_method.loc22_3: = bound_method %b.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %Param.as.Destroy.impl.Op.call.loc22: init %empty_tuple.type = call %Param.as.Destroy.impl.Op.bound.loc22(%addr.loc22_20) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %b.var, constants.%T.as.Destroy.impl.Op.e6a +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(constants.%i32) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method: = bound_method %b.var, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr.loc22_3: %ptr.235 = addr_of %b.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc22_3: init %empty_tuple.type = call %bound_method.loc22_3(%addr.loc22_3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc21: = bound_method %.loc21_20.1, constants.%T.as.Destroy.impl.Op.e46 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.e46, @T.as.Destroy.impl.Op(constants.%Param) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.022] -// CHECK:STDOUT: %bound_method.loc21: = bound_method %.loc21_20.1, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc22_3) +// CHECK:STDOUT: %Param.as.Destroy.impl.Op.bound.loc21: = bound_method %.loc21_20.1, constants.%Param.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc21: %ptr.756 = addr_of %.loc21_20.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc21: init %empty_tuple.type = call %bound_method.loc21(%addr.loc21) +// CHECK:STDOUT: %Param.as.Destroy.impl.Op.call.loc21: init %empty_tuple.type = call %Param.as.Destroy.impl.Op.bound.loc21(%addr.loc21) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -364,8 +409,8 @@ class X(U:! type) { // CHECK:STDOUT: %I.generic: %I.type.dac = struct_value () [concrete] // CHECK:STDOUT: %I.type.325e65.1: type = facet_type <@I, @I(%T)> [symbolic] // CHECK:STDOUT: %Self.209206.1: %I.type.325e65.1 = bind_symbolic_name Self, 1 [symbolic] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.209206.1 [symbolic] -// CHECK:STDOUT: %pattern_type.4be: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Self.as_type.928: type = facet_access_type %Self.209206.1 [symbolic] +// CHECK:STDOUT: %pattern_type.4be: type = pattern_type %Self.as_type.928 [symbolic] // CHECK:STDOUT: %pattern_type.7dcd0a.1: type = pattern_type %T [symbolic] // CHECK:STDOUT: %I.F.type.2aef59.1: type = fn_type @I.F, @I(%T) [symbolic] // CHECK:STDOUT: %I.F.bb2dd4.1: %I.F.type.2aef59.1 = struct_value () [symbolic] @@ -388,6 +433,13 @@ class X(U:! type) { // CHECK:STDOUT: %X.as.I.impl.F.type: type = fn_type @X.as.I.impl.F, @X.as.I.impl(%U) [symbolic] // CHECK:STDOUT: %X.as.I.impl.F: %X.as.I.impl.F.type = struct_value () [symbolic] // CHECK:STDOUT: %I.facet: %I.type.325e65.2 = facet_value %X, (%I.impl_witness) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @X.%Destroy.impl_witness_table, @X.as.Destroy.impl(%U) [symbolic] +// CHECK:STDOUT: %ptr.428: type = ptr_type %X [symbolic] +// CHECK:STDOUT: %pattern_type.d72: type = pattern_type %ptr.428 [symbolic] +// CHECK:STDOUT: %X.as.Destroy.impl.Op.type: type = fn_type @X.as.Destroy.impl.Op, @X.as.Destroy.impl(%U) [symbolic] +// CHECK:STDOUT: %X.as.Destroy.impl.Op: %X.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %require_complete.441: = require_complete_type %X [symbolic] @@ -396,9 +448,11 @@ class X(U:! type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -439,14 +493,14 @@ class X(U:! type) { // CHECK:STDOUT: %t.patt: @I.F.%pattern_type.loc5_20 (%pattern_type.7dcd0a.1) = binding_pattern t [concrete] // CHECK:STDOUT: %t.param_patt: @I.F.%pattern_type.loc5_20 (%pattern_type.7dcd0a.1) = value_param_pattern %t.patt, call_param1 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param: @I.F.%Self.as_type.loc5_14.1 (%Self.as_type) = value_param call_param0 -// CHECK:STDOUT: %.loc5_14.1: type = splice_block %.loc5_14.3 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] { +// CHECK:STDOUT: %self.param: @I.F.%Self.as_type.loc5_14.1 (%Self.as_type.928) = value_param call_param0 +// CHECK:STDOUT: %.loc5_14.1: type = splice_block %.loc5_14.3 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.928)] { // CHECK:STDOUT: %.loc5_14.2: @I.F.%I.type (%I.type.325e65.1) = specific_constant @I.%Self.1, @I(constants.%T) [symbolic = %Self (constants.%Self.209206.1)] // CHECK:STDOUT: %Self.ref: @I.F.%I.type (%I.type.325e65.1) = name_ref Self, %.loc5_14.2 [symbolic = %Self (constants.%Self.209206.1)] -// CHECK:STDOUT: %Self.as_type.loc5_14.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] -// CHECK:STDOUT: %.loc5_14.3: type = converted %Self.ref, %Self.as_type.loc5_14.2 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self.as_type.loc5_14.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.928)] +// CHECK:STDOUT: %.loc5_14.3: type = converted %Self.ref, %Self.as_type.loc5_14.2 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.928)] // CHECK:STDOUT: } -// CHECK:STDOUT: %self: @I.F.%Self.as_type.loc5_14.1 (%Self.as_type) = bind_name self, %self.param +// CHECK:STDOUT: %self: @I.F.%Self.as_type.loc5_14.1 (%Self.as_type.928) = bind_name self, %self.param // CHECK:STDOUT: %t.param: @I.F.%T (%T) = value_param call_param1 // CHECK:STDOUT: %T.ref: type = name_ref T, @I.%T.loc4_13.2 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %t: @I.F.%T (%T) = bind_name t, %t.param @@ -498,6 +552,34 @@ class X(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @X.as.Destroy.impl(@X.%U.loc8_9.2: type) { +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @X.%Destroy.impl_witness_table, @X.as.Destroy.impl(%U) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %X.as.Destroy.impl.Op.type: type = fn_type @X.as.Destroy.impl.Op, @X.as.Destroy.impl(%U) [symbolic = %X.as.Destroy.impl.Op.type (constants.%X.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %X.as.Destroy.impl.Op: @X.as.Destroy.impl.%X.as.Destroy.impl.Op.type (%X.as.Destroy.impl.Op.type) = struct_value () [symbolic = %X.as.Destroy.impl.Op (constants.%X.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%X as constants.%Destroy.type { +// CHECK:STDOUT: %X.as.Destroy.impl.Op.decl: @X.as.Destroy.impl.%X.as.Destroy.impl.Op.type (%X.as.Destroy.impl.Op.type) = fn_decl @X.as.Destroy.impl.Op [symbolic = @X.as.Destroy.impl.%X.as.Destroy.impl.Op (constants.%X.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @X.as.Destroy.impl.Op.%pattern_type (%pattern_type.d72) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @X.as.Destroy.impl.Op.%pattern_type (%pattern_type.d72) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @X.as.Destroy.impl.Op.%ptr (%ptr.428) = value_param call_param0 +// CHECK:STDOUT: %.loc8_19.2: type = splice_block %Self.ref [symbolic = %X (constants.%X)] { +// CHECK:STDOUT: %.loc8_19.3: type = specific_constant constants.%X, @X(constants.%U) [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc8_19.3 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @X.as.Destroy.impl.Op.%ptr (%ptr.428) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %X.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @X.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @X(%U.loc8_9.2: type) { // CHECK:STDOUT: %U.loc8_9.1: type = bind_symbolic_name U, 0 [symbolic = %U.loc8_9.1 (constants.%U)] // CHECK:STDOUT: @@ -515,6 +597,9 @@ class X(U:! type) { // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (@X.as.I.impl.%X.as.I.impl.F.decl), @X.as.I.impl [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table, @X.as.I.impl(constants.%U) [symbolic = @X.as.I.impl.%I.impl_witness (constants.%I.impl_witness)] // CHECK:STDOUT: %.loc9: type = specific_constant @X.as.I.impl.%I.type.loc9_21.2, @X.as.I.impl(constants.%U) [symbolic = %I.type (constants.%I.type.325e65.2)] +// CHECK:STDOUT: impl_decl @X.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@X.as.Destroy.impl.%X.as.Destroy.impl.Op.decl), @X.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @X.as.Destroy.impl(constants.%U) [symbolic = @X.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -531,11 +616,11 @@ class X(U:! type) { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%T)> [symbolic = %I.type (constants.%I.type.325e65.1)] // CHECK:STDOUT: %Self: @I.F.%I.type (%I.type.325e65.1) = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.209206.1)] -// CHECK:STDOUT: %Self.as_type.loc5_14.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self.as_type.loc5_14.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.928)] // CHECK:STDOUT: %pattern_type.loc5_8: type = pattern_type %Self.as_type.loc5_14.1 [symbolic = %pattern_type.loc5_8 (constants.%pattern_type.4be)] // CHECK:STDOUT: %pattern_type.loc5_20: type = pattern_type %T [symbolic = %pattern_type.loc5_20 (constants.%pattern_type.7dcd0a.1)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%self.param: @I.F.%Self.as_type.loc5_14.1 (%Self.as_type), %t.param: @I.F.%T (%T)); +// CHECK:STDOUT: fn(%self.param: @I.F.%Self.as_type.loc5_14.1 (%Self.as_type.928), %t.param: @I.F.%T (%T)); // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @X.as.I.impl.F(@X.%U.loc8_9.2: type) { @@ -556,6 +641,17 @@ class X(U:! type) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @X.as.Destroy.impl.Op(@X.%U.loc8_9.2: type) { +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %X: type = class_type @X, @X(%U) [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %ptr: type = ptr_type %X [symbolic = %ptr (constants.%ptr.428)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.d72)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @X.as.Destroy.impl.Op.%ptr (%ptr.428)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @I(constants.%T) { // CHECK:STDOUT: %T.loc4_13.1 => constants.%T // CHECK:STDOUT: } @@ -564,7 +660,7 @@ class X(U:! type) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %I.type => constants.%I.type.325e65.1 // CHECK:STDOUT: %Self => constants.%Self.209206.1 -// CHECK:STDOUT: %Self.as_type.loc5_14.1 => constants.%Self.as_type +// CHECK:STDOUT: %Self.as_type.loc5_14.1 => constants.%Self.as_type.928 // CHECK:STDOUT: %pattern_type.loc5_8 => constants.%pattern_type.4be // CHECK:STDOUT: %pattern_type.loc5_20 => constants.%pattern_type.7dcd0a.1 // CHECK:STDOUT: } @@ -619,3 +715,15 @@ class X(U:! type) { // CHECK:STDOUT: %pattern_type.loc5_20 => constants.%pattern_type.7dcd0a.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @X.as.Destroy.impl(constants.%U) { +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @X.as.Destroy.impl.Op(constants.%U) { +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %ptr => constants.%ptr.428 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d72 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/fail_extend_impl_scope.carbon b/toolchain/check/testdata/impl/fail_extend_impl_scope.carbon index 7dc19a19a111..8993f7851fdb 100644 --- a/toolchain/check/testdata/impl/fail_extend_impl_scope.carbon +++ b/toolchain/check/testdata/impl/fail_extend_impl_scope.carbon @@ -180,17 +180,19 @@ fn F() { // CHECK:STDOUT: %Point.as.Z.impl.Zero.type: type = fn_type @Point.as.Z.impl.Zero [concrete] // CHECK:STDOUT: %Point.as.Z.impl.Zero: %Point.as.Z.impl.Zero.type = struct_value () [concrete] // CHECK:STDOUT: %Z.facet: %Z.type = facet_value %Point, (%Z.impl_witness) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e19: = impl_witness @Point.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.536: type = ptr_type %Point [concrete] +// CHECK:STDOUT: %pattern_type.bbc: type = pattern_type %ptr.536 [concrete] +// CHECK:STDOUT: %Point.as.Destroy.impl.Op.type: type = fn_type @Point.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Point.as.Destroy.impl.Op: %Point.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %Point.val: %Point = struct_value () [concrete] // CHECK:STDOUT: %.766: type = fn_type_with_self_type %Z.Zero.type, %Z.facet [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.003: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Point) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d2d: %T.as.Destroy.impl.Op.type.003 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.536: type = ptr_type %Point [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.d2d, @T.as.Destroy.impl.Op(%Point) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -253,6 +255,22 @@ fn F() { // CHECK:STDOUT: witness = @Point.%Z.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Point.as.Destroy.impl: constants.%Point as constants.%Destroy.type { +// CHECK:STDOUT: %Point.as.Destroy.impl.Op.decl: %Point.as.Destroy.impl.Op.type = fn_decl @Point.as.Destroy.impl.Op [concrete = constants.%Point.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.bbc = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.bbc = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.536 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Point [concrete = constants.%Point] +// CHECK:STDOUT: %self: %ptr.536 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Point.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Point.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Point { // CHECK:STDOUT: impl_decl @Point.as.Z.impl [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Point [concrete = constants.%Point] @@ -260,8 +278,11 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: %Z.impl_witness_table = impl_witness_table (@Point.as.Z.impl.%Point.as.Z.impl.Zero.decl), @Point.as.Z.impl [concrete] // CHECK:STDOUT: %Z.impl_witness: = impl_witness %Z.impl_witness_table [concrete = constants.%Z.impl_witness] +// CHECK:STDOUT: impl_decl @Point.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Point.as.Destroy.impl.%Point.as.Destroy.impl.Op.decl), @Point.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e19] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -289,6 +310,8 @@ fn F() { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Point.as.Destroy.impl.Op(%self.param: %ptr.536) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc25_5.1: %empty_struct_type = struct_literal () @@ -300,11 +323,9 @@ fn F() { // CHECK:STDOUT: %Zero.ref: %Z.assoc_type = name_ref Zero, @Z.%assoc0 [concrete = constants.%assoc0.534] // CHECK:STDOUT: %impl.elem0: %.766 = impl_witness_access constants.%Z.impl_witness, element0 [concrete = constants.%Point.as.Z.impl.Zero] // CHECK:STDOUT: %Point.as.Z.impl.Zero.call: init %empty_tuple.type = call %impl.elem0() -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc25_5.2, constants.%T.as.Destroy.impl.Op.d2d -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d2d, @T.as.Destroy.impl.Op(constants.%Point) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc25_5.2, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Point.as.Destroy.impl.Op.bound: = bound_method %.loc25_5.2, constants.%Point.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.536 = addr_of %.loc25_5.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %Point.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Point.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/fail_extend_impl_type_as.carbon b/toolchain/check/testdata/impl/fail_extend_impl_type_as.carbon index 6947b61fe272..48027250c136 100644 --- a/toolchain/check/testdata/impl/fail_extend_impl_type_as.carbon +++ b/toolchain/check/testdata/impl/fail_extend_impl_type_as.carbon @@ -52,28 +52,47 @@ class E { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %I.impl_witness.bf7: = impl_witness @C.%I.impl_witness_table [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] // CHECK:STDOUT: %I.impl_witness.fa5: = impl_witness @D.%I.impl_witness_table [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %E: type = class_type @E [concrete] // CHECK:STDOUT: %I.impl_witness.7f3: = impl_witness @E.%I.impl_witness_table [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.c1f: = impl_witness @E.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.742: type = ptr_type %E [concrete] +// CHECK:STDOUT: %pattern_type.88c: type = pattern_type %ptr.742 [concrete] +// CHECK:STDOUT: %E.as.Destroy.impl.Op.type: type = fn_type @E.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %E.as.Destroy.impl.Op: %E.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -92,7 +111,7 @@ class E { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = %Self @@ -104,13 +123,61 @@ class E { // CHECK:STDOUT: witness = // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc17: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @D.as.I.impl: %D.ref as %I.ref; // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc25: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @E.as.I.impl: %Self.ref as %I.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = @E.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @E.as.Destroy.impl: constants.%E as constants.%Destroy.type { +// CHECK:STDOUT: %E.as.Destroy.impl.Op.decl: %E.as.Destroy.impl.Op.type = fn_decl @E.as.Destroy.impl.Op [concrete = constants.%E.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.88c = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.88c = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc36: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.742 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%E [concrete = constants.%E] +// CHECK:STDOUT: %self: %ptr.742 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %E.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @E.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: impl_decl @i32.as.I.impl [concrete] {} { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] @@ -119,6 +186,9 @@ class E { // CHECK:STDOUT: } // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @i32.as.I.impl [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness.bf7] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -136,6 +206,9 @@ class E { // CHECK:STDOUT: } // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @D.as.I.impl [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness.fa5] +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -154,6 +227,9 @@ class E { // CHECK:STDOUT: } // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @E.as.I.impl [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness.7f3] +// CHECK:STDOUT: impl_decl @E.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@E.as.Destroy.impl.%E.as.Destroy.impl.Op.decl), @E.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.c1f] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -164,3 +240,9 @@ class E { // CHECK:STDOUT: extend @E.as.I.impl.%I.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @E.as.Destroy.impl.Op(%self.param: %ptr.742) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/fail_extend_non_interface.carbon b/toolchain/check/testdata/impl/fail_extend_non_interface.carbon index cb57a5c696c6..6e95d0f76786 100644 --- a/toolchain/check/testdata/impl/fail_extend_non_interface.carbon +++ b/toolchain/check/testdata/impl/fail_extend_non_interface.carbon @@ -28,6 +28,13 @@ class C { // CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } @@ -35,10 +42,12 @@ class C { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -52,12 +61,31 @@ class C { // CHECK:STDOUT: // CHECK:STDOUT: impl @C.as..impl: %Self.ref as %i32; // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: impl_decl @C.as..impl [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -68,3 +96,5 @@ class C { // CHECK:STDOUT: has_error // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/fail_impl_as_scope.carbon b/toolchain/check/testdata/impl/fail_impl_as_scope.carbon index 2ff374b19085..7992c71d2bff 100644 --- a/toolchain/check/testdata/impl/fail_impl_as_scope.carbon +++ b/toolchain/check/testdata/impl/fail_impl_as_scope.carbon @@ -247,18 +247,20 @@ class X { // CHECK:STDOUT: %Point.as.Z.impl.Method.type: type = fn_type @Point.as.Z.impl.Method [concrete] // CHECK:STDOUT: %Point.as.Z.impl.Method: %Point.as.Z.impl.Method.type = struct_value () [concrete] // CHECK:STDOUT: %Z.facet: %Z.type = facet_value %Point, (%Z.impl_witness) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e19: = impl_witness @Point.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.536: type = ptr_type %Point [concrete] +// CHECK:STDOUT: %pattern_type.bbc: type = pattern_type %ptr.536 [concrete] +// CHECK:STDOUT: %Point.as.Destroy.impl.Op.type: type = fn_type @Point.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Point.as.Destroy.impl.Op: %Point.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %.d52: type = fn_type_with_self_type %Z.Zero.type, %Z.facet [concrete] // CHECK:STDOUT: %Point.val: %Point = struct_value () [concrete] // CHECK:STDOUT: %.462: type = fn_type_with_self_type %Z.Method.type, %Z.facet [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.003: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Point) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d2d: %T.as.Destroy.impl.Op.type.003 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.536: type = ptr_type %Point [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.d2d, @T.as.Destroy.impl.Op(%Point) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -359,6 +361,22 @@ class X { // CHECK:STDOUT: witness = @Point.%Z.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Point.as.Destroy.impl: constants.%Point as constants.%Destroy.type { +// CHECK:STDOUT: %Point.as.Destroy.impl.Op.decl: %Point.as.Destroy.impl.Op.type = fn_decl @Point.as.Destroy.impl.Op [concrete = constants.%Point.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.bbc = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.bbc = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc17: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.536 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Point [concrete = constants.%Point] +// CHECK:STDOUT: %self: %ptr.536 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Point.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Point.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Point { // CHECK:STDOUT: impl_decl @Point.as.Z.impl [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Point [concrete = constants.%Point] @@ -366,8 +384,11 @@ class X { // CHECK:STDOUT: } // CHECK:STDOUT: %Z.impl_witness_table = impl_witness_table (@Point.as.Z.impl.%Point.as.Z.impl.Zero.decl, @Point.as.Z.impl.%Point.as.Z.impl.Method.decl), @Point.as.Z.impl [concrete] // CHECK:STDOUT: %Z.impl_witness: = impl_witness %Z.impl_witness_table [concrete = constants.%Z.impl_witness] +// CHECK:STDOUT: impl_decl @Point.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Point.as.Destroy.impl.%Point.as.Destroy.impl.Op.decl), @Point.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.e19] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -420,6 +441,8 @@ class X { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Point.as.Destroy.impl.Op(%self.param: %ptr.536) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Point.ref.loc28: type = name_ref Point, file.%Point.decl [concrete = constants.%Point] @@ -438,14 +461,12 @@ class X { // CHECK:STDOUT: %Z.ref.loc29: type = name_ref Z, file.%Z.decl [concrete = constants.%Z.type] // CHECK:STDOUT: %Method.ref: %Z.assoc_type = name_ref Method, @Z.%assoc1 [concrete = constants.%assoc1] // CHECK:STDOUT: %impl.elem1: %.462 = impl_witness_access constants.%Z.impl_witness, element1 [concrete = constants.%Point.as.Z.impl.Method] -// CHECK:STDOUT: %bound_method.loc29_16: = bound_method %.loc29_7.1, %impl.elem1 +// CHECK:STDOUT: %bound_method: = bound_method %.loc29_7.1, %impl.elem1 // CHECK:STDOUT: %.loc29_7.2: %Point = bind_value %.loc29_7.1 -// CHECK:STDOUT: %Point.as.Z.impl.Method.call: init %empty_tuple.type = call %bound_method.loc29_16(%.loc29_7.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc29_5.2, constants.%T.as.Destroy.impl.Op.d2d -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d2d, @T.as.Destroy.impl.Op(constants.%Point) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc29_5: = bound_method %.loc29_5.2, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Point.as.Z.impl.Method.call: init %empty_tuple.type = call %bound_method(%.loc29_7.2) +// CHECK:STDOUT: %Point.as.Destroy.impl.Op.bound: = bound_method %.loc29_5.2, constants.%Point.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.536 = addr_of %.loc29_5.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc29_5(%addr) +// CHECK:STDOUT: %Point.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Point.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -501,15 +522,24 @@ class X { // CHECK:STDOUT: %X.as.A.impl.B.type: type = fn_type @X.as.A.impl.B [concrete] // CHECK:STDOUT: %X.as.A.impl.B: %X.as.A.impl.B.type = struct_value () [concrete] // CHECK:STDOUT: %A.facet: %A.type = facet_value %X, (%A.impl_witness) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @X.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete] +// CHECK:STDOUT: %pattern_type.1c6: type = pattern_type %ptr.d17 [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op.type: type = fn_type @X.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op: %X.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -564,6 +594,22 @@ class X { // CHECK:STDOUT: witness = // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @X.as.Destroy.impl: constants.%X as constants.%Destroy.type { +// CHECK:STDOUT: %X.as.Destroy.impl.Op.decl: %X.as.Destroy.impl.Op.type = fn_decl @X.as.Destroy.impl.Op [concrete = constants.%X.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1c6 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1c6 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.d17 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%X [concrete = constants.%X] +// CHECK:STDOUT: %self: %ptr.d17 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %X.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @X.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @X { // CHECK:STDOUT: impl_decl @X.as.A.impl [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%X [concrete = constants.%X] @@ -571,6 +617,9 @@ class X { // CHECK:STDOUT: } // CHECK:STDOUT: %A.impl_witness_table = impl_witness_table (@X.as.A.impl.%X.as.A.impl.B.decl), @X.as.A.impl [concrete] // CHECK:STDOUT: %A.impl_witness: = impl_witness %A.impl_witness_table [concrete = constants.%A.impl_witness] +// CHECK:STDOUT: impl_decl @X.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@X.as.Destroy.impl.%X.as.Destroy.impl.Op.decl), @X.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -598,6 +647,8 @@ class X { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @X.as.Destroy.impl.Op(%self.param: %ptr.d17) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @A.B(constants.%Self.31d) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @A.B(constants.%A.facet) {} diff --git a/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon b/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon index 191a45b17882..a406d1b4a809 100644 --- a/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon +++ b/toolchain/check/testdata/impl/fail_impl_bad_assoc_fn.carbon @@ -252,15 +252,32 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %assoc0.82e: %I.assoc_type = assoc_entity element0, @I.%I.F.decl [concrete] // CHECK:STDOUT: %NoF: type = class_type @NoF [concrete] // CHECK:STDOUT: %I.impl_witness.901: = impl_witness @NoF.%I.impl_witness_table [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9b3: = impl_witness @NoF.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.0f9: type = ptr_type %NoF [concrete] +// CHECK:STDOUT: %pattern_type.7b5: type = pattern_type %ptr.0f9 [concrete] +// CHECK:STDOUT: %NoF.as.Destroy.impl.Op.type: type = fn_type @NoF.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %NoF.as.Destroy.impl.Op: %NoF.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %FNotFunction: type = class_type @FNotFunction [concrete] // CHECK:STDOUT: %I.impl_witness.44e: = impl_witness @FNotFunction.%I.impl_witness_table [concrete] // CHECK:STDOUT: %F: type = class_type @F [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.f9b: = impl_witness @FNotFunction.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.2b2: type = ptr_type %FNotFunction [concrete] +// CHECK:STDOUT: %pattern_type.27c: type = pattern_type %ptr.2b2 [concrete] +// CHECK:STDOUT: %FNotFunction.as.Destroy.impl.Op.type: type = fn_type @FNotFunction.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %FNotFunction.as.Destroy.impl.Op: %FNotFunction.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %PossiblyF.type: type = fn_type @PossiblyF [concrete] // CHECK:STDOUT: %PossiblyF: %PossiblyF.type = struct_value () [concrete] // CHECK:STDOUT: %FAlias: type = class_type @FAlias [concrete] // CHECK:STDOUT: %I.impl_witness.c80: = impl_witness @FAlias.%I.impl_witness_table [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.740: = impl_witness @FAlias.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.4bf: type = ptr_type %FAlias [concrete] +// CHECK:STDOUT: %pattern_type.310: type = pattern_type %ptr.4bf [concrete] +// CHECK:STDOUT: %FAlias.as.Destroy.impl.Op.type: type = fn_type @FAlias.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %FAlias.as.Destroy.impl.Op: %FAlias.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %FExtraParam: type = class_type @FExtraParam [concrete] // CHECK:STDOUT: %I.impl_witness.1f3: = impl_witness @FExtraParam.%I.impl_witness_table [concrete] // CHECK:STDOUT: %Bool.type: type = fn_type @Bool [concrete] @@ -271,6 +288,11 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %I.facet.fa4: %I.type = facet_value %FExtraParam, (%I.impl_witness.1f3) [concrete] // CHECK:STDOUT: %FExtraParam.as.I.impl.F.type.44ef8c.2: type = fn_type @FExtraParam.as.I.impl.F.loc69_18.2 [concrete] // CHECK:STDOUT: %FExtraParam.as.I.impl.F.424e9e.2: %FExtraParam.as.I.impl.F.type.44ef8c.2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.44a: = impl_witness @FExtraParam.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.0f2: type = ptr_type %FExtraParam [concrete] +// CHECK:STDOUT: %pattern_type.8d3: type = pattern_type %ptr.0f2 [concrete] +// CHECK:STDOUT: %FExtraParam.as.Destroy.impl.Op.type: type = fn_type @FExtraParam.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %FExtraParam.as.Destroy.impl.Op: %FExtraParam.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %FExtraImplicitParam: type = class_type @FExtraImplicitParam [concrete] // CHECK:STDOUT: %I.impl_witness.a7b: = impl_witness @FExtraImplicitParam.%I.impl_witness_table [concrete] // CHECK:STDOUT: %pattern_type.8ae: type = pattern_type %FExtraImplicitParam [concrete] @@ -279,11 +301,21 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %I.facet.ee5: %I.type = facet_value %FExtraImplicitParam, (%I.impl_witness.a7b) [concrete] // CHECK:STDOUT: %FExtraImplicitParam.as.I.impl.F.type.e1abdd.2: type = fn_type @FExtraImplicitParam.as.I.impl.F.loc85_23.2 [concrete] // CHECK:STDOUT: %FExtraImplicitParam.as.I.impl.F.6ff574.2: %FExtraImplicitParam.as.I.impl.F.type.e1abdd.2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.a05: = impl_witness @FExtraImplicitParam.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.8c7: type = ptr_type %FExtraImplicitParam [concrete] +// CHECK:STDOUT: %pattern_type.ab8: type = pattern_type %ptr.8c7 [concrete] +// CHECK:STDOUT: %FExtraImplicitParam.as.Destroy.impl.Op.type: type = fn_type @FExtraImplicitParam.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %FExtraImplicitParam.as.Destroy.impl.Op: %FExtraImplicitParam.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %FExtraReturnType: type = class_type @FExtraReturnType [concrete] // CHECK:STDOUT: %I.impl_witness.59a: = impl_witness @FExtraReturnType.%I.impl_witness_table [concrete] // CHECK:STDOUT: %FExtraReturnType.as.I.impl.F.type: type = fn_type @FExtraReturnType.as.I.impl.F [concrete] // CHECK:STDOUT: %FExtraReturnType.as.I.impl.F: %FExtraReturnType.as.I.impl.F.type = struct_value () [concrete] // CHECK:STDOUT: %I.facet.d5c: %I.type = facet_value %FExtraReturnType, (%I.impl_witness.59a) [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.3ea: = impl_witness @FExtraReturnType.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.147: type = ptr_type %FExtraReturnType [concrete] +// CHECK:STDOUT: %pattern_type.f1c: type = pattern_type %ptr.147 [concrete] +// CHECK:STDOUT: %FExtraReturnType.as.Destroy.impl.Op.type: type = fn_type @FExtraReturnType.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %FExtraReturnType.as.Destroy.impl.Op: %FExtraReturnType.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %J.type: type = facet_type <@J> [concrete] // CHECK:STDOUT: %Self.ccd: %J.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %J.F.type: type = fn_type @J.F [concrete] @@ -297,6 +329,11 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %J.facet.94c: %J.type = facet_value %FMissingParam, (%J.impl_witness.4e9) [concrete] // CHECK:STDOUT: %FMissingParam.as.J.impl.F.type.69596c.2: type = fn_type @FMissingParam.as.J.impl.F.loc117_31.2 [concrete] // CHECK:STDOUT: %FMissingParam.as.J.impl.F.738f31.2: %FMissingParam.as.J.impl.F.type.69596c.2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.672: = impl_witness @FMissingParam.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.fc8: type = ptr_type %FMissingParam [concrete] +// CHECK:STDOUT: %pattern_type.c8f: type = pattern_type %ptr.fc8 [concrete] +// CHECK:STDOUT: %FMissingParam.as.Destroy.impl.Op.type: type = fn_type @FMissingParam.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %FMissingParam.as.Destroy.impl.Op: %FMissingParam.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %FMissingImplicitParam: type = class_type @FMissingImplicitParam [concrete] // CHECK:STDOUT: %J.impl_witness.841: = impl_witness @FMissingImplicitParam.%J.impl_witness_table [concrete] // CHECK:STDOUT: %FMissingImplicitParam.as.J.impl.F.type.d97cef.1: type = fn_type @FMissingImplicitParam.as.J.impl.F.loc130_26.1 [concrete] @@ -304,6 +341,11 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %J.facet.e7e: %J.type = facet_value %FMissingImplicitParam, (%J.impl_witness.841) [concrete] // CHECK:STDOUT: %FMissingImplicitParam.as.J.impl.F.type.d97cef.2: type = fn_type @FMissingImplicitParam.as.J.impl.F.loc130_26.2 [concrete] // CHECK:STDOUT: %FMissingImplicitParam.as.J.impl.F.01de92.2: %FMissingImplicitParam.as.J.impl.F.type.d97cef.2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae6: = impl_witness @FMissingImplicitParam.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.c3c: type = ptr_type %FMissingImplicitParam [concrete] +// CHECK:STDOUT: %pattern_type.575: type = pattern_type %ptr.c3c [concrete] +// CHECK:STDOUT: %FMissingImplicitParam.as.Destroy.impl.Op.type: type = fn_type @FMissingImplicitParam.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %FMissingImplicitParam.as.Destroy.impl.Op: %FMissingImplicitParam.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %FMissingReturnType: type = class_type @FMissingReturnType [concrete] // CHECK:STDOUT: %J.impl_witness.e75: = impl_witness @FMissingReturnType.%J.impl_witness_table [concrete] // CHECK:STDOUT: %FMissingReturnType.as.J.impl.F.type.123d7a.1: type = fn_type @FMissingReturnType.as.J.impl.F.loc152_30.1 [concrete] @@ -311,6 +353,11 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %J.facet.974: %J.type = facet_value %FMissingReturnType, (%J.impl_witness.e75) [concrete] // CHECK:STDOUT: %FMissingReturnType.as.J.impl.F.type.123d7a.2: type = fn_type @FMissingReturnType.as.J.impl.F.loc152_30.2 [concrete] // CHECK:STDOUT: %FMissingReturnType.as.J.impl.F.c7d02d.2: %FMissingReturnType.as.J.impl.F.type.123d7a.2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.8d8: = impl_witness @FMissingReturnType.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.41e: type = ptr_type %FMissingReturnType [concrete] +// CHECK:STDOUT: %pattern_type.585: type = pattern_type %ptr.41e [concrete] +// CHECK:STDOUT: %FMissingReturnType.as.Destroy.impl.Op.type: type = fn_type @FMissingReturnType.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %FMissingReturnType.as.Destroy.impl.Op: %FMissingReturnType.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %FDifferentParamType: type = class_type @FDifferentParamType [concrete] @@ -321,6 +368,11 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %J.facet.37e: %J.type = facet_value %FDifferentParamType, (%J.impl_witness.cbe) [concrete] // CHECK:STDOUT: %FDifferentParamType.as.J.impl.F.type.6b537d.2: type = fn_type @FDifferentParamType.as.J.impl.F.loc171_38.2 [concrete] // CHECK:STDOUT: %FDifferentParamType.as.J.impl.F.04313a.2: %FDifferentParamType.as.J.impl.F.type.6b537d.2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.443: = impl_witness @FDifferentParamType.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.f1f: type = ptr_type %FDifferentParamType [concrete] +// CHECK:STDOUT: %pattern_type.e0c: type = pattern_type %ptr.f1f [concrete] +// CHECK:STDOUT: %FDifferentParamType.as.Destroy.impl.Op.type: type = fn_type @FDifferentParamType.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %FDifferentParamType.as.Destroy.impl.Op: %FDifferentParamType.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %FDifferentImplicitParamType: type = class_type @FDifferentImplicitParamType [concrete] // CHECK:STDOUT: %J.impl_witness.af2: = impl_witness @FDifferentImplicitParamType.%J.impl_witness_table [concrete] // CHECK:STDOUT: %pattern_type.9cc: type = pattern_type %FDifferentImplicitParamType [concrete] @@ -329,6 +381,11 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %J.facet.bf1: %J.type = facet_value %FDifferentImplicitParamType, (%J.impl_witness.af2) [concrete] // CHECK:STDOUT: %FDifferentImplicitParamType.as.J.impl.F.type.d6232a.2: type = fn_type @FDifferentImplicitParamType.as.J.impl.F.loc184_38.2 [concrete] // CHECK:STDOUT: %FDifferentImplicitParamType.as.J.impl.F.886f70.2: %FDifferentImplicitParamType.as.J.impl.F.type.d6232a.2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.c2a: = impl_witness @FDifferentImplicitParamType.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.dc5: type = ptr_type %FDifferentImplicitParamType [concrete] +// CHECK:STDOUT: %pattern_type.986: type = pattern_type %ptr.dc5 [concrete] +// CHECK:STDOUT: %FDifferentImplicitParamType.as.Destroy.impl.Op.type: type = fn_type @FDifferentImplicitParamType.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %FDifferentImplicitParamType.as.Destroy.impl.Op: %FDifferentImplicitParamType.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %FDifferentReturnType: type = class_type @FDifferentReturnType [concrete] // CHECK:STDOUT: %J.impl_witness.bc1: = impl_witness @FDifferentReturnType.%J.impl_witness_table [concrete] // CHECK:STDOUT: %pattern_type.8ee: type = pattern_type %FDifferentReturnType [concrete] @@ -337,11 +394,11 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %J.facet.67f: %J.type = facet_value %FDifferentReturnType, (%J.impl_witness.bc1) [concrete] // CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.type.d3b58f.2: type = fn_type @FDifferentReturnType.as.J.impl.F.loc200_38.2 [concrete] // CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.be86c9.2: %FDifferentReturnType.as.J.impl.F.type.d3b58f.2 = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.3d3: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%FDifferentReturnType) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.ddd: %T.as.Destroy.impl.Op.type.3d3 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.6d2: = impl_witness @FDifferentReturnType.%Destroy.impl_witness_table [concrete] // CHECK:STDOUT: %ptr.954: type = ptr_type %FDifferentReturnType [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.b4b: = specific_function %T.as.Destroy.impl.Op.ddd, @T.as.Destroy.impl.Op(%FDifferentReturnType) [concrete] +// CHECK:STDOUT: %pattern_type.246: type = pattern_type %ptr.954 [concrete] +// CHECK:STDOUT: %FDifferentReturnType.as.Destroy.impl.Op.type: type = fn_type @FDifferentReturnType.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %FDifferentReturnType.as.Destroy.impl.Op: %FDifferentReturnType.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %SelfNested.type: type = facet_type <@SelfNested> [concrete] // CHECK:STDOUT: %Self.2ff: %SelfNested.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %Self.as_type.e1e: type = facet_access_type %Self.2ff [symbolic] @@ -377,10 +434,14 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %pattern_type.a5c: type = pattern_type %tuple.type.9c9 [concrete] // CHECK:STDOUT: %SelfNestedBadParam.as.SelfNested.impl.F.type.f90165.2: type = fn_type @SelfNestedBadParam.as.SelfNested.impl.F.loc223_87.2 [concrete] // CHECK:STDOUT: %SelfNestedBadParam.as.SelfNested.impl.F.fa8d04.2: %SelfNestedBadParam.as.SelfNested.impl.F.type.f90165.2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.908: = impl_witness @SelfNestedBadParam.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %pattern_type.2a7: type = pattern_type %ptr.4cd [concrete] +// CHECK:STDOUT: %SelfNestedBadParam.as.Destroy.impl.Op.type: type = fn_type @SelfNestedBadParam.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %SelfNestedBadParam.as.Destroy.impl.Op: %SelfNestedBadParam.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.f40: type = ptr_type %array_type.a41 [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.ba3: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%array_type.a41) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.d25: %T.as.Destroy.impl.Op.type.ba3 = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.235: = specific_function %T.as.Destroy.impl.Op.d25, @T.as.Destroy.impl.Op(%array_type.a41) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.d25, @T.as.Destroy.impl.Op(%array_type.a41) [concrete] // CHECK:STDOUT: %SelfNestedBadReturnType: type = class_type @SelfNestedBadReturnType [concrete] // CHECK:STDOUT: %SelfNested.impl_witness.d5e: = impl_witness @SelfNestedBadReturnType.%SelfNested.impl_witness_table [concrete] // CHECK:STDOUT: %ptr.612: type = ptr_type %SelfNestedBadReturnType [concrete] @@ -394,20 +455,24 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %pattern_type.f56: type = pattern_type %array_type.126 [concrete] // CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.0e7d1d.2: type = fn_type @SelfNestedBadReturnType.as.SelfNested.impl.F.loc239_112.2 [concrete] // CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.0bc78a.2: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.0e7d1d.2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9f5: = impl_witness @SelfNestedBadReturnType.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %pattern_type.4de: type = pattern_type %ptr.612 [concrete] +// CHECK:STDOUT: %SelfNestedBadReturnType.as.Destroy.impl.Op.type: type = fn_type @SelfNestedBadReturnType.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %SelfNestedBadReturnType.as.Destroy.impl.Op: %SelfNestedBadReturnType.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Bool = %Core.Bool // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs -// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Bool: %Bool.type = import_ref Core//prelude/parts/bool, Bool, loaded [concrete = constants.%Bool] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -549,6 +614,22 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @NoF.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @NoF.as.Destroy.impl: constants.%NoF as constants.%Destroy.type { +// CHECK:STDOUT: %NoF.as.Destroy.impl.Op.decl: %NoF.as.Destroy.impl.Op.type = fn_decl @NoF.as.Destroy.impl.Op [concrete = constants.%NoF.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.7b5 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.7b5 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc17: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.0f9 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%NoF [concrete = constants.%NoF] +// CHECK:STDOUT: %self: %ptr.0f9 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %NoF.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @NoF.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @FNotFunction.as.I.impl: %Self.ref as %I.ref { // CHECK:STDOUT: %F.decl: type = class_decl @F [concrete = constants.%F] {} {} // CHECK:STDOUT: @@ -557,6 +638,22 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FNotFunction.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @FNotFunction.as.Destroy.impl: constants.%FNotFunction as constants.%Destroy.type { +// CHECK:STDOUT: %FNotFunction.as.Destroy.impl.Op.decl: %FNotFunction.as.Destroy.impl.Op.type = fn_decl @FNotFunction.as.Destroy.impl.Op [concrete = constants.%FNotFunction.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.27c = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.27c = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc28: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.2b2 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FNotFunction [concrete = constants.%FNotFunction] +// CHECK:STDOUT: %self: %ptr.2b2 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %FNotFunction.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @FNotFunction.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @FAlias.as.I.impl: %Self.ref as %I.ref { // CHECK:STDOUT: %PossiblyF.ref: %PossiblyF.type = name_ref PossiblyF, file.%PossiblyF.decl [concrete = constants.%PossiblyF] // CHECK:STDOUT: %F: %PossiblyF.type = bind_alias F, file.%PossiblyF.decl [concrete = constants.%PossiblyF] @@ -567,6 +664,22 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FAlias.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @FAlias.as.Destroy.impl: constants.%FAlias as constants.%Destroy.type { +// CHECK:STDOUT: %FAlias.as.Destroy.impl.Op.decl: %FAlias.as.Destroy.impl.Op.type = fn_decl @FAlias.as.Destroy.impl.Op [concrete = constants.%FAlias.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.310 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.310 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc44: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.4bf = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FAlias [concrete = constants.%FAlias] +// CHECK:STDOUT: %self: %ptr.4bf = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %FAlias.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @FAlias.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @FExtraParam.as.I.impl: %Self.ref as %I.ref { // CHECK:STDOUT: %FExtraParam.as.I.impl.F.decl.loc69_18.1: %FExtraParam.as.I.impl.F.type.44ef8c.1 = fn_decl @FExtraParam.as.I.impl.F.loc69_18.1 [concrete = constants.%FExtraParam.as.I.impl.F.424e9e.1] { // CHECK:STDOUT: %b.patt: %pattern_type.831 = binding_pattern b [concrete] @@ -587,6 +700,22 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FExtraParam.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @FExtraParam.as.Destroy.impl: constants.%FExtraParam as constants.%Destroy.type { +// CHECK:STDOUT: %FExtraParam.as.Destroy.impl.Op.decl: %FExtraParam.as.Destroy.impl.Op.type = fn_decl @FExtraParam.as.Destroy.impl.Op [concrete = constants.%FExtraParam.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.8d3 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.8d3 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc57: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.0f2 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FExtraParam [concrete = constants.%FExtraParam] +// CHECK:STDOUT: %self: %ptr.0f2 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %FExtraParam.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @FExtraParam.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @FExtraImplicitParam.as.I.impl: %Self.ref as %I.ref { // CHECK:STDOUT: %FExtraImplicitParam.as.I.impl.F.decl.loc85_23.1: %FExtraImplicitParam.as.I.impl.F.type.e1abdd.1 = fn_decl @FExtraImplicitParam.as.I.impl.F.loc85_23.1 [concrete = constants.%FExtraImplicitParam.as.I.impl.F.6ff574.1] { // CHECK:STDOUT: %self.patt: %pattern_type.8ae = binding_pattern self [concrete] @@ -603,6 +732,22 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FExtraImplicitParam.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @FExtraImplicitParam.as.Destroy.impl: constants.%FExtraImplicitParam as constants.%Destroy.type { +// CHECK:STDOUT: %FExtraImplicitParam.as.Destroy.impl.Op.decl: %FExtraImplicitParam.as.Destroy.impl.Op.type = fn_decl @FExtraImplicitParam.as.Destroy.impl.Op [concrete = constants.%FExtraImplicitParam.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.ab8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.ab8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc73: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.8c7 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FExtraImplicitParam [concrete = constants.%FExtraImplicitParam] +// CHECK:STDOUT: %self: %ptr.8c7 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %FExtraImplicitParam.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @FExtraImplicitParam.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @FExtraReturnType.as.I.impl: %Self.ref as %I.ref { // CHECK:STDOUT: %FExtraReturnType.as.I.impl.F.decl: %FExtraReturnType.as.I.impl.F.type = fn_decl @FExtraReturnType.as.I.impl.F [concrete = constants.%FExtraReturnType.as.I.impl.F] { // CHECK:STDOUT: %return.patt: %pattern_type.831 = return_slot_pattern [concrete] @@ -620,6 +765,22 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FExtraReturnType.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @FExtraReturnType.as.Destroy.impl: constants.%FExtraReturnType as constants.%Destroy.type { +// CHECK:STDOUT: %FExtraReturnType.as.Destroy.impl.Op.decl: %FExtraReturnType.as.Destroy.impl.Op.type = fn_decl @FExtraReturnType.as.Destroy.impl.Op [concrete = constants.%FExtraReturnType.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f1c = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f1c = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc90: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.147 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FExtraReturnType [concrete = constants.%FExtraReturnType] +// CHECK:STDOUT: %self: %ptr.147 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %FExtraReturnType.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @FExtraReturnType.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @FMissingParam.as.J.impl: %Self.ref as %J.ref { // CHECK:STDOUT: %FMissingParam.as.J.impl.F.decl.loc117_31.1: %FMissingParam.as.J.impl.F.type.69596c.1 = fn_decl @FMissingParam.as.J.impl.F.loc117_31.1 [concrete = constants.%FMissingParam.as.J.impl.F.738f31.1] { // CHECK:STDOUT: %self.patt: %pattern_type.831 = binding_pattern self [concrete] @@ -661,6 +822,22 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FMissingParam.%J.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @FMissingParam.as.Destroy.impl: constants.%FMissingParam as constants.%Destroy.type { +// CHECK:STDOUT: %FMissingParam.as.Destroy.impl.Op.decl: %FMissingParam.as.Destroy.impl.Op.type = fn_decl @FMissingParam.as.Destroy.impl.Op [concrete = constants.%FMissingParam.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.c8f = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.c8f = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc105: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.fc8 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FMissingParam [concrete = constants.%FMissingParam] +// CHECK:STDOUT: %self: %ptr.fc8 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %FMissingParam.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @FMissingParam.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @FMissingImplicitParam.as.J.impl: %Self.ref as %J.ref { // CHECK:STDOUT: %FMissingImplicitParam.as.J.impl.F.decl.loc130_26.1: %FMissingImplicitParam.as.J.impl.F.type.d97cef.1 = fn_decl @FMissingImplicitParam.as.J.impl.F.loc130_26.1 [concrete = constants.%FMissingImplicitParam.as.J.impl.F.01de92.1] { // CHECK:STDOUT: %b.patt: %pattern_type.831 = binding_pattern b [concrete] @@ -702,6 +879,22 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FMissingImplicitParam.%J.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @FMissingImplicitParam.as.Destroy.impl: constants.%FMissingImplicitParam as constants.%Destroy.type { +// CHECK:STDOUT: %FMissingImplicitParam.as.Destroy.impl.Op.decl: %FMissingImplicitParam.as.Destroy.impl.Op.type = fn_decl @FMissingImplicitParam.as.Destroy.impl.Op [concrete = constants.%FMissingImplicitParam.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.575 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.575 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc121: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.c3c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FMissingImplicitParam [concrete = constants.%FMissingImplicitParam] +// CHECK:STDOUT: %self: %ptr.c3c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %FMissingImplicitParam.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @FMissingImplicitParam.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @FMissingReturnType.as.J.impl: %Self.ref as %J.ref { // CHECK:STDOUT: %FMissingReturnType.as.J.impl.F.decl.loc152_30.1: %FMissingReturnType.as.J.impl.F.type.123d7a.1 = fn_decl @FMissingReturnType.as.J.impl.F.loc152_30.1 [concrete = constants.%FMissingReturnType.as.J.impl.F.c7d02d.1] { // CHECK:STDOUT: %self.patt: %pattern_type.831 = binding_pattern self [concrete] @@ -745,6 +938,22 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FMissingReturnType.%J.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @FMissingReturnType.as.Destroy.impl: constants.%FMissingReturnType as constants.%Destroy.type { +// CHECK:STDOUT: %FMissingReturnType.as.Destroy.impl.Op.decl: %FMissingReturnType.as.Destroy.impl.Op.type = fn_decl @FMissingReturnType.as.Destroy.impl.Op [concrete = constants.%FMissingReturnType.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.585 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.585 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc134: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.41e = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FMissingReturnType [concrete = constants.%FMissingReturnType] +// CHECK:STDOUT: %self: %ptr.41e = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %FMissingReturnType.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @FMissingReturnType.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @FDifferentParamType.as.J.impl: %Self.ref as %J.ref { // CHECK:STDOUT: %FDifferentParamType.as.J.impl.F.decl.loc171_38.1: %FDifferentParamType.as.J.impl.F.type.6b537d.1 = fn_decl @FDifferentParamType.as.J.impl.F.loc171_38.1 [concrete = constants.%FDifferentParamType.as.J.impl.F.04313a.1] { // CHECK:STDOUT: %self.patt: %pattern_type.831 = binding_pattern self [concrete] @@ -791,6 +1000,22 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FDifferentParamType.%J.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @FDifferentParamType.as.Destroy.impl: constants.%FDifferentParamType as constants.%Destroy.type { +// CHECK:STDOUT: %FDifferentParamType.as.Destroy.impl.Op.decl: %FDifferentParamType.as.Destroy.impl.Op.type = fn_decl @FDifferentParamType.as.Destroy.impl.Op [concrete = constants.%FDifferentParamType.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.e0c = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.e0c = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc156: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.f1f = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FDifferentParamType [concrete = constants.%FDifferentParamType] +// CHECK:STDOUT: %self: %ptr.f1f = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %FDifferentParamType.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @FDifferentParamType.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @FDifferentImplicitParamType.as.J.impl: %Self.ref as %J.ref { // CHECK:STDOUT: %FDifferentImplicitParamType.as.J.impl.F.decl.loc184_38.1: %FDifferentImplicitParamType.as.J.impl.F.type.d6232a.1 = fn_decl @FDifferentImplicitParamType.as.J.impl.F.loc184_38.1 [concrete = constants.%FDifferentImplicitParamType.as.J.impl.F.886f70.1] { // CHECK:STDOUT: %self.patt: %pattern_type.9cc = binding_pattern self [concrete] @@ -837,6 +1062,22 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FDifferentImplicitParamType.%J.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @FDifferentImplicitParamType.as.Destroy.impl: constants.%FDifferentImplicitParamType as constants.%Destroy.type { +// CHECK:STDOUT: %FDifferentImplicitParamType.as.Destroy.impl.Op.decl: %FDifferentImplicitParamType.as.Destroy.impl.Op.type = fn_decl @FDifferentImplicitParamType.as.Destroy.impl.Op [concrete = constants.%FDifferentImplicitParamType.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.986 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.986 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc175: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.dc5 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FDifferentImplicitParamType [concrete = constants.%FDifferentImplicitParamType] +// CHECK:STDOUT: %self: %ptr.dc5 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %FDifferentImplicitParamType.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @FDifferentImplicitParamType.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @FDifferentReturnType.as.J.impl: %Self.ref as %J.ref { // CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.decl.loc200_38.1: %FDifferentReturnType.as.J.impl.F.type.d3b58f.1 = fn_decl @FDifferentReturnType.as.J.impl.F.loc200_38.1 [concrete = constants.%FDifferentReturnType.as.J.impl.F.be86c9.1] { // CHECK:STDOUT: %self.patt: %pattern_type.831 = binding_pattern self [concrete] @@ -885,6 +1126,22 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @FDifferentReturnType.%J.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @FDifferentReturnType.as.Destroy.impl: constants.%FDifferentReturnType as constants.%Destroy.type { +// CHECK:STDOUT: %FDifferentReturnType.as.Destroy.impl.Op.decl: %FDifferentReturnType.as.Destroy.impl.Op.type = fn_decl @FDifferentReturnType.as.Destroy.impl.Op [concrete = constants.%FDifferentReturnType.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.246 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.246 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc188: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.954 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%FDifferentReturnType [concrete = constants.%FDifferentReturnType] +// CHECK:STDOUT: %self: %ptr.954 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %FDifferentReturnType.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @FDifferentReturnType.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @SelfNestedBadParam.as.SelfNested.impl: %Self.ref as %SelfNested.ref { // CHECK:STDOUT: %SelfNestedBadParam.as.SelfNested.impl.F.decl.loc223_87.1: %SelfNestedBadParam.as.SelfNested.impl.F.type.f90165.1 = fn_decl @SelfNestedBadParam.as.SelfNested.impl.F.loc223_87.1 [concrete = constants.%SelfNestedBadParam.as.SelfNested.impl.F.fa8d04.1] { // CHECK:STDOUT: %x.patt: %pattern_type.714 = binding_pattern x [concrete] @@ -929,6 +1186,22 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @SelfNestedBadParam.%SelfNested.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @SelfNestedBadParam.as.Destroy.impl: constants.%SelfNestedBadParam as constants.%Destroy.type { +// CHECK:STDOUT: %SelfNestedBadParam.as.Destroy.impl.Op.decl: %SelfNestedBadParam.as.Destroy.impl.Op.type = fn_decl @SelfNestedBadParam.as.Destroy.impl.Op [concrete = constants.%SelfNestedBadParam.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.2a7 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.2a7 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc214: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.4cd = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SelfNestedBadParam [concrete = constants.%SelfNestedBadParam] +// CHECK:STDOUT: %self: %ptr.4cd = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %SelfNestedBadParam.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @SelfNestedBadParam.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @SelfNestedBadReturnType.as.SelfNested.impl: %Self.ref as %SelfNested.ref { // CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc239_112.1: %SelfNestedBadReturnType.as.SelfNested.impl.F.type.0e7d1d.1 = fn_decl @SelfNestedBadReturnType.as.SelfNested.impl.F.loc239_112.1 [concrete = constants.%SelfNestedBadReturnType.as.SelfNested.impl.F.0bc78a.1] { // CHECK:STDOUT: %x.patt: %pattern_type.23f = binding_pattern x [concrete] @@ -973,6 +1246,22 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: witness = @SelfNestedBadReturnType.%SelfNested.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @SelfNestedBadReturnType.as.Destroy.impl: constants.%SelfNestedBadReturnType as constants.%Destroy.type { +// CHECK:STDOUT: %SelfNestedBadReturnType.as.Destroy.impl.Op.decl: %SelfNestedBadReturnType.as.Destroy.impl.Op.type = fn_decl @SelfNestedBadReturnType.as.Destroy.impl.Op [concrete = constants.%SelfNestedBadReturnType.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.4de = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.4de = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc227: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.612 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SelfNestedBadReturnType [concrete = constants.%SelfNestedBadReturnType] +// CHECK:STDOUT: %self: %ptr.612 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %SelfNestedBadReturnType.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @SelfNestedBadReturnType.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @NoF { // CHECK:STDOUT: impl_decl @NoF.as.I.impl [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%NoF [concrete = constants.%NoF] @@ -980,6 +1269,9 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @NoF.as.I.impl [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness.901] +// CHECK:STDOUT: impl_decl @NoF.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@NoF.as.Destroy.impl.%NoF.as.Destroy.impl.Op.decl), @NoF.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.9b3] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -996,6 +1288,9 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @FNotFunction.as.I.impl [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness.44e] +// CHECK:STDOUT: impl_decl @FNotFunction.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@FNotFunction.as.Destroy.impl.%FNotFunction.as.Destroy.impl.Op.decl), @FNotFunction.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.f9b] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1014,6 +1309,9 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @FAlias.as.I.impl [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness.c80] +// CHECK:STDOUT: impl_decl @FAlias.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@FAlias.as.Destroy.impl.%FAlias.as.Destroy.impl.Op.decl), @FAlias.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.740] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1031,6 +1329,9 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (@FExtraParam.as.I.impl.%FExtraParam.as.I.impl.F.decl.loc69_18.2), @FExtraParam.as.I.impl [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness.1f3] +// CHECK:STDOUT: impl_decl @FExtraParam.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@FExtraParam.as.Destroy.impl.%FExtraParam.as.Destroy.impl.Op.decl), @FExtraParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.44a] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1047,6 +1348,9 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (@FExtraImplicitParam.as.I.impl.%FExtraImplicitParam.as.I.impl.F.decl.loc85_23.2), @FExtraImplicitParam.as.I.impl [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness.a7b] +// CHECK:STDOUT: impl_decl @FExtraImplicitParam.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@FExtraImplicitParam.as.Destroy.impl.%FExtraImplicitParam.as.Destroy.impl.Op.decl), @FExtraImplicitParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.a05] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1063,6 +1367,9 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @FExtraReturnType.as.I.impl [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness.59a] +// CHECK:STDOUT: impl_decl @FExtraReturnType.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@FExtraReturnType.as.Destroy.impl.%FExtraReturnType.as.Destroy.impl.Op.decl), @FExtraReturnType.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.3ea] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1079,6 +1386,9 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: %J.impl_witness_table = impl_witness_table (@FMissingParam.as.J.impl.%FMissingParam.as.J.impl.F.decl.loc117_31.2), @FMissingParam.as.J.impl [concrete] // CHECK:STDOUT: %J.impl_witness: = impl_witness %J.impl_witness_table [concrete = constants.%J.impl_witness.4e9] +// CHECK:STDOUT: impl_decl @FMissingParam.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@FMissingParam.as.Destroy.impl.%FMissingParam.as.Destroy.impl.Op.decl), @FMissingParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.672] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1095,6 +1405,9 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: %J.impl_witness_table = impl_witness_table (@FMissingImplicitParam.as.J.impl.%FMissingImplicitParam.as.J.impl.F.decl.loc130_26.2), @FMissingImplicitParam.as.J.impl [concrete] // CHECK:STDOUT: %J.impl_witness: = impl_witness %J.impl_witness_table [concrete = constants.%J.impl_witness.841] +// CHECK:STDOUT: impl_decl @FMissingImplicitParam.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@FMissingImplicitParam.as.Destroy.impl.%FMissingImplicitParam.as.Destroy.impl.Op.decl), @FMissingImplicitParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.ae6] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1111,6 +1424,9 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: %J.impl_witness_table = impl_witness_table (@FMissingReturnType.as.J.impl.%FMissingReturnType.as.J.impl.F.decl.loc152_30.2), @FMissingReturnType.as.J.impl [concrete] // CHECK:STDOUT: %J.impl_witness: = impl_witness %J.impl_witness_table [concrete = constants.%J.impl_witness.e75] +// CHECK:STDOUT: impl_decl @FMissingReturnType.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@FMissingReturnType.as.Destroy.impl.%FMissingReturnType.as.Destroy.impl.Op.decl), @FMissingReturnType.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.8d8] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1127,6 +1443,9 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: %J.impl_witness_table = impl_witness_table (@FDifferentParamType.as.J.impl.%FDifferentParamType.as.J.impl.F.decl.loc171_38.2), @FDifferentParamType.as.J.impl [concrete] // CHECK:STDOUT: %J.impl_witness: = impl_witness %J.impl_witness_table [concrete = constants.%J.impl_witness.cbe] +// CHECK:STDOUT: impl_decl @FDifferentParamType.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@FDifferentParamType.as.Destroy.impl.%FDifferentParamType.as.Destroy.impl.Op.decl), @FDifferentParamType.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.443] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1143,6 +1462,9 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: %J.impl_witness_table = impl_witness_table (@FDifferentImplicitParamType.as.J.impl.%FDifferentImplicitParamType.as.J.impl.F.decl.loc184_38.2), @FDifferentImplicitParamType.as.J.impl [concrete] // CHECK:STDOUT: %J.impl_witness: = impl_witness %J.impl_witness_table [concrete = constants.%J.impl_witness.af2] +// CHECK:STDOUT: impl_decl @FDifferentImplicitParamType.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@FDifferentImplicitParamType.as.Destroy.impl.%FDifferentImplicitParamType.as.Destroy.impl.Op.decl), @FDifferentImplicitParamType.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.c2a] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1159,6 +1481,9 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: %J.impl_witness_table = impl_witness_table (@FDifferentReturnType.as.J.impl.%FDifferentReturnType.as.J.impl.F.decl.loc200_38.2), @FDifferentReturnType.as.J.impl [concrete] // CHECK:STDOUT: %J.impl_witness: = impl_witness %J.impl_witness_table [concrete = constants.%J.impl_witness.bc1] +// CHECK:STDOUT: impl_decl @FDifferentReturnType.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@FDifferentReturnType.as.Destroy.impl.%FDifferentReturnType.as.Destroy.impl.Op.decl), @FDifferentReturnType.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.6d2] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1175,6 +1500,9 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: %SelfNested.impl_witness_table = impl_witness_table (@SelfNestedBadParam.as.SelfNested.impl.%SelfNestedBadParam.as.SelfNested.impl.F.decl.loc223_87.2), @SelfNestedBadParam.as.SelfNested.impl [concrete] // CHECK:STDOUT: %SelfNested.impl_witness: = impl_witness %SelfNested.impl_witness_table [concrete = constants.%SelfNested.impl_witness.e31] +// CHECK:STDOUT: impl_decl @SelfNestedBadParam.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@SelfNestedBadParam.as.Destroy.impl.%SelfNestedBadParam.as.Destroy.impl.Op.decl), @SelfNestedBadParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.908] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1192,6 +1520,9 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: } // CHECK:STDOUT: %SelfNested.impl_witness_table = impl_witness_table (@SelfNestedBadReturnType.as.SelfNested.impl.%SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc239_112.2), @SelfNestedBadReturnType.as.SelfNested.impl [concrete] // CHECK:STDOUT: %SelfNested.impl_witness: = impl_witness %SelfNested.impl_witness_table [concrete = constants.%SelfNested.impl_witness.d5e] +// CHECK:STDOUT: impl_decl @SelfNestedBadReturnType.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@SelfNestedBadReturnType.as.Destroy.impl.%SelfNestedBadReturnType.as.Destroy.impl.Op.decl), @SelfNestedBadReturnType.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.9f5] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1207,8 +1538,14 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: fn(); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @NoF.as.Destroy.impl.Op(%self.param: %ptr.0f9) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @FNotFunction.as.Destroy.impl.Op(%self.param: %ptr.2b2) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @PossiblyF(); // CHECK:STDOUT: +// CHECK:STDOUT: fn @FAlias.as.Destroy.impl.Op(%self.param: %ptr.4bf) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @FExtraParam.as.I.impl.F.loc69_18.1(%b.param: bool); // CHECK:STDOUT: // CHECK:STDOUT: fn @FExtraParam.as.I.impl.F.loc69_18.2() [thunk @FExtraParam.as.I.impl.%FExtraParam.as.I.impl.F.decl.loc69_18.1] { @@ -1217,6 +1554,8 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @FExtraParam.as.Destroy.impl.Op(%self.param: %ptr.0f2) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @FExtraImplicitParam.as.I.impl.F.loc85_23.1(%self.param: %FExtraImplicitParam); // CHECK:STDOUT: // CHECK:STDOUT: fn @FExtraImplicitParam.as.I.impl.F.loc85_23.2() [thunk @FExtraImplicitParam.as.I.impl.%FExtraImplicitParam.as.I.impl.F.decl.loc85_23.1] { @@ -1226,8 +1565,12 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @FExtraImplicitParam.as.Destroy.impl.Op(%self.param: %ptr.8c7) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @FExtraReturnType.as.I.impl.F() -> bool; // CHECK:STDOUT: +// CHECK:STDOUT: fn @FExtraReturnType.as.Destroy.impl.Op(%self.param: %ptr.147) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @J.F(@J.%Self: %J.type) { // CHECK:STDOUT: fn(%self.param: bool, %b.param: bool) -> bool; // CHECK:STDOUT: } @@ -1244,6 +1587,8 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @FMissingParam.as.Destroy.impl.Op(%self.param: %ptr.fc8) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @FMissingImplicitParam.as.J.impl.F.loc130_26.1(%b.param: bool) -> bool; // CHECK:STDOUT: // CHECK:STDOUT: fn @FMissingImplicitParam.as.J.impl.F.loc130_26.2(%self.param: bool, %b.param: bool) -> bool [thunk @FMissingImplicitParam.as.J.impl.%FMissingImplicitParam.as.J.impl.F.decl.loc130_26.1] { @@ -1258,6 +1603,8 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: return %.loc130_26.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @FMissingImplicitParam.as.Destroy.impl.Op(%self.param: %ptr.c3c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @FMissingReturnType.as.J.impl.F.loc152_30.1(%self.param: bool, %b.param: bool); // CHECK:STDOUT: // CHECK:STDOUT: fn @FMissingReturnType.as.J.impl.F.loc152_30.2(%self.param: bool, %b.param: bool) -> bool [thunk @FMissingReturnType.as.J.impl.%FMissingReturnType.as.J.impl.F.decl.loc152_30.1] { @@ -1272,6 +1619,8 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @FMissingReturnType.as.Destroy.impl.Op(%self.param: %ptr.41e) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @FDifferentParamType.as.J.impl.F.loc171_38.1(%self.param: bool, %b.param: %FDifferentParamType) -> bool; // CHECK:STDOUT: // CHECK:STDOUT: fn @FDifferentParamType.as.J.impl.F.loc171_38.2(%self.param: bool, %b.param: bool) -> bool [thunk @FDifferentParamType.as.J.impl.%FDifferentParamType.as.J.impl.F.decl.loc171_38.1] { @@ -1288,6 +1637,8 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: return %.loc171_38.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @FDifferentParamType.as.Destroy.impl.Op(%self.param: %ptr.f1f) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @FDifferentImplicitParamType.as.J.impl.F.loc184_38.1(%self.param: %FDifferentImplicitParamType, %b.param: bool) -> bool; // CHECK:STDOUT: // CHECK:STDOUT: fn @FDifferentImplicitParamType.as.J.impl.F.loc184_38.2(%self.param: bool, %b.param: bool) -> bool [thunk @FDifferentImplicitParamType.as.J.impl.%FDifferentImplicitParamType.as.J.impl.F.decl.loc184_38.1] { @@ -1304,6 +1655,8 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: return %.loc184_38.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @FDifferentImplicitParamType.as.Destroy.impl.Op(%self.param: %ptr.dc5) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @FDifferentReturnType.as.J.impl.F.loc200_38.1(%self.param: bool, %b.param: bool) -> %return.param: %FDifferentReturnType; // CHECK:STDOUT: // CHECK:STDOUT: fn @FDifferentReturnType.as.J.impl.F.loc200_38.2(%self.param: bool, %b.param: bool) -> bool [thunk @FDifferentReturnType.as.J.impl.%FDifferentReturnType.as.J.impl.F.decl.loc200_38.1] { @@ -1316,14 +1669,14 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %.loc200_38.1: ref %FDifferentReturnType = temporary_storage // CHECK:STDOUT: %FDifferentReturnType.as.J.impl.F.call: init %FDifferentReturnType = call %FDifferentReturnType.as.J.impl.F.bound(%self.ref, %b.ref) to %.loc200_38.1 // CHECK:STDOUT: %.loc200_38.2: bool = converted %FDifferentReturnType.as.J.impl.F.call, [concrete = ] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc200_38.1, constants.%T.as.Destroy.impl.Op.ddd -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.ddd, @T.as.Destroy.impl.Op(constants.%FDifferentReturnType) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.b4b] -// CHECK:STDOUT: %bound_method: = bound_method %.loc200_38.1, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %FDifferentReturnType.as.Destroy.impl.Op.bound: = bound_method %.loc200_38.1, constants.%FDifferentReturnType.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.954 = addr_of %.loc200_38.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %FDifferentReturnType.as.Destroy.impl.Op.call: init %empty_tuple.type = call %FDifferentReturnType.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @FDifferentReturnType.as.Destroy.impl.Op(%self.param: %ptr.954) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @SelfNested.F(@SelfNested.%Self: %SelfNested.type) { // CHECK:STDOUT: %Self: %SelfNested.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.2ff)] // CHECK:STDOUT: %Self.as_type.loc211_16.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc211_16.1 (constants.%Self.as_type.e1e)] @@ -1351,13 +1704,15 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %.loc211_9.2: %i32 = converted %.loc211_9.1, [concrete = ] // CHECK:STDOUT: %SelfNestedBadParam.as.SelfNested.impl.F.call: init %array_type.a41 = call %F.ref() to %.loc211_41 // CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc211_41, constants.%T.as.Destroy.impl.Op.d25 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d25, @T.as.Destroy.impl.Op(constants.%array_type.a41) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.235] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d25, @T.as.Destroy.impl.Op(constants.%array_type.a41) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method: = bound_method %.loc211_41, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr: %ptr.f40 = addr_of %.loc211_41 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) // CHECK:STDOUT: return %SelfNestedBadParam.as.SelfNested.impl.F.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @SelfNestedBadParam.as.Destroy.impl.Op(%self.param: %ptr.4cd) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @SelfNestedBadReturnType.as.SelfNested.impl.F.loc239_112.1(%x.param: %tuple.type.eb9) -> %return.param: %array_type.a41; // CHECK:STDOUT: // CHECK:STDOUT: fn @SelfNestedBadReturnType.as.SelfNested.impl.F.loc239_112.2(%x.param: %tuple.type.eb9) -> %return.param: %array_type.126 [thunk @SelfNestedBadReturnType.as.SelfNested.impl.%SelfNestedBadReturnType.as.SelfNested.impl.F.decl.loc239_112.1] { @@ -1369,13 +1724,15 @@ class SelfNestedBadReturnType { // CHECK:STDOUT: %SelfNestedBadReturnType.as.SelfNested.impl.F.call: init %array_type.a41 = call %F.ref(%x.ref) to %.loc239_112.1 // CHECK:STDOUT: %.loc239_112.2: %array_type.126 = converted %SelfNestedBadReturnType.as.SelfNested.impl.F.call, [concrete = ] // CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc239_112.1, constants.%T.as.Destroy.impl.Op.d25 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d25, @T.as.Destroy.impl.Op(constants.%array_type.a41) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.235] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d25, @T.as.Destroy.impl.Op(constants.%array_type.a41) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method: = bound_method %.loc239_112.1, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr: %ptr.f40 = addr_of %.loc239_112.1 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) // CHECK:STDOUT: return to %return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @SelfNestedBadReturnType.as.Destroy.impl.Op(%self.param: %ptr.612) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @I.F(constants.%Self.826) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @I.F(constants.%I.facet.fa4) {} diff --git a/toolchain/check/testdata/impl/fail_self_type_mismatch.carbon b/toolchain/check/testdata/impl/fail_self_type_mismatch.carbon index 5b22c4b6d3a1..50e76d242932 100644 --- a/toolchain/check/testdata/impl/fail_self_type_mismatch.carbon +++ b/toolchain/check/testdata/impl/fail_self_type_mismatch.carbon @@ -54,6 +54,14 @@ impl i32 as I { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.b36: type = class_type @C, @C(%T, %X) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.e7a: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T, %X) [symbolic] +// CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] +// CHECK:STDOUT: %ptr.555: type = ptr_type %C.b36 [symbolic] +// CHECK:STDOUT: %pattern_type.7e5: type = pattern_type %ptr.555 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T, %X) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] @@ -87,18 +95,22 @@ impl i32 as I { // CHECK:STDOUT: %pattern_type.c65: type = pattern_type %C.d88 [concrete] // CHECK:STDOUT: %i32.as.I.impl.F.type.066a53.2: type = fn_type @i32.as.I.impl.F.loc43_18.2 [concrete] // CHECK:STDOUT: %i32.as.I.impl.F.9ec58f.2: %i32.as.I.impl.F.type.066a53.2 = struct_value () [concrete] +// CHECK:STDOUT: %complete_type.acb: = complete_type_witness %I.type [concrete] +// CHECK:STDOUT: %complete_type.473: = complete_type_witness type [concrete] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Bool = %Core.Bool // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Bool: %Bool.type = import_ref Core//prelude/parts/bool, Bool, loaded [concrete = constants.%Bool] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] @@ -160,6 +172,35 @@ impl i32 as I { // CHECK:STDOUT: witness = (%I.F.decl) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc15_9.2: type, @C.%X.loc15_19.2: @C.%T.loc15_9.1 (%T)) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %X: @C.as.Destroy.impl.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T, %X) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.e7a)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T, %X) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.b36 as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.7e5) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.7e5) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15_26.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.555) = value_param call_param0 +// CHECK:STDOUT: %.loc15_26.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.b36)] { +// CHECK:STDOUT: %.loc15_26.3: type = specific_constant constants.%C.b36, @C(constants.%T, constants.%X) [symbolic = %C (constants.%C.b36)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc15_26.3 [symbolic = %C (constants.%C.b36)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.555) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @bool.as.I.impl: %.loc28_6.2 as %I.ref { // CHECK:STDOUT: %bool.as.I.impl.F.decl: %bool.as.I.impl.F.type = fn_decl @bool.as.I.impl.F [concrete = constants.%bool.as.I.impl.F] { // CHECK:STDOUT: %c.patt: %pattern_type.225 = binding_pattern c [concrete] @@ -218,8 +259,12 @@ impl i32 as I { // CHECK:STDOUT: %pattern_type: type = pattern_type %T.loc15_9.1 [symbolic = %pattern_type (constants.%pattern_type.7dcd0a.1)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type %T.loc15_9.1 [symbolic = %require_complete (constants.%require_complete.4ae)] // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T, constants.%X) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.e7a)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -229,6 +274,18 @@ impl i32 as I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc15_9.2: type, @C.%X.loc15_19.2: @C.%T.loc15_9.1 (%T)) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %X: @C.as.Destroy.impl.Op.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T, %X) [symbolic = %C (constants.%C.b36)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.555)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.7e5)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.555)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @I.F(@I.%Self: %I.type) { // CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)] // CHECK:STDOUT: %C.loc25_17.1: type = class_type @C, @C(constants.%I.type, %Self) [symbolic = %C.loc25_17.1 (constants.%C.dbb)] @@ -256,6 +313,20 @@ impl i32 as I { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.7dcd0a.1 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T, constants.%X) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.e7a +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T, constants.%X) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %C => constants.%C.b36 +// CHECK:STDOUT: %ptr => constants.%ptr.555 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.7e5 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%I.type, constants.%Self.826) { // CHECK:STDOUT: %T.loc15_9.1 => constants.%I.type // CHECK:STDOUT: %X.loc15_19.1 => constants.%Self.826 @@ -286,6 +357,7 @@ impl i32 as I { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.98f // CHECK:STDOUT: // CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete => constants.%complete_type.473 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @I.F(constants.%I.facet.118) { @@ -300,5 +372,6 @@ impl i32 as I { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.2b5 // CHECK:STDOUT: // CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete => constants.%complete_type.acb // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/forward_decls.carbon b/toolchain/check/testdata/impl/forward_decls.carbon index 0f00f011ff47..588507396172 100644 --- a/toolchain/check/testdata/impl/forward_decls.carbon +++ b/toolchain/check/testdata/impl/forward_decls.carbon @@ -582,10 +582,18 @@ interface I { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self] @@ -593,19 +601,20 @@ interface I { // CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self, @I [symbolic_self] // CHECK:STDOUT: %I.facet.74c: %I.type = facet_value %.Self.as_type, (%I.lookup_impl_witness) [symbolic_self] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_tuple.type> [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness file.%I.impl_witness_table [concrete] // CHECK:STDOUT: %I.facet.880: %I.type = facet_value %C, (%I.impl_witness) [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete] +// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete] // CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -637,7 +646,7 @@ interface I { // CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness] // CHECK:STDOUT: %impl_witness_assoc_constant: type = impl_witness_assoc_constant constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %x.patt: %pattern_type = binding_pattern x [concrete] +// CHECK:STDOUT: %x.patt: %pattern_type.cb1 = binding_pattern x [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %.loc9_9.1: type = splice_block %impl.elem0 [concrete = constants.%empty_tuple.type] { // CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [concrete = constants.%C] @@ -668,7 +677,7 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826] // CHECK:STDOUT: %T: type = assoc_const_decl @T [concrete] { // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [concrete = constants.%assoc0] // CHECK:STDOUT: } @@ -683,12 +692,31 @@ interface I { // CHECK:STDOUT: assoc_const T:! type; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.I.impl: %C.ref.loc7 as %.loc7_13 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -697,13 +725,15 @@ interface I { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc9: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @T(constants.%Self) {} +// CHECK:STDOUT: specific @T(constants.%Self.826) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @T(constants.%I.facet.74c) {} // CHECK:STDOUT: @@ -713,10 +743,18 @@ interface I { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self] @@ -724,19 +762,20 @@ interface I { // CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self, @I [symbolic_self] // CHECK:STDOUT: %I.facet.74c: %I.type = facet_value %.Self.as_type, (%I.lookup_impl_witness) [symbolic_self] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_tuple.type> [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness file.%I.impl_witness_table [concrete] // CHECK:STDOUT: %I.facet.880: %I.type = facet_value %C, (%I.impl_witness) [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete] +// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete] // CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -768,7 +807,7 @@ interface I { // CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness] // CHECK:STDOUT: %impl_witness_assoc_constant: type = impl_witness_assoc_constant constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %x.patt: %pattern_type = binding_pattern x [concrete] +// CHECK:STDOUT: %x.patt: %pattern_type.cb1 = binding_pattern x [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %.loc9_16.1: type = splice_block %impl.elem0 [concrete = constants.%empty_tuple.type] { // CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [concrete = constants.%C] @@ -801,7 +840,7 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826] // CHECK:STDOUT: %T: type = assoc_const_decl @T [concrete] { // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [concrete = constants.%assoc0] // CHECK:STDOUT: } @@ -816,12 +855,31 @@ interface I { // CHECK:STDOUT: assoc_const T:! type; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.I.impl: %C.ref.loc7 as %.loc7_13 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -830,13 +888,15 @@ interface I { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc9: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @T(constants.%Self) {} +// CHECK:STDOUT: specific @T(constants.%Self.826) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @T(constants.%I.facet.74c) {} // CHECK:STDOUT: @@ -846,22 +906,31 @@ interface I { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness file.%I.impl_witness_table [concrete] // CHECK:STDOUT: %I.facet: %I.type = facet_value %C, (%I.impl_witness) [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -901,7 +970,7 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826] // CHECK:STDOUT: %T: type = assoc_const_decl @T [concrete] { // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [concrete = constants.%assoc0] // CHECK:STDOUT: } @@ -916,12 +985,31 @@ interface I { // CHECK:STDOUT: assoc_const T:! type; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.I.impl: %C.ref.loc7 as %I.ref.loc7 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -930,13 +1018,15 @@ interface I { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc13: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @T(constants.%Self) {} +// CHECK:STDOUT: specific @T(constants.%Self.826) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @T(constants.%I.facet) {} // CHECK:STDOUT: @@ -946,17 +1036,31 @@ interface I { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -996,7 +1100,7 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = %Self @@ -1004,12 +1108,47 @@ interface I { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @D.as..impl: %D.ref.loc13 as %.loc13 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc16: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1019,6 +1158,9 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1027,11 +1169,15 @@ interface I { // CHECK:STDOUT: .Self = constants.%D // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- associated_const_of_parameterized.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic] -// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete] +// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %I.type.dac: type = generic_interface_type @I [concrete] // CHECK:STDOUT: %I.generic: %I.type.dac = struct_value () [concrete] // CHECK:STDOUT: %I.type.325: type = facet_type <@I, @I(%U)> [symbolic] @@ -1040,6 +1186,13 @@ interface I { // CHECK:STDOUT: %assoc0.7f3: %I.assoc_type.1e5 = assoc_entity element0, @I.%T [symbolic] // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %I.type.e7a: type = facet_type <@I, @I(%C)> [concrete] @@ -1053,13 +1206,20 @@ interface I { // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self] // CHECK:STDOUT: %I_where.type: type = facet_type <@I, @I(%C) where %impl.elem0 = %C> [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness file.%I.impl_witness_table [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1071,7 +1231,7 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %I.decl: %I.type.dac = interface_decl @I [concrete = constants.%I.generic] { -// CHECK:STDOUT: %U.patt: %pattern_type = symbolic_binding_pattern U, 0 [concrete] +// CHECK:STDOUT: %U.patt: %pattern_type.98f = symbolic_binding_pattern U, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %U.loc3_13.2: type = bind_symbolic_name U, 0 [symbolic = %U.loc3_13.1 (constants.%U)] // CHECK:STDOUT: } @@ -1143,12 +1303,47 @@ interface I { // CHECK:STDOUT: assoc_const T:! type; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @D.as.I.impl: %D.ref.loc8 as %.loc8_16 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc10: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1158,6 +1353,9 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1166,6 +1364,10 @@ interface I { // CHECK:STDOUT: .Self = constants.%D // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @I(constants.%U) { // CHECK:STDOUT: %U.loc3_13.1 => constants.%U // CHECK:STDOUT: } @@ -1189,6 +1391,13 @@ interface I { // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness file.%I.impl_witness_table [concrete] @@ -1202,14 +1411,21 @@ interface I { // CHECK:STDOUT: %pattern_type.da9: type = pattern_type %C.8b1 [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.2b7: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.777: type = ptr_type %C.54e [symbolic] +// CHECK:STDOUT: %pattern_type.610: type = pattern_type %ptr.777 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1277,19 +1493,66 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = %Self // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @D.as.I.impl: %D.ref.loc5 as %I.ref.loc5 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc12: %I.type) { +// CHECK:STDOUT: %T: %I.type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.2b7)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.54e as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.610) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.610) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12_16.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.777) = value_param call_param0 +// CHECK:STDOUT: %.loc12_16.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.54e)] { +// CHECK:STDOUT: %.loc12_16.3: type = specific_constant constants.%C.54e, @C(constants.%T) [symbolic = %C (constants.%C.54e)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc12_16.3 [symbolic = %C (constants.%C.54e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.777) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1304,6 +1567,9 @@ interface I { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.2b7)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1313,11 +1579,24 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%x.param.loc14: %C.8b1) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc12: %I.type) { +// CHECK:STDOUT: %T: %I.type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.54e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.777)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.610)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.777)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%T) { // CHECK:STDOUT: %T.loc6_9.1 => constants.%T // CHECK:STDOUT: } @@ -1328,6 +1607,18 @@ interface I { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.2b7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.54e +// CHECK:STDOUT: %ptr => constants.%ptr.777 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.610 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_todo_two_interfaces.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -1406,11 +1697,19 @@ interface I { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [concrete] // CHECK:STDOUT: %assoc1: %I.assoc_type = assoc_entity element1, @I.%U [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self] @@ -1418,16 +1717,17 @@ interface I { // CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %.Self, @I [symbolic_self] // CHECK:STDOUT: %I.facet: %I.type = facet_value %.Self.as_type, (%I.lookup_impl_witness) [symbolic_self] // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %I_where.type: type = facet_type <@I where %impl.elem0 = %empty_tuple.type> [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness file.%I.impl_witness_table [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1475,7 +1775,7 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826] // CHECK:STDOUT: %T: type = assoc_const_decl @T [concrete] { // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%T [concrete = constants.%assoc0] // CHECK:STDOUT: } @@ -1498,12 +1798,31 @@ interface I { // CHECK:STDOUT: assoc_const U:! type; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.I.impl: %C.ref.loc9 as %.loc9_13 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1512,9 +1831,11 @@ interface I { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @T(constants.%Self) {} +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; // CHECK:STDOUT: -// CHECK:STDOUT: specific @U(constants.%Self) {} +// CHECK:STDOUT: specific @T(constants.%Self.826) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @U(constants.%Self.826) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @T(constants.%I.facet) {} // CHECK:STDOUT: @@ -1535,6 +1856,13 @@ interface I { // CHECK:STDOUT: %X.impl_witness: = impl_witness file.%X.impl_witness_table [concrete] // CHECK:STDOUT: %Y.type: type = facet_type <@Y> [concrete] // CHECK:STDOUT: %Self.e5e: %X.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] @@ -1550,9 +1878,11 @@ interface I { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1665,12 +1995,31 @@ interface I { // CHECK:STDOUT: witness = file.%X.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc23: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.Y.impl: %C.ref.loc36 as %Y.ref.loc36 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%Y.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1704,6 +2053,8 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @H(%c.param: %C) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl.loc6 [concrete = constants.%F] @@ -1752,22 +2103,31 @@ interface I { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %I.F.type: type = fn_type @I.F [concrete] // CHECK:STDOUT: %I.F: %I.F.type = struct_value () [concrete] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%I.F.decl [concrete] -// CHECK:STDOUT: %C: type = class_type @C, @C(%Self) [symbolic] +// CHECK:STDOUT: %C: type = class_type @C, @C(%Self.826) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%Self.826) [symbolic] +// CHECK:STDOUT: %ptr.ec7: type = ptr_type %C [symbolic] +// CHECK:STDOUT: %pattern_type.6b6: type = pattern_type %ptr.ec7 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%Self.826) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %I.impl_witness: = impl_witness @I.F.%I.impl_witness_table, @C.as.I.impl(%Self) [symbolic] +// CHECK:STDOUT: %I.impl_witness: = impl_witness @I.F.%I.impl_witness_table, @C.as.I.impl(%Self.826) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1780,7 +2140,7 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826] // CHECK:STDOUT: %I.F.decl: %I.F.type = fn_decl @I.F [concrete = constants.%I.F] {} {} // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, %I.F.decl [concrete = constants.%assoc0] // CHECK:STDOUT: @@ -1791,8 +2151,36 @@ interface I { // CHECK:STDOUT: witness = (%I.F.decl) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@I.%Self: %I.type) { +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%Self) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%Self) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.6b6) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.6b6) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc10_13.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.ec7) = value_param call_param0 +// CHECK:STDOUT: %.loc10_13.2: type = splice_block %Self.ref [symbolic = %C (constants.%C)] { +// CHECK:STDOUT: %.loc10_13.3: type = specific_constant constants.%C, @C(constants.%Self.826) [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc10_13.3 [symbolic = %C (constants.%C)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.ec7) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl @C.as.I.impl(@I.%Self: %I.type) { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)] // CHECK:STDOUT: %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C)] // CHECK:STDOUT: %I.impl_witness: = impl_witness @I.F.%I.impl_witness_table, @C.as.I.impl(%Self) [symbolic = %I.impl_witness (constants.%I.impl_witness)] // CHECK:STDOUT: @@ -1809,6 +2197,9 @@ interface I { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%Self.826) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1820,7 +2211,7 @@ interface I { // CHECK:STDOUT: // CHECK:STDOUT: generic fn @I.F(@I.%Self: %I.type) { // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)] // CHECK:STDOUT: %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C)] // CHECK:STDOUT: // CHECK:STDOUT: fn() { @@ -1831,7 +2222,7 @@ interface I { // CHECK:STDOUT: %I.ref.loc11: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: } // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @C.as.I.impl [concrete] -// CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table, @C.as.I.impl(constants.%Self) [symbolic = @C.as.I.impl.%I.impl_witness (constants.%I.impl_witness)] +// CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table, @C.as.I.impl(constants.%Self.826) [symbolic = @C.as.I.impl.%I.impl_witness (constants.%I.impl_witness)] // CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { // CHECK:STDOUT: %C.ref.loc20: type = name_ref C, @I.F.%C.decl [symbolic = %C (constants.%C)] // CHECK:STDOUT: %I.ref.loc20: type = name_ref I, file.%I.decl [concrete = constants.%I.type] @@ -1840,12 +2231,35 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @I.F(constants.%Self) {} +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@I.%Self: %I.type) { +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.ec7)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.6b6)] // CHECK:STDOUT: -// CHECK:STDOUT: specific @C(constants.%Self) {} +// CHECK:STDOUT: !definition: // CHECK:STDOUT: -// CHECK:STDOUT: specific @C.as.I.impl(constants.%Self) { -// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.ec7)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I.F(constants.%Self.826) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%Self.826) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%Self.826) { +// CHECK:STDOUT: %Self => constants.%Self.826 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%Self.826) { +// CHECK:STDOUT: %Self => constants.%Self.826 +// CHECK:STDOUT: %C => constants.%C +// CHECK:STDOUT: %ptr => constants.%ptr.ec7 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.6b6 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.I.impl(constants.%Self.826) { +// CHECK:STDOUT: %Self => constants.%Self.826 // CHECK:STDOUT: %C => constants.%C // CHECK:STDOUT: %I.impl_witness => constants.%I.impl_witness // CHECK:STDOUT: } @@ -1854,13 +2268,20 @@ interface I { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%U [concrete] // CHECK:STDOUT: %I.F.type: type = fn_type @I.F [concrete] // CHECK:STDOUT: %I.F: %I.F.type = struct_value () [concrete] // CHECK:STDOUT: %assoc1: %I.assoc_type = assoc_entity element1, @I.%I.F.decl [concrete] -// CHECK:STDOUT: %C: type = class_type @C, @C(%Self) [symbolic] +// CHECK:STDOUT: %C: type = class_type @C, @C(%Self.826) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%Self.826) [symbolic] +// CHECK:STDOUT: %ptr.ec7: type = ptr_type %C [symbolic] +// CHECK:STDOUT: %pattern_type.6b6: type = pattern_type %ptr.ec7 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%Self.826) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %.Self: %I.type = bind_symbolic_name .Self [symbolic_self] @@ -1870,14 +2291,16 @@ interface I { // CHECK:STDOUT: %impl.elem0: type = impl_witness_access %I.lookup_impl_witness, element0 [symbolic_self] // CHECK:STDOUT: %I_where.type: type = facet_type <@I where %impl.elem0 = %C> [symbolic] // CHECK:STDOUT: %require_complete: = require_complete_type %I_where.type [symbolic] -// CHECK:STDOUT: %I.impl_witness: = impl_witness @I.F.%I.impl_witness_table, @C.as.I.impl(%Self) [symbolic] +// CHECK:STDOUT: %I.impl_witness: = impl_witness @I.F.%I.impl_witness_table, @C.as.I.impl(%Self.826) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1890,7 +2313,7 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826] // CHECK:STDOUT: %U: type = assoc_const_decl @U [concrete] { // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%U [concrete = constants.%assoc0] // CHECK:STDOUT: } @@ -1909,8 +2332,36 @@ interface I { // CHECK:STDOUT: assoc_const U:! type; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@I.%Self: %I.type) { +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%Self) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%Self) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.6b6) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.6b6) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc11_13.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.ec7) = value_param call_param0 +// CHECK:STDOUT: %.loc11_13.2: type = splice_block %Self.ref [symbolic = %C (constants.%C)] { +// CHECK:STDOUT: %.loc11_13.3: type = specific_constant constants.%C, @C(constants.%Self.826) [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc11_13.3 [symbolic = %C (constants.%C)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.ec7) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl @C.as.I.impl(@I.%Self: %I.type) { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)] // CHECK:STDOUT: %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C)] // CHECK:STDOUT: %I_where.type: type = facet_type <@I where constants.%impl.elem0 = %C> [symbolic = %I_where.type (constants.%I_where.type)] // CHECK:STDOUT: %require_complete: = require_complete_type %I_where.type [symbolic = %require_complete (constants.%require_complete)] @@ -1929,6 +2380,9 @@ interface I { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%Self.826) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1940,7 +2394,7 @@ interface I { // CHECK:STDOUT: // CHECK:STDOUT: generic fn @I.F(@I.%Self: %I.type) { // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)] // CHECK:STDOUT: %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C)] // CHECK:STDOUT: // CHECK:STDOUT: fn() { @@ -1961,7 +2415,7 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (%impl_witness_assoc_constant, ), @C.as.I.impl [concrete] -// CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table, @C.as.I.impl(constants.%Self) [symbolic = @C.as.I.impl.%I.impl_witness (constants.%I.impl_witness)] +// CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table, @C.as.I.impl(constants.%Self.826) [symbolic = @C.as.I.impl.%I.impl_witness (constants.%I.impl_witness)] // CHECK:STDOUT: %impl_witness_assoc_constant: type = impl_witness_assoc_constant constants.%C [symbolic = @C.as.I.impl.%C (constants.%C)] // CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { // CHECK:STDOUT: %C.ref.loc21_10: type = name_ref C, @I.F.%C.decl [symbolic = %C (constants.%C)] @@ -1981,16 +2435,39 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @U(constants.%Self) {} +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@I.%Self: %I.type) { +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.ec7)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.6b6)] // CHECK:STDOUT: -// CHECK:STDOUT: specific @I.F(constants.%Self) {} +// CHECK:STDOUT: !definition: // CHECK:STDOUT: -// CHECK:STDOUT: specific @C(constants.%Self) {} +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.ec7)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @U(constants.%Self.826) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @I.F(constants.%Self.826) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%Self.826) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%Self.826) { +// CHECK:STDOUT: %Self => constants.%Self.826 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%Self.826) { +// CHECK:STDOUT: %Self => constants.%Self.826 +// CHECK:STDOUT: %C => constants.%C +// CHECK:STDOUT: %ptr => constants.%ptr.ec7 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.6b6 +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @U(constants.%I.facet) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @C.as.I.impl(constants.%Self) { -// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: specific @C.as.I.impl(constants.%Self.826) { +// CHECK:STDOUT: %Self => constants.%Self.826 // CHECK:STDOUT: %C => constants.%C // CHECK:STDOUT: %I_where.type => constants.%I_where.type // CHECK:STDOUT: %require_complete => constants.%require_complete diff --git a/toolchain/check/testdata/impl/impl_as.carbon b/toolchain/check/testdata/impl/impl_as.carbon index 29b4745dc493..e6c2996cba6e 100644 --- a/toolchain/check/testdata/impl/impl_as.carbon +++ b/toolchain/check/testdata/impl/impl_as.carbon @@ -40,15 +40,17 @@ class C { // CHECK:STDOUT: %C.as.Simple.impl.F.type: type = fn_type @C.as.Simple.impl.F [concrete] // CHECK:STDOUT: %C.as.Simple.impl.F: %C.as.Simple.impl.F.type = struct_value () [concrete] // CHECK:STDOUT: %Simple.facet: %Simple.type = facet_value %C, (%Simple.impl_witness) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -91,6 +93,22 @@ class C { // CHECK:STDOUT: witness = @C.%Simple.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc19: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: impl_decl @C.as.Simple.impl [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] @@ -98,8 +116,11 @@ class C { // CHECK:STDOUT: } // CHECK:STDOUT: %Simple.impl_witness_table = impl_witness_table (@C.as.Simple.impl.%C.as.Simple.impl.F.decl), @C.as.Simple.impl [concrete] // CHECK:STDOUT: %Simple.impl_witness: = impl_witness %Simple.impl_witness_table [concrete = constants.%Simple.impl_witness] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -125,14 +146,14 @@ class C { // CHECK:STDOUT: assign %c.var, %.loc23_7 // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %c: ref %C = bind_name c, %c.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %c.var, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.019 = addr_of %c.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @Simple.F(constants.%Self.3c9) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @Simple.F(constants.%Simple.facet) {} diff --git a/toolchain/check/testdata/impl/impl_thunk.carbon b/toolchain/check/testdata/impl/impl_thunk.carbon index 4433e79fbc44..f2710440b08e 100644 --- a/toolchain/check/testdata/impl/impl_thunk.carbon +++ b/toolchain/check/testdata/impl/impl_thunk.carbon @@ -404,16 +404,16 @@ impl () as I({}) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %A: type = class_type @A [concrete] -// CHECK:STDOUT: %B: type = class_type @B [concrete] -// CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] // CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] // CHECK:STDOUT: %B.as.X.impl.F.type.f1b0b1.1: type = fn_type @B.as.X.impl.F.loc14_39.1 [concrete] // CHECK:STDOUT: %B.as.X.impl.F.5161e9.1: %B.as.X.impl.F.type.f1b0b1.1 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] // CHECK:STDOUT: %B.as.X.impl.F.type.f1b0b1.2: type = fn_type @B.as.X.impl.F.loc14_39.2 [concrete] // CHECK:STDOUT: %B.as.X.impl.F.5161e9.2: %B.as.X.impl.F.type.f1b0b1.2 = struct_value () [concrete] // CHECK:STDOUT: } @@ -483,8 +483,8 @@ impl () as I({}) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %A: type = class_type @A [concrete] -// CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %pattern_type.c10: type = pattern_type %A [concrete] // CHECK:STDOUT: %B.as.X.impl.F.type.f1b0b1.1: type = fn_type @B.as.X.impl.F.loc13_26.1 [concrete] // CHECK:STDOUT: %B.as.X.impl.F.5161e9.1: %B.as.X.impl.F.type.f1b0b1.1 = struct_value () [concrete] @@ -537,16 +537,16 @@ impl () as I({}) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %A: type = class_type @A [concrete] -// CHECK:STDOUT: %B: type = class_type @B [concrete] -// CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] // CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] // CHECK:STDOUT: %B.as.X.impl.F.type.f1b0b1.1: type = fn_type @B.as.X.impl.F.loc14_39.1 [concrete] // CHECK:STDOUT: %B.as.X.impl.F.5161e9.1: %B.as.X.impl.F.type.f1b0b1.1 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] // CHECK:STDOUT: %B.as.X.impl.F.type.f1b0b1.2: type = fn_type @B.as.X.impl.F.loc14_39.2 [concrete] // CHECK:STDOUT: %B.as.X.impl.F.5161e9.2: %B.as.X.impl.F.type.f1b0b1.2 = struct_value () [concrete] // CHECK:STDOUT: } @@ -616,16 +616,16 @@ impl () as I({}) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %A: type = class_type @A [concrete] -// CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.049: type = pattern_type %B [concrete] // CHECK:STDOUT: %A.as.X.impl.F.type.b24d6f.1: type = fn_type @A.as.X.impl.F.loc20_14.1 [concrete] // CHECK:STDOUT: %A.as.X.impl.F.77e9d5.1: %A.as.X.impl.F.type.b24d6f.1 = struct_value () [concrete] // CHECK:STDOUT: %A.as.X.impl.F.type.b24d6f.2: type = fn_type @A.as.X.impl.F.loc20_14.2 [concrete] // CHECK:STDOUT: %A.as.X.impl.F.77e9d5.2: %A.as.X.impl.F.type.b24d6f.2 = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.1a6: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%B) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.3c2: %T.as.Destroy.impl.Op.type.1a6 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -664,11 +664,9 @@ impl () as I({}) { // CHECK:STDOUT: %.loc20_14.3: ref %A = class_element_access %.loc20_14.2, element0 // CHECK:STDOUT: %.loc20_14.4: ref %A = converted %A.as.X.impl.F.call, %.loc20_14.3 // CHECK:STDOUT: %.loc20_14.5: %A = bind_value %.loc20_14.4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc20_14.1, constants.%T.as.Destroy.impl.Op.3c2 -// CHECK:STDOUT: -// CHECK:STDOUT: %bound_method: = bound_method %.loc20_14.1, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %B.as.Destroy.impl.Op.bound: = bound_method %.loc20_14.1, constants.%B.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.e79 = addr_of %.loc20_14.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %B.as.Destroy.impl.Op.call: init %empty_tuple.type = call %B.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return to %return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/import_thunk.carbon b/toolchain/check/testdata/impl/import_thunk.carbon index b5ed21f89cb4..609a351fd0a5 100644 --- a/toolchain/check/testdata/impl/import_thunk.carbon +++ b/toolchain/check/testdata/impl/import_thunk.carbon @@ -106,6 +106,15 @@ fn G() { // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.13320f.1: type = class_type @C, @C(%X) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] +// CHECK:STDOUT: %Destroy.Op: %Destroy.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.35ec57.1: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%X) [symbolic] +// CHECK:STDOUT: %ptr.40dc71.1: type = ptr_type %C.13320f.1 [symbolic] +// CHECK:STDOUT: %pattern_type.2a1e48.1: type = pattern_type %ptr.40dc71.1 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%X) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Y: %empty_tuple.type = bind_symbolic_name Y, 0 [symbolic] @@ -125,18 +134,16 @@ fn G() { // CHECK:STDOUT: %require_complete.a35: = require_complete_type %C.13320f.2 [symbolic] // CHECK:STDOUT: %C.as.I.impl.F.specific_fn: = specific_function %C.as.I.impl.F.49c1ac.1, @C.as.I.impl.F.loc8_17.1(%Y) [symbolic] // CHECK:STDOUT: %C.val: %C.13320f.2 = struct_value () [symbolic] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %Destroy.assoc_type: type = assoc_entity_type @Destroy [concrete] // CHECK:STDOUT: %assoc0: %Destroy.assoc_type = assoc_entity element0, imports.%Core.import_ref.725 [concrete] -// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] -// CHECK:STDOUT: %Destroy.Op: %Destroy.Op.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr.40d: type = ptr_type %C.13320f.2 [symbolic] -// CHECK:STDOUT: %require_complete.0b0: = require_complete_type %ptr.40d [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.35ec57.2: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%Y) [symbolic] +// CHECK:STDOUT: %ptr.40dc71.2: type = ptr_type %C.13320f.2 [symbolic] +// CHECK:STDOUT: %require_complete.0b0: = require_complete_type %ptr.40dc71.2 [symbolic] // CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %C.13320f.2, @Destroy [symbolic] -// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %C.13320f.2, (%Destroy.lookup_impl_witness) [symbolic] -// CHECK:STDOUT: %.97f: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet [symbolic] +// CHECK:STDOUT: %Destroy.facet.6e0: %Destroy.type = facet_value %C.13320f.2, (%Destroy.lookup_impl_witness) [symbolic] +// CHECK:STDOUT: %.97f: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.6e0 [symbolic] // CHECK:STDOUT: %impl.elem0: %.97f = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic] -// CHECK:STDOUT: %specific_impl_fn: = specific_impl_function %impl.elem0, @Destroy.Op(%Destroy.facet) [symbolic] +// CHECK:STDOUT: %specific_impl_fn: = specific_impl_function %impl.elem0, @Destroy.Op(%Destroy.facet.6e0) [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -146,12 +153,12 @@ fn G() { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Core.import_ref.f99: %Destroy.assoc_type = import_ref Core//prelude/parts/destroy, loc5_28, loaded [concrete = constants.%assoc0] // CHECK:STDOUT: %Main.import_ref.e5d = import_ref Main//a, inst19 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.507 = import_ref Main//a, loc5_14, unloaded // CHECK:STDOUT: %Main.F: %I.F.type = import_ref Main//a, F, loaded [concrete = constants.%I.F] // CHECK:STDOUT: %Main.import_ref.5dd: %I.type = import_ref Main//a, inst19 [no loc], loaded [symbolic = constants.%Self.826] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] -// CHECK:STDOUT: %Core.import_ref.f99: %Destroy.assoc_type = import_ref Core//prelude/parts/destroy, loc5_28, loaded [concrete = constants.%assoc0] // CHECK:STDOUT: %Core.import_ref.725: %Destroy.Op.type = import_ref Core//prelude/parts/destroy, loc5_28, loaded [concrete = constants.%Destroy.Op] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -196,6 +203,34 @@ fn G() { // CHECK:STDOUT: witness = (imports.%Main.F) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%X.loc5_9.2: %empty_tuple.type) { +// CHECK:STDOUT: %X: %empty_tuple.type = bind_symbolic_name X, 0 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%X) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.35ec57.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%X) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.13320f.1 as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.2a1e48.1) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.2a1e48.1) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5_17.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.40dc71.1) = value_param call_param0 +// CHECK:STDOUT: %.loc5_17.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.13320f.1)] { +// CHECK:STDOUT: %.loc5_17.3: type = specific_constant constants.%C.13320f.1, @C(constants.%X) [symbolic = %C (constants.%C.13320f.1)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc5_17.3 [symbolic = %C (constants.%C.13320f.1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.40dc71.1) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl @C.as.I.impl(%Y.loc7_14.2: %empty_tuple.type) { // CHECK:STDOUT: %Y.loc7_14.1: %empty_tuple.type = bind_symbolic_name Y, 0 [symbolic = %Y.loc7_14.1 (constants.%Y)] // CHECK:STDOUT: %C.loc7_25.1: type = class_type @C, @C(%Y.loc7_14.1) [symbolic = %C.loc7_25.1 (constants.%C.13320f.2)] @@ -242,6 +277,9 @@ fn G() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%X) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.35ec57.1)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -251,6 +289,17 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%X.loc5_9.2: %empty_tuple.type) { +// CHECK:STDOUT: %X: %empty_tuple.type = bind_symbolic_name X, 0 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%X) [symbolic = %C (constants.%C.13320f.1)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.40dc71.1)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.2a1e48.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.40dc71.1)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @I.F(imports.%Main.import_ref.5dd: %I.type) [from "a.carbon"] { // CHECK:STDOUT: fn; // CHECK:STDOUT: } @@ -279,11 +328,11 @@ fn G() { // CHECK:STDOUT: %require_complete.1: = require_complete_type %C [symbolic = %require_complete.1 (constants.%require_complete.a35)] // CHECK:STDOUT: %C.val: @C.as.I.impl.F.loc8_17.2.%C (%C.13320f.2) = struct_value () [symbolic = %C.val (constants.%C.val)] // CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %C, @Destroy [symbolic = %Destroy.lookup_impl_witness (constants.%Destroy.lookup_impl_witness)] -// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %C, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet)] +// CHECK:STDOUT: %Destroy.facet: %Destroy.type = facet_value %C, (%Destroy.lookup_impl_witness) [symbolic = %Destroy.facet (constants.%Destroy.facet.6e0)] // CHECK:STDOUT: %.7: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [symbolic = %.7 (constants.%.97f)] // CHECK:STDOUT: %impl.elem0.2: @C.as.I.impl.F.loc8_17.2.%.7 (%.97f) = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.2 (constants.%impl.elem0)] // CHECK:STDOUT: %specific_impl_fn.2: = specific_impl_function %impl.elem0.2, @Destroy.Op(%Destroy.facet) [symbolic = %specific_impl_fn.2 (constants.%specific_impl_fn)] -// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.40d)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.40dc71.2)] // CHECK:STDOUT: %require_complete.2: = require_complete_type %ptr [symbolic = %require_complete.2 (constants.%require_complete.0b0)] // CHECK:STDOUT: // CHECK:STDOUT: fn(%x.param: %empty_struct_type) [thunk @C.as.I.impl.%C.as.I.impl.F.decl.loc8_17.1] { @@ -301,9 +350,9 @@ fn G() { // CHECK:STDOUT: %Op.ref: %Destroy.assoc_type = name_ref Op, imports.%Core.import_ref.f99 [concrete = constants.%assoc0] // CHECK:STDOUT: %impl.elem0.1: @C.as.I.impl.F.loc8_17.2.%.7 (%.97f) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.2 (constants.%impl.elem0)] // CHECK:STDOUT: %bound_method.1: = bound_method %.1, %impl.elem0.1 -// CHECK:STDOUT: %specific_impl_fn.1: = specific_impl_function %impl.elem0.1, @Destroy.Op(constants.%Destroy.facet) [symbolic = %specific_impl_fn.2 (constants.%specific_impl_fn)] +// CHECK:STDOUT: %specific_impl_fn.1: = specific_impl_function %impl.elem0.1, @Destroy.Op(constants.%Destroy.facet.6e0) [symbolic = %specific_impl_fn.2 (constants.%specific_impl_fn)] // CHECK:STDOUT: %bound_method.2: = bound_method %.1, %specific_impl_fn.1 -// CHECK:STDOUT: %addr: @C.as.I.impl.F.loc8_17.2.%ptr (%ptr.40d) = addr_of %.1 +// CHECK:STDOUT: %addr: @C.as.I.impl.F.loc8_17.2.%ptr (%ptr.40dc71.2) = addr_of %.1 // CHECK:STDOUT: %.6: init %empty_tuple.type = call %bound_method.2(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } @@ -313,6 +362,18 @@ fn G() { // CHECK:STDOUT: %X.loc5_9.1 => constants.%X // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%X) { +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.35ec57.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%X) { +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %C => constants.%C.13320f.1 +// CHECK:STDOUT: %ptr => constants.%ptr.40dc71.1 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.2a1e48.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%Y) { // CHECK:STDOUT: %X.loc5_9.1 => constants.%Y // CHECK:STDOUT: @@ -346,6 +407,11 @@ fn G() { // CHECK:STDOUT: // CHECK:STDOUT: specific @C.as.I.impl.F.loc8_17.2(constants.%Y) {} // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%Y) { +// CHECK:STDOUT: %X => constants.%Y +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.35ec57.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- c.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -357,6 +423,7 @@ fn G() { // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %X: %empty_tuple.type = bind_symbolic_name X, 0 [symbolic] +// CHECK:STDOUT: %C.13320f.1: type = class_type @C, @C(%X) [symbolic] // CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] // CHECK:STDOUT: %C.607: type = class_type @C, @C(%empty_tuple) [concrete] // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] @@ -365,6 +432,12 @@ fn G() { // CHECK:STDOUT: %assoc0.3f3: %I.assoc_type = assoc_entity element0, imports.%Main.import_ref.e03 [concrete] // CHECK:STDOUT: %I.F.type: type = fn_type @I.F [concrete] // CHECK:STDOUT: %I.F: %I.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.763: = impl_witness imports.%Destroy.impl_witness_table.629, @C.as.Destroy.impl(%X) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%X) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.40dc71.1: type = ptr_type %C.13320f.1 [symbolic] +// CHECK:STDOUT: %pattern_type.2a1: type = pattern_type %ptr.40dc71.1 [symbolic] // CHECK:STDOUT: %Y: %empty_tuple.type = bind_symbolic_name Y, 0 [symbolic] // CHECK:STDOUT: %C.13320f.2: type = class_type @C, @C(%Y) [symbolic] // CHECK:STDOUT: %I.impl_witness.7d9: = impl_witness imports.%I.impl_witness_table, @C.as.I.impl(%Y) [symbolic] @@ -376,15 +449,14 @@ fn G() { // CHECK:STDOUT: %require_complete.a35: = require_complete_type %C.13320f.2 [symbolic] // CHECK:STDOUT: %C.as.I.impl.F.specific_fn.8d9: = specific_function %C.as.I.impl.F.49c1ac.1, @C.as.I.impl.F.1(%Y) [symbolic] // CHECK:STDOUT: %C.val.56a: %C.13320f.2 = struct_value () [symbolic] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %Destroy.lookup_impl_witness: = lookup_impl_witness %C.13320f.2, @Destroy [symbolic] // CHECK:STDOUT: %Destroy.facet.666: %Destroy.type = facet_value %C.13320f.2, (%Destroy.lookup_impl_witness) [symbolic] // CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] // CHECK:STDOUT: %.5fd: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.666 [symbolic] // CHECK:STDOUT: %impl.elem0: %.5fd = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic] // CHECK:STDOUT: %specific_impl_fn: = specific_impl_function %impl.elem0, @Destroy.Op(%Destroy.facet.666) [symbolic] -// CHECK:STDOUT: %ptr.40d: type = ptr_type %C.13320f.2 [symbolic] -// CHECK:STDOUT: %require_complete.0b0: = require_complete_type %ptr.40d [symbolic] +// CHECK:STDOUT: %ptr.40dc71.2: type = ptr_type %C.13320f.2 [symbolic] +// CHECK:STDOUT: %require_complete.0b0: = require_complete_type %ptr.40dc71.2 [symbolic] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.ed4: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%T) [symbolic] // CHECK:STDOUT: %T.as.Destroy.impl.Op.486: %T.as.Destroy.impl.Op.type.ed4 = struct_value () [symbolic] @@ -400,7 +472,8 @@ fn G() { // CHECK:STDOUT: %pattern_type.186: type = pattern_type %C.607 [concrete] // CHECK:STDOUT: %C.as.I.impl.F.specific_fn.4832e8.2: = specific_function %C.as.I.impl.F.5fa954.1, @C.as.I.impl.F.1(%empty_tuple) [concrete] // CHECK:STDOUT: %C.val.12f: %C.607 = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.impl_witness.ce0: = impl_witness imports.%Destroy.impl_witness_table, @T.as.Destroy.impl(%C.607) [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.880: = impl_witness imports.%Destroy.impl_witness_table.629, @C.as.Destroy.impl(%empty_tuple) [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ce0: = impl_witness imports.%Destroy.impl_witness_table.18d, @T.as.Destroy.impl(%C.607) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.ea0: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.607) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.ac0: %T.as.Destroy.impl.Op.type.ea0 = struct_value () [concrete] // CHECK:STDOUT: %ptr.2ce: type = ptr_type %C.607 [concrete] @@ -426,17 +499,24 @@ fn G() { // CHECK:STDOUT: %Main.F.8b9 = import_ref Main//a, F, unloaded // CHECK:STDOUT: %Main.import_ref.e03: %I.F.type = import_ref Main//a, loc5_14, loaded [concrete = constants.%I.F] // CHECK:STDOUT: %Main.import_ref.5dd: %I.type = import_ref Main//a, inst19 [no loc], loaded [symbolic = constants.%Self.826] +// CHECK:STDOUT: %Main.import_ref.404 = import_ref Main//b, loc5_17, unloaded +// CHECK:STDOUT: %Main.import_ref.eb1c17.2: %empty_tuple.type = import_ref Main//b, loc5_9, loaded [symbolic = @C.%X (constants.%X)] +// CHECK:STDOUT: %Main.import_ref.dbf7cd.1: type = import_ref Main//b, inst31 [no loc], loaded [symbolic = constants.%C.13320f.1] +// CHECK:STDOUT: %Main.import_ref.cb9: type = import_ref Main//b, inst34 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.7dd = import_ref Main//b, loc5_17, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.629 = impl_witness_table (%Main.import_ref.7dd), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.eb1c17.3: %empty_tuple.type = import_ref Main//b, loc5_9, loaded [symbolic = @C.%X (constants.%X)] // CHECK:STDOUT: %Main.import_ref.f89: = import_ref Main//b, loc7_32, loaded [symbolic = @C.as.I.impl.%I.impl_witness (constants.%I.impl_witness.7d9)] -// CHECK:STDOUT: %Main.import_ref.eb1c17.2: %empty_tuple.type = import_ref Main//b, loc7_14, loaded [symbolic = @C.as.I.impl.%Y (constants.%Y)] -// CHECK:STDOUT: %Main.import_ref.dbf: type = import_ref Main//b, loc7_25, loaded [symbolic = @C.as.I.impl.%C (constants.%C.13320f.2)] +// CHECK:STDOUT: %Main.import_ref.eb1c17.4: %empty_tuple.type = import_ref Main//b, loc7_14, loaded [symbolic = @C.as.I.impl.%Y (constants.%Y)] +// CHECK:STDOUT: %Main.import_ref.dbf7cd.2: type = import_ref Main//b, loc7_25, loaded [symbolic = @C.as.I.impl.%C (constants.%C.13320f.2)] // CHECK:STDOUT: %Main.import_ref.f50: type = import_ref Main//b, loc7_30, loaded [concrete = constants.%I.type] // CHECK:STDOUT: %Main.import_ref.047: @C.as.I.impl.%C.as.I.impl.F.type.2 (%C.as.I.impl.F.type.0daaa1.2) = import_ref Main//b, loc8_17, loaded [symbolic = @C.as.I.impl.%C.as.I.impl.F.2 (constants.%C.as.I.impl.F.49c1ac.2)] // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (%Main.import_ref.047), @C.as.I.impl [concrete] -// CHECK:STDOUT: %Main.import_ref.eb1c17.3: %empty_tuple.type = import_ref Main//b, loc7_14, loaded [symbolic = @C.as.I.impl.%Y (constants.%Y)] -// CHECK:STDOUT: %Main.import_ref.eb1c17.4: %empty_tuple.type = import_ref Main//b, loc7_14, loaded [symbolic = @C.as.I.impl.%Y (constants.%Y)] +// CHECK:STDOUT: %Main.import_ref.eb1c17.5: %empty_tuple.type = import_ref Main//b, loc7_14, loaded [symbolic = @C.as.I.impl.%Y (constants.%Y)] +// CHECK:STDOUT: %Main.import_ref.eb1c17.6: %empty_tuple.type = import_ref Main//b, loc7_14, loaded [symbolic = @C.as.I.impl.%Y (constants.%Y)] // CHECK:STDOUT: %Main.F.5a8: @C.as.I.impl.%C.as.I.impl.F.type.1 (%C.as.I.impl.F.type.0daaa1.1) = import_ref Main//b, F, loaded [symbolic = @C.as.I.impl.%C.as.I.impl.F.1 (constants.%C.as.I.impl.F.49c1ac.1)] -// CHECK:STDOUT: %Main.import_ref.fcc: @T.as.Destroy.impl.%T.as.Destroy.impl.Op.type (%T.as.Destroy.impl.Op.type.ed4) = import_ref Main//b, inst153 [indirect], loaded [symbolic = @T.as.Destroy.impl.%T.as.Destroy.impl.Op (constants.%T.as.Destroy.impl.Op.486)] -// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (%Main.import_ref.fcc), @T.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Main.import_ref.fcc: @T.as.Destroy.impl.%T.as.Destroy.impl.Op.type (%T.as.Destroy.impl.Op.type.ed4) = import_ref Main//b, inst179 [indirect], loaded [symbolic = @T.as.Destroy.impl.%T.as.Destroy.impl.Op (constants.%T.as.Destroy.impl.Op.486)] +// CHECK:STDOUT: %Destroy.impl_witness_table.18d = impl_witness_table (%Main.import_ref.fcc), @T.as.Destroy.impl [concrete] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -459,7 +539,21 @@ fn G() { // CHECK:STDOUT: witness = (imports.%Main.F.8b9) // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic impl @C.as.I.impl(imports.%Main.import_ref.eb1c17.2: %empty_tuple.type) [from "b.carbon"] { +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(imports.%Main.import_ref.eb1c17.2: %empty_tuple.type) [from "b.carbon"] { +// CHECK:STDOUT: %X: %empty_tuple.type = bind_symbolic_name X, 0 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.629, @C.as.Destroy.impl(%X) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.763)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%X) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%Main.import_ref.dbf7cd.1 as imports.%Main.import_ref.cb9 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.404 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.I.impl(imports.%Main.import_ref.eb1c17.4: %empty_tuple.type) [from "b.carbon"] { // CHECK:STDOUT: %Y: %empty_tuple.type = bind_symbolic_name Y, 0 [symbolic = %Y (constants.%Y)] // CHECK:STDOUT: %C: type = class_type @C, @C(%Y) [symbolic = %C (constants.%C.13320f.2)] // CHECK:STDOUT: %I.impl_witness: = impl_witness imports.%I.impl_witness_table, @C.as.I.impl(%Y) [symbolic = %I.impl_witness (constants.%I.impl_witness.7d9)] @@ -470,7 +564,7 @@ fn G() { // CHECK:STDOUT: %C.as.I.impl.F.type.2: type = fn_type @C.as.I.impl.F.2, @C.as.I.impl(%Y) [symbolic = %C.as.I.impl.F.type.2 (constants.%C.as.I.impl.F.type.0daaa1.2)] // CHECK:STDOUT: %C.as.I.impl.F.2: @C.as.I.impl.%C.as.I.impl.F.type.2 (%C.as.I.impl.F.type.0daaa1.2) = struct_value () [symbolic = %C.as.I.impl.F.2 (constants.%C.as.I.impl.F.49c1ac.2)] // CHECK:STDOUT: -// CHECK:STDOUT: impl: imports.%Main.import_ref.dbf as imports.%Main.import_ref.f50 { +// CHECK:STDOUT: impl: imports.%Main.import_ref.dbf7cd.2 as imports.%Main.import_ref.f50 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%Main.import_ref.f89 // CHECK:STDOUT: } @@ -528,7 +622,18 @@ fn G() { // CHECK:STDOUT: fn; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic fn @C.as.I.impl.F.1(imports.%Main.import_ref.eb1c17.3: %empty_tuple.type) [from "b.carbon"] { +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(imports.%Main.import_ref.eb1c17.3: %empty_tuple.type) [from "b.carbon"] { +// CHECK:STDOUT: %X: %empty_tuple.type = bind_symbolic_name X, 0 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%X) [symbolic = %C (constants.%C.13320f.1)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.40dc71.1)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.2a1)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.I.impl.F.1(imports.%Main.import_ref.eb1c17.5: %empty_tuple.type) [from "b.carbon"] { // CHECK:STDOUT: %Y: %empty_tuple.type = bind_symbolic_name Y, 0 [symbolic = %Y (constants.%Y)] // CHECK:STDOUT: %C: type = class_type @C, @C(%Y) [symbolic = %C (constants.%C.13320f.2)] // CHECK:STDOUT: %pattern_type: type = pattern_type %C [symbolic = %pattern_type (constants.%pattern_type.ccc)] @@ -539,7 +644,7 @@ fn G() { // CHECK:STDOUT: fn; // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic fn @C.as.I.impl.F.2(imports.%Main.import_ref.eb1c17.4: %empty_tuple.type) [from "b.carbon"] { +// CHECK:STDOUT: generic fn @C.as.I.impl.F.2(imports.%Main.import_ref.eb1c17.6: %empty_tuple.type) [from "b.carbon"] { // CHECK:STDOUT: !definition: // CHECK:STDOUT: %Y: %empty_tuple.type = bind_symbolic_name Y, 0 [symbolic = %Y (constants.%Y)] // CHECK:STDOUT: %C.as.I.impl.F.type: type = fn_type @C.as.I.impl.F.1, @C.as.I.impl(%Y) [symbolic = %C.as.I.impl.F.type (constants.%C.as.I.impl.F.type.0daaa1.1)] @@ -553,7 +658,7 @@ fn G() { // CHECK:STDOUT: %.1: type = fn_type_with_self_type constants.%Destroy.Op.type, %Destroy.facet [symbolic = %.1 (constants.%.5fd)] // CHECK:STDOUT: %impl.elem0: @C.as.I.impl.F.2.%.1 (%.5fd) = impl_witness_access %Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0 (constants.%impl.elem0)] // CHECK:STDOUT: %specific_impl_fn: = specific_impl_function %impl.elem0, @Destroy.Op(%Destroy.facet) [symbolic = %specific_impl_fn (constants.%specific_impl_fn)] -// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.40d)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.40dc71.2)] // CHECK:STDOUT: %require_complete.2: = require_complete_type %ptr [symbolic = %require_complete.2 (constants.%require_complete.0b0)] // CHECK:STDOUT: // CHECK:STDOUT: fn [thunk imports.%Main.F.5a8]; @@ -571,6 +676,18 @@ fn G() { // CHECK:STDOUT: // CHECK:STDOUT: specific @I.F(constants.%Self.826) {} // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%X) { +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.763 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%X) { +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %C => constants.%C.13320f.1 +// CHECK:STDOUT: %ptr => constants.%ptr.40dc71.1 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.2a1 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%Y) { // CHECK:STDOUT: %X => constants.%Y // CHECK:STDOUT: @@ -639,3 +756,8 @@ fn G() { // CHECK:STDOUT: %require_complete => constants.%complete_type.357 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%empty_tuple) { +// CHECK:STDOUT: %X => constants.%empty_tuple +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.880 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/interface_args.carbon b/toolchain/check/testdata/impl/interface_args.carbon index 0254daa04cbf..e1a611eae6ee 100644 --- a/toolchain/check/testdata/impl/interface_args.carbon +++ b/toolchain/check/testdata/impl/interface_args.carbon @@ -211,17 +211,34 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %Action.generic: %Action.type.29c = struct_value () [concrete] // CHECK:STDOUT: %Action.type.cca: type = facet_type <@Action, @Action(%T)> [symbolic] // CHECK:STDOUT: %Self.e98: %Action.type.cca = bind_symbolic_name Self, 1 [symbolic] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.e98 [symbolic] -// CHECK:STDOUT: %pattern_type.8db: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Self.as_type.566: type = facet_access_type %Self.e98 [symbolic] +// CHECK:STDOUT: %pattern_type.8db: type = pattern_type %Self.as_type.566 [symbolic] // CHECK:STDOUT: %Action.Op.type.036: type = fn_type @Action.Op, @Action(%T) [symbolic] // CHECK:STDOUT: %Action.Op.6ed: %Action.Op.type.036 = struct_value () [symbolic] // CHECK:STDOUT: %Action.assoc_type.32e: type = assoc_entity_type @Action, @Action(%T) [symbolic] // CHECK:STDOUT: %assoc0.268: %Action.assoc_type.32e = assoc_entity element0, @Action.%Action.Op.decl [symbolic] // CHECK:STDOUT: %A: type = class_type @A [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Action.type.cb0: type = facet_type <@Action, @Action(%B)> [concrete] // CHECK:STDOUT: %Self.0d1: %Action.type.cb0 = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %Action.Op.type.54d: type = fn_type @Action.Op, @Action(%B) [concrete] @@ -240,9 +257,11 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -298,14 +317,14 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %self.patt: @Action.Op.%pattern_type (%pattern_type.8db) = binding_pattern self [concrete] // CHECK:STDOUT: %self.param_patt: @Action.Op.%pattern_type (%pattern_type.8db) = value_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param: @Action.Op.%Self.as_type.loc5_15.1 (%Self.as_type) = value_param call_param0 -// CHECK:STDOUT: %.loc5_15.1: type = splice_block %.loc5_15.3 [symbolic = %Self.as_type.loc5_15.1 (constants.%Self.as_type)] { +// CHECK:STDOUT: %self.param: @Action.Op.%Self.as_type.loc5_15.1 (%Self.as_type.566) = value_param call_param0 +// CHECK:STDOUT: %.loc5_15.1: type = splice_block %.loc5_15.3 [symbolic = %Self.as_type.loc5_15.1 (constants.%Self.as_type.566)] { // CHECK:STDOUT: %.loc5_15.2: @Action.Op.%Action.type (%Action.type.cca) = specific_constant @Action.%Self.1, @Action(constants.%T) [symbolic = %Self (constants.%Self.e98)] // CHECK:STDOUT: %Self.ref: @Action.Op.%Action.type (%Action.type.cca) = name_ref Self, %.loc5_15.2 [symbolic = %Self (constants.%Self.e98)] -// CHECK:STDOUT: %Self.as_type.loc5_15.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc5_15.1 (constants.%Self.as_type)] -// CHECK:STDOUT: %.loc5_15.3: type = converted %Self.ref, %Self.as_type.loc5_15.2 [symbolic = %Self.as_type.loc5_15.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self.as_type.loc5_15.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc5_15.1 (constants.%Self.as_type.566)] +// CHECK:STDOUT: %.loc5_15.3: type = converted %Self.ref, %Self.as_type.loc5_15.2 [symbolic = %Self.as_type.loc5_15.1 (constants.%Self.as_type.566)] // CHECK:STDOUT: } -// CHECK:STDOUT: %self: @Action.Op.%Self.as_type.loc5_15.1 (%Self.as_type) = bind_name self, %self.param +// CHECK:STDOUT: %self: @Action.Op.%Self.as_type.loc5_15.1 (%Self.as_type.566) = bind_name self, %self.param // CHECK:STDOUT: } // CHECK:STDOUT: %assoc0.loc5_22.1: @Action.%Action.assoc_type (%Action.assoc_type.32e) = assoc_entity element0, %Action.Op.decl [symbolic = %assoc0.loc5_22.2 (constants.%assoc0.268)] // CHECK:STDOUT: @@ -316,6 +335,54 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc10: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @A.as.Action.impl: %A.ref as %Action.type { // CHECK:STDOUT: %A.as.Action.impl.Op.decl: %A.as.Action.impl.Op.type = fn_decl @A.as.Action.impl.Op [concrete = constants.%A.as.Action.impl.Op] { // CHECK:STDOUT: %self.patt: %pattern_type.c10 = binding_pattern self [concrete] @@ -332,6 +399,9 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @A { +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -341,6 +411,9 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @B { +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -350,6 +423,9 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -362,12 +438,18 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %Action.type: type = facet_type <@Action, @Action(%T)> [symbolic = %Action.type (constants.%Action.type.cca)] // CHECK:STDOUT: %Self: @Action.Op.%Action.type (%Action.type.cca) = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.e98)] -// CHECK:STDOUT: %Self.as_type.loc5_15.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc5_15.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self.as_type.loc5_15.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc5_15.1 (constants.%Self.as_type.566)] // CHECK:STDOUT: %pattern_type: type = pattern_type %Self.as_type.loc5_15.1 [symbolic = %pattern_type (constants.%pattern_type.8db)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%self.param: @Action.Op.%Self.as_type.loc5_15.1 (%Self.as_type)); +// CHECK:STDOUT: fn(%self.param: @Action.Op.%Self.as_type.loc5_15.1 (%Self.as_type.566)); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @A.as.Action.impl.Op(%self.param: %A) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return @@ -395,7 +477,7 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %Action.type => constants.%Action.type.cca // CHECK:STDOUT: %Self => constants.%Self.e98 -// CHECK:STDOUT: %Self.as_type.loc5_15.1 => constants.%Self.as_type +// CHECK:STDOUT: %Self.as_type.loc5_15.1 => constants.%Self.as_type.566 // CHECK:STDOUT: %pattern_type => constants.%pattern_type.8db // CHECK:STDOUT: } // CHECK:STDOUT: @@ -422,9 +504,12 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: --- action.impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %A: type = class_type @A [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %Action.type.29c: type = generic_interface_type @Action [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Action.generic: %Action.type.29c = struct_value () [concrete] @@ -432,7 +517,6 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %Action.type.cca: type = facet_type <@Action, @Action(%T)> [symbolic] // CHECK:STDOUT: %Self.e98: %Action.type.cca = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %Action.type.cb0: type = facet_type <@Action, @Action(%B)> [concrete] -// CHECK:STDOUT: %A: type = class_type @A [concrete] // CHECK:STDOUT: %Action.Op.type.036: type = fn_type @Action.Op, @Action(%T) [symbolic] // CHECK:STDOUT: %Action.Op.6ed: %Action.Op.type.036 = struct_value () [symbolic] // CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.e98 [symbolic] @@ -461,19 +545,33 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %Main.B: type = import_ref Main//action, B, loaded [concrete = constants.%B] // CHECK:STDOUT: %Main.C = import_ref Main//action, C, unloaded // CHECK:STDOUT: %Main.F = import_ref Main//action, F, unloaded -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: %Core.ece: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//action, loc9_10, loaded [concrete = constants.%complete_type] -// CHECK:STDOUT: %Main.import_ref.54a = import_ref Main//action, inst64 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.7b0 = import_ref Main//action, loc8_9, unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//action, loc8_10, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.da3 = import_ref Main//action, inst58 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.93c: type = import_ref Main//action, inst58 [no loc], loaded [concrete = constants.%A] +// CHECK:STDOUT: %Main.import_ref.cb9298.1: type = import_ref Main//action, inst61 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.2d5 = import_ref Main//action, loc8_9, unloaded +// CHECK:STDOUT: %Main.import_ref.ae7 = import_ref Main//action, loc9_9, unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//action, loc9_10, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.54a = import_ref Main//action, inst102 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.bfe: type = import_ref Main//action, inst102 [no loc], loaded [concrete = constants.%B] +// CHECK:STDOUT: %Main.import_ref.cb9298.2: type = import_ref Main//action, inst61 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.fc3 = import_ref Main//action, loc9_9, unloaded +// CHECK:STDOUT: %Main.import_ref.34c = import_ref Main//action, loc10_9, unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.3: = import_ref Main//action, loc10_10, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.2c4 = import_ref Main//action, inst122 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.c0c: type = import_ref Main//action, inst122 [no loc], loaded [concrete = constants.%C] +// CHECK:STDOUT: %Main.import_ref.cb9298.3: type = import_ref Main//action, inst61 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.b3d = import_ref Main//action, loc10_9, unloaded // CHECK:STDOUT: %Main.import_ref.5ab3ec.1: type = import_ref Main//action, loc4_18, loaded [symbolic = @Action.%T (constants.%T)] // CHECK:STDOUT: %Main.import_ref.ddc = import_ref Main//action, inst27 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.c55: @Action.%Action.assoc_type (%Action.assoc_type.32e) = import_ref Main//action, loc5_22, loaded [symbolic = @Action.%assoc0 (constants.%assoc0.f18741.2)] -// CHECK:STDOUT: %Main.Op = import_ref Main//action, Op, unloaded +// CHECK:STDOUT: %Main.Op.ae2 = import_ref Main//action, Op, unloaded // CHECK:STDOUT: %Main.import_ref.995: = import_ref Main//action, loc12_21, loaded [concrete = constants.%Action.impl_witness] -// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//action, loc8_10, loaded [concrete = constants.%complete_type] -// CHECK:STDOUT: %Main.import_ref.da3 = import_ref Main//action, inst58 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.984: type = import_ref Main//action, loc12_6, loaded [concrete = constants.%A] // CHECK:STDOUT: %Main.import_ref.bb2: type = import_ref Main//action, loc12_19, loaded [concrete = constants.%Action.type.cb0] // CHECK:STDOUT: %Main.import_ref.7b5 = import_ref Main//action, loc13_23, unloaded @@ -493,7 +591,7 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: .B = imports.%Main.B // CHECK:STDOUT: .C = imports.%Main.C // CHECK:STDOUT: .F = imports.%Main.F -// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Core = imports.%Core.ece // CHECK:STDOUT: .G = %G.decl // CHECK:STDOUT: } // CHECK:STDOUT: %default.import.loc2_22.1 = import @@ -524,28 +622,53 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = imports.%Main.import_ref.ddc // CHECK:STDOUT: .Op = imports.%Main.import_ref.c55 -// CHECK:STDOUT: witness = (imports.%Main.Op) +// CHECK:STDOUT: witness = (imports.%Main.Op.ae2) // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: imports.%Main.import_ref.93c as imports.%Main.import_ref.cb9298.1 [from "action.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = imports.%Main.import_ref.2d5 +// CHECK:STDOUT: witness = imports.%Main.import_ref.7b0 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: imports.%Main.import_ref.bfe as imports.%Main.import_ref.cb9298.2 [from "action.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = imports.%Main.import_ref.fc3 +// CHECK:STDOUT: witness = imports.%Main.import_ref.ae7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: imports.%Main.import_ref.c0c as imports.%Main.import_ref.cb9298.3 [from "action.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = imports.%Main.import_ref.b3d +// CHECK:STDOUT: witness = imports.%Main.import_ref.34c +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @A.as.Action.impl: imports.%Main.import_ref.984 as imports.%Main.import_ref.bb2 [from "action.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: .Op = imports.%Main.import_ref.7b5 // CHECK:STDOUT: witness = imports.%Main.import_ref.995 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @B [from "action.carbon"] { +// CHECK:STDOUT: class @A [from "action.carbon"] { // CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.1 // CHECK:STDOUT: // CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Main.import_ref.da3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @B [from "action.carbon"] { +// CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.2 +// CHECK:STDOUT: +// CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = imports.%Main.import_ref.54a // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @A [from "action.carbon"] { -// CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.2 +// CHECK:STDOUT: class @C [from "action.carbon"] { +// CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.3 // CHECK:STDOUT: // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = imports.%Main.import_ref.da3 +// CHECK:STDOUT: .Self = imports.%Main.import_ref.2c4 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @Action.Op(imports.%Main.import_ref.5ab3ec.2: type, imports.%Main.import_ref.835: @Action.%Action.type (%Action.type.cca)) [from "action.carbon"] { @@ -601,16 +724,18 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: --- fail_action.impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %A: type = class_type @A [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %Action.type.29c: type = generic_interface_type @Action [concrete] // CHECK:STDOUT: %Action.generic: %Action.type.29c = struct_value () [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %Action.type.cca: type = facet_type <@Action, @Action(%T)> [symbolic] // CHECK:STDOUT: %Self.e98: %Action.type.cca = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %Action.type.cb0: type = facet_type <@Action, @Action(%B)> [concrete] -// CHECK:STDOUT: %A: type = class_type @A [concrete] // CHECK:STDOUT: %Action.Op.type.036: type = fn_type @Action.Op, @Action(%T) [symbolic] // CHECK:STDOUT: %Action.Op.6ed: %Action.Op.type.036 = struct_value () [symbolic] // CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.e98 [symbolic] @@ -625,7 +750,6 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %pattern_type.c10: type = pattern_type %A [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] -// CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %Action.type.e2b: type = facet_type <@Action, @Action(%C)> [concrete] // CHECK:STDOUT: %Self.4bb: %Action.type.e2b = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %Action.Op.type.5ad: type = fn_type @Action.Op, @Action(%C) [concrete] @@ -641,19 +765,33 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %Main.B = import_ref Main//action, B, unloaded // CHECK:STDOUT: %Main.C: type = import_ref Main//action, C, loaded [concrete = constants.%C] // CHECK:STDOUT: %Main.F = import_ref Main//action, F, unloaded -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: %Core.ece: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//action, loc9_10, loaded [concrete = constants.%complete_type] -// CHECK:STDOUT: %Main.import_ref.54a = import_ref Main//action, inst64 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.7b0 = import_ref Main//action, loc8_9, unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//action, loc8_10, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.da3 = import_ref Main//action, inst58 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.93c: type = import_ref Main//action, inst58 [no loc], loaded [concrete = constants.%A] +// CHECK:STDOUT: %Main.import_ref.cb9298.1: type = import_ref Main//action, inst61 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.2d5 = import_ref Main//action, loc8_9, unloaded +// CHECK:STDOUT: %Main.import_ref.ae7 = import_ref Main//action, loc9_9, unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//action, loc9_10, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.54a = import_ref Main//action, inst102 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.bfe: type = import_ref Main//action, inst102 [no loc], loaded [concrete = constants.%B] +// CHECK:STDOUT: %Main.import_ref.cb9298.2: type = import_ref Main//action, inst61 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.fc3 = import_ref Main//action, loc9_9, unloaded +// CHECK:STDOUT: %Main.import_ref.34c = import_ref Main//action, loc10_9, unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.3: = import_ref Main//action, loc10_10, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.2c4 = import_ref Main//action, inst122 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.c0c: type = import_ref Main//action, inst122 [no loc], loaded [concrete = constants.%C] +// CHECK:STDOUT: %Main.import_ref.cb9298.3: type = import_ref Main//action, inst61 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.b3d = import_ref Main//action, loc10_9, unloaded // CHECK:STDOUT: %Main.import_ref.5ab3ec.1: type = import_ref Main//action, loc4_18, loaded [symbolic = @Action.%T (constants.%T)] // CHECK:STDOUT: %Main.import_ref.ddc = import_ref Main//action, inst27 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.c55: @Action.%Action.assoc_type (%Action.assoc_type.32e) = import_ref Main//action, loc5_22, loaded [symbolic = @Action.%assoc0 (constants.%assoc0.f18)] -// CHECK:STDOUT: %Main.Op = import_ref Main//action, Op, unloaded +// CHECK:STDOUT: %Main.Op.ae2 = import_ref Main//action, Op, unloaded // CHECK:STDOUT: %Main.import_ref.19c = import_ref Main//action, loc12_21, unloaded -// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//action, loc8_10, loaded [concrete = constants.%complete_type] -// CHECK:STDOUT: %Main.import_ref.da3 = import_ref Main//action, inst58 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.984: type = import_ref Main//action, loc12_6, loaded [concrete = constants.%A] // CHECK:STDOUT: %Main.import_ref.bb2: type = import_ref Main//action, loc12_19, loaded [concrete = constants.%Action.type.cb0] // CHECK:STDOUT: %Main.import_ref.7b5 = import_ref Main//action, loc13_23, unloaded @@ -661,8 +799,6 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %Main.import_ref.835: @Action.%Action.type (%Action.type.cca) = import_ref Main//action, inst27 [no loc], loaded [symbolic = @Action.%Self (constants.%Self.e98)] // CHECK:STDOUT: %Main.import_ref.1f6: @Action.%Action.Op.type (%Action.Op.type.036) = import_ref Main//action, loc5_22, loaded [symbolic = @Action.%Action.Op (constants.%Action.Op.6ed)] // CHECK:STDOUT: %Main.import_ref.0e3753.1 = import_ref Main//action, loc5_22, unloaded -// CHECK:STDOUT: %Main.import_ref.8f24d3.3: = import_ref Main//action, loc10_10, loaded [concrete = constants.%complete_type] -// CHECK:STDOUT: %Main.import_ref.2c4 = import_ref Main//action, inst68 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.0e3753.2 = import_ref Main//action, loc5_22, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: @@ -673,7 +809,7 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: .B = imports.%Main.B // CHECK:STDOUT: .C = imports.%Main.C // CHECK:STDOUT: .F = imports.%Main.F -// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Core = imports.%Core.ece // CHECK:STDOUT: .G = %G.decl // CHECK:STDOUT: } // CHECK:STDOUT: %default.import.loc2_22.1 = import @@ -704,28 +840,46 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = imports.%Main.import_ref.ddc // CHECK:STDOUT: .Op = imports.%Main.import_ref.c55 -// CHECK:STDOUT: witness = (imports.%Main.Op) +// CHECK:STDOUT: witness = (imports.%Main.Op.ae2) // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: imports.%Main.import_ref.93c as imports.%Main.import_ref.cb9298.1 [from "action.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = imports.%Main.import_ref.2d5 +// CHECK:STDOUT: witness = imports.%Main.import_ref.7b0 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: imports.%Main.import_ref.bfe as imports.%Main.import_ref.cb9298.2 [from "action.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = imports.%Main.import_ref.fc3 +// CHECK:STDOUT: witness = imports.%Main.import_ref.ae7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: imports.%Main.import_ref.c0c as imports.%Main.import_ref.cb9298.3 [from "action.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = imports.%Main.import_ref.b3d +// CHECK:STDOUT: witness = imports.%Main.import_ref.34c +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @A.as.Action.impl: imports.%Main.import_ref.984 as imports.%Main.import_ref.bb2 [from "action.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: .Op = imports.%Main.import_ref.7b5 // CHECK:STDOUT: witness = imports.%Main.import_ref.19c // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @B [from "action.carbon"] { +// CHECK:STDOUT: class @A [from "action.carbon"] { // CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.1 // CHECK:STDOUT: // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = imports.%Main.import_ref.54a +// CHECK:STDOUT: .Self = imports.%Main.import_ref.da3 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @A [from "action.carbon"] { +// CHECK:STDOUT: class @B [from "action.carbon"] { // CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.2 // CHECK:STDOUT: // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = imports.%Main.import_ref.da3 +// CHECK:STDOUT: .Self = imports.%Main.import_ref.54a // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C [from "action.carbon"] { @@ -806,15 +960,27 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %Factory.Make.737: %Factory.Make.type.598 = struct_value () [symbolic] // CHECK:STDOUT: %Factory.assoc_type.207: type = assoc_entity_type @Factory, @Factory(%T) [symbolic] // CHECK:STDOUT: %assoc0.b3c: %Factory.assoc_type.207 = assoc_entity element0, @Factory.%Factory.Make.decl [symbolic] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.9ba [symbolic] -// CHECK:STDOUT: %pattern_type.5ea: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Self.as_type.56c: type = facet_access_type %Self.9ba [symbolic] +// CHECK:STDOUT: %pattern_type.5ea: type = pattern_type %Self.as_type.56c [symbolic] // CHECK:STDOUT: %Factory.Method.type.7ee: type = fn_type @Factory.Method, @Factory(%T) [symbolic] // CHECK:STDOUT: %Factory.Method.a71: %Factory.Method.type.7ee = struct_value () [symbolic] // CHECK:STDOUT: %assoc1.e30: %Factory.assoc_type.207 = assoc_entity element1, @Factory.%Factory.Method.decl [symbolic] // CHECK:STDOUT: %A: type = class_type @A [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Factory.type.a5d: type = facet_type <@Factory, @Factory(%B)> [concrete] // CHECK:STDOUT: %Self.187: %Factory.type.a5d = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %Factory.Make.type.c59: type = fn_type @Factory.Make, @Factory(%B) [concrete] @@ -836,9 +1002,11 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -898,14 +1066,14 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %return.param_patt: @Factory.Method.%pattern_type.loc8_27 (%pattern_type.7dc) = out_param_pattern %return.patt, call_param1 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.ref: type = name_ref T, @Factory.%T.loc4_19.2 [symbolic = %T (constants.%T)] -// CHECK:STDOUT: %self.param: @Factory.Method.%Self.as_type.loc8_19.1 (%Self.as_type) = value_param call_param0 -// CHECK:STDOUT: %.loc8_19.1: type = splice_block %.loc8_19.3 [symbolic = %Self.as_type.loc8_19.1 (constants.%Self.as_type)] { +// CHECK:STDOUT: %self.param: @Factory.Method.%Self.as_type.loc8_19.1 (%Self.as_type.56c) = value_param call_param0 +// CHECK:STDOUT: %.loc8_19.1: type = splice_block %.loc8_19.3 [symbolic = %Self.as_type.loc8_19.1 (constants.%Self.as_type.56c)] { // CHECK:STDOUT: %.loc8_19.2: @Factory.Method.%Factory.type (%Factory.type.c96) = specific_constant @Factory.%Self.1, @Factory(constants.%T) [symbolic = %Self (constants.%Self.9ba)] // CHECK:STDOUT: %Self.ref: @Factory.Method.%Factory.type (%Factory.type.c96) = name_ref Self, %.loc8_19.2 [symbolic = %Self (constants.%Self.9ba)] -// CHECK:STDOUT: %Self.as_type.loc8_19.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc8_19.1 (constants.%Self.as_type)] -// CHECK:STDOUT: %.loc8_19.3: type = converted %Self.ref, %Self.as_type.loc8_19.2 [symbolic = %Self.as_type.loc8_19.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self.as_type.loc8_19.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc8_19.1 (constants.%Self.as_type.56c)] +// CHECK:STDOUT: %.loc8_19.3: type = converted %Self.ref, %Self.as_type.loc8_19.2 [symbolic = %Self.as_type.loc8_19.1 (constants.%Self.as_type.56c)] // CHECK:STDOUT: } -// CHECK:STDOUT: %self: @Factory.Method.%Self.as_type.loc8_19.1 (%Self.as_type) = bind_name self, %self.param +// CHECK:STDOUT: %self: @Factory.Method.%Self.as_type.loc8_19.1 (%Self.as_type.56c) = bind_name self, %self.param // CHECK:STDOUT: %return.param: ref @Factory.Method.%T (%T) = out_param call_param1 // CHECK:STDOUT: %return: ref @Factory.Method.%T (%T) = return_slot %return.param // CHECK:STDOUT: } @@ -920,6 +1088,38 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @A.as.Factory.impl: %A.ref as %Factory.type { // CHECK:STDOUT: %A.as.Factory.impl.Make.decl: %A.as.Factory.impl.Make.type = fn_decl @A.as.Factory.impl.Make [concrete = constants.%A.as.Factory.impl.Make] { // CHECK:STDOUT: %return.patt: %pattern_type.049 = return_slot_pattern [concrete] @@ -951,6 +1151,9 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @A { +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -960,6 +1163,9 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @B { +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -979,13 +1185,17 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %Factory.type: type = facet_type <@Factory, @Factory(%T)> [symbolic = %Factory.type (constants.%Factory.type.c96)] // CHECK:STDOUT: %Self: @Factory.Method.%Factory.type (%Factory.type.c96) = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.9ba)] -// CHECK:STDOUT: %Self.as_type.loc8_19.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc8_19.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self.as_type.loc8_19.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc8_19.1 (constants.%Self.as_type.56c)] // CHECK:STDOUT: %pattern_type.loc8_13: type = pattern_type %Self.as_type.loc8_19.1 [symbolic = %pattern_type.loc8_13 (constants.%pattern_type.5ea)] // CHECK:STDOUT: %pattern_type.loc8_27: type = pattern_type %T [symbolic = %pattern_type.loc8_27 (constants.%pattern_type.7dc)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%self.param: @Factory.Method.%Self.as_type.loc8_19.1 (%Self.as_type)) -> @Factory.Method.%T (%T); +// CHECK:STDOUT: fn(%self.param: @Factory.Method.%Self.as_type.loc8_19.1 (%Self.as_type.56c)) -> @Factory.Method.%T (%T); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @A.as.Factory.impl.Make() -> %B; // CHECK:STDOUT: // CHECK:STDOUT: fn @A.as.Factory.impl.Method(%self.param: %A) -> %B; @@ -1003,7 +1213,7 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %Factory.type => constants.%Factory.type.c96 // CHECK:STDOUT: %Self => constants.%Self.9ba -// CHECK:STDOUT: %Self.as_type.loc8_19.1 => constants.%Self.as_type +// CHECK:STDOUT: %Self.as_type.loc8_19.1 => constants.%Self.as_type.56c // CHECK:STDOUT: %pattern_type.loc8_13 => constants.%pattern_type.5ea // CHECK:STDOUT: %pattern_type.loc8_27 => constants.%pattern_type.7dc // CHECK:STDOUT: } @@ -1040,9 +1250,11 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: --- factory.impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %A: type = class_type @A [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %Factory.type.1a8: type = generic_interface_type @Factory [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Factory.generic: %Factory.type.1a8 = struct_value () [concrete] @@ -1050,7 +1262,6 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %Factory.type.c96: type = facet_type <@Factory, @Factory(%T)> [symbolic] // CHECK:STDOUT: %Self.9ba: %Factory.type.c96 = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %Factory.type.a5d: type = facet_type <@Factory, @Factory(%B)> [concrete] -// CHECK:STDOUT: %A: type = class_type @A [concrete] // CHECK:STDOUT: %Factory.Make.type.598: type = fn_type @Factory.Make, @Factory(%T) [symbolic] // CHECK:STDOUT: %Factory.Make.737: %Factory.Make.type.598 = struct_value () [symbolic] // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] @@ -1078,11 +1289,10 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %.711: type = fn_type_with_self_type %Factory.Make.type.c59, %Factory.facet [concrete] // CHECK:STDOUT: %A.as.Factory.impl.Make.type: type = fn_type @A.as.Factory.impl.Make [concrete] // CHECK:STDOUT: %A.as.Factory.impl.Make: %A.as.Factory.impl.Make.type = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.1a6: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%B) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.3c2: %T.as.Destroy.impl.Op.type.1a6 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.5cf: = impl_witness imports.%Destroy.impl_witness_table.f6b [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.3c2, @T.as.Destroy.impl.Op(%B) [concrete] // CHECK:STDOUT: %pattern_type.c10: type = pattern_type %A [concrete] // CHECK:STDOUT: %InstanceB.type: type = fn_type @InstanceB [concrete] // CHECK:STDOUT: %InstanceB: %InstanceB.type = struct_value () [concrete] @@ -1096,13 +1306,23 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %Main.Factory: %Factory.type.1a8 = import_ref Main//factory, Factory, loaded [concrete = constants.%Factory.generic] // CHECK:STDOUT: %Main.A: type = import_ref Main//factory, A, loaded [concrete = constants.%A] // CHECK:STDOUT: %Main.B: type = import_ref Main//factory, B, loaded [concrete = constants.%B] -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: %Core.ece: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//factory, loc12_10, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Main.import_ref.54a = import_ref Main//factory, inst86 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.7b0 = import_ref Main//factory, loc11_9, unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//factory, loc11_10, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.da3 = import_ref Main//factory, inst80 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.93c: type = import_ref Main//factory, inst80 [no loc], loaded [concrete = constants.%A] +// CHECK:STDOUT: %Main.import_ref.cb9298.1: type = import_ref Main//factory, inst83 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.2d5 = import_ref Main//factory, loc11_9, unloaded +// CHECK:STDOUT: %Main.import_ref.6c7: = import_ref Main//factory, loc12_9, loaded [concrete = constants.%Destroy.impl_witness.5cf] +// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//factory, loc12_10, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.54a = import_ref Main//factory, inst124 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.bfe: type = import_ref Main//factory, inst124 [no loc], loaded [concrete = constants.%B] +// CHECK:STDOUT: %Main.import_ref.cb9298.2: type = import_ref Main//factory, inst83 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.fc3 = import_ref Main//factory, loc12_9, unloaded // CHECK:STDOUT: %Main.import_ref.5ab3ec.1: type = import_ref Main//factory, loc4_19, loaded [symbolic = @Factory.%T (constants.%T)] // CHECK:STDOUT: %Main.import_ref.fbb = import_ref Main//factory, inst27 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.46c: @Factory.%Factory.assoc_type (%Factory.assoc_type.207) = import_ref Main//factory, loc6_17, loaded [symbolic = @Factory.%assoc0 (constants.%assoc0.46d25f.2)] @@ -1110,8 +1330,6 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %Main.Make = import_ref Main//factory, Make, unloaded // CHECK:STDOUT: %Main.Method = import_ref Main//factory, Method, unloaded // CHECK:STDOUT: %Main.import_ref.6fd: = import_ref Main//factory, loc14_22, loaded [concrete = constants.%Factory.impl_witness] -// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//factory, loc11_10, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Main.import_ref.da3 = import_ref Main//factory, inst80 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.984: type = import_ref Main//factory, loc14_6, loaded [concrete = constants.%A] // CHECK:STDOUT: %Main.import_ref.bd2: type = import_ref Main//factory, loc14_20, loaded [concrete = constants.%Factory.type.a5d] // CHECK:STDOUT: %Main.import_ref.a27 = import_ref Main//factory, loc15_17, unloaded @@ -1129,6 +1347,8 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %Main.import_ref.7dd: %A.as.Factory.impl.Method.type = import_ref Main//factory, loc16_31, loaded [concrete = constants.%A.as.Factory.impl.Method] // CHECK:STDOUT: %Factory.impl_witness_table = impl_witness_table (%Main.import_ref.9ec, %Main.import_ref.7dd), @A.as.Factory.impl [concrete] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.82a: %B.as.Destroy.impl.Op.type = import_ref Main//factory, loc12_9, loaded [concrete = constants.%B.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.f6b = impl_witness_table (%Main.import_ref.82a), @B.as.Destroy.impl [concrete] // CHECK:STDOUT: %Main.import_ref.46fc3c.2 = import_ref Main//factory, loc8_31, unloaded // CHECK:STDOUT: } // CHECK:STDOUT: @@ -1137,7 +1357,7 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: .Factory = imports.%Main.Factory // CHECK:STDOUT: .A = imports.%Main.A // CHECK:STDOUT: .B = imports.%Main.B -// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Core = imports.%Core.ece // CHECK:STDOUT: .MakeB = %MakeB.decl // CHECK:STDOUT: .InstanceB = %InstanceB.decl // CHECK:STDOUT: } @@ -1190,6 +1410,18 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: imports.%Main.import_ref.93c as imports.%Main.import_ref.cb9298.1 [from "factory.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = imports.%Main.import_ref.2d5 +// CHECK:STDOUT: witness = imports.%Main.import_ref.7b0 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: imports.%Main.import_ref.bfe as imports.%Main.import_ref.cb9298.2 [from "factory.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = imports.%Main.import_ref.fc3 +// CHECK:STDOUT: witness = imports.%Main.import_ref.6c7 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @A.as.Factory.impl: imports.%Main.import_ref.984 as imports.%Main.import_ref.bd2 [from "factory.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: .Make = imports.%Main.import_ref.a27 @@ -1197,18 +1429,18 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: witness = imports.%Main.import_ref.6fd // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @B [from "factory.carbon"] { +// CHECK:STDOUT: class @A [from "factory.carbon"] { // CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.1 // CHECK:STDOUT: // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = imports.%Main.import_ref.54a +// CHECK:STDOUT: .Self = imports.%Main.import_ref.da3 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @A [from "factory.carbon"] { +// CHECK:STDOUT: class @B [from "factory.carbon"] { // CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.2 // CHECK:STDOUT: // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = imports.%Main.import_ref.da3 +// CHECK:STDOUT: .Self = imports.%Main.import_ref.54a // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @Factory.Make(imports.%Main.import_ref.5ab3ec.2: type, imports.%Main.import_ref.91b53a.1: @Factory.%Factory.type (%Factory.type.c96)) [from "factory.carbon"] { @@ -1242,16 +1474,16 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %impl.elem0: %.711 = impl_witness_access constants.%Factory.impl_witness, element0 [concrete = constants.%A.as.Factory.impl.Make] // CHECK:STDOUT: %.loc4: ref %B = splice_block %return {} // CHECK:STDOUT: %A.as.Factory.impl.Make.call: init %B = call %impl.elem0() to %.loc4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc4, constants.%T.as.Destroy.impl.Op.3c2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.3c2, @T.as.Destroy.impl.Op(constants.%B) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc4, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %B.as.Destroy.impl.Op.bound: = bound_method %.loc4, constants.%B.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.e79 = addr_of %.loc4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %B.as.Destroy.impl.Op.call: init %empty_tuple.type = call %B.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %A.as.Factory.impl.Make.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @A.as.Factory.impl.Make [from "factory.carbon"]; // CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op = "no_op" [from "factory.carbon"]; +// CHECK:STDOUT: // CHECK:STDOUT: fn @InstanceB(%a.param: %A) -> %return.param: %B { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %A = name_ref a, %a @@ -1261,14 +1493,12 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %.loc8: %Factory.assoc_type.579 = specific_constant imports.%Main.import_ref.2e4, @Factory(constants.%B) [concrete = constants.%assoc1.a48] // CHECK:STDOUT: %Method.ref: %Factory.assoc_type.579 = name_ref Method, %.loc8 [concrete = constants.%assoc1.a48] // CHECK:STDOUT: %impl.elem1: %.fed = impl_witness_access constants.%Factory.impl_witness, element1 [concrete = constants.%A.as.Factory.impl.Method] -// CHECK:STDOUT: %bound_method.loc8: = bound_method %a.ref, %impl.elem1 +// CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem1 // CHECK:STDOUT: %.loc7: ref %B = splice_block %return {} -// CHECK:STDOUT: %A.as.Factory.impl.Method.call: init %B = call %bound_method.loc8(%a.ref) to %.loc7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc7, constants.%T.as.Destroy.impl.Op.3c2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.3c2, @T.as.Destroy.impl.Op(constants.%B) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc7: = bound_method %.loc7, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %A.as.Factory.impl.Method.call: init %B = call %bound_method(%a.ref) to %.loc7 +// CHECK:STDOUT: %B.as.Destroy.impl.Op.bound: = bound_method %.loc7, constants.%B.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.e79 = addr_of %.loc7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc7(%addr) +// CHECK:STDOUT: %B.as.Destroy.impl.Op.call: init %empty_tuple.type = call %B.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %A.as.Factory.impl.Method.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -1310,16 +1540,17 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: --- fail_factory.impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %A: type = class_type @A [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %Factory.type.1a8: type = generic_interface_type @Factory [concrete] // CHECK:STDOUT: %Factory.generic: %Factory.type.1a8 = struct_value () [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %Factory.type.c96: type = facet_type <@Factory, @Factory(%T)> [symbolic] // CHECK:STDOUT: %Self.9ba: %Factory.type.c96 = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %Factory.type.a5d: type = facet_type <@Factory, @Factory(%B)> [concrete] -// CHECK:STDOUT: %A: type = class_type @A [concrete] // CHECK:STDOUT: %Factory.Make.type.598: type = fn_type @Factory.Make, @Factory(%T) [symbolic] // CHECK:STDOUT: %Factory.Make.737: %Factory.Make.type.598 = struct_value () [symbolic] // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] @@ -1327,8 +1558,8 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %assoc0.fe4: %Factory.assoc_type.207 = assoc_entity element0, imports.%Main.import_ref.1aa [symbolic] // CHECK:STDOUT: %Factory.Method.type.7ee: type = fn_type @Factory.Method, @Factory(%T) [symbolic] // CHECK:STDOUT: %Factory.Method.a71: %Factory.Method.type.7ee = struct_value () [symbolic] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.9ba [symbolic] -// CHECK:STDOUT: %pattern_type.5ea: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Self.as_type.56c: type = facet_access_type %Self.9ba [symbolic] +// CHECK:STDOUT: %pattern_type.5ea: type = pattern_type %Self.as_type.56c [symbolic] // CHECK:STDOUT: %assoc1.ea6: %Factory.assoc_type.207 = assoc_entity element1, imports.%Main.import_ref.5be [symbolic] // CHECK:STDOUT: %Self.187: %Factory.type.a5d = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %Factory.Make.type.c59: type = fn_type @Factory.Make, @Factory(%B) [concrete] @@ -1339,6 +1570,12 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %Factory.Method.ea9: %Factory.Method.type.117 = struct_value () [concrete] // CHECK:STDOUT: %assoc1.535: %Factory.assoc_type.579 = assoc_entity element1, imports.%Main.import_ref.46fc3c.1 [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %MakeC.type: type = fn_type @MakeC [concrete] // CHECK:STDOUT: %MakeC: %MakeC.type = struct_value () [concrete] @@ -1362,13 +1599,24 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %Main.Factory: %Factory.type.1a8 = import_ref Main//factory, Factory, loaded [concrete = constants.%Factory.generic] // CHECK:STDOUT: %Main.A: type = import_ref Main//factory, A, loaded [concrete = constants.%A] // CHECK:STDOUT: %Main.B = import_ref Main//factory, B, unloaded -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: %Core.ece: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//default // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//factory, loc12_10, loaded [concrete = constants.%complete_type] -// CHECK:STDOUT: %Main.import_ref.54a = import_ref Main//factory, inst86 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.7b0 = import_ref Main//factory, loc11_9, unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//factory, loc11_10, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.da3 = import_ref Main//factory, inst80 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.93c: type = import_ref Main//factory, inst80 [no loc], loaded [concrete = constants.%A] +// CHECK:STDOUT: %Main.import_ref.cb9298.1: type = import_ref Main//factory, inst83 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.2d5 = import_ref Main//factory, loc11_9, unloaded +// CHECK:STDOUT: %Main.import_ref.ae7 = import_ref Main//factory, loc12_9, unloaded +// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//factory, loc12_10, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Main.import_ref.54a = import_ref Main//factory, inst124 [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.bfe: type = import_ref Main//factory, inst124 [no loc], loaded [concrete = constants.%B] +// CHECK:STDOUT: %Main.import_ref.cb9298.2: type = import_ref Main//factory, inst83 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.fc3 = import_ref Main//factory, loc12_9, unloaded // CHECK:STDOUT: %Main.import_ref.5ab3ec.1: type = import_ref Main//factory, loc4_19, loaded [symbolic = @Factory.%T (constants.%T)] // CHECK:STDOUT: %Main.import_ref.fbb = import_ref Main//factory, inst27 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.46c: @Factory.%Factory.assoc_type (%Factory.assoc_type.207) = import_ref Main//factory, loc6_17, loaded [symbolic = @Factory.%assoc0 (constants.%assoc0.46d)] @@ -1376,8 +1624,6 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %Main.Make = import_ref Main//factory, Make, unloaded // CHECK:STDOUT: %Main.Method = import_ref Main//factory, Method, unloaded // CHECK:STDOUT: %Main.import_ref.4c3 = import_ref Main//factory, loc14_22, unloaded -// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//factory, loc11_10, loaded [concrete = constants.%complete_type] -// CHECK:STDOUT: %Main.import_ref.da3 = import_ref Main//factory, inst80 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.984: type = import_ref Main//factory, loc14_6, loaded [concrete = constants.%A] // CHECK:STDOUT: %Main.import_ref.bd2: type = import_ref Main//factory, loc14_20, loaded [concrete = constants.%Factory.type.a5d] // CHECK:STDOUT: %Main.import_ref.a27 = import_ref Main//factory, loc15_17, unloaded @@ -1390,6 +1636,7 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %Main.import_ref.5be: @Factory.%Factory.Method.type (%Factory.Method.type.7ee) = import_ref Main//factory, loc8_31, loaded [symbolic = @Factory.%Factory.Method (constants.%Factory.Method.a71)] // CHECK:STDOUT: %Main.import_ref.21018a.1 = import_ref Main//factory, loc6_17, unloaded // CHECK:STDOUT: %Main.import_ref.46fc3c.1 = import_ref Main//factory, loc8_31, unloaded +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Main.import_ref.21018a.2 = import_ref Main//factory, loc6_17, unloaded // CHECK:STDOUT: %Main.import_ref.46fc3c.2 = import_ref Main//factory, loc8_31, unloaded // CHECK:STDOUT: } @@ -1399,7 +1646,7 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: .Factory = imports.%Main.Factory // CHECK:STDOUT: .A = imports.%Main.A // CHECK:STDOUT: .B = imports.%Main.B -// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Core = imports.%Core.ece // CHECK:STDOUT: .C = %C.decl // CHECK:STDOUT: .MakeC = %MakeC.decl // CHECK:STDOUT: .InstanceC = %InstanceC.decl @@ -1454,6 +1701,18 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: imports.%Main.import_ref.93c as imports.%Main.import_ref.cb9298.1 [from "factory.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = imports.%Main.import_ref.2d5 +// CHECK:STDOUT: witness = imports.%Main.import_ref.7b0 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: imports.%Main.import_ref.bfe as imports.%Main.import_ref.cb9298.2 [from "factory.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = imports.%Main.import_ref.fc3 +// CHECK:STDOUT: witness = imports.%Main.import_ref.ae7 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @A.as.Factory.impl: imports.%Main.import_ref.984 as imports.%Main.import_ref.bd2 [from "factory.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: .Make = imports.%Main.import_ref.a27 @@ -1461,21 +1720,40 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: witness = imports.%Main.import_ref.4c3 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: class @B [from "factory.carbon"] { -// CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.1 +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = imports.%Main.import_ref.54a +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @A [from "factory.carbon"] { -// CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.2 +// CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.1 // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = imports.%Main.import_ref.da3 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: class @B [from "factory.carbon"] { +// CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.2 +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Main.import_ref.54a +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1495,13 +1773,15 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %Factory.type: type = facet_type <@Factory, @Factory(%T)> [symbolic = %Factory.type (constants.%Factory.type.c96)] // CHECK:STDOUT: %Self: @Factory.Method.%Factory.type (%Factory.type.c96) = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.9ba)] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type)] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type.56c)] // CHECK:STDOUT: %pattern_type.1: type = pattern_type %Self.as_type [symbolic = %pattern_type.1 (constants.%pattern_type.5ea)] // CHECK:STDOUT: %pattern_type.2: type = pattern_type %T [symbolic = %pattern_type.2 (constants.%pattern_type.7dc)] // CHECK:STDOUT: // CHECK:STDOUT: fn; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @MakeC() -> %return.param: %C { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %A.ref: type = name_ref A, imports.%Main.A [concrete = constants.%A] @@ -1552,7 +1832,7 @@ fn InstanceC(a: A) -> C { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %Factory.type => constants.%Factory.type.c96 // CHECK:STDOUT: %Self => constants.%Self.9ba -// CHECK:STDOUT: %Self.as_type => constants.%Self.as_type +// CHECK:STDOUT: %Self.as_type => constants.%Self.as_type.56c // CHECK:STDOUT: %pattern_type.1 => constants.%pattern_type.5ea // CHECK:STDOUT: %pattern_type.2 => constants.%pattern_type.7dc // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/impl/lookup/canonical_query_self.carbon b/toolchain/check/testdata/impl/lookup/canonical_query_self.carbon index 164eaf698379..d1f21b0d19dc 100644 --- a/toolchain/check/testdata/impl/lookup/canonical_query_self.carbon +++ b/toolchain/check/testdata/impl/lookup/canonical_query_self.carbon @@ -103,17 +103,19 @@ fn G() { // CHECK:STDOUT: %C.as.J.impl.JJ.type: type = fn_type @C.as.J.impl.JJ [concrete] // CHECK:STDOUT: %C.as.J.impl.JJ: %C.as.J.impl.JJ.type = struct_value () [concrete] // CHECK:STDOUT: %J.facet.5df: %J.type = facet_value %C, (%J.impl_witness) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.bd5: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.8e6: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.663: type = pattern_type %ptr.8e6 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %.638: type = fn_type_with_self_type %J.JJ.type, %J.facet.5df [concrete] // CHECK:STDOUT: %facet_value: %facet_type = facet_value %C, (%I.impl_witness, %J.impl_witness) [concrete] // CHECK:STDOUT: %F.specific_fn: = specific_function %F, @F(%facet_value) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.8e9: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.ddb: %T.as.Destroy.impl.Op.type.8e9 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.8e6: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.ddb, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -242,6 +244,22 @@ fn G() { // CHECK:STDOUT: witness = @C.%J.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.663 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.663 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc30: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.8e6 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.8e6 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] @@ -255,8 +273,11 @@ fn G() { // CHECK:STDOUT: } // CHECK:STDOUT: %J.impl_witness_table = impl_witness_table (@C.as.J.impl.%C.as.J.impl.JJ.decl), @C.as.J.impl [concrete] // CHECK:STDOUT: %J.impl_witness: = impl_witness %J.impl_witness_table [concrete = constants.%J.impl_witness] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.bd5] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -368,9 +389,9 @@ fn G() { // CHECK:STDOUT: %.loc40_75: type = converted %.loc40_71, %as_type.loc40_75 [concrete = constants.%C] // CHECK:STDOUT: %JJ.ref: %J.assoc_type = name_ref JJ, @J.%assoc0 [concrete = constants.%assoc0.78c] // CHECK:STDOUT: %impl.elem0: %.638 = impl_witness_access constants.%J.impl_witness, element0 [concrete = constants.%C.as.J.impl.JJ] -// CHECK:STDOUT: %bound_method.loc40_77: = bound_method %.loc40_8.1, %impl.elem0 +// CHECK:STDOUT: %bound_method: = bound_method %.loc40_8.1, %impl.elem0 // CHECK:STDOUT: %.loc40_8.2: %C = bind_value %.loc40_8.1 -// CHECK:STDOUT: %C.as.J.impl.JJ.call: init %empty_tuple.type = call %bound_method.loc40_77(%.loc40_8.2) +// CHECK:STDOUT: %C.as.J.impl.JJ.call: init %empty_tuple.type = call %bound_method(%.loc40_8.2) // CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] // CHECK:STDOUT: %C.ref.loc46_5: type = name_ref C, %C.decl [concrete = constants.%C] // CHECK:STDOUT: %.loc46_9.1: %empty_struct_type = struct_literal () @@ -388,16 +409,12 @@ fn G() { // CHECK:STDOUT: %F.specific_fn: = specific_function %F.ref, @F(constants.%facet_value) [concrete = constants.%F.specific_fn] // CHECK:STDOUT: %.loc46_11.2: %C = bind_value %.loc46_11.1 // CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.specific_fn(%.loc46_11.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc46: = bound_method %.loc46_9.2, constants.%T.as.Destroy.impl.Op.ddb -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.ddb, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc46: = bound_method %.loc46_9.2, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound.loc46: = bound_method %.loc46_9.2, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc46: %ptr.8e6 = addr_of %.loc46_9.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc46: init %empty_tuple.type = call %bound_method.loc46(%addr.loc46) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc40: = bound_method %.loc40_6.2, constants.%T.as.Destroy.impl.Op.ddb -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.ddb, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc40_6: = bound_method %.loc40_6.2, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call.loc46: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound.loc46(%addr.loc46) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound.loc40: = bound_method %.loc40_6.2, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc40: %ptr.8e6 = addr_of %.loc40_6.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc40: init %empty_tuple.type = call %bound_method.loc40_6(%addr.loc40) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call.loc40: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound.loc40(%addr.loc40) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -411,6 +428,8 @@ fn G() { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.8e6) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @I.II(constants.%Self.826) { // CHECK:STDOUT: %Self => constants.%Self.826 // CHECK:STDOUT: %Self.as_type.loc16_15.1 => constants.%Self.as_type.b70 @@ -453,7 +472,7 @@ fn G() { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.893 // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete => constants.%complete_type.357 +// CHECK:STDOUT: %require_complete => constants.%complete_type // CHECK:STDOUT: %I.lookup_impl_witness => constants.%I.impl_witness // CHECK:STDOUT: %I.facet.loc26_18.2 => constants.%I.facet.98f // CHECK:STDOUT: %J.lookup_impl_witness => constants.%J.impl_witness diff --git a/toolchain/check/testdata/impl/lookup/generic.carbon b/toolchain/check/testdata/impl/lookup/generic.carbon index f58b68c12331..c9a5ccef55f0 100644 --- a/toolchain/check/testdata/impl/lookup/generic.carbon +++ b/toolchain/check/testdata/impl/lookup/generic.carbon @@ -554,9 +554,9 @@ fn G(x: A) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %HasF.type: type = facet_type <@HasF> [concrete] -// CHECK:STDOUT: %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic] -// CHECK:STDOUT: %pattern_type.28f: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Self.f0c: %HasF.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.as_type.308: type = facet_access_type %Self.f0c [symbolic] +// CHECK:STDOUT: %pattern_type.28f: type = pattern_type %Self.as_type.308 [symbolic] // CHECK:STDOUT: %HasF.F.type: type = fn_type @HasF.F [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %HasF.F: %HasF.F.type = struct_value () [concrete] @@ -567,6 +567,13 @@ fn G(x: A) { // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.f2e: type = class_type @C, @C(%T) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %HasF.impl_witness.834: = impl_witness file.%HasF.impl_witness_table, @C.as.HasF.impl(%T) [symbolic] @@ -589,9 +596,11 @@ fn G(x: A) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -635,18 +644,18 @@ fn G(x: A) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @HasF { -// CHECK:STDOUT: %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.f0c] // CHECK:STDOUT: %HasF.F.decl: %HasF.F.type = fn_decl @HasF.F [concrete = constants.%HasF.F] { // CHECK:STDOUT: %self.patt: @HasF.F.%pattern_type (%pattern_type.28f) = binding_pattern self [concrete] // CHECK:STDOUT: %self.param_patt: @HasF.F.%pattern_type (%pattern_type.28f) = value_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type) = value_param call_param0 -// CHECK:STDOUT: %.loc5_14.1: type = splice_block %.loc5_14.2 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] { -// CHECK:STDOUT: %Self.ref: %HasF.type = name_ref Self, @HasF.%Self [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.as_type.loc5_14.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] -// CHECK:STDOUT: %.loc5_14.2: type = converted %Self.ref, %Self.as_type.loc5_14.2 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %self.param: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type.308) = value_param call_param0 +// CHECK:STDOUT: %.loc5_14.1: type = splice_block %.loc5_14.2 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.308)] { +// CHECK:STDOUT: %Self.ref: %HasF.type = name_ref Self, @HasF.%Self [symbolic = %Self (constants.%Self.f0c)] +// CHECK:STDOUT: %Self.as_type.loc5_14.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.308)] +// CHECK:STDOUT: %.loc5_14.2: type = converted %Self.ref, %Self.as_type.loc5_14.2 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.308)] // CHECK:STDOUT: } -// CHECK:STDOUT: %self: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type) = bind_name self, %self.param +// CHECK:STDOUT: %self: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type.308) = bind_name self, %self.param // CHECK:STDOUT: } // CHECK:STDOUT: %assoc0: %HasF.assoc_type = assoc_entity element0, %HasF.F.decl [concrete = constants.%assoc0] // CHECK:STDOUT: @@ -656,6 +665,34 @@ fn G(x: A) { // CHECK:STDOUT: witness = (%HasF.F.decl) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc8_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f2e as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc8_19.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.f2e)] { +// CHECK:STDOUT: %.loc8_19.3: type = specific_constant constants.%C.f2e, @C(constants.%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc8_19.3 [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl @C.as.HasF.impl(%T.loc10_14.2: type) { // CHECK:STDOUT: %T.loc10_14.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc10_14.1 (constants.%T)] // CHECK:STDOUT: %C.loc10_27.1: type = class_type @C, @C(%T.loc10_14.1) [symbolic = %C.loc10_27.1 (constants.%C.f2e)] @@ -687,6 +724,9 @@ fn G(x: A) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -697,11 +737,22 @@ fn G(x: A) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @HasF.F(@HasF.%Self: %HasF.type) { -// CHECK:STDOUT: %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.as_type.loc5_14.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.f0c)] +// CHECK:STDOUT: %Self.as_type.loc5_14.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.308)] // CHECK:STDOUT: %pattern_type: type = pattern_type %Self.as_type.loc5_14.1 [symbolic = %pattern_type (constants.%pattern_type.28f)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%self.param: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type)); +// CHECK:STDOUT: fn(%self.param: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type.308)); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc8_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @C.as.HasF.impl.F(@C.as.HasF.impl.%T.loc10_14.2: type) { @@ -731,9 +782,9 @@ fn G(x: A) { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @HasF.F(constants.%Self) { -// CHECK:STDOUT: %Self => constants.%Self -// CHECK:STDOUT: %Self.as_type.loc5_14.1 => constants.%Self.as_type +// CHECK:STDOUT: specific @HasF.F(constants.%Self.f0c) { +// CHECK:STDOUT: %Self => constants.%Self.f0c +// CHECK:STDOUT: %Self.as_type.loc5_14.1 => constants.%Self.as_type.308 // CHECK:STDOUT: %pattern_type => constants.%pattern_type.28f // CHECK:STDOUT: } // CHECK:STDOUT: @@ -743,6 +794,18 @@ fn G(x: A) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.f2e +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C.as.HasF.impl(constants.%T) { // CHECK:STDOUT: %T.loc10_14.1 => constants.%T // CHECK:STDOUT: %C.loc10_27.1 => constants.%C.f2e @@ -1209,8 +1272,8 @@ fn G(x: A) { // CHECK:STDOUT: %HasF.generic: %HasF.type.fe3 = struct_value () [concrete] // CHECK:STDOUT: %HasF.type.901: type = facet_type <@HasF, @HasF(%T)> [symbolic] // CHECK:STDOUT: %Self.322: %HasF.type.901 = bind_symbolic_name Self, 1 [symbolic] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.322 [symbolic] -// CHECK:STDOUT: %pattern_type.dfb: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Self.as_type.859: type = facet_access_type %Self.322 [symbolic] +// CHECK:STDOUT: %pattern_type.dfb: type = pattern_type %Self.as_type.859 [symbolic] // CHECK:STDOUT: %HasF.F.type.46c: type = fn_type @HasF.F, @HasF(%T) [symbolic] // CHECK:STDOUT: %HasF.F.823: %HasF.F.type.46c = struct_value () [symbolic] // CHECK:STDOUT: %HasF.assoc_type.dd8: type = assoc_entity_type @HasF, @HasF(%T) [symbolic] @@ -1223,9 +1286,21 @@ fn G(x: A) { // CHECK:STDOUT: %HasF.facet: %HasF.type.901 = facet_value %T, (%HasF.impl_witness) [symbolic] // CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %A: type = class_type @A [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b44: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.40d: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.c10: type = pattern_type %A [concrete] // CHECK:STDOUT: %G.type: type = fn_type @G [concrete] // CHECK:STDOUT: %G: %G.type = struct_value () [concrete] @@ -1239,9 +1314,11 @@ fn G(x: A) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1298,14 +1375,14 @@ fn G(x: A) { // CHECK:STDOUT: %self.patt: @HasF.F.%pattern_type (%pattern_type.dfb) = binding_pattern self [concrete] // CHECK:STDOUT: %self.param_patt: @HasF.F.%pattern_type (%pattern_type.dfb) = value_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type) = value_param call_param0 -// CHECK:STDOUT: %.loc5_14.1: type = splice_block %.loc5_14.3 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] { +// CHECK:STDOUT: %self.param: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type.859) = value_param call_param0 +// CHECK:STDOUT: %.loc5_14.1: type = splice_block %.loc5_14.3 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.859)] { // CHECK:STDOUT: %.loc5_14.2: @HasF.F.%HasF.type (%HasF.type.901) = specific_constant @HasF.%Self.1, @HasF(constants.%T) [symbolic = %Self (constants.%Self.322)] // CHECK:STDOUT: %Self.ref: @HasF.F.%HasF.type (%HasF.type.901) = name_ref Self, %.loc5_14.2 [symbolic = %Self (constants.%Self.322)] -// CHECK:STDOUT: %Self.as_type.loc5_14.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] -// CHECK:STDOUT: %.loc5_14.3: type = converted %Self.ref, %Self.as_type.loc5_14.2 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self.as_type.loc5_14.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.859)] +// CHECK:STDOUT: %.loc5_14.3: type = converted %Self.ref, %Self.as_type.loc5_14.2 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.859)] // CHECK:STDOUT: } -// CHECK:STDOUT: %self: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type) = bind_name self, %self.param +// CHECK:STDOUT: %self: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type.859) = bind_name self, %self.param // CHECK:STDOUT: } // CHECK:STDOUT: %assoc0.loc5_21.1: @HasF.%HasF.assoc_type (%HasF.assoc_type.dd8) = assoc_entity element0, %HasF.F.decl [symbolic = %assoc0.loc5_21.2 (constants.%assoc0.d31)] // CHECK:STDOUT: @@ -1342,7 +1419,42 @@ fn G(x: A) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.6db = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc13: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.e79 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b44] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1352,6 +1464,9 @@ fn G(x: A) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @B { +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.40d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1364,10 +1479,10 @@ fn G(x: A) { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %HasF.type: type = facet_type <@HasF, @HasF(%T)> [symbolic = %HasF.type (constants.%HasF.type.901)] // CHECK:STDOUT: %Self: @HasF.F.%HasF.type (%HasF.type.901) = bind_symbolic_name Self, 1 [symbolic = %Self (constants.%Self.322)] -// CHECK:STDOUT: %Self.as_type.loc5_14.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self.as_type.loc5_14.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.859)] // CHECK:STDOUT: %pattern_type: type = pattern_type %Self.as_type.loc5_14.1 [symbolic = %pattern_type (constants.%pattern_type.dfb)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%self.param: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type)); +// CHECK:STDOUT: fn(%self.param: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type.859)); // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @T.as.HasF.impl.F(@T.as.HasF.impl.%T.loc8_14.2: type) { @@ -1383,6 +1498,10 @@ fn G(x: A) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.6db) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.e79) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @G(%x.param: %A) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %x.ref: %A = name_ref x, %x @@ -1410,7 +1529,7 @@ fn G(x: A) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %HasF.type => constants.%HasF.type.901 // CHECK:STDOUT: %Self => constants.%Self.322 -// CHECK:STDOUT: %Self.as_type.loc5_14.1 => constants.%Self.as_type +// CHECK:STDOUT: %Self.as_type.loc5_14.1 => constants.%Self.as_type.859 // CHECK:STDOUT: %pattern_type => constants.%pattern_type.dfb // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/lookup/impl_forall.carbon b/toolchain/check/testdata/impl/lookup/impl_forall.carbon index 26fc28c7f52c..b48014879948 100644 --- a/toolchain/check/testdata/impl/lookup/impl_forall.carbon +++ b/toolchain/check/testdata/impl/lookup/impl_forall.carbon @@ -48,6 +48,13 @@ fn TestSpecific(a: A({})) -> {} { // CHECK:STDOUT: %A.13025a.1: type = class_type @A, @A(%T) [symbolic] // CHECK:STDOUT: %require_complete.4aeca8.1: = require_complete_type %T [symbolic] // CHECK:STDOUT: %A.elem.1ceb36.1: type = unbound_element_type %A.13025a.1, %T [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d93: = impl_witness @A.%Destroy.impl_witness_table, @A.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.ca9: type = ptr_type %A.13025a.1 [symbolic] +// CHECK:STDOUT: %pattern_type.09b: type = pattern_type %ptr.ca9 [symbolic] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op, @A.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %struct_type.n.848971.1: type = struct_type {.n: %T} [symbolic] // CHECK:STDOUT: %complete_type.84bb3d.1: = complete_type_witness %struct_type.n.848971.1 [symbolic] // CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic] @@ -132,7 +139,6 @@ fn TestSpecific(a: A({})) -> {} { // CHECK:STDOUT: %.8fd: type = fn_type_with_self_type %I.F.type.684, %I.facet.bd5 [concrete] // CHECK:STDOUT: %A.as.I.impl.F.specific_fn: = specific_function %A.as.I.impl.F.158, @A.as.I.impl.F(%empty_struct_type) [concrete] // CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.069: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%empty_struct_type) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.d5a: %T.as.Destroy.impl.Op.type.069 = struct_value () [concrete] // CHECK:STDOUT: %ptr.c28: type = ptr_type %empty_struct_type [concrete] @@ -261,6 +267,34 @@ fn TestSpecific(a: A({})) -> {} { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @A.as.Destroy.impl(@A.%T.loc3_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @A.%Destroy.impl_witness_table, @A.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.d93)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op, @A.as.Destroy.impl(%T) [symbolic = %A.as.Destroy.impl.Op.type (constants.%A.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: @A.as.Destroy.impl.%A.as.Destroy.impl.Op.type (%A.as.Destroy.impl.Op.type) = struct_value () [symbolic = %A.as.Destroy.impl.Op (constants.%A.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%A.13025a.1 as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: @A.as.Destroy.impl.%A.as.Destroy.impl.Op.type (%A.as.Destroy.impl.Op.type) = fn_decl @A.as.Destroy.impl.Op [symbolic = @A.as.Destroy.impl.%A.as.Destroy.impl.Op (constants.%A.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @A.as.Destroy.impl.Op.%pattern_type (%pattern_type.09b) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @A.as.Destroy.impl.Op.%pattern_type (%pattern_type.09b) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc3_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @A.as.Destroy.impl.Op.%ptr (%ptr.ca9) = value_param call_param0 +// CHECK:STDOUT: %.loc3_19.2: type = splice_block %Self.ref [symbolic = %A (constants.%A.13025a.1)] { +// CHECK:STDOUT: %.loc3_19.3: type = specific_constant constants.%A.13025a.1, @A(constants.%T) [symbolic = %A (constants.%A.13025a.1)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc3_19.3 [symbolic = %A (constants.%A.13025a.1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @A.as.Destroy.impl.Op.%ptr (%ptr.ca9) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl @A.as.I.impl(%V.loc11_14.2: type) { // CHECK:STDOUT: %V.loc11_14.1: type = bind_symbolic_name V, 0 [symbolic = %V.loc11_14.1 (constants.%V)] // CHECK:STDOUT: %A.loc11_27.1: type = class_type @A, @A(%V.loc11_14.1) [symbolic = %A.loc11_27.1 (constants.%A.13025a.2)] @@ -307,6 +341,9 @@ fn TestSpecific(a: A({})) -> {} { // CHECK:STDOUT: class { // CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc3_9.2 [symbolic = %T.loc3_9.1 (constants.%T)] // CHECK:STDOUT: %.loc4: @A.%A.elem (%A.elem.1ceb36.1) = field_decl n, element0 [concrete] +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @A.as.Destroy.impl(constants.%T) [symbolic = @A.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.d93)] // CHECK:STDOUT: %struct_type.n.loc5_1.1: type = struct_type {.n: %T} [symbolic = %struct_type.n.loc5_1.2 (constants.%struct_type.n.848971.1)] // CHECK:STDOUT: %complete_type.loc5_1.1: = complete_type_witness %struct_type.n.loc5_1.1 [symbolic = %complete_type.loc5_1.2 (constants.%complete_type.84bb3d.1)] // CHECK:STDOUT: complete_type_witness = %complete_type.loc5_1.1 @@ -318,6 +355,17 @@ fn TestSpecific(a: A({})) -> {} { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @A.as.Destroy.impl.Op(@A.%T.loc3_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %A: type = class_type @A, @A(%T) [symbolic = %A (constants.%A.13025a.1)] +// CHECK:STDOUT: %ptr: type = ptr_type %A [symbolic = %ptr (constants.%ptr.ca9)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.09b)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @A.as.Destroy.impl.Op.%ptr (%ptr.ca9)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @I.F(@I.%U.loc7_13.2: type, @I.%Self.1: @I.%I.type (%I.type.325e65.1)) { // CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic = %U (constants.%U)] // CHECK:STDOUT: %I.type: type = facet_type <@I, @I(%U)> [symbolic = %I.type (constants.%I.type.325e65.1)] @@ -419,6 +467,18 @@ fn TestSpecific(a: A({})) -> {} { // CHECK:STDOUT: %T.loc3_9.1 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @A.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.d93 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %A => constants.%A.13025a.1 +// CHECK:STDOUT: %ptr => constants.%ptr.ca9 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.09b +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @I(constants.%U) { // CHECK:STDOUT: %U.loc7_13.1 => constants.%U // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/impl/lookup/import.carbon b/toolchain/check/testdata/impl/lookup/import.carbon index 0252f7e95a13..e28e727b4582 100644 --- a/toolchain/check/testdata/impl/lookup/import.carbon +++ b/toolchain/check/testdata/impl/lookup/import.carbon @@ -227,14 +227,21 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %HasF.type: type = facet_type <@HasF> [concrete] -// CHECK:STDOUT: %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic] -// CHECK:STDOUT: %pattern_type.28f: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Self.f0c: %HasF.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.as_type.308: type = facet_access_type %Self.f0c [symbolic] +// CHECK:STDOUT: %pattern_type.28f: type = pattern_type %Self.as_type.308 [symbolic] // CHECK:STDOUT: %HasF.F.type: type = fn_type @HasF.F [concrete] // CHECK:STDOUT: %HasF.F: %HasF.F.type = struct_value () [concrete] // CHECK:STDOUT: %HasF.assoc_type: type = assoc_entity_type @HasF [concrete] // CHECK:STDOUT: %assoc0: %HasF.assoc_type = assoc_entity element0, @HasF.%HasF.F.decl [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %HasF.impl_witness: = impl_witness file.%HasF.impl_witness_table [concrete] @@ -246,9 +253,11 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -269,18 +278,18 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @HasF { -// CHECK:STDOUT: %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.f0c] // CHECK:STDOUT: %HasF.F.decl: %HasF.F.type = fn_decl @HasF.F [concrete = constants.%HasF.F] { // CHECK:STDOUT: %self.patt: @HasF.F.%pattern_type (%pattern_type.28f) = binding_pattern self [concrete] // CHECK:STDOUT: %self.param_patt: @HasF.F.%pattern_type (%pattern_type.28f) = value_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type) = value_param call_param0 -// CHECK:STDOUT: %.loc5_14.1: type = splice_block %.loc5_14.2 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] { -// CHECK:STDOUT: %Self.ref: %HasF.type = name_ref Self, @HasF.%Self [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.as_type.loc5_14.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] -// CHECK:STDOUT: %.loc5_14.2: type = converted %Self.ref, %Self.as_type.loc5_14.2 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %self.param: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type.308) = value_param call_param0 +// CHECK:STDOUT: %.loc5_14.1: type = splice_block %.loc5_14.2 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.308)] { +// CHECK:STDOUT: %Self.ref: %HasF.type = name_ref Self, @HasF.%Self [symbolic = %Self (constants.%Self.f0c)] +// CHECK:STDOUT: %Self.as_type.loc5_14.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.308)] +// CHECK:STDOUT: %.loc5_14.2: type = converted %Self.ref, %Self.as_type.loc5_14.2 [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.308)] // CHECK:STDOUT: } -// CHECK:STDOUT: %self: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type) = bind_name self, %self.param +// CHECK:STDOUT: %self: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type.308) = bind_name self, %self.param // CHECK:STDOUT: } // CHECK:STDOUT: %assoc0: %HasF.assoc_type = assoc_entity element0, %HasF.F.decl [concrete = constants.%assoc0] // CHECK:STDOUT: @@ -290,6 +299,22 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = (%HasF.F.decl) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.HasF.impl: %C.ref as %HasF.ref { // CHECK:STDOUT: %C.as.HasF.impl.F.decl: %C.as.HasF.impl.F.type = fn_decl @C.as.HasF.impl.F [concrete = constants.%C.as.HasF.impl.F] { // CHECK:STDOUT: %self.patt: %pattern_type.c48 = binding_pattern self [concrete] @@ -306,6 +331,9 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -315,21 +343,23 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @HasF.F(@HasF.%Self: %HasF.type) { -// CHECK:STDOUT: %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.as_type.loc5_14.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.f0c)] +// CHECK:STDOUT: %Self.as_type.loc5_14.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc5_14.1 (constants.%Self.as_type.308)] // CHECK:STDOUT: %pattern_type: type = pattern_type %Self.as_type.loc5_14.1 [symbolic = %pattern_type (constants.%pattern_type.28f)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%self.param: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type)); +// CHECK:STDOUT: fn(%self.param: @HasF.F.%Self.as_type.loc5_14.1 (%Self.as_type.308)); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.HasF.impl.F(%self.param: %C) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @HasF.F(constants.%Self) { -// CHECK:STDOUT: %Self => constants.%Self -// CHECK:STDOUT: %Self.as_type.loc5_14.1 => constants.%Self.as_type +// CHECK:STDOUT: specific @HasF.F(constants.%Self.f0c) { +// CHECK:STDOUT: %Self => constants.%Self.f0c +// CHECK:STDOUT: %Self.as_type.loc5_14.1 => constants.%Self.as_type.308 // CHECK:STDOUT: %pattern_type => constants.%pattern_type.28f // CHECK:STDOUT: } // CHECK:STDOUT: @@ -351,6 +381,13 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %HasG.assoc_type: type = assoc_entity_type @HasG [concrete] // CHECK:STDOUT: %assoc0: %HasG.assoc_type = assoc_entity element0, @HasG.%HasG.G.decl [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] @@ -378,6 +415,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -386,6 +424,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: .HasF = %PackageA.HasF // CHECK:STDOUT: import PackageA//default // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %PackageA.C: type = import_ref PackageA//default, C, loaded [concrete = constants.%C] // CHECK:STDOUT: %PackageA.import_ref.8f2: = import_ref PackageA//default, loc8_10, loaded [concrete = constants.%complete_type] // CHECK:STDOUT: %PackageA.import_ref.2c4 = import_ref PackageA//default, inst43 [no loc], unloaded @@ -458,6 +497,22 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = (imports.%PackageA.F) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc10: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.HasG.impl: %C.ref as %HasG.ref { // CHECK:STDOUT: %C.as.HasG.impl.G.decl: %C.as.HasG.impl.G.type = fn_decl @C.as.HasG.impl.G [concrete = constants.%C.as.HasG.impl.G] { // CHECK:STDOUT: %self.patt: %pattern_type.8e5 = binding_pattern self [concrete] @@ -504,6 +559,9 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -527,6 +585,8 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: fn(%self.param: @HasG.G.%Self.as_type.loc7_14.1 (%Self.as_type.133)); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.HasG.impl.G(%self.param: %C) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return @@ -591,13 +651,14 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %TestCF: %TestCF.type = struct_value () [concrete] // CHECK:STDOUT: %HasF.type: type = facet_type <@HasF> [concrete] -// CHECK:STDOUT: %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.cf3: %HasF.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %HasF.assoc_type: type = assoc_entity_type @HasF [concrete] // CHECK:STDOUT: %assoc0: %HasF.assoc_type = assoc_entity element0, imports.%PackageA.import_ref.ab2 [concrete] // CHECK:STDOUT: %HasF.F.type: type = fn_type @HasF.F [concrete] // CHECK:STDOUT: %HasF.F: %HasF.F.type = struct_value () [concrete] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.cf3 [symbolic] // CHECK:STDOUT: %pattern_type.dc3: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %HasF.impl_witness: = impl_witness imports.%HasF.impl_witness_table [concrete] // CHECK:STDOUT: %HasF.facet: %HasF.type = facet_value %C, (%HasF.impl_witness) [concrete] // CHECK:STDOUT: %.d3f: type = fn_type_with_self_type %HasF.F.type, %HasF.facet [concrete] @@ -606,7 +667,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: %Core.ece: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -623,7 +684,10 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %PackageA.import_ref.b36: %HasF.assoc_type = import_ref PackageA//default, loc5_21, loaded [concrete = constants.%assoc0] // CHECK:STDOUT: %PackageA.F = import_ref PackageA//default, F, unloaded // CHECK:STDOUT: %PackageA.import_ref.ab2: %HasF.F.type = import_ref PackageA//default, loc5_21, loaded [concrete = constants.%HasF.F] -// CHECK:STDOUT: %PackageA.import_ref.e73: %HasF.type = import_ref PackageA//default, inst19 [no loc], loaded [symbolic = constants.%Self] +// CHECK:STDOUT: %PackageA.import_ref.e73: %HasF.type = import_ref PackageA//default, inst19 [no loc], loaded [symbolic = constants.%Self.cf3] +// CHECK:STDOUT: %PackageA.import_ref.34c = import_ref PackageA//default, loc8_9, unloaded +// CHECK:STDOUT: %PackageA.import_ref.c0c: type = import_ref PackageA//default, inst43 [no loc], loaded [concrete = constants.%C] +// CHECK:STDOUT: %PackageA.import_ref.cb9: type = import_ref PackageA//default, inst46 [no loc], loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %PackageA.import_ref.c12: = import_ref PackageA//default, loc11_16, loaded [concrete = constants.%HasF.impl_witness] // CHECK:STDOUT: %PackageA.import_ref.29a: type = import_ref PackageA//default, loc11_6, loaded [concrete = constants.%C] // CHECK:STDOUT: %PackageA.import_ref.e8c: type = import_ref PackageA//default, loc11_11, loaded [concrete = constants.%HasF.type] @@ -633,7 +697,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Core = imports.%Core.ece // CHECK:STDOUT: .PackageA = imports.%PackageA // CHECK:STDOUT: .TestCF = %TestCF.decl // CHECK:STDOUT: } @@ -659,6 +723,11 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = (imports.%PackageA.F) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: imports.%PackageA.import_ref.c0c as imports.%PackageA.import_ref.cb9 [from "package_a.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%PackageA.import_ref.34c +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.HasF.impl: imports.%PackageA.import_ref.29a as imports.%PackageA.import_ref.e8c [from "package_a.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageA.import_ref.c12 @@ -684,7 +753,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @HasF.F(imports.%PackageA.import_ref.e73: %HasF.type) [from "package_a.carbon"] { -// CHECK:STDOUT: %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self: %HasF.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.cf3)] // CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type)] // CHECK:STDOUT: %pattern_type: type = pattern_type %Self.as_type [symbolic = %pattern_type (constants.%pattern_type.dc3)] // CHECK:STDOUT: @@ -693,8 +762,8 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.HasF.impl.F [from "package_a.carbon"]; // CHECK:STDOUT: -// CHECK:STDOUT: specific @HasF.F(constants.%Self) { -// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: specific @HasF.F(constants.%Self.cf3) { +// CHECK:STDOUT: %Self => constants.%Self.cf3 // CHECK:STDOUT: %Self.as_type => constants.%Self.as_type // CHECK:STDOUT: %pattern_type => constants.%pattern_type.dc3 // CHECK:STDOUT: } @@ -717,6 +786,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %HasF.F: %HasF.F.type = struct_value () [concrete] // CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.cf3 [symbolic] // CHECK:STDOUT: %pattern_type.dc3: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %HasG.type: type = facet_type <@HasG> [concrete] // CHECK:STDOUT: %HasF.impl_witness: = impl_witness imports.%HasF.impl_witness_table [concrete] @@ -727,7 +797,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: %Core.ece: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -748,11 +818,17 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %PackageA.F = import_ref PackageA//default, F, unloaded // CHECK:STDOUT: %PackageA.import_ref.ab2: %HasF.F.type = import_ref PackageA//default, loc5_21, loaded [concrete = constants.%HasF.F] // CHECK:STDOUT: %PackageA.import_ref.e73: %HasF.type = import_ref PackageA//default, inst19 [no loc], loaded [symbolic = constants.%Self.cf3] -// CHECK:STDOUT: %PackageA.import_ref.5cd = import_ref PackageA//default, loc11_16, unloaded +// CHECK:STDOUT: %PackageA.import_ref.34c = import_ref PackageA//default, loc8_9, unloaded // CHECK:STDOUT: %PackageA.import_ref.8f2: = import_ref PackageA//default, loc8_10, loaded [concrete = constants.%complete_type] // CHECK:STDOUT: %PackageA.import_ref.2c4 = import_ref PackageA//default, inst43 [no loc], unloaded +// CHECK:STDOUT: %PackageA.import_ref.c0c: type = import_ref PackageA//default, inst43 [no loc], loaded [concrete = constants.%C] +// CHECK:STDOUT: %PackageA.import_ref.cb9: type = import_ref PackageA//default, inst46 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %PackageA.import_ref.5cd = import_ref PackageA//default, loc11_16, unloaded // CHECK:STDOUT: %PackageA.import_ref.29a: type = import_ref PackageA//default, loc11_6, loaded [concrete = constants.%C] // CHECK:STDOUT: %PackageA.import_ref.e8c: type = import_ref PackageA//default, loc11_11, loaded [concrete = constants.%HasF.type] +// CHECK:STDOUT: %PackageB.import_ref.0c3 = import_ref PackageB//default, loc10_9, unloaded +// CHECK:STDOUT: %PackageB.import_ref.4aa: type = import_ref PackageB//default, inst45 [no loc], loaded [concrete = constants.%D] +// CHECK:STDOUT: %PackageB.import_ref.cb9: type = import_ref PackageB//default, inst48 [no loc], loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %PackageB.import_ref.5d8 = import_ref PackageB//default, inst21 [no loc], unloaded // CHECK:STDOUT: %PackageB.import_ref.910 = import_ref PackageB//default, loc7_21, unloaded // CHECK:STDOUT: %PackageB.G = import_ref PackageB//default, G, unloaded @@ -771,7 +847,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Core = imports.%Core.ece // CHECK:STDOUT: .PackageA = imports.%PackageA // CHECK:STDOUT: .PackageB = imports.%PackageB // CHECK:STDOUT: .TestDF = %TestDF.decl @@ -806,11 +882,21 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = (imports.%PackageB.G) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: imports.%PackageA.import_ref.c0c as imports.%PackageA.import_ref.cb9 [from "package_a.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%PackageA.import_ref.34c +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.HasF.impl: imports.%PackageA.import_ref.29a as imports.%PackageA.import_ref.e8c [from "package_a.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageA.import_ref.5cd // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: imports.%PackageB.import_ref.4aa as imports.%PackageB.import_ref.cb9 [from "package_b.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%PackageB.import_ref.0c3 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.HasG.impl: imports.%PackageB.import_ref.dfb as imports.%PackageB.import_ref.cee586.1 [from "package_b.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageB.import_ref.ea7 @@ -886,6 +972,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %HasG.G: %HasG.G.type = struct_value () [concrete] // CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.fcb [symbolic] // CHECK:STDOUT: %pattern_type.76a: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %HasF.type: type = facet_type <@HasF> [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] // CHECK:STDOUT: %HasG.impl_witness: = impl_witness imports.%HasG.impl_witness_table [concrete] @@ -896,7 +983,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: %Core.ece: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -917,18 +1004,24 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %PackageB.G = import_ref PackageB//default, G, unloaded // CHECK:STDOUT: %PackageB.import_ref.70a: %HasG.G.type = import_ref PackageB//default, loc7_21, loaded [concrete = constants.%HasG.G] // CHECK:STDOUT: %PackageB.import_ref.ef5: %HasG.type = import_ref PackageB//default, inst21 [no loc], loaded [symbolic = constants.%Self.fcb] +// CHECK:STDOUT: %PackageA.import_ref.34c = import_ref PackageA//default, loc8_9, unloaded +// CHECK:STDOUT: %PackageA.import_ref.c0c: type = import_ref PackageA//default, inst43 [no loc], loaded [concrete = constants.%C] +// CHECK:STDOUT: %PackageA.import_ref.cb9: type = import_ref PackageA//default, inst46 [no loc], loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %PackageA.import_ref.28c = import_ref PackageA//default, inst19 [no loc], unloaded // CHECK:STDOUT: %PackageA.import_ref.c63 = import_ref PackageA//default, loc5_21, unloaded // CHECK:STDOUT: %PackageA.F = import_ref PackageA//default, F, unloaded // CHECK:STDOUT: %PackageA.import_ref.5cd = import_ref PackageA//default, loc11_16, unloaded // CHECK:STDOUT: %PackageA.import_ref.29a: type = import_ref PackageA//default, loc11_6, loaded [concrete = constants.%C] // CHECK:STDOUT: %PackageA.import_ref.e8c: type = import_ref PackageA//default, loc11_11, loaded [concrete = constants.%HasF.type] +// CHECK:STDOUT: %PackageB.import_ref.0c3 = import_ref PackageB//default, loc10_9, unloaded +// CHECK:STDOUT: %PackageB.import_ref.8f2: = import_ref PackageB//default, loc10_10, loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %PackageB.import_ref.cab = import_ref PackageB//default, inst45 [no loc], unloaded +// CHECK:STDOUT: %PackageB.import_ref.4aa: type = import_ref PackageB//default, inst45 [no loc], loaded [concrete = constants.%D] +// CHECK:STDOUT: %PackageB.import_ref.cb9: type = import_ref PackageB//default, inst48 [no loc], loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %PackageB.import_ref.1f6: = import_ref PackageB//default, loc13_25, loaded [concrete = constants.%HasG.impl_witness] // CHECK:STDOUT: %PackageB.import_ref.dfb: type = import_ref PackageB//default, loc13_14, loaded [concrete = constants.%C] // CHECK:STDOUT: %PackageB.import_ref.cee586.1: type = import_ref PackageB//default, loc13_20, loaded [concrete = constants.%HasG.type] // CHECK:STDOUT: %PackageB.import_ref.5ba = import_ref PackageB//default, loc18_25, unloaded -// CHECK:STDOUT: %PackageB.import_ref.8f2: = import_ref PackageB//default, loc10_10, loaded [concrete = constants.%complete_type] -// CHECK:STDOUT: %PackageB.import_ref.cab = import_ref PackageB//default, inst45 [no loc], unloaded // CHECK:STDOUT: %PackageB.import_ref.aa9f8a.1: type = import_ref PackageB//default, loc18_6, loaded [concrete = constants.%D] // CHECK:STDOUT: %PackageB.import_ref.831: type = import_ref PackageB//default, loc18_19, loaded [concrete = constants.%HasF.type] // CHECK:STDOUT: %PackageB.import_ref.569 = import_ref PackageB//default, loc23_16, unloaded @@ -940,7 +1033,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Core = imports.%Core.ece // CHECK:STDOUT: .PackageA = imports.%PackageA // CHECK:STDOUT: .PackageB = imports.%PackageB // CHECK:STDOUT: .TestCG = %TestCG.decl @@ -975,11 +1068,21 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = (imports.%PackageA.F) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: imports.%PackageA.import_ref.c0c as imports.%PackageA.import_ref.cb9 [from "package_a.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%PackageA.import_ref.34c +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.HasF.impl: imports.%PackageA.import_ref.29a as imports.%PackageA.import_ref.e8c [from "package_a.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageA.import_ref.5cd // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: imports.%PackageB.import_ref.4aa as imports.%PackageB.import_ref.cb9 [from "package_b.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%PackageB.import_ref.0c3 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.HasG.impl: imports.%PackageB.import_ref.dfb as imports.%PackageB.import_ref.cee586.1 [from "package_b.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageB.import_ref.1f6 @@ -1055,6 +1158,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %HasG.G: %HasG.G.type = struct_value () [concrete] // CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.fcb [symbolic] // CHECK:STDOUT: %pattern_type.76a: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %HasF.type: type = facet_type <@HasF> [concrete] // CHECK:STDOUT: %HasG.impl_witness: = impl_witness imports.%HasG.impl_witness_table [concrete] @@ -1065,7 +1169,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: %Core.ece: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -1083,13 +1187,16 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %PackageB.G = import_ref PackageB//default, G, unloaded // CHECK:STDOUT: %PackageB.import_ref.70a: %HasG.G.type = import_ref PackageB//default, loc7_21, loaded [concrete = constants.%HasG.G] // CHECK:STDOUT: %PackageB.import_ref.ef5: %HasG.type = import_ref PackageB//default, inst21 [no loc], loaded [symbolic = constants.%Self.fcb] +// CHECK:STDOUT: %PackageB.import_ref.0c3 = import_ref PackageB//default, loc10_9, unloaded +// CHECK:STDOUT: %PackageB.import_ref.4aa: type = import_ref PackageB//default, inst45 [no loc], loaded [concrete = constants.%D] +// CHECK:STDOUT: %PackageB.import_ref.cb9: type = import_ref PackageB//default, inst48 [no loc], loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %PackageB.import_ref.ea7 = import_ref PackageB//default, loc13_25, unloaded -// CHECK:STDOUT: %PackageB.import_ref.8db: = import_ref PackageB//default, inst54 [indirect], loaded [concrete = constants.%complete_type] -// CHECK:STDOUT: %PackageB.import_ref.6a9 = import_ref PackageB//default, inst55 [indirect], unloaded +// CHECK:STDOUT: %PackageB.import_ref.8db: = import_ref PackageB//default, inst92 [indirect], loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %PackageB.import_ref.6a9 = import_ref PackageB//default, inst93 [indirect], unloaded // CHECK:STDOUT: %PackageB.import_ref.dfb: type = import_ref PackageB//default, loc13_14, loaded [concrete = constants.%C] // CHECK:STDOUT: %PackageB.import_ref.cee586.1: type = import_ref PackageB//default, loc13_20, loaded [concrete = constants.%HasG.type] -// CHECK:STDOUT: %PackageB.import_ref.96f = import_ref PackageB//default, inst80 [indirect], unloaded -// CHECK:STDOUT: %PackageB.import_ref.a0b = import_ref PackageB//default, inst81 [indirect], unloaded +// CHECK:STDOUT: %PackageB.import_ref.96f = import_ref PackageB//default, inst118 [indirect], unloaded +// CHECK:STDOUT: %PackageB.import_ref.a0b = import_ref PackageB//default, inst119 [indirect], unloaded // CHECK:STDOUT: %PackageB.F = import_ref PackageB//default, F, unloaded // CHECK:STDOUT: %PackageB.import_ref.5ba = import_ref PackageB//default, loc18_25, unloaded // CHECK:STDOUT: %PackageB.import_ref.aa9f8a.1: type = import_ref PackageB//default, loc18_6, loaded [concrete = constants.%D] @@ -1103,7 +1210,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Core = imports.%Core.ece // CHECK:STDOUT: .PackageB = imports.%PackageB // CHECK:STDOUT: .TestDG = %TestDG.decl // CHECK:STDOUT: } @@ -1136,6 +1243,11 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = (imports.%PackageB.F) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: imports.%PackageB.import_ref.4aa as imports.%PackageB.import_ref.cb9 [from "package_b.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%PackageB.import_ref.0c3 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.HasG.impl: imports.%PackageB.import_ref.dfb as imports.%PackageB.import_ref.cee586.1 [from "package_b.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageB.import_ref.ea7 @@ -1404,24 +1516,34 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %AnyParam.type: type = generic_class_type @AnyParam [concrete] // CHECK:STDOUT: %AnyParam.generic: %AnyParam.type = struct_value () [concrete] // CHECK:STDOUT: %AnyParam: type = class_type @AnyParam, @AnyParam(%T, %X) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @AnyParam.%Destroy.impl_witness_table, @AnyParam.as.Destroy.impl(%T, %X) [symbolic] +// CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] +// CHECK:STDOUT: %ptr.eba: type = ptr_type %AnyParam [symbolic] +// CHECK:STDOUT: %pattern_type.74e: type = pattern_type %ptr.eba [symbolic] +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op.type: type = fn_type @AnyParam.as.Destroy.impl.Op, @AnyParam.as.Destroy.impl(%T, %X) [symbolic] +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op: %AnyParam.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Y.type: type = facet_type <@Y> [concrete] -// CHECK:STDOUT: %Self: %Y.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic] -// CHECK:STDOUT: %pattern_type.f04: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Self.b29: %Y.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.as_type.744: type = facet_access_type %Self.b29 [symbolic] +// CHECK:STDOUT: %pattern_type.f04: type = pattern_type %Self.as_type.744 [symbolic] // CHECK:STDOUT: %Y.K.type: type = fn_type @Y.K [concrete] // CHECK:STDOUT: %Y.K: %Y.K.type = struct_value () [concrete] // CHECK:STDOUT: %Y.assoc_type: type = assoc_entity_type @Y [concrete] // CHECK:STDOUT: %assoc0: %Y.assoc_type = assoc_entity element0, @Y.%Y.K.decl [concrete] -// CHECK:STDOUT: %require_complete: = require_complete_type %Self.as_type [symbolic] +// CHECK:STDOUT: %require_complete.18c: = require_complete_type %Self.as_type.744 [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1443,18 +1565,18 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @Y { -// CHECK:STDOUT: %Self: %Y.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %Y.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.b29] // CHECK:STDOUT: %Y.K.decl: %Y.K.type = fn_decl @Y.K [concrete = constants.%Y.K] { // CHECK:STDOUT: %self.patt: @Y.K.%pattern_type (%pattern_type.f04) = binding_pattern self [concrete] // CHECK:STDOUT: %self.param_patt: @Y.K.%pattern_type (%pattern_type.f04) = value_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param: @Y.K.%Self.as_type.loc7_14.1 (%Self.as_type) = value_param call_param0 -// CHECK:STDOUT: %.loc7_14.1: type = splice_block %.loc7_14.2 [symbolic = %Self.as_type.loc7_14.1 (constants.%Self.as_type)] { -// CHECK:STDOUT: %Self.ref: %Y.type = name_ref Self, @Y.%Self [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.as_type.loc7_14.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc7_14.1 (constants.%Self.as_type)] -// CHECK:STDOUT: %.loc7_14.2: type = converted %Self.ref, %Self.as_type.loc7_14.2 [symbolic = %Self.as_type.loc7_14.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %self.param: @Y.K.%Self.as_type.loc7_14.1 (%Self.as_type.744) = value_param call_param0 +// CHECK:STDOUT: %.loc7_14.1: type = splice_block %.loc7_14.2 [symbolic = %Self.as_type.loc7_14.1 (constants.%Self.as_type.744)] { +// CHECK:STDOUT: %Self.ref: %Y.type = name_ref Self, @Y.%Self [symbolic = %Self (constants.%Self.b29)] +// CHECK:STDOUT: %Self.as_type.loc7_14.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc7_14.1 (constants.%Self.as_type.744)] +// CHECK:STDOUT: %.loc7_14.2: type = converted %Self.ref, %Self.as_type.loc7_14.2 [symbolic = %Self.as_type.loc7_14.1 (constants.%Self.as_type.744)] // CHECK:STDOUT: } -// CHECK:STDOUT: %self: @Y.K.%Self.as_type.loc7_14.1 (%Self.as_type) = bind_name self, %self.param +// CHECK:STDOUT: %self: @Y.K.%Self.as_type.loc7_14.1 (%Self.as_type.744) = bind_name self, %self.param // CHECK:STDOUT: } // CHECK:STDOUT: %assoc0: %Y.assoc_type = assoc_entity element0, %Y.K.decl [concrete = constants.%assoc0] // CHECK:STDOUT: @@ -1464,14 +1586,47 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = (%Y.K.decl) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @AnyParam.as.Destroy.impl(@AnyParam.%T.loc4_16.2: type, @AnyParam.%X.loc4_26.2: @AnyParam.%T.loc4_16.1 (%T)) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %X: @AnyParam.as.Destroy.impl.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @AnyParam.%Destroy.impl_witness_table, @AnyParam.as.Destroy.impl(%T, %X) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op.type: type = fn_type @AnyParam.as.Destroy.impl.Op, @AnyParam.as.Destroy.impl(%T, %X) [symbolic = %AnyParam.as.Destroy.impl.Op.type (constants.%AnyParam.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op: @AnyParam.as.Destroy.impl.%AnyParam.as.Destroy.impl.Op.type (%AnyParam.as.Destroy.impl.Op.type) = struct_value () [symbolic = %AnyParam.as.Destroy.impl.Op (constants.%AnyParam.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%AnyParam as constants.%Destroy.type { +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op.decl: @AnyParam.as.Destroy.impl.%AnyParam.as.Destroy.impl.Op.type (%AnyParam.as.Destroy.impl.Op.type) = fn_decl @AnyParam.as.Destroy.impl.Op [symbolic = @AnyParam.as.Destroy.impl.%AnyParam.as.Destroy.impl.Op (constants.%AnyParam.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @AnyParam.as.Destroy.impl.Op.%pattern_type (%pattern_type.74e) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @AnyParam.as.Destroy.impl.Op.%pattern_type (%pattern_type.74e) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_33.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @AnyParam.as.Destroy.impl.Op.%ptr (%ptr.eba) = value_param call_param0 +// CHECK:STDOUT: %.loc4_33.2: type = splice_block %Self.ref [symbolic = %AnyParam (constants.%AnyParam)] { +// CHECK:STDOUT: %.loc4_33.3: type = specific_constant constants.%AnyParam, @AnyParam(constants.%T, constants.%X) [symbolic = %AnyParam (constants.%AnyParam)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_33.3 [symbolic = %AnyParam (constants.%AnyParam)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @AnyParam.as.Destroy.impl.Op.%ptr (%ptr.eba) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %AnyParam.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @AnyParam.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @AnyParam(%T.loc4_16.2: type, %X.loc4_26.2: @AnyParam.%T.loc4_16.1 (%T)) { // CHECK:STDOUT: %T.loc4_16.1: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_16.1 (constants.%T)] // CHECK:STDOUT: %X.loc4_26.1: @AnyParam.%T.loc4_16.1 (%T) = bind_symbolic_name X, 1 [symbolic = %X.loc4_26.1 (constants.%X)] // CHECK:STDOUT: %pattern_type: type = pattern_type %T.loc4_16.1 [symbolic = %pattern_type (constants.%pattern_type.7dc)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type %T.loc4_16.1 [symbolic = %require_complete (constants.%require_complete.4ae)] // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @AnyParam.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@AnyParam.as.Destroy.impl.%AnyParam.as.Destroy.impl.Op.decl), @AnyParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @AnyParam.as.Destroy.impl(constants.%T, constants.%X) [symbolic = @AnyParam.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1481,15 +1636,27 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @AnyParam.as.Destroy.impl.Op(@AnyParam.%T.loc4_16.2: type, @AnyParam.%X.loc4_26.2: @AnyParam.%T.loc4_16.1 (%T)) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %X: @AnyParam.as.Destroy.impl.Op.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %AnyParam: type = class_type @AnyParam, @AnyParam(%T, %X) [symbolic = %AnyParam (constants.%AnyParam)] +// CHECK:STDOUT: %ptr: type = ptr_type %AnyParam [symbolic = %ptr (constants.%ptr.eba)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.74e)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @AnyParam.as.Destroy.impl.Op.%ptr (%ptr.eba)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @Y.K(@Y.%Self: %Y.type) { -// CHECK:STDOUT: %Self: %Y.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.as_type.loc7_14.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc7_14.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self: %Y.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.b29)] +// CHECK:STDOUT: %Self.as_type.loc7_14.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc7_14.1 (constants.%Self.as_type.744)] // CHECK:STDOUT: %pattern_type: type = pattern_type %Self.as_type.loc7_14.1 [symbolic = %pattern_type (constants.%pattern_type.f04)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete: = require_complete_type %Self.as_type.loc7_14.1 [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: %require_complete: = require_complete_type %Self.as_type.loc7_14.1 [symbolic = %require_complete (constants.%require_complete.18c)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%self.param: @Y.K.%Self.as_type.loc7_14.1 (%Self.as_type)) { +// CHECK:STDOUT: fn(%self.param: @Y.K.%Self.as_type.loc7_14.1 (%Self.as_type.744)) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return // CHECK:STDOUT: } @@ -1501,9 +1668,23 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.7dc // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @Y.K(constants.%Self) { -// CHECK:STDOUT: %Self => constants.%Self -// CHECK:STDOUT: %Self.as_type.loc7_14.1 => constants.%Self.as_type +// CHECK:STDOUT: specific @AnyParam.as.Destroy.impl(constants.%T, constants.%X) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @AnyParam.as.Destroy.impl.Op(constants.%T, constants.%X) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %AnyParam => constants.%AnyParam +// CHECK:STDOUT: %ptr => constants.%ptr.eba +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.74e +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Y.K(constants.%Self.b29) { +// CHECK:STDOUT: %Self => constants.%Self.b29 +// CHECK:STDOUT: %Self.as_type.loc7_14.1 => constants.%Self.as_type.744 // CHECK:STDOUT: %pattern_type => constants.%pattern_type.f04 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -1523,7 +1704,9 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %X: %T = bind_symbolic_name X, 1 [symbolic] +// CHECK:STDOUT: %AnyParam.560: type = class_type @AnyParam, @AnyParam(%T, %X) [symbolic] // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] +// CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %pattern_type.438: type = pattern_type %GenericInterface.type.c92 [concrete] // CHECK:STDOUT: %AnyParam.241: type = class_type @AnyParam, @AnyParam(%GenericInterface.type.c92, %GenericInterface.generic) [concrete] // CHECK:STDOUT: %Y.type: type = facet_type <@Y> [concrete] @@ -1538,21 +1721,28 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %AnyParam.as.Y.impl.K.type: type = fn_type @AnyParam.as.Y.impl.K [concrete] // CHECK:STDOUT: %AnyParam.as.Y.impl.K: %AnyParam.as.Y.impl.K.type = struct_value () [concrete] // CHECK:STDOUT: %Y.facet: %Y.type = facet_value %AnyParam.241, (%Y.impl_witness) [concrete] +// CHECK:STDOUT: %complete_type.eb2: = complete_type_witness %GenericInterface.type.c92 [concrete] // CHECK:STDOUT: %L.type: type = fn_type @L [concrete] // CHECK:STDOUT: %L: %L.type = struct_value () [concrete] // CHECK:STDOUT: %AnyParam.val: %AnyParam.241 = struct_value () [concrete] // CHECK:STDOUT: %Y.assoc_type: type = assoc_entity_type @Y [concrete] // CHECK:STDOUT: %assoc0.494: %Y.assoc_type = assoc_entity element0, imports.%PackageHasParam.import_ref.ce2 [concrete] -// CHECK:STDOUT: %.0fb: type = fn_type_with_self_type %Y.K.type, %Y.facet [concrete] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.5fc: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%AnyParam.241) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.6f3: %T.as.Destroy.impl.Op.type.5fc = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.7ff: = impl_witness imports.%Destroy.impl_witness_table.f0b, @AnyParam.as.Destroy.impl(%T, %X) [symbolic] +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op.type: type = fn_type @AnyParam.as.Destroy.impl.Op, @AnyParam.as.Destroy.impl(%T, %X) [symbolic] +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op: %AnyParam.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.4a9: type = ptr_type %AnyParam.560 [symbolic] +// CHECK:STDOUT: %pattern_type.84c: type = pattern_type %ptr.4a9 [symbolic] +// CHECK:STDOUT: %.0fb: type = fn_type_with_self_type %Y.K.type, %Y.facet [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.0ad: = impl_witness imports.%Destroy.impl_witness_table.f0b, @AnyParam.as.Destroy.impl(%GenericInterface.type.c92, %GenericInterface.generic) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.90e: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%AnyParam.241) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.ec3: %T.as.Destroy.impl.Op.type.90e = struct_value () [concrete] // CHECK:STDOUT: %ptr.301: type = ptr_type %AnyParam.241 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.6f3, @T.as.Destroy.impl.Op(%AnyParam.241) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.ec3, @T.as.Destroy.impl.Op(%AnyParam.241) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: %Core.ece: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... @@ -1563,22 +1753,31 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: import PackageHasParam//default // CHECK:STDOUT: } // CHECK:STDOUT: %PackageHasParam.AnyParam: %AnyParam.type = import_ref PackageHasParam//default, AnyParam, loaded [concrete = constants.%AnyParam.generic] -// CHECK:STDOUT: %PackageHasParam.import_ref.5ab: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] -// CHECK:STDOUT: %PackageHasParam.import_ref.34c: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] +// CHECK:STDOUT: %PackageHasParam.import_ref.5ab3ec.1: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] +// CHECK:STDOUT: %PackageHasParam.import_ref.34c075.1: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] // CHECK:STDOUT: %PackageHasParam.import_ref.8f2: = import_ref PackageHasParam//default, loc4_34, loaded [concrete = constants.%complete_type.357] // CHECK:STDOUT: %PackageHasParam.import_ref.601 = import_ref PackageHasParam//default, inst33 [no loc], unloaded // CHECK:STDOUT: %PackageHasParam.Y: type = import_ref PackageHasParam//default, Y, loaded [concrete = constants.%Y.type] -// CHECK:STDOUT: %PackageHasParam.import_ref.dc1 = import_ref PackageHasParam//default, inst40 [no loc], unloaded +// CHECK:STDOUT: %PackageHasParam.import_ref.dc1 = import_ref PackageHasParam//default, inst93 [no loc], unloaded // CHECK:STDOUT: %PackageHasParam.import_ref.f69: %Y.assoc_type = import_ref PackageHasParam//default, loc7_22, loaded [concrete = constants.%assoc0.494] // CHECK:STDOUT: %PackageHasParam.K: %Y.K.type = import_ref PackageHasParam//default, K, loaded [concrete = constants.%Y.K] -// CHECK:STDOUT: %PackageHasParam.import_ref.292: %Y.type = import_ref PackageHasParam//default, inst40 [no loc], loaded [symbolic = constants.%Self.f64] +// CHECK:STDOUT: %PackageHasParam.import_ref.292: %Y.type = import_ref PackageHasParam//default, inst93 [no loc], loaded [symbolic = constants.%Self.f64] // CHECK:STDOUT: %PackageHasParam.import_ref.ce2: %Y.K.type = import_ref PackageHasParam//default, loc7_22, loaded [concrete = constants.%Y.K] +// CHECK:STDOUT: %PackageHasParam.import_ref.9da = import_ref PackageHasParam//default, loc4_33, unloaded +// CHECK:STDOUT: %PackageHasParam.import_ref.5ab3ec.2: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] +// CHECK:STDOUT: %PackageHasParam.import_ref.34c075.2: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] +// CHECK:STDOUT: %PackageHasParam.import_ref.758: type = import_ref PackageHasParam//default, inst33 [no loc], loaded [symbolic = constants.%AnyParam.560] +// CHECK:STDOUT: %PackageHasParam.import_ref.cb9: type = import_ref PackageHasParam//default, inst36 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %PackageHasParam.import_ref.ba8 = import_ref PackageHasParam//default, loc4_33, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.f0b = impl_witness_table (%PackageHasParam.import_ref.ba8), @AnyParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %PackageHasParam.import_ref.5ab3ec.3: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] +// CHECK:STDOUT: %PackageHasParam.import_ref.34c075.3: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Core = imports.%Core.ece // CHECK:STDOUT: .PackageHasParam = imports.%PackageHasParam // CHECK:STDOUT: .GenericInterface = %GenericInterface.decl // CHECK:STDOUT: .L = %L.decl @@ -1641,12 +1840,28 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = file.%Y.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic class @AnyParam(imports.%PackageHasParam.import_ref.5ab: type, imports.%PackageHasParam.import_ref.34c: @AnyParam.%T (%T)) [from "has_param.carbon"] { +// CHECK:STDOUT: generic impl @AnyParam.as.Destroy.impl(imports.%PackageHasParam.import_ref.5ab3ec.2: type, imports.%PackageHasParam.import_ref.34c075.2: @AnyParam.%T (%T)) [from "has_param.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %X: @AnyParam.as.Destroy.impl.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.f0b, @AnyParam.as.Destroy.impl(%T, %X) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.7ff)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op.type: type = fn_type @AnyParam.as.Destroy.impl.Op, @AnyParam.as.Destroy.impl(%T, %X) [symbolic = %AnyParam.as.Destroy.impl.Op.type (constants.%AnyParam.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op: @AnyParam.as.Destroy.impl.%AnyParam.as.Destroy.impl.Op.type (%AnyParam.as.Destroy.impl.Op.type) = struct_value () [symbolic = %AnyParam.as.Destroy.impl.Op (constants.%AnyParam.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%PackageHasParam.import_ref.758 as imports.%PackageHasParam.import_ref.cb9 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%PackageHasParam.import_ref.9da +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @AnyParam(imports.%PackageHasParam.import_ref.5ab3ec.1: type, imports.%PackageHasParam.import_ref.34c075.1: @AnyParam.%T (%T)) [from "has_param.carbon"] { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %X: @AnyParam.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] // CHECK:STDOUT: %pattern_type: type = pattern_type %T [symbolic = %pattern_type (constants.%pattern_type.7dc)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type %T [symbolic = %require_complete (constants.%require_complete.4ae)] // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: complete_type_witness = imports.%PackageHasParam.import_ref.8f2 @@ -1698,14 +1913,26 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %bound_method.loc14: = bound_method %obj.ref, %impl.elem0 // CHECK:STDOUT: %.loc14: %AnyParam.241 = bind_value %obj.ref // CHECK:STDOUT: %AnyParam.as.Y.impl.K.call: init %empty_tuple.type = call %bound_method.loc14(%.loc14) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %obj.var, constants.%T.as.Destroy.impl.Op.6f3 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.6f3, @T.as.Destroy.impl.Op(constants.%AnyParam.241) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %obj.var, constants.%T.as.Destroy.impl.Op.ec3 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.ec3, @T.as.Destroy.impl.Op(constants.%AnyParam.241) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method.loc13: = bound_method %obj.var, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr: %ptr.301 = addr_of %obj.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc13(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @AnyParam.as.Destroy.impl.Op(imports.%PackageHasParam.import_ref.5ab3ec.3: type, imports.%PackageHasParam.import_ref.34c075.3: @AnyParam.%T (%T)) [from "has_param.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %X: @AnyParam.as.Destroy.impl.Op.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %AnyParam: type = class_type @AnyParam, @AnyParam(%T, %X) [symbolic = %AnyParam (constants.%AnyParam.560)] +// CHECK:STDOUT: %ptr: type = ptr_type %AnyParam [symbolic = %ptr (constants.%ptr.4a9)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.84c)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @GenericInterface(constants.%U) { // CHECK:STDOUT: %U.loc6_28.1 => constants.%U // CHECK:STDOUT: } @@ -1722,6 +1949,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.438 // CHECK:STDOUT: // CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete => constants.%complete_type.eb2 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @Y.K(constants.%Self.f64) { @@ -1736,6 +1964,26 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.004 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @AnyParam.as.Destroy.impl(constants.%T, constants.%X) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.7ff +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @AnyParam.as.Destroy.impl.Op(constants.%T, constants.%X) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %AnyParam => constants.%AnyParam.560 +// CHECK:STDOUT: %ptr => constants.%ptr.4a9 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.84c +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @AnyParam.as.Destroy.impl(constants.%GenericInterface.type.c92, constants.%GenericInterface.generic) { +// CHECK:STDOUT: %T => constants.%GenericInterface.type.c92 +// CHECK:STDOUT: %X => constants.%GenericInterface.generic +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.0ad +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- use_generic_interface_as_param.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -1748,7 +1996,9 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %X: %T = bind_symbolic_name X, 1 [symbolic] +// CHECK:STDOUT: %AnyParam.560: type = class_type @AnyParam, @AnyParam(%T, %X) [symbolic] // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] +// CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %GenericInterface.type.0da: type = generic_interface_type @GenericInterface [concrete] // CHECK:STDOUT: %GenericInterface.generic: %GenericInterface.type.0da = struct_value () [concrete] // CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic] @@ -1756,6 +2006,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %Self.13b: %GenericInterface.type.138 = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %pattern_type.a64: type = pattern_type %GenericInterface.type.0da [concrete] // CHECK:STDOUT: %AnyParam.861: type = class_type @AnyParam, @AnyParam(%GenericInterface.type.0da, %GenericInterface.generic) [concrete] +// CHECK:STDOUT: %complete_type.42f: = complete_type_witness %GenericInterface.type.0da [concrete] // CHECK:STDOUT: %pattern_type.3ad: type = pattern_type %AnyParam.861 [concrete] // CHECK:STDOUT: %AnyParam.val: %AnyParam.861 = struct_value () [concrete] // CHECK:STDOUT: %Y.type: type = facet_type <@Y> [concrete] @@ -1768,15 +2019,21 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %pattern_type.cb4: type = pattern_type %Self.as_type.61d [symbolic] // CHECK:STDOUT: %require_complete.b14: = require_complete_type %Self.as_type.61d [symbolic] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.7ff: = impl_witness imports.%Destroy.impl_witness_table.f0b, @AnyParam.as.Destroy.impl(%T, %X) [symbolic] +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op.type: type = fn_type @AnyParam.as.Destroy.impl.Op, @AnyParam.as.Destroy.impl(%T, %X) [symbolic] +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op: %AnyParam.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.4a9: type = ptr_type %AnyParam.560 [symbolic] +// CHECK:STDOUT: %pattern_type.84c: type = pattern_type %ptr.4a9 [symbolic] // CHECK:STDOUT: %Y.impl_witness: = impl_witness imports.%Y.impl_witness_table [concrete] // CHECK:STDOUT: %Y.facet: %Y.type = facet_value %AnyParam.861, (%Y.impl_witness) [concrete] // CHECK:STDOUT: %.e17: type = fn_type_with_self_type %Y.K.type, %Y.facet [concrete] // CHECK:STDOUT: %AnyParam.as.Y.impl.K.type: type = fn_type @AnyParam.as.Y.impl.K [concrete] // CHECK:STDOUT: %AnyParam.as.Y.impl.K: %AnyParam.as.Y.impl.K.type = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.77e: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%AnyParam.861) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.49f: %T.as.Destroy.impl.Op.type.77e = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.ae4: = impl_witness imports.%Destroy.impl_witness_table.f0b, @AnyParam.as.Destroy.impl(%GenericInterface.type.0da, %GenericInterface.generic) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.d25: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%AnyParam.861) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.a41: %T.as.Destroy.impl.Op.type.d25 = struct_value () [concrete] // CHECK:STDOUT: %ptr.1ef: type = ptr_type %AnyParam.861 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.49f, @T.as.Destroy.impl.Op(%AnyParam.861) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.a41, @T.as.Destroy.impl.Op(%AnyParam.861) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -1795,19 +2052,28 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: import PackageGenericInterface//default // CHECK:STDOUT: } // CHECK:STDOUT: %PackageHasParam.AnyParam: %AnyParam.type = import_ref PackageHasParam//default, AnyParam, loaded [concrete = constants.%AnyParam.generic] -// CHECK:STDOUT: %PackageHasParam.import_ref.5ab: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] -// CHECK:STDOUT: %PackageHasParam.import_ref.34c: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] +// CHECK:STDOUT: %PackageHasParam.import_ref.5ab3ec.1: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] +// CHECK:STDOUT: %PackageHasParam.import_ref.34c075.1: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] // CHECK:STDOUT: %PackageHasParam.import_ref.8f2: = import_ref PackageHasParam//default, loc4_34, loaded [concrete = constants.%complete_type.357] // CHECK:STDOUT: %PackageHasParam.import_ref.601 = import_ref PackageHasParam//default, inst33 [no loc], unloaded // CHECK:STDOUT: %PackageGenericInterface.GenericInterface: %GenericInterface.type.0da = import_ref PackageGenericInterface//default, GenericInterface, loaded [concrete = constants.%GenericInterface.generic] // CHECK:STDOUT: %PackageGenericInterface.import_ref.5ab: type = import_ref PackageGenericInterface//default, loc6_28, loaded [symbolic = @GenericInterface.%U (constants.%U)] // CHECK:STDOUT: %PackageGenericInterface.import_ref.c3b = import_ref PackageGenericInterface//default, inst29 [no loc], unloaded // CHECK:STDOUT: %PackageHasParam.Y: type = import_ref PackageHasParam//default, Y, loaded [concrete = constants.%Y.type] -// CHECK:STDOUT: %PackageHasParam.import_ref.dc1 = import_ref PackageHasParam//default, inst40 [no loc], unloaded +// CHECK:STDOUT: %PackageHasParam.import_ref.dc1 = import_ref PackageHasParam//default, inst93 [no loc], unloaded // CHECK:STDOUT: %PackageHasParam.import_ref.f69: %Y.assoc_type = import_ref PackageHasParam//default, loc7_22, loaded [concrete = constants.%assoc0.494] // CHECK:STDOUT: %PackageHasParam.K = import_ref PackageHasParam//default, K, unloaded // CHECK:STDOUT: %PackageHasParam.import_ref.ce2: %Y.K.type = import_ref PackageHasParam//default, loc7_22, loaded [concrete = constants.%Y.K] -// CHECK:STDOUT: %PackageHasParam.import_ref.292: %Y.type = import_ref PackageHasParam//default, inst40 [no loc], loaded [symbolic = constants.%Self.f64] +// CHECK:STDOUT: %PackageHasParam.import_ref.292: %Y.type = import_ref PackageHasParam//default, inst93 [no loc], loaded [symbolic = constants.%Self.f64] +// CHECK:STDOUT: %PackageHasParam.import_ref.9da = import_ref PackageHasParam//default, loc4_33, unloaded +// CHECK:STDOUT: %PackageHasParam.import_ref.5ab3ec.2: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] +// CHECK:STDOUT: %PackageHasParam.import_ref.34c075.2: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] +// CHECK:STDOUT: %PackageHasParam.import_ref.758: type = import_ref PackageHasParam//default, inst33 [no loc], loaded [symbolic = constants.%AnyParam.560] +// CHECK:STDOUT: %PackageHasParam.import_ref.cb9: type = import_ref PackageHasParam//default, inst36 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %PackageHasParam.import_ref.ba8 = import_ref PackageHasParam//default, loc4_33, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.f0b = impl_witness_table (%PackageHasParam.import_ref.ba8), @AnyParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %PackageHasParam.import_ref.5ab3ec.3: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] +// CHECK:STDOUT: %PackageHasParam.import_ref.34c075.3: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] // CHECK:STDOUT: %PackageGenericInterface.import_ref.53c: = import_ref PackageGenericInterface//default, loc8_70, loaded [concrete = constants.%Y.impl_witness] // CHECK:STDOUT: %PackageGenericInterface.import_ref.321: type = import_ref PackageGenericInterface//default, loc8_47, loaded [concrete = constants.%AnyParam.861] // CHECK:STDOUT: %PackageGenericInterface.import_ref.ca6: type = import_ref PackageGenericInterface//default, loc8_67, loaded [concrete = constants.%Y.type] @@ -1850,17 +2116,33 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = (imports.%PackageHasParam.K) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @AnyParam.as.Destroy.impl(imports.%PackageHasParam.import_ref.5ab3ec.2: type, imports.%PackageHasParam.import_ref.34c075.2: @AnyParam.%T (%T)) [from "has_param.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %X: @AnyParam.as.Destroy.impl.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.f0b, @AnyParam.as.Destroy.impl(%T, %X) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.7ff)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op.type: type = fn_type @AnyParam.as.Destroy.impl.Op, @AnyParam.as.Destroy.impl(%T, %X) [symbolic = %AnyParam.as.Destroy.impl.Op.type (constants.%AnyParam.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op: @AnyParam.as.Destroy.impl.%AnyParam.as.Destroy.impl.Op.type (%AnyParam.as.Destroy.impl.Op.type) = struct_value () [symbolic = %AnyParam.as.Destroy.impl.Op (constants.%AnyParam.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%PackageHasParam.import_ref.758 as imports.%PackageHasParam.import_ref.cb9 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%PackageHasParam.import_ref.9da +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @AnyParam.as.Y.impl: imports.%PackageGenericInterface.import_ref.321 as imports.%PackageGenericInterface.import_ref.ca6 [from "has_generic_interface.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageGenericInterface.import_ref.53c // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic class @AnyParam(imports.%PackageHasParam.import_ref.5ab: type, imports.%PackageHasParam.import_ref.34c: @AnyParam.%T (%T)) [from "has_param.carbon"] { +// CHECK:STDOUT: generic class @AnyParam(imports.%PackageHasParam.import_ref.5ab3ec.1: type, imports.%PackageHasParam.import_ref.34c075.1: @AnyParam.%T (%T)) [from "has_param.carbon"] { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %X: @AnyParam.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] // CHECK:STDOUT: %pattern_type: type = pattern_type %T [symbolic = %pattern_type (constants.%pattern_type.7dc)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type %T [symbolic = %require_complete (constants.%require_complete.4ae)] // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: complete_type_witness = imports.%PackageHasParam.import_ref.8f2 @@ -1897,8 +2179,8 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %bound_method.loc10: = bound_method %obj.ref, %impl.elem0 // CHECK:STDOUT: %.loc10: %AnyParam.861 = bind_value %obj.ref // CHECK:STDOUT: %AnyParam.as.Y.impl.K.call: init %empty_tuple.type = call %bound_method.loc10(%.loc10) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %obj.var, constants.%T.as.Destroy.impl.Op.49f -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.49f, @T.as.Destroy.impl.Op(constants.%AnyParam.861) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %obj.var, constants.%T.as.Destroy.impl.Op.a41 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.a41, @T.as.Destroy.impl.Op(constants.%AnyParam.861) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method.loc8: = bound_method %obj.var, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr: %ptr.1ef = addr_of %obj.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc8(%addr) @@ -1916,6 +2198,18 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: fn; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @AnyParam.as.Destroy.impl.Op(imports.%PackageHasParam.import_ref.5ab3ec.3: type, imports.%PackageHasParam.import_ref.34c075.3: @AnyParam.%T (%T)) [from "has_param.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %X: @AnyParam.as.Destroy.impl.Op.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %AnyParam: type = class_type @AnyParam, @AnyParam(%T, %X) [symbolic = %AnyParam (constants.%AnyParam.560)] +// CHECK:STDOUT: %ptr: type = ptr_type %AnyParam [symbolic = %ptr (constants.%ptr.4a9)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.84c)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @AnyParam.as.Y.impl.K [from "has_generic_interface.carbon"]; // CHECK:STDOUT: // CHECK:STDOUT: specific @AnyParam(constants.%T, constants.%X) { @@ -1934,6 +2228,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.a64 // CHECK:STDOUT: // CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete => constants.%complete_type.42f // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @Y.K(constants.%Self.f64) { @@ -1942,6 +2237,26 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.cb4 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @AnyParam.as.Destroy.impl(constants.%T, constants.%X) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.7ff +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @AnyParam.as.Destroy.impl.Op(constants.%T, constants.%X) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %AnyParam => constants.%AnyParam.560 +// CHECK:STDOUT: %ptr => constants.%ptr.4a9 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.84c +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @AnyParam.as.Destroy.impl(constants.%GenericInterface.type.0da, constants.%GenericInterface.generic) { +// CHECK:STDOUT: %T => constants.%GenericInterface.type.0da +// CHECK:STDOUT: %X => constants.%GenericInterface.generic +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.ae4 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- has_generic_class.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -1951,13 +2266,22 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %GenericClass.generic: %GenericClass.type = struct_value () [concrete] // CHECK:STDOUT: %GenericClass: type = class_type @GenericClass, @GenericClass(%U) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.633: = impl_witness @GenericClass.%Destroy.impl_witness_table, @GenericClass.as.Destroy.impl(%U) [symbolic] +// CHECK:STDOUT: %ptr.b1a: type = ptr_type %GenericClass [symbolic] +// CHECK:STDOUT: %pattern_type.0e2: type = pattern_type %ptr.b1a [symbolic] +// CHECK:STDOUT: %GenericClass.as.Destroy.impl.Op.type: type = fn_type @GenericClass.as.Destroy.impl.Op, @GenericClass.as.Destroy.impl(%U) [symbolic] +// CHECK:STDOUT: %GenericClass.as.Destroy.impl.Op: %GenericClass.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %AnyParam.type: type = generic_class_type @AnyParam [concrete] // CHECK:STDOUT: %AnyParam.generic: %AnyParam.type = struct_value () [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %X: %T = bind_symbolic_name X, 1 [symbolic] +// CHECK:STDOUT: %AnyParam.560: type = class_type @AnyParam, @AnyParam(%T, %X) [symbolic] // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] +// CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %pattern_type.17e: type = pattern_type %GenericClass.type [concrete] // CHECK:STDOUT: %AnyParam.0dd: type = class_type @AnyParam, @AnyParam(%GenericClass.type, %GenericClass.generic) [concrete] // CHECK:STDOUT: %Y.type: type = facet_type <@Y> [concrete] @@ -1972,13 +2296,19 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %AnyParam.as.Y.impl.K.type: type = fn_type @AnyParam.as.Y.impl.K [concrete] // CHECK:STDOUT: %AnyParam.as.Y.impl.K: %AnyParam.as.Y.impl.K.type = struct_value () [concrete] // CHECK:STDOUT: %Y.facet: %Y.type = facet_value %AnyParam.0dd, (%Y.impl_witness) [concrete] +// CHECK:STDOUT: %complete_type.398: = complete_type_witness %GenericClass.type [concrete] // CHECK:STDOUT: %L.type: type = fn_type @L [concrete] // CHECK:STDOUT: %L: %L.type = struct_value () [concrete] // CHECK:STDOUT: %AnyParam.val: %AnyParam.0dd = struct_value () [concrete] // CHECK:STDOUT: %Y.assoc_type: type = assoc_entity_type @Y [concrete] // CHECK:STDOUT: %assoc0.494: %Y.assoc_type = assoc_entity element0, imports.%PackageHasParam.import_ref.ce2 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.2c3: = impl_witness imports.%Destroy.impl_witness_table.5b0, @AnyParam.as.Destroy.impl(%T, %X) [symbolic] +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op.type: type = fn_type @AnyParam.as.Destroy.impl.Op, @AnyParam.as.Destroy.impl(%T, %X) [symbolic] +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op: %AnyParam.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.4a9: type = ptr_type %AnyParam.560 [symbolic] +// CHECK:STDOUT: %pattern_type.84c: type = pattern_type %ptr.4a9 [symbolic] // CHECK:STDOUT: %.701: type = fn_type_with_self_type %Y.K.type, %Y.facet [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.105: = impl_witness imports.%Destroy.impl_witness_table.5b0, @AnyParam.as.Destroy.impl(%GenericClass.type, %GenericClass.generic) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.f56: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%AnyParam.0dd) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.1fa: %T.as.Destroy.impl.Op.type.f56 = struct_value () [concrete] // CHECK:STDOUT: %ptr.d96: type = ptr_type %AnyParam.0dd [concrete] @@ -1996,18 +2326,27 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: .Y = %PackageHasParam.Y // CHECK:STDOUT: import PackageHasParam//default // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %PackageHasParam.AnyParam: %AnyParam.type = import_ref PackageHasParam//default, AnyParam, loaded [concrete = constants.%AnyParam.generic] -// CHECK:STDOUT: %PackageHasParam.import_ref.5ab: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] -// CHECK:STDOUT: %PackageHasParam.import_ref.34c: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] +// CHECK:STDOUT: %PackageHasParam.import_ref.5ab3ec.1: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] +// CHECK:STDOUT: %PackageHasParam.import_ref.34c075.1: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] // CHECK:STDOUT: %PackageHasParam.import_ref.8f2: = import_ref PackageHasParam//default, loc4_34, loaded [concrete = constants.%complete_type.357] // CHECK:STDOUT: %PackageHasParam.import_ref.601 = import_ref PackageHasParam//default, inst33 [no loc], unloaded // CHECK:STDOUT: %PackageHasParam.Y: type = import_ref PackageHasParam//default, Y, loaded [concrete = constants.%Y.type] -// CHECK:STDOUT: %PackageHasParam.import_ref.dc1 = import_ref PackageHasParam//default, inst40 [no loc], unloaded +// CHECK:STDOUT: %PackageHasParam.import_ref.dc1 = import_ref PackageHasParam//default, inst93 [no loc], unloaded // CHECK:STDOUT: %PackageHasParam.import_ref.f69: %Y.assoc_type = import_ref PackageHasParam//default, loc7_22, loaded [concrete = constants.%assoc0.494] // CHECK:STDOUT: %PackageHasParam.K: %Y.K.type = import_ref PackageHasParam//default, K, loaded [concrete = constants.%Y.K] -// CHECK:STDOUT: %PackageHasParam.import_ref.292: %Y.type = import_ref PackageHasParam//default, inst40 [no loc], loaded [symbolic = constants.%Self.f64] +// CHECK:STDOUT: %PackageHasParam.import_ref.292: %Y.type = import_ref PackageHasParam//default, inst93 [no loc], loaded [symbolic = constants.%Self.f64] // CHECK:STDOUT: %PackageHasParam.import_ref.ce2: %Y.K.type = import_ref PackageHasParam//default, loc7_22, loaded [concrete = constants.%Y.K] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %PackageHasParam.import_ref.9da = import_ref PackageHasParam//default, loc4_33, unloaded +// CHECK:STDOUT: %PackageHasParam.import_ref.5ab3ec.2: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] +// CHECK:STDOUT: %PackageHasParam.import_ref.34c075.2: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] +// CHECK:STDOUT: %PackageHasParam.import_ref.758: type = import_ref PackageHasParam//default, inst33 [no loc], loaded [symbolic = constants.%AnyParam.560] +// CHECK:STDOUT: %PackageHasParam.import_ref.cb9: type = import_ref PackageHasParam//default, inst36 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %PackageHasParam.import_ref.ba8 = import_ref PackageHasParam//default, loc4_33, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.5b0 = impl_witness_table (%PackageHasParam.import_ref.ba8), @AnyParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %PackageHasParam.import_ref.5ab3ec.3: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] +// CHECK:STDOUT: %PackageHasParam.import_ref.34c075.3: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -2044,6 +2383,34 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = (imports.%PackageHasParam.K) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @GenericClass.as.Destroy.impl(@GenericClass.%U.loc6_20.2: type) { +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @GenericClass.%Destroy.impl_witness_table, @GenericClass.as.Destroy.impl(%U) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.633)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %GenericClass.as.Destroy.impl.Op.type: type = fn_type @GenericClass.as.Destroy.impl.Op, @GenericClass.as.Destroy.impl(%U) [symbolic = %GenericClass.as.Destroy.impl.Op.type (constants.%GenericClass.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %GenericClass.as.Destroy.impl.Op: @GenericClass.as.Destroy.impl.%GenericClass.as.Destroy.impl.Op.type (%GenericClass.as.Destroy.impl.Op.type) = struct_value () [symbolic = %GenericClass.as.Destroy.impl.Op (constants.%GenericClass.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%GenericClass as constants.%Destroy.type { +// CHECK:STDOUT: %GenericClass.as.Destroy.impl.Op.decl: @GenericClass.as.Destroy.impl.%GenericClass.as.Destroy.impl.Op.type (%GenericClass.as.Destroy.impl.Op.type) = fn_decl @GenericClass.as.Destroy.impl.Op [symbolic = @GenericClass.as.Destroy.impl.%GenericClass.as.Destroy.impl.Op (constants.%GenericClass.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @GenericClass.as.Destroy.impl.Op.%pattern_type (%pattern_type.0e2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @GenericClass.as.Destroy.impl.Op.%pattern_type (%pattern_type.0e2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6_30.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @GenericClass.as.Destroy.impl.Op.%ptr (%ptr.b1a) = value_param call_param0 +// CHECK:STDOUT: %.loc6_30.2: type = splice_block %Self.ref [symbolic = %GenericClass (constants.%GenericClass)] { +// CHECK:STDOUT: %.loc6_30.3: type = specific_constant constants.%GenericClass, @GenericClass(constants.%U) [symbolic = %GenericClass (constants.%GenericClass)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc6_30.3 [symbolic = %GenericClass (constants.%GenericClass)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @GenericClass.as.Destroy.impl.Op.%ptr (%ptr.b1a) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %GenericClass.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @GenericClass.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @AnyParam.as.Y.impl: %AnyParam as %Y.ref { // CHECK:STDOUT: %AnyParam.as.Y.impl.K.decl: %AnyParam.as.Y.impl.K.type = fn_decl @AnyParam.as.Y.impl.K [concrete = constants.%AnyParam.as.Y.impl.K] { // CHECK:STDOUT: %self.patt: %pattern_type.64f = binding_pattern self [concrete] @@ -2059,12 +2426,30 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = file.%Y.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @AnyParam.as.Destroy.impl(imports.%PackageHasParam.import_ref.5ab3ec.2: type, imports.%PackageHasParam.import_ref.34c075.2: @AnyParam.%T (%T)) [from "has_param.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %X: @AnyParam.as.Destroy.impl.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.5b0, @AnyParam.as.Destroy.impl(%T, %X) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.2c3)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op.type: type = fn_type @AnyParam.as.Destroy.impl.Op, @AnyParam.as.Destroy.impl(%T, %X) [symbolic = %AnyParam.as.Destroy.impl.Op.type (constants.%AnyParam.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op: @AnyParam.as.Destroy.impl.%AnyParam.as.Destroy.impl.Op.type (%AnyParam.as.Destroy.impl.Op.type) = struct_value () [symbolic = %AnyParam.as.Destroy.impl.Op (constants.%AnyParam.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%PackageHasParam.import_ref.758 as imports.%PackageHasParam.import_ref.cb9 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%PackageHasParam.import_ref.9da +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @GenericClass(%U.loc6_20.2: type) { // CHECK:STDOUT: %U.loc6_20.1: type = bind_symbolic_name U, 0 [symbolic = %U.loc6_20.1 (constants.%U)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @GenericClass.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@GenericClass.as.Destroy.impl.%GenericClass.as.Destroy.impl.Op.decl), @GenericClass.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @GenericClass.as.Destroy.impl(constants.%U) [symbolic = @GenericClass.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.633)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -2074,12 +2459,13 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic class @AnyParam(imports.%PackageHasParam.import_ref.5ab: type, imports.%PackageHasParam.import_ref.34c: @AnyParam.%T (%T)) [from "has_param.carbon"] { +// CHECK:STDOUT: generic class @AnyParam(imports.%PackageHasParam.import_ref.5ab3ec.1: type, imports.%PackageHasParam.import_ref.34c075.1: @AnyParam.%T (%T)) [from "has_param.carbon"] { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %X: @AnyParam.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] // CHECK:STDOUT: %pattern_type: type = pattern_type %T [symbolic = %pattern_type (constants.%pattern_type.7dc)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type %T [symbolic = %require_complete (constants.%require_complete.4ae)] // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: complete_type_witness = imports.%PackageHasParam.import_ref.8f2 @@ -2089,6 +2475,17 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @GenericClass.as.Destroy.impl.Op(@GenericClass.%U.loc6_20.2: type) { +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %GenericClass: type = class_type @GenericClass, @GenericClass(%U) [symbolic = %GenericClass (constants.%GenericClass)] +// CHECK:STDOUT: %ptr: type = ptr_type %GenericClass [symbolic = %ptr (constants.%ptr.b1a)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.0e2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @GenericClass.as.Destroy.impl.Op.%ptr (%ptr.b1a)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @Y.K(imports.%PackageHasParam.import_ref.292: %Y.type) [from "has_param.carbon"] { // CHECK:STDOUT: %Self: %Y.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.f64)] // CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type.61d)] @@ -2139,10 +2536,34 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @AnyParam.as.Destroy.impl.Op(imports.%PackageHasParam.import_ref.5ab3ec.3: type, imports.%PackageHasParam.import_ref.34c075.3: @AnyParam.%T (%T)) [from "has_param.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %X: @AnyParam.as.Destroy.impl.Op.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %AnyParam: type = class_type @AnyParam, @AnyParam(%T, %X) [symbolic = %AnyParam (constants.%AnyParam.560)] +// CHECK:STDOUT: %ptr: type = ptr_type %AnyParam [symbolic = %ptr (constants.%ptr.4a9)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.84c)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @GenericClass(constants.%U) { // CHECK:STDOUT: %U.loc6_20.1 => constants.%U // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @GenericClass.as.Destroy.impl(constants.%U) { +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.633 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @GenericClass.as.Destroy.impl.Op(constants.%U) { +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %GenericClass => constants.%GenericClass +// CHECK:STDOUT: %ptr => constants.%ptr.b1a +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.0e2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @AnyParam(constants.%T, constants.%X) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: %X => constants.%X @@ -2155,6 +2576,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.17e // CHECK:STDOUT: // CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete => constants.%complete_type.398 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @Y.K(constants.%Self.f64) { @@ -2169,6 +2591,26 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.64f // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @AnyParam.as.Destroy.impl(constants.%T, constants.%X) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.2c3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @AnyParam.as.Destroy.impl.Op(constants.%T, constants.%X) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %AnyParam => constants.%AnyParam.560 +// CHECK:STDOUT: %ptr => constants.%ptr.4a9 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.84c +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @AnyParam.as.Destroy.impl(constants.%GenericClass.type, constants.%GenericClass.generic) { +// CHECK:STDOUT: %T => constants.%GenericClass.type +// CHECK:STDOUT: %X => constants.%GenericClass.generic +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.105 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- use_generic_class_as_param.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -2181,12 +2623,16 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %X: %T = bind_symbolic_name X, 1 [symbolic] +// CHECK:STDOUT: %AnyParam.560: type = class_type @AnyParam, @AnyParam(%T, %X) [symbolic] // CHECK:STDOUT: %pattern_type.7dc: type = pattern_type %T [symbolic] +// CHECK:STDOUT: %require_complete.4ae: = require_complete_type %T [symbolic] // CHECK:STDOUT: %GenericClass.type: type = generic_class_type @GenericClass [concrete] // CHECK:STDOUT: %GenericClass.generic: %GenericClass.type = struct_value () [concrete] // CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic] +// CHECK:STDOUT: %GenericClass: type = class_type @GenericClass, @GenericClass(%U) [symbolic] // CHECK:STDOUT: %pattern_type.17a: type = pattern_type %GenericClass.type [concrete] // CHECK:STDOUT: %AnyParam.d71: type = class_type @AnyParam, @AnyParam(%GenericClass.type, %GenericClass.generic) [concrete] +// CHECK:STDOUT: %complete_type.426: = complete_type_witness %GenericClass.type [concrete] // CHECK:STDOUT: %pattern_type.312: type = pattern_type %AnyParam.d71 [concrete] // CHECK:STDOUT: %AnyParam.val: %AnyParam.d71 = struct_value () [concrete] // CHECK:STDOUT: %Y.type: type = facet_type <@Y> [concrete] @@ -2199,15 +2645,26 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %pattern_type.cb4: type = pattern_type %Self.as_type.61d [symbolic] // CHECK:STDOUT: %require_complete.b14: = require_complete_type %Self.as_type.61d [symbolic] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.7ff: = impl_witness imports.%Destroy.impl_witness_table.f0b, @AnyParam.as.Destroy.impl(%T, %X) [symbolic] +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op.type: type = fn_type @AnyParam.as.Destroy.impl.Op, @AnyParam.as.Destroy.impl(%T, %X) [symbolic] +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op: %AnyParam.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.4a9: type = ptr_type %AnyParam.560 [symbolic] +// CHECK:STDOUT: %pattern_type.84c: type = pattern_type %ptr.4a9 [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.4c0: = impl_witness imports.%Destroy.impl_witness_table.c53, @GenericClass.as.Destroy.impl(%U) [symbolic] +// CHECK:STDOUT: %GenericClass.as.Destroy.impl.Op.type: type = fn_type @GenericClass.as.Destroy.impl.Op, @GenericClass.as.Destroy.impl(%U) [symbolic] +// CHECK:STDOUT: %GenericClass.as.Destroy.impl.Op: %GenericClass.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.d95: type = ptr_type %GenericClass [symbolic] +// CHECK:STDOUT: %pattern_type.327: type = pattern_type %ptr.d95 [symbolic] // CHECK:STDOUT: %Y.impl_witness: = impl_witness imports.%Y.impl_witness_table [concrete] // CHECK:STDOUT: %Y.facet: %Y.type = facet_value %AnyParam.d71, (%Y.impl_witness) [concrete] // CHECK:STDOUT: %.0dd: type = fn_type_with_self_type %Y.K.type, %Y.facet [concrete] // CHECK:STDOUT: %AnyParam.as.Y.impl.K.type: type = fn_type @AnyParam.as.Y.impl.K [concrete] // CHECK:STDOUT: %AnyParam.as.Y.impl.K: %AnyParam.as.Y.impl.K.type = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.051: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%AnyParam.d71) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.d0b: %T.as.Destroy.impl.Op.type.051 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.339: = impl_witness imports.%Destroy.impl_witness_table.f0b, @AnyParam.as.Destroy.impl(%GenericClass.type, %GenericClass.generic) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.ce0: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%AnyParam.d71) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.07d: %T.as.Destroy.impl.Op.type.ce0 = struct_value () [concrete] // CHECK:STDOUT: %ptr.8ee: type = ptr_type %AnyParam.d71 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.d0b, @T.as.Destroy.impl.Op(%AnyParam.d71) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.07d, @T.as.Destroy.impl.Op(%AnyParam.d71) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -2226,20 +2683,36 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: import PackageGenericClass//default // CHECK:STDOUT: } // CHECK:STDOUT: %PackageHasParam.AnyParam: %AnyParam.type = import_ref PackageHasParam//default, AnyParam, loaded [concrete = constants.%AnyParam.generic] -// CHECK:STDOUT: %PackageHasParam.import_ref.5ab: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] -// CHECK:STDOUT: %PackageHasParam.import_ref.34c: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] +// CHECK:STDOUT: %PackageHasParam.import_ref.5ab3ec.1: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] +// CHECK:STDOUT: %PackageHasParam.import_ref.34c075.1: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] // CHECK:STDOUT: %PackageHasParam.import_ref.8f2: = import_ref PackageHasParam//default, loc4_34, loaded [concrete = constants.%complete_type.357] // CHECK:STDOUT: %PackageHasParam.import_ref.601 = import_ref PackageHasParam//default, inst33 [no loc], unloaded // CHECK:STDOUT: %PackageGenericClass.GenericClass: %GenericClass.type = import_ref PackageGenericClass//default, GenericClass, loaded [concrete = constants.%GenericClass.generic] -// CHECK:STDOUT: %PackageGenericClass.import_ref.5ab: type = import_ref PackageGenericClass//default, loc6_20, loaded [symbolic = @GenericClass.%U (constants.%U)] +// CHECK:STDOUT: %PackageGenericClass.import_ref.5ab3ec.1: type = import_ref PackageGenericClass//default, loc6_20, loaded [symbolic = @GenericClass.%U (constants.%U)] // CHECK:STDOUT: %PackageGenericClass.import_ref.8f2: = import_ref PackageGenericClass//default, loc6_31, loaded [concrete = constants.%complete_type.357] // CHECK:STDOUT: %PackageGenericClass.import_ref.065 = import_ref PackageGenericClass//default, inst28 [no loc], unloaded // CHECK:STDOUT: %PackageHasParam.Y: type = import_ref PackageHasParam//default, Y, loaded [concrete = constants.%Y.type] -// CHECK:STDOUT: %PackageHasParam.import_ref.dc1 = import_ref PackageHasParam//default, inst40 [no loc], unloaded +// CHECK:STDOUT: %PackageHasParam.import_ref.dc1 = import_ref PackageHasParam//default, inst93 [no loc], unloaded // CHECK:STDOUT: %PackageHasParam.import_ref.f69: %Y.assoc_type = import_ref PackageHasParam//default, loc7_22, loaded [concrete = constants.%assoc0.494] // CHECK:STDOUT: %PackageHasParam.K = import_ref PackageHasParam//default, K, unloaded // CHECK:STDOUT: %PackageHasParam.import_ref.ce2: %Y.K.type = import_ref PackageHasParam//default, loc7_22, loaded [concrete = constants.%Y.K] -// CHECK:STDOUT: %PackageHasParam.import_ref.292: %Y.type = import_ref PackageHasParam//default, inst40 [no loc], loaded [symbolic = constants.%Self.f64] +// CHECK:STDOUT: %PackageHasParam.import_ref.292: %Y.type = import_ref PackageHasParam//default, inst93 [no loc], loaded [symbolic = constants.%Self.f64] +// CHECK:STDOUT: %PackageHasParam.import_ref.9da = import_ref PackageHasParam//default, loc4_33, unloaded +// CHECK:STDOUT: %PackageHasParam.import_ref.5ab3ec.2: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] +// CHECK:STDOUT: %PackageHasParam.import_ref.34c075.2: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] +// CHECK:STDOUT: %PackageHasParam.import_ref.758: type = import_ref PackageHasParam//default, inst33 [no loc], loaded [symbolic = constants.%AnyParam.560] +// CHECK:STDOUT: %PackageHasParam.import_ref.cb9: type = import_ref PackageHasParam//default, inst36 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %PackageHasParam.import_ref.ba8 = import_ref PackageHasParam//default, loc4_33, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.f0b = impl_witness_table (%PackageHasParam.import_ref.ba8), @AnyParam.as.Destroy.impl [concrete] +// CHECK:STDOUT: %PackageHasParam.import_ref.5ab3ec.3: type = import_ref PackageHasParam//default, loc4_16, loaded [symbolic = @AnyParam.%T (constants.%T)] +// CHECK:STDOUT: %PackageHasParam.import_ref.34c075.3: @AnyParam.%T (%T) = import_ref PackageHasParam//default, loc4_26, loaded [symbolic = @AnyParam.%X (constants.%X)] +// CHECK:STDOUT: %PackageGenericClass.import_ref.877 = import_ref PackageGenericClass//default, loc6_30, unloaded +// CHECK:STDOUT: %PackageGenericClass.import_ref.5ab3ec.2: type = import_ref PackageGenericClass//default, loc6_20, loaded [symbolic = @GenericClass.%U (constants.%U)] +// CHECK:STDOUT: %PackageGenericClass.import_ref.594: type = import_ref PackageGenericClass//default, inst28 [no loc], loaded [symbolic = constants.%GenericClass] +// CHECK:STDOUT: %PackageGenericClass.import_ref.cb9: type = import_ref PackageGenericClass//default, inst31 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %PackageGenericClass.import_ref.5f2 = import_ref PackageGenericClass//default, loc6_30, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.c53 = impl_witness_table (%PackageGenericClass.import_ref.5f2), @GenericClass.as.Destroy.impl [concrete] +// CHECK:STDOUT: %PackageGenericClass.import_ref.5ab3ec.3: type = import_ref PackageGenericClass//default, loc6_20, loaded [symbolic = @GenericClass.%U (constants.%U)] // CHECK:STDOUT: %PackageGenericClass.import_ref.246: = import_ref PackageGenericClass//default, loc8_66, loaded [concrete = constants.%Y.impl_witness] // CHECK:STDOUT: %PackageGenericClass.import_ref.a0e: type = import_ref PackageGenericClass//default, loc8_43, loaded [concrete = constants.%AnyParam.d71] // CHECK:STDOUT: %PackageGenericClass.import_ref.ca6: type = import_ref PackageGenericClass//default, loc8_63, loaded [concrete = constants.%Y.type] @@ -2268,17 +2741,47 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = (imports.%PackageHasParam.K) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @AnyParam.as.Destroy.impl(imports.%PackageHasParam.import_ref.5ab3ec.2: type, imports.%PackageHasParam.import_ref.34c075.2: @AnyParam.%T (%T)) [from "has_param.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %X: @AnyParam.as.Destroy.impl.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.f0b, @AnyParam.as.Destroy.impl(%T, %X) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.7ff)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op.type: type = fn_type @AnyParam.as.Destroy.impl.Op, @AnyParam.as.Destroy.impl(%T, %X) [symbolic = %AnyParam.as.Destroy.impl.Op.type (constants.%AnyParam.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %AnyParam.as.Destroy.impl.Op: @AnyParam.as.Destroy.impl.%AnyParam.as.Destroy.impl.Op.type (%AnyParam.as.Destroy.impl.Op.type) = struct_value () [symbolic = %AnyParam.as.Destroy.impl.Op (constants.%AnyParam.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%PackageHasParam.import_ref.758 as imports.%PackageHasParam.import_ref.cb9 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%PackageHasParam.import_ref.9da +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @GenericClass.as.Destroy.impl(imports.%PackageGenericClass.import_ref.5ab3ec.2: type) [from "has_generic_class.carbon"] { +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.c53, @GenericClass.as.Destroy.impl(%U) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.4c0)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %GenericClass.as.Destroy.impl.Op.type: type = fn_type @GenericClass.as.Destroy.impl.Op, @GenericClass.as.Destroy.impl(%U) [symbolic = %GenericClass.as.Destroy.impl.Op.type (constants.%GenericClass.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %GenericClass.as.Destroy.impl.Op: @GenericClass.as.Destroy.impl.%GenericClass.as.Destroy.impl.Op.type (%GenericClass.as.Destroy.impl.Op.type) = struct_value () [symbolic = %GenericClass.as.Destroy.impl.Op (constants.%GenericClass.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%PackageGenericClass.import_ref.594 as imports.%PackageGenericClass.import_ref.cb9 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%PackageGenericClass.import_ref.877 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @AnyParam.as.Y.impl: imports.%PackageGenericClass.import_ref.a0e as imports.%PackageGenericClass.import_ref.ca6 [from "has_generic_class.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%PackageGenericClass.import_ref.246 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic class @AnyParam(imports.%PackageHasParam.import_ref.5ab: type, imports.%PackageHasParam.import_ref.34c: @AnyParam.%T (%T)) [from "has_param.carbon"] { +// CHECK:STDOUT: generic class @AnyParam(imports.%PackageHasParam.import_ref.5ab3ec.1: type, imports.%PackageHasParam.import_ref.34c075.1: @AnyParam.%T (%T)) [from "has_param.carbon"] { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: %X: @AnyParam.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] // CHECK:STDOUT: %pattern_type: type = pattern_type %T [symbolic = %pattern_type (constants.%pattern_type.7dc)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type %T [symbolic = %require_complete (constants.%require_complete.4ae)] // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: complete_type_witness = imports.%PackageHasParam.import_ref.8f2 @@ -2288,7 +2791,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic class @GenericClass(imports.%PackageGenericClass.import_ref.5ab: type) [from "has_generic_class.carbon"] { +// CHECK:STDOUT: generic class @GenericClass(imports.%PackageGenericClass.import_ref.5ab3ec.1: type) [from "has_generic_class.carbon"] { // CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic = %U (constants.%U)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: @@ -2328,8 +2831,8 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %bound_method.loc9: = bound_method %obj.ref, %impl.elem0 // CHECK:STDOUT: %.loc9: %AnyParam.d71 = bind_value %obj.ref // CHECK:STDOUT: %AnyParam.as.Y.impl.K.call: init %empty_tuple.type = call %bound_method.loc9(%.loc9) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %obj.var, constants.%T.as.Destroy.impl.Op.d0b -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.d0b, @T.as.Destroy.impl.Op(constants.%AnyParam.d71) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %obj.var, constants.%T.as.Destroy.impl.Op.07d +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.07d, @T.as.Destroy.impl.Op(constants.%AnyParam.d71) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method.loc8: = bound_method %obj.var, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr: %ptr.8ee = addr_of %obj.var // CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc8(%addr) @@ -2347,6 +2850,29 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: fn; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @AnyParam.as.Destroy.impl.Op(imports.%PackageHasParam.import_ref.5ab3ec.3: type, imports.%PackageHasParam.import_ref.34c075.3: @AnyParam.%T (%T)) [from "has_param.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %X: @AnyParam.as.Destroy.impl.Op.%T (%T) = bind_symbolic_name X, 1 [symbolic = %X (constants.%X)] +// CHECK:STDOUT: %AnyParam: type = class_type @AnyParam, @AnyParam(%T, %X) [symbolic = %AnyParam (constants.%AnyParam.560)] +// CHECK:STDOUT: %ptr: type = ptr_type %AnyParam [symbolic = %ptr (constants.%ptr.4a9)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.84c)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @GenericClass.as.Destroy.impl.Op(imports.%PackageGenericClass.import_ref.5ab3ec.3: type) [from "has_generic_class.carbon"] { +// CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic = %U (constants.%U)] +// CHECK:STDOUT: %GenericClass: type = class_type @GenericClass, @GenericClass(%U) [symbolic = %GenericClass (constants.%GenericClass)] +// CHECK:STDOUT: %ptr: type = ptr_type %GenericClass [symbolic = %ptr (constants.%ptr.d95)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.327)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @AnyParam.as.Y.impl.K [from "has_generic_class.carbon"]; // CHECK:STDOUT: // CHECK:STDOUT: specific @AnyParam(constants.%T, constants.%X) { @@ -2365,6 +2891,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.17a // CHECK:STDOUT: // CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete => constants.%complete_type.426 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @Y.K(constants.%Self.f64) { @@ -2373,6 +2900,38 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.cb4 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @AnyParam.as.Destroy.impl(constants.%T, constants.%X) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.7ff +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @AnyParam.as.Destroy.impl.Op(constants.%T, constants.%X) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %X => constants.%X +// CHECK:STDOUT: %AnyParam => constants.%AnyParam.560 +// CHECK:STDOUT: %ptr => constants.%ptr.4a9 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.84c +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @GenericClass.as.Destroy.impl(constants.%U) { +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.4c0 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @GenericClass.as.Destroy.impl.Op(constants.%U) { +// CHECK:STDOUT: %U => constants.%U +// CHECK:STDOUT: %GenericClass => constants.%GenericClass +// CHECK:STDOUT: %ptr => constants.%ptr.d95 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.327 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @AnyParam.as.Destroy.impl(constants.%GenericClass.type, constants.%GenericClass.generic) { +// CHECK:STDOUT: %T => constants.%GenericClass.type +// CHECK:STDOUT: %X => constants.%GenericClass.generic +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.339 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- has_extra_interfaces.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -2397,12 +2956,19 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.f2e: type = class_type @C, @C(%T) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] // CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.826 [symbolic] -// CHECK:STDOUT: %pattern_type.6de: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Self.as_type.b70: type = facet_access_type %Self.826 [symbolic] +// CHECK:STDOUT: %pattern_type.6de: type = pattern_type %Self.as_type.b70 [symbolic] // CHECK:STDOUT: %I.F.type: type = fn_type @I.F [concrete] // CHECK:STDOUT: %I.F: %I.F.type = struct_value () [concrete] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] @@ -2419,9 +2985,11 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -2542,13 +3110,13 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %self.patt: @I.F.%pattern_type (%pattern_type.6de) = binding_pattern self [concrete] // CHECK:STDOUT: %self.param_patt: @I.F.%pattern_type (%pattern_type.6de) = value_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param: @I.F.%Self.as_type.loc14_26.1 (%Self.as_type) = value_param call_param0 -// CHECK:STDOUT: %.loc14_26.1: type = splice_block %.loc14_26.2 [symbolic = %Self.as_type.loc14_26.1 (constants.%Self.as_type)] { +// CHECK:STDOUT: %self.param: @I.F.%Self.as_type.loc14_26.1 (%Self.as_type.b70) = value_param call_param0 +// CHECK:STDOUT: %.loc14_26.1: type = splice_block %.loc14_26.2 [symbolic = %Self.as_type.loc14_26.1 (constants.%Self.as_type.b70)] { // CHECK:STDOUT: %Self.ref: %I.type = name_ref Self, @I.%Self [symbolic = %Self (constants.%Self.826)] -// CHECK:STDOUT: %Self.as_type.loc14_26.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc14_26.1 (constants.%Self.as_type)] -// CHECK:STDOUT: %.loc14_26.2: type = converted %Self.ref, %Self.as_type.loc14_26.2 [symbolic = %Self.as_type.loc14_26.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self.as_type.loc14_26.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc14_26.1 (constants.%Self.as_type.b70)] +// CHECK:STDOUT: %.loc14_26.2: type = converted %Self.ref, %Self.as_type.loc14_26.2 [symbolic = %Self.as_type.loc14_26.1 (constants.%Self.as_type.b70)] // CHECK:STDOUT: } -// CHECK:STDOUT: %self: @I.F.%Self.as_type.loc14_26.1 (%Self.as_type) = bind_name self, %self.param +// CHECK:STDOUT: %self: @I.F.%Self.as_type.loc14_26.1 (%Self.as_type.b70) = bind_name self, %self.param // CHECK:STDOUT: } // CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, %I.F.decl [concrete = constants.%assoc0] // CHECK:STDOUT: @@ -2558,6 +3126,34 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = (%I.F.decl) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc13_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f2e as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc13_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc13_19.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.f2e)] { +// CHECK:STDOUT: %.loc13_19.3: type = specific_constant constants.%C.f2e, @C(constants.%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc13_19.3 [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.I.impl: %C as %I.ref { // CHECK:STDOUT: %C.as.I.impl.F.decl: %C.as.I.impl.F.type = fn_decl @C.as.I.impl.F [concrete = constants.%C.as.I.impl.F] { // CHECK:STDOUT: %self.patt: %pattern_type.e23 = binding_pattern self [concrete] @@ -2579,6 +3175,9 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -2588,12 +3187,23 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc13_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @I.F(@I.%Self: %I.type) { // CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)] -// CHECK:STDOUT: %Self.as_type.loc14_26.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc14_26.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self.as_type.loc14_26.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc14_26.1 (constants.%Self.as_type.b70)] // CHECK:STDOUT: %pattern_type: type = pattern_type %Self.as_type.loc14_26.1 [symbolic = %pattern_type (constants.%pattern_type.6de)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%self.param: @I.F.%Self.as_type.loc14_26.1 (%Self.as_type)); +// CHECK:STDOUT: fn(%self.param: @I.F.%Self.as_type.loc14_26.1 (%Self.as_type.b70)); // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.I.impl.F(%self.param: %C.69b) { @@ -2605,9 +3215,21 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %T.loc13_9.1 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.f2e +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @I.F(constants.%Self.826) { // CHECK:STDOUT: %Self => constants.%Self.826 -// CHECK:STDOUT: %Self.as_type.loc14_26.1 => constants.%Self.as_type +// CHECK:STDOUT: %Self.as_type.loc14_26.1 => constants.%Self.as_type.b70 // CHECK:STDOUT: %pattern_type => constants.%pattern_type.6de // CHECK:STDOUT: } // CHECK:STDOUT: @@ -2631,6 +3253,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %C.c77: type = class_type @C, @C(%T) [symbolic] // CHECK:STDOUT: %C.42e: type = class_type @C, @C(type) [concrete] // CHECK:STDOUT: %pattern_type.6e4: type = pattern_type %C.42e [concrete] // CHECK:STDOUT: %Test.type: type = fn_type @Test [concrete] @@ -2643,6 +3266,12 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %I.F: %I.F.type = struct_value () [concrete] // CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.013 [symbolic] // CHECK:STDOUT: %pattern_type.e10: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.534: type = ptr_type %C.c77 [symbolic] +// CHECK:STDOUT: %pattern_type.663: type = pattern_type %ptr.534 [symbolic] // CHECK:STDOUT: %Extra8.type: type = facet_type <@Extra8> [concrete] // CHECK:STDOUT: %Extra7.type: type = facet_type <@Extra7> [concrete] // CHECK:STDOUT: %Extra6.type: type = facet_type <@Extra6> [concrete] @@ -2656,7 +3285,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: %Core.ece: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -2666,15 +3295,22 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: import HasExtraInterfaces//default // CHECK:STDOUT: } // CHECK:STDOUT: %HasExtraInterfaces.C: %C.type = import_ref HasExtraInterfaces//default, C, loaded [concrete = constants.%C.generic] -// CHECK:STDOUT: %HasExtraInterfaces.import_ref.5ab: type = import_ref HasExtraInterfaces//default, loc13_9, loaded [symbolic = @C.%T (constants.%T)] +// CHECK:STDOUT: %HasExtraInterfaces.import_ref.5ab3ec.1: type = import_ref HasExtraInterfaces//default, loc13_9, loaded [symbolic = @C.%T (constants.%T)] // CHECK:STDOUT: %HasExtraInterfaces.import_ref.8f2: = import_ref HasExtraInterfaces//default, loc13_20, loaded [concrete = constants.%complete_type] // CHECK:STDOUT: %HasExtraInterfaces.import_ref.4c0 = import_ref HasExtraInterfaces//default, inst66 [no loc], unloaded // CHECK:STDOUT: %HasExtraInterfaces.I: type = import_ref HasExtraInterfaces//default, I, loaded [concrete = constants.%I.type] -// CHECK:STDOUT: %HasExtraInterfaces.import_ref.e5d = import_ref HasExtraInterfaces//default, inst73 [no loc], unloaded +// CHECK:STDOUT: %HasExtraInterfaces.import_ref.e5d = import_ref HasExtraInterfaces//default, inst121 [no loc], unloaded // CHECK:STDOUT: %HasExtraInterfaces.import_ref.be9: %I.assoc_type = import_ref HasExtraInterfaces//default, loc14_33, loaded [concrete = constants.%assoc0] // CHECK:STDOUT: %HasExtraInterfaces.F = import_ref HasExtraInterfaces//default, F, unloaded // CHECK:STDOUT: %HasExtraInterfaces.import_ref.d54: %I.F.type = import_ref HasExtraInterfaces//default, loc14_33, loaded [concrete = constants.%I.F] -// CHECK:STDOUT: %HasExtraInterfaces.import_ref.1db: %I.type = import_ref HasExtraInterfaces//default, inst73 [no loc], loaded [symbolic = constants.%Self.013] +// CHECK:STDOUT: %HasExtraInterfaces.import_ref.1db: %I.type = import_ref HasExtraInterfaces//default, inst121 [no loc], loaded [symbolic = constants.%Self.013] +// CHECK:STDOUT: %HasExtraInterfaces.import_ref.21a = import_ref HasExtraInterfaces//default, loc13_19, unloaded +// CHECK:STDOUT: %HasExtraInterfaces.import_ref.5ab3ec.2: type = import_ref HasExtraInterfaces//default, loc13_9, loaded [symbolic = @C.%T (constants.%T)] +// CHECK:STDOUT: %HasExtraInterfaces.import_ref.499: type = import_ref HasExtraInterfaces//default, inst66 [no loc], loaded [symbolic = constants.%C.c77] +// CHECK:STDOUT: %HasExtraInterfaces.import_ref.cb9: type = import_ref HasExtraInterfaces//default, inst69 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %HasExtraInterfaces.import_ref.251 = import_ref HasExtraInterfaces//default, loc13_19, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (%HasExtraInterfaces.import_ref.251), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %HasExtraInterfaces.import_ref.5ab3ec.3: type = import_ref HasExtraInterfaces//default, loc13_9, loaded [symbolic = @C.%T (constants.%T)] // CHECK:STDOUT: %HasExtraInterfaces.import_ref.bca = import_ref HasExtraInterfaces//default, loc16_79, unloaded // CHECK:STDOUT: %HasExtraInterfaces.import_ref.9c8 = import_ref HasExtraInterfaces//default, inst54 [no loc], unloaded // CHECK:STDOUT: %HasExtraInterfaces.import_ref.dfe = import_ref HasExtraInterfaces//default, inst49 [no loc], unloaded @@ -2690,7 +3326,7 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Core = imports.%Core.ece // CHECK:STDOUT: .HasExtraInterfaces = imports.%HasExtraInterfaces // CHECK:STDOUT: .Test = %Test.decl // CHECK:STDOUT: } @@ -2765,12 +3401,26 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(imports.%HasExtraInterfaces.import_ref.5ab3ec.2: type) [from "has_extra_interfaces.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%HasExtraInterfaces.import_ref.499 as imports.%HasExtraInterfaces.import_ref.cb9 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%HasExtraInterfaces.import_ref.21a +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.I.impl: imports.%HasExtraInterfaces.import_ref.aa8 as imports.%HasExtraInterfaces.import_ref.301 [from "has_extra_interfaces.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%HasExtraInterfaces.import_ref.bca // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic class @C(imports.%HasExtraInterfaces.import_ref.5ab: type) [from "has_extra_interfaces.carbon"] { +// CHECK:STDOUT: generic class @C(imports.%HasExtraInterfaces.import_ref.5ab3ec.1: type) [from "has_extra_interfaces.carbon"] { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: @@ -2800,6 +3450,17 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: fn; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(imports.%HasExtraInterfaces.import_ref.5ab3ec.3: type) [from "has_extra_interfaces.carbon"] { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.c77)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.534)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.663)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%T) { // CHECK:STDOUT: %T => constants.%T // CHECK:STDOUT: } @@ -2816,6 +3477,18 @@ fn Test(c: HasExtraInterfaces.C(type)) { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.e10 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.c77 +// CHECK:STDOUT: %ptr => constants.%ptr.534 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.663 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%tuple.type) { // CHECK:STDOUT: %T => constants.%tuple.type // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/lookup/instance_method.carbon b/toolchain/check/testdata/impl/lookup/instance_method.carbon index 17c35003bab9..bf7901fe34f0 100644 --- a/toolchain/check/testdata/impl/lookup/instance_method.carbon +++ b/toolchain/check/testdata/impl/lookup/instance_method.carbon @@ -33,9 +33,9 @@ fn F(c: C) -> i32 { // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic] -// CHECK:STDOUT: %pattern_type.6de: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.as_type.b70: type = facet_access_type %Self.826 [symbolic] +// CHECK:STDOUT: %pattern_type.6de: type = pattern_type %Self.as_type.b70 [symbolic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] @@ -50,6 +50,13 @@ fn F(c: C) -> i32 { // CHECK:STDOUT: %C.as.I.impl.F.type: type = fn_type @C.as.I.impl.F [concrete] // CHECK:STDOUT: %C.as.I.impl.F: %C.as.I.impl.F.type = struct_value () [concrete] // CHECK:STDOUT: %I.facet: %I.type = facet_value %C, (%I.impl_witness) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] @@ -60,10 +67,12 @@ fn F(c: C) -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -94,7 +103,7 @@ fn F(c: C) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826] // CHECK:STDOUT: %I.F.decl: %I.F.type = fn_decl @I.F [concrete = constants.%I.F] { // CHECK:STDOUT: %self.patt: @I.F.%pattern_type (%pattern_type.6de) = binding_pattern self [concrete] // CHECK:STDOUT: %self.param_patt: @I.F.%pattern_type (%pattern_type.6de) = value_param_pattern %self.patt, call_param0 [concrete] @@ -103,13 +112,13 @@ fn F(c: C) -> i32 { // CHECK:STDOUT: } { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %self.param: @I.F.%Self.as_type.loc18_14.1 (%Self.as_type) = value_param call_param0 -// CHECK:STDOUT: %.loc18_14.1: type = splice_block %.loc18_14.2 [symbolic = %Self.as_type.loc18_14.1 (constants.%Self.as_type)] { -// CHECK:STDOUT: %Self.ref: %I.type = name_ref Self, @I.%Self [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.as_type.loc18_14.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc18_14.1 (constants.%Self.as_type)] -// CHECK:STDOUT: %.loc18_14.2: type = converted %Self.ref, %Self.as_type.loc18_14.2 [symbolic = %Self.as_type.loc18_14.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %self.param: @I.F.%Self.as_type.loc18_14.1 (%Self.as_type.b70) = value_param call_param0 +// CHECK:STDOUT: %.loc18_14.1: type = splice_block %.loc18_14.2 [symbolic = %Self.as_type.loc18_14.1 (constants.%Self.as_type.b70)] { +// CHECK:STDOUT: %Self.ref: %I.type = name_ref Self, @I.%Self [symbolic = %Self (constants.%Self.826)] +// CHECK:STDOUT: %Self.as_type.loc18_14.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc18_14.1 (constants.%Self.as_type.b70)] +// CHECK:STDOUT: %.loc18_14.2: type = converted %Self.ref, %Self.as_type.loc18_14.2 [symbolic = %Self.as_type.loc18_14.1 (constants.%Self.as_type.b70)] // CHECK:STDOUT: } -// CHECK:STDOUT: %self: @I.F.%Self.as_type.loc18_14.1 (%Self.as_type) = bind_name self, %self.param +// CHECK:STDOUT: %self: @I.F.%Self.as_type.loc18_14.1 (%Self.as_type.b70) = bind_name self, %self.param // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } @@ -142,6 +151,22 @@ fn F(c: C) -> i32 { // CHECK:STDOUT: witness = @C.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc21: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] @@ -149,6 +174,9 @@ fn F(c: C) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (@C.as.I.impl.%C.as.I.impl.F.decl), @C.as.I.impl [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -161,15 +189,17 @@ fn F(c: C) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @I.F(@I.%Self: %I.type) { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.as_type.loc18_14.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc18_14.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)] +// CHECK:STDOUT: %Self.as_type.loc18_14.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc18_14.1 (constants.%Self.as_type.b70)] // CHECK:STDOUT: %pattern_type: type = pattern_type %Self.as_type.loc18_14.1 [symbolic = %pattern_type (constants.%pattern_type.6de)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%self.param: @I.F.%Self.as_type.loc18_14.1 (%Self.as_type)) -> %i32; +// CHECK:STDOUT: fn(%self.param: @I.F.%Self.as_type.loc18_14.1 (%Self.as_type.b70)) -> %i32; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.I.impl.F(%self.param: %C) -> %i32; // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%c.param: %C) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %c.ref: %C = name_ref c, %c @@ -182,9 +212,9 @@ fn F(c: C) -> i32 { // CHECK:STDOUT: return %.loc28_15.2 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @I.F(constants.%Self) { -// CHECK:STDOUT: %Self => constants.%Self -// CHECK:STDOUT: %Self.as_type.loc18_14.1 => constants.%Self.as_type +// CHECK:STDOUT: specific @I.F(constants.%Self.826) { +// CHECK:STDOUT: %Self => constants.%Self.826 +// CHECK:STDOUT: %Self.as_type.loc18_14.1 => constants.%Self.as_type.b70 // CHECK:STDOUT: %pattern_type => constants.%pattern_type.6de // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/lookup/lookup_interface_with_enclosing_generic_inside_rewrite_constraint.carbon b/toolchain/check/testdata/impl/lookup/lookup_interface_with_enclosing_generic_inside_rewrite_constraint.carbon index cab6192ac335..85effe658ea4 100644 --- a/toolchain/check/testdata/impl/lookup/lookup_interface_with_enclosing_generic_inside_rewrite_constraint.carbon +++ b/toolchain/check/testdata/impl/lookup/lookup_interface_with_enclosing_generic_inside_rewrite_constraint.carbon @@ -124,6 +124,13 @@ fn F() { // CHECK:STDOUT: %pattern_type.f71: type = pattern_type %Y_where.type.324 [symbolic] // CHECK:STDOUT: %Outer.G.type.d49: type = fn_type @Outer.G, @Outer(%OuterParam) [symbolic] // CHECK:STDOUT: %Outer.G.f3c: %Outer.G.type.d49 = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%OuterParam) [symbolic] +// CHECK:STDOUT: %ptr.6ff: type = ptr_type %Outer.9d6 [symbolic] +// CHECK:STDOUT: %pattern_type.07e: type = pattern_type %ptr.6ff [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%OuterParam) [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: %Outer.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] @@ -151,9 +158,11 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -222,6 +231,34 @@ fn F() { // CHECK:STDOUT: assoc_const T:! type; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Outer.as.Destroy.impl(@Outer.%OuterParam.loc49_13.2: type) { +// CHECK:STDOUT: %OuterParam: type = bind_symbolic_name OuterParam, 0 [symbolic = %OuterParam (constants.%OuterParam)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%OuterParam) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%OuterParam) [symbolic = %Outer.as.Destroy.impl.Op.type (constants.%Outer.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Outer.9d6 as constants.%Destroy.type { +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.decl: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = fn_decl @Outer.as.Destroy.impl.Op [symbolic = @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.07e) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.07e) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc49_32.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff) = value_param call_param0 +// CHECK:STDOUT: %.loc49_32.2: type = splice_block %Self.ref [symbolic = %Outer (constants.%Outer.9d6)] { +// CHECK:STDOUT: %.loc49_32.3: type = specific_constant constants.%Outer.9d6, @Outer(constants.%OuterParam) [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc49_32.3 [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Outer.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Outer.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.Y.impl: %C.ref as %.loc58_23 { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%Y.impl_witness @@ -258,6 +295,9 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: %H.loc54_8.2: @Outer.G.%Y_where.type (%Y_where.type.324) = bind_symbolic_name H, 1 [symbolic = %H.loc54_8.1 (constants.%H)] // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @Outer.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.decl), @Outer.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Outer.as.Destroy.impl(constants.%OuterParam) [symbolic = @Outer.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -293,6 +333,17 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Outer.as.Destroy.impl.Op(@Outer.%OuterParam.loc49_13.2: type) { +// CHECK:STDOUT: %OuterParam: type = bind_symbolic_name OuterParam, 0 [symbolic = %OuterParam (constants.%OuterParam)] +// CHECK:STDOUT: %Outer: type = class_type @Outer, @Outer(%OuterParam) [symbolic = %Outer (constants.%Outer.9d6)] +// CHECK:STDOUT: %ptr: type = ptr_type %Outer [symbolic = %ptr (constants.%ptr.6ff)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.07e)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.6ff)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Outer.ref: %Outer.type = name_ref Outer, file.%Outer.decl [concrete = constants.%Outer.generic] @@ -346,6 +397,18 @@ fn F() { // CHECK:STDOUT: %pattern_type => constants.%pattern_type.f71 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl(constants.%OuterParam) { +// CHECK:STDOUT: %OuterParam => constants.%OuterParam +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl.Op(constants.%OuterParam) { +// CHECK:STDOUT: %OuterParam => constants.%OuterParam +// CHECK:STDOUT: %Outer => constants.%Outer.9d6 +// CHECK:STDOUT: %ptr => constants.%ptr.6ff +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.07e +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Outer(constants.%empty_tuple.type) { // CHECK:STDOUT: %OuterParam.loc49_13.1 => constants.%empty_tuple.type // CHECK:STDOUT: @@ -414,6 +477,13 @@ fn F() { // CHECK:STDOUT: %C.4b0: type = class_type @C, @C(%OuterParam) [symbolic] // CHECK:STDOUT: %require_complete.1fd: = require_complete_type %Y_where.type.fee [symbolic] // CHECK:STDOUT: %Y.impl_witness.f45: = impl_witness @Outer.%Y.impl_witness_table, @C.as.Y.impl(%OuterParam) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%OuterParam) [symbolic] +// CHECK:STDOUT: %ptr.00b: type = ptr_type %Outer.fea [symbolic] +// CHECK:STDOUT: %pattern_type.f97: type = pattern_type %ptr.00b [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%OuterParam) [symbolic] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: %Outer.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Z1.impl_witness: = impl_witness file.%Z1.impl_witness_table [concrete] @@ -456,10 +526,12 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .BitAndWith = %Core.BitAndWith // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.BitAndWith: %BitAndWith.type.f2e = import_ref Core//prelude, BitAndWith, loaded [concrete = constants.%BitAndWith.generic] // CHECK:STDOUT: %Core.import_ref.012: %type.as.BitAndWith.impl.Op.type = import_ref Core//prelude, loc13_42, loaded [concrete = constants.%type.as.BitAndWith.impl.Op] // CHECK:STDOUT: %BitAndWith.impl_witness_table = impl_witness_table (%Core.import_ref.012), @type.as.BitAndWith.impl [concrete] @@ -563,6 +635,34 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @Outer.as.Destroy.impl(@Outer.%OuterParam.loc6_13.2: %Z1.type) { +// CHECK:STDOUT: %OuterParam: %Z1.type = bind_symbolic_name OuterParam, 0 [symbolic = %OuterParam (constants.%OuterParam)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Outer.%Destroy.impl_witness_table, @Outer.as.Destroy.impl(%OuterParam) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.type: type = fn_type @Outer.as.Destroy.impl.Op, @Outer.as.Destroy.impl(%OuterParam) [symbolic = %Outer.as.Destroy.impl.Op.type (constants.%Outer.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = struct_value () [symbolic = %Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%Outer.fea as constants.%Destroy.type { +// CHECK:STDOUT: %Outer.as.Destroy.impl.Op.decl: @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.type (%Outer.as.Destroy.impl.Op.type) = fn_decl @Outer.as.Destroy.impl.Op [symbolic = @Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op (constants.%Outer.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.f97) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Outer.as.Destroy.impl.Op.%pattern_type (%pattern_type.f97) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6_30.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.00b) = value_param call_param0 +// CHECK:STDOUT: %.loc6_30.2: type = splice_block %Self.ref [symbolic = %Outer (constants.%Outer.fea)] { +// CHECK:STDOUT: %.loc6_30.3: type = specific_constant constants.%Outer.fea, @Outer(constants.%OuterParam) [symbolic = %Outer (constants.%Outer.fea)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc6_30.3 [symbolic = %Outer (constants.%Outer.fea)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Outer.as.Destroy.impl.Op.%ptr (%ptr.00b) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Outer.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Outer.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @empty_tuple.type.as.Z1.impl: %.loc17_7.2 as %Z1.ref { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = file.%Z1.impl_witness @@ -627,6 +727,9 @@ fn F() { // CHECK:STDOUT: %Y.impl_witness_table = impl_witness_table (%impl_witness_assoc_constant), @C.as.Y.impl [concrete] // CHECK:STDOUT: %Y.impl_witness: = impl_witness %Y.impl_witness_table, @C.as.Y.impl(constants.%OuterParam) [symbolic = @C.as.Y.impl.%Y.impl_witness (constants.%Y.impl_witness.f45)] // CHECK:STDOUT: %impl_witness_assoc_constant: type = impl_witness_assoc_constant constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: impl_decl @Outer.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Outer.as.Destroy.impl.%Outer.as.Destroy.impl.Op.decl), @Outer.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @Outer.as.Destroy.impl(constants.%OuterParam) [symbolic = @Outer.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -665,6 +768,17 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Outer.as.Destroy.impl.Op(@Outer.%OuterParam.loc6_13.2: %Z1.type) { +// CHECK:STDOUT: %OuterParam: %Z1.type = bind_symbolic_name OuterParam, 0 [symbolic = %OuterParam (constants.%OuterParam)] +// CHECK:STDOUT: %Outer: type = class_type @Outer, @Outer(%OuterParam) [symbolic = %Outer (constants.%Outer.fea)] +// CHECK:STDOUT: %ptr: type = ptr_type %Outer [symbolic = %ptr (constants.%ptr.00b)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.f97)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Outer.as.Destroy.impl.Op.%ptr (%ptr.00b)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Outer.ref.loc21_3: %Outer.type = name_ref Outer, file.%Outer.decl [concrete = constants.%Outer.generic] @@ -764,6 +878,18 @@ fn F() { // CHECK:STDOUT: %Y.impl_witness => constants.%Y.impl_witness.f45 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl(constants.%OuterParam) { +// CHECK:STDOUT: %OuterParam => constants.%OuterParam +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Outer.as.Destroy.impl.Op(constants.%OuterParam) { +// CHECK:STDOUT: %OuterParam => constants.%OuterParam +// CHECK:STDOUT: %Outer => constants.%Outer.fea +// CHECK:STDOUT: %ptr => constants.%ptr.00b +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.f97 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @Outer(constants.%Z1.facet) { // CHECK:STDOUT: %OuterParam.loc6_13.1 => constants.%Z1.facet // CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/lookup/specialization_with_symbolic_rewrite.carbon b/toolchain/check/testdata/impl/lookup/specialization_with_symbolic_rewrite.carbon index cb2f5c054115..9c0d892e34fb 100644 --- a/toolchain/check/testdata/impl/lookup/specialization_with_symbolic_rewrite.carbon +++ b/toolchain/check/testdata/impl/lookup/specialization_with_symbolic_rewrite.carbon @@ -107,6 +107,13 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: %Z.assoc_type.26e: type = assoc_entity_type @Z, @Z(%T.8b3) [symbolic] // CHECK:STDOUT: %assoc0.1cd: %Z.assoc_type.26e = assoc_entity element0, @Z.%X [symbolic] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %S: type = bind_symbolic_name S, 1 [symbolic] @@ -150,9 +157,11 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -265,6 +274,22 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: assoc_const X:! type; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl @T.as.Z.impl.119(%T.loc9_14.1: type, %S.loc9_24.1: type) { // CHECK:STDOUT: %T.loc9_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc9_14.2 (constants.%T.8b3)] // CHECK:STDOUT: %S.loc9_24.2: type = bind_symbolic_name S, 1 [symbolic = %S.loc9_24.2 (constants.%S)] @@ -303,6 +328,9 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -311,6 +339,8 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc13_6.2: %Z.type.049) { // CHECK:STDOUT: %T.loc13_6.1: %Z.type.049 = bind_symbolic_name T, 0 [symbolic = %T.loc13_6.1 (constants.%T.62d)] // CHECK:STDOUT: %T.as_type.loc13_19.1: type = facet_access_type %T.loc13_6.1 [symbolic = %T.as_type.loc13_19.1 (constants.%T.as_type)] @@ -426,6 +456,13 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: %Y.type: type = facet_type <@Y> [concrete] // CHECK:STDOUT: %Self.b29: %Y.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %S: type = bind_symbolic_name S, 1 [symbolic] @@ -481,10 +518,12 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.492: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.ca0) = import_ref Core//prelude/parts/as, loc12_35, loaded [symbolic = @ImplicitAs.%assoc0 (constants.%assoc0.dc0)] // CHECK:STDOUT: %Core.import_ref.1c7: @ImplicitAs.%ImplicitAs.Convert.type (%ImplicitAs.Convert.type.275) = import_ref Core//prelude/parts/as, loc12_35, loaded [symbolic = @ImplicitAs.%ImplicitAs.Convert (constants.%ImplicitAs.Convert.42e)] @@ -611,6 +650,22 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: assoc_const X:! type; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl @T.as.Z.impl.119(%T.loc10_14.1: type, %S.loc10_24.1: type) { // CHECK:STDOUT: %T.loc10_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc10_14.2 (constants.%T.8b3)] // CHECK:STDOUT: %S.loc10_24.2: type = bind_symbolic_name S, 1 [symbolic = %S.loc10_24.2 (constants.%S)] @@ -649,6 +704,9 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -657,6 +715,8 @@ fn F[T:! Ptr](var t: T) -> T.(Ptr.Type) { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @F(%T.loc14_6.2: %Z.type.049) { // CHECK:STDOUT: %T.loc14_6.1: %Z.type.049 = bind_symbolic_name T, 0 [symbolic = %T.loc14_6.1 (constants.%T.62d)] // CHECK:STDOUT: %T.as_type.loc14_19.1: type = facet_access_type %T.loc14_6.1 [symbolic = %T.as_type.loc14_19.1 (constants.%T.as_type)] diff --git a/toolchain/check/testdata/impl/lookup/transitive.carbon b/toolchain/check/testdata/impl/lookup/transitive.carbon index d8a3d8a81ea6..d412adc1f54e 100644 --- a/toolchain/check/testdata/impl/lookup/transitive.carbon +++ b/toolchain/check/testdata/impl/lookup/transitive.carbon @@ -116,14 +116,21 @@ fn Call() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %I.F.type: type = fn_type @I.F [concrete] // CHECK:STDOUT: %I.F: %I.F.type = struct_value () [concrete] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic] -// CHECK:STDOUT: %pattern_type.6de: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Self.as_type.b70: type = facet_access_type %Self.826 [symbolic] +// CHECK:STDOUT: %pattern_type.6de: type = pattern_type %Self.as_type.b70 [symbolic] // CHECK:STDOUT: %I.impl_witness: = impl_witness file.%I.impl_witness_table [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %C.as.I.impl.F.type: type = fn_type @C.as.I.impl.F [concrete] @@ -134,13 +141,15 @@ fn Call() { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Main.I: type = import_ref Main//i, I, loaded [concrete = constants.%I.type] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Main.import_ref.e5d = import_ref Main//i, inst19 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.507 = import_ref Main//i, loc4_33, unloaded // CHECK:STDOUT: %Main.F: %I.F.type = import_ref Main//i, F, loaded [concrete = constants.%I.F] -// CHECK:STDOUT: %Main.import_ref.5dd: %I.type = import_ref Main//i, inst19 [no loc], loaded [symbolic = constants.%Self] +// CHECK:STDOUT: %Main.import_ref.5dd: %I.type = import_ref Main//i, inst19 [no loc], loaded [symbolic = constants.%Self.826] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -167,6 +176,22 @@ fn Call() { // CHECK:STDOUT: witness = (imports.%Main.F) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.I.impl: %C.ref as %I.ref { // CHECK:STDOUT: %C.as.I.impl.F.decl: %C.as.I.impl.F.type = fn_decl @C.as.I.impl.F [concrete = constants.%C.as.I.impl.F] { // CHECK:STDOUT: %self.patt: %pattern_type.c48 = binding_pattern self [concrete] @@ -183,6 +208,9 @@ fn Call() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -191,9 +219,11 @@ fn Call() { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @I.F(imports.%Main.import_ref.5dd: %I.type) [from "i.carbon"] { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type)] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.826)] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic = %Self.as_type (constants.%Self.as_type.b70)] // CHECK:STDOUT: %pattern_type: type = pattern_type %Self.as_type [symbolic = %pattern_type (constants.%pattern_type.6de)] // CHECK:STDOUT: // CHECK:STDOUT: fn; @@ -204,9 +234,9 @@ fn Call() { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @I.F(constants.%Self) { -// CHECK:STDOUT: %Self => constants.%Self -// CHECK:STDOUT: %Self.as_type => constants.%Self.as_type +// CHECK:STDOUT: specific @I.F(constants.%Self.826) { +// CHECK:STDOUT: %Self => constants.%Self.826 +// CHECK:STDOUT: %Self.as_type => constants.%Self.as_type.b70 // CHECK:STDOUT: %pattern_type => constants.%pattern_type.6de // CHECK:STDOUT: } // CHECK:STDOUT: @@ -274,7 +304,7 @@ fn Call() { // CHECK:STDOUT: %Get: %Get.type = struct_value () [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] // CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I [concrete] @@ -283,46 +313,51 @@ fn Call() { // CHECK:STDOUT: %I.F: %I.F.type = struct_value () [concrete] // CHECK:STDOUT: %Self.as_type.b70: type = facet_access_type %Self.826 [symbolic] // CHECK:STDOUT: %pattern_type.6de: type = pattern_type %Self.as_type.b70 [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness imports.%I.impl_witness_table [concrete] // CHECK:STDOUT: %I.facet: %I.type = facet_value %C, (%I.impl_witness) [concrete] // CHECK:STDOUT: %.1b3: type = fn_type_with_self_type %I.F.type, %I.facet [concrete] // CHECK:STDOUT: %C.as.I.impl.F.type: type = fn_type @C.as.I.impl.F [concrete] // CHECK:STDOUT: %C.as.I.impl.F: %C.as.I.impl.F.type = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.0cc: = impl_witness imports.%Destroy.impl_witness_table.170 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Main.Get: %Get.type = import_ref Main//get, Get, loaded [concrete = constants.%Get] // CHECK:STDOUT: %Main.I: type = import_ref Main//i, I, loaded [concrete = constants.%I.type] -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: %Core.ece: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Main.import_ref.8db: = import_ref Main//get, inst23 [indirect], loaded [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %Main.import_ref.8db: = import_ref Main//get, inst23 [indirect], loaded [concrete = constants.%complete_type] // CHECK:STDOUT: %Main.import_ref.6a9 = import_ref Main//get, inst24 [indirect], unloaded // CHECK:STDOUT: %Main.import_ref.e5d = import_ref Main//i, inst19 [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.c44: %I.assoc_type = import_ref Main//i, loc4_33, loaded [concrete = constants.%assoc0.3f3] // CHECK:STDOUT: %Main.F = import_ref Main//i, F, unloaded // CHECK:STDOUT: %Main.import_ref.e03: %I.F.type = import_ref Main//i, loc4_33, loaded [concrete = constants.%I.F] // CHECK:STDOUT: %Main.import_ref.5dd: %I.type = import_ref Main//i, inst19 [no loc], loaded [symbolic = constants.%Self.826] +// CHECK:STDOUT: %Main.import_ref.4c7: = import_ref Main//c, loc6_9, loaded [concrete = constants.%Destroy.impl_witness.0cc] +// CHECK:STDOUT: %Main.import_ref.c0c: type = import_ref Main//c, inst20 [no loc], loaded [concrete = constants.%C] +// CHECK:STDOUT: %Main.import_ref.cb9: type = import_ref Main//c, inst23 [no loc], loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Main.import_ref.f0d: = import_ref Main//c, loc7_13, loaded [concrete = constants.%I.impl_witness] // CHECK:STDOUT: %Main.import_ref.29a: type = import_ref Main//c, loc7_6, loaded [concrete = constants.%C] // CHECK:STDOUT: %Main.import_ref.f50: type = import_ref Main//c, loc7_11, loaded [concrete = constants.%I.type] // CHECK:STDOUT: %Main.import_ref.742: %C.as.I.impl.F.type = import_ref Main//c, loc7_34, loaded [concrete = constants.%C.as.I.impl.F] // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (%Main.import_ref.742), @C.as.I.impl [concrete] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Main.import_ref.2e8: %C.as.Destroy.impl.Op.type = import_ref Main//c, loc6_9, loaded [concrete = constants.%C.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.170 = impl_witness_table (%Main.import_ref.2e8), @C.as.Destroy.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { // CHECK:STDOUT: package: = namespace [concrete] { // CHECK:STDOUT: .Get = imports.%Main.Get // CHECK:STDOUT: .I = imports.%Main.I -// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Core = imports.%Core.ece // CHECK:STDOUT: .Call = %Call.decl // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core @@ -337,6 +372,11 @@ fn Call() { // CHECK:STDOUT: witness = (imports.%Main.F) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: imports.%Main.import_ref.c0c as imports.%Main.import_ref.cb9 [from "c.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Main.import_ref.4c7 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.I.impl: imports.%Main.import_ref.29a as imports.%Main.import_ref.f50 [from "c.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%Main.import_ref.f0d @@ -357,15 +397,13 @@ fn Call() { // CHECK:STDOUT: %I.ref: type = name_ref I, imports.%Main.I [concrete = constants.%I.type] // CHECK:STDOUT: %F.ref: %I.assoc_type = name_ref F, imports.%Main.import_ref.c44 [concrete = constants.%assoc0.3f3] // CHECK:STDOUT: %impl.elem0: %.1b3 = impl_witness_access constants.%I.impl_witness, element0 [concrete = constants.%C.as.I.impl.F] -// CHECK:STDOUT: %bound_method.loc9_8: = bound_method %Get.call, %impl.elem0 +// CHECK:STDOUT: %bound_method: = bound_method %Get.call, %impl.elem0 // CHECK:STDOUT: %.loc9_7.2: ref %C = temporary %.loc9_7.1, %Get.call // CHECK:STDOUT: %.loc9_7.3: %C = bind_value %.loc9_7.2 -// CHECK:STDOUT: %C.as.I.impl.F.call: init %empty_tuple.type = call %bound_method.loc9_8(%.loc9_7.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc9_7.1, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc9_7: = bound_method %.loc9_7.1, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.I.impl.F.call: init %empty_tuple.type = call %bound_method(%.loc9_7.3) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc9_7.1, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.019 = addr_of %.loc9_7.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc9_7(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -381,6 +419,8 @@ fn Call() { // CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.I.impl.F [from "c.carbon"]; // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op = "no_op" [from "c.carbon"]; +// CHECK:STDOUT: // CHECK:STDOUT: specific @I.F(constants.%Self.826) { // CHECK:STDOUT: %Self => constants.%Self.826 // CHECK:STDOUT: %Self.as_type => constants.%Self.as_type.b70 diff --git a/toolchain/check/testdata/impl/redeclaration.carbon b/toolchain/check/testdata/impl/redeclaration.carbon index ce881fc167c1..ae3138c76ce9 100644 --- a/toolchain/check/testdata/impl/redeclaration.carbon +++ b/toolchain/check/testdata/impl/redeclaration.carbon @@ -26,13 +26,20 @@ impl i32 as I {} // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness file.%I.impl_witness_table [concrete] // CHECK:STDOUT: %X: type = class_type @X [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @X.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete] +// CHECK:STDOUT: %pattern_type.1c6: type = pattern_type %ptr.d17 [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op.type: type = fn_type @X.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op: %X.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } @@ -40,10 +47,12 @@ impl i32 as I {} // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -70,7 +79,7 @@ impl i32 as I {} // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I { -// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826] // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = %Self @@ -82,12 +91,31 @@ impl i32 as I {} // CHECK:STDOUT: witness = file.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @X.as.Destroy.impl: constants.%X as constants.%Destroy.type { +// CHECK:STDOUT: %X.as.Destroy.impl.Op.decl: %X.as.Destroy.impl.Op.type = fn_decl @X.as.Destroy.impl.Op [concrete = constants.%X.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1c6 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1c6 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc19: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.d17 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%X [concrete = constants.%X] +// CHECK:STDOUT: %self: %ptr.d17 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %X.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @X.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @X { // CHECK:STDOUT: impl_decl @i32.as.I.impl [concrete] {} { // CHECK:STDOUT: %int_32.loc20: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc20: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %I.ref.loc20: type = name_ref I, file.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @X.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@X.as.Destroy.impl.%X.as.Destroy.impl.Op.decl), @X.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -97,3 +125,5 @@ impl i32 as I {} // CHECK:STDOUT: .I = // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @X.as.Destroy.impl.Op(%self.param: %ptr.d17) = "no_op"; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/impl/use_assoc_const.carbon b/toolchain/check/testdata/impl/use_assoc_const.carbon index 22037aa12131..fefb127c2520 100644 --- a/toolchain/check/testdata/impl/use_assoc_const.carbon +++ b/toolchain/check/testdata/impl/use_assoc_const.carbon @@ -321,6 +321,8 @@ fn F() { // CHECK:STDOUT: %J.facet.ecc: %J.type = facet_value %empty_tuple.type, (%J.impl_witness.e42) [concrete] // CHECK:STDOUT: %Negate.type: type = facet_type <@Negate> [concrete] // CHECK:STDOUT: %Negate.Op.type: type = fn_type @Negate.Op [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] @@ -351,6 +353,11 @@ fn F() { // CHECK:STDOUT: %int_40.518: %i32 = int_value 40 [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %J_where.type.0bc: type = facet_type <@J where %impl.elem0.83f = %C> [concrete] // CHECK:STDOUT: %J.impl_witness.12d: = impl_witness file.%J.impl_witness_table.loc21 [concrete] @@ -365,6 +372,7 @@ fn F() { // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .Negate = %Core.Negate // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -376,6 +384,7 @@ fn F() { // CHECK:STDOUT: %Core.import_ref.ff2: @Int.as.Negate.impl.%Int.as.Negate.impl.Op.type (%Int.as.Negate.impl.Op.type.fc5) = import_ref Core//prelude/parts/int, loc36_31, loaded [symbolic = @Int.as.Negate.impl.%Int.as.Negate.impl.Op (constants.%Int.as.Negate.impl.Op.8d0)] // CHECK:STDOUT: %Negate.impl_witness_table = impl_witness_table (%Core.import_ref.5f5, %Core.import_ref.ff2), @Int.as.Negate.impl [concrete] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -516,6 +525,22 @@ fn F() { // CHECK:STDOUT: witness = file.%J.impl_witness.loc8 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc16: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.J.impl: %C.ref.loc21_6 as %.loc21_13 { // CHECK:STDOUT: %C.as.J.impl.F.decl: %C.as.J.impl.F.type = fn_decl @C.as.J.impl.F [concrete = constants.%C.as.J.impl.F] { // CHECK:STDOUT: %self.patt: %pattern_type.c48 = binding_pattern self [concrete] @@ -546,6 +571,9 @@ fn F() { // CHECK:STDOUT: %.loc18_10: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc18_11: type = converted %.loc18_10, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: adapt_decl %.loc18_11 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -598,6 +626,8 @@ fn F() { // CHECK:STDOUT: return %.loc13_21.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.J.impl.F(%self.param: %C, %u.param: %C) -> %C { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %self.ref: %C = name_ref self, %self @@ -653,6 +683,13 @@ fn F() { // CHECK:STDOUT: %J.F: %J.F.type = struct_value () [concrete] // CHECK:STDOUT: %assoc1.572: %J.assoc_type = assoc_entity element1, @J.%J.F.decl [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %.Self.968: %J.type = bind_symbolic_name .Self [symbolic_self] @@ -705,12 +742,14 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .Negate = %Core.Negate // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.Negate: type = import_ref Core//prelude/parts/int_literal, Negate, loaded [concrete = constants.%Negate.type] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] @@ -795,6 +834,22 @@ fn F() { // CHECK:STDOUT: assoc_const U:! type; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @D.as.J.impl: %D.ref as %.loc10_13 { // CHECK:STDOUT: %D.as.J.impl.F.decl: %D.as.J.impl.F.type = fn_decl @D.as.J.impl.F [concrete = constants.%D.as.J.impl.F] { // CHECK:STDOUT: %u.patt: %pattern_type.7ce = binding_pattern u [concrete] @@ -820,6 +875,9 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -837,6 +895,8 @@ fn F() { // CHECK:STDOUT: fn(%u.param: @J.F.%impl.elem0.loc5_11.1 (%impl.elem0.11f)) -> @J.F.%impl.elem0.loc5_11.1 (%impl.elem0.11f); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @D.as.J.impl.F(%u.param: %i32) -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %u.ref: %i32 = name_ref u, %u @@ -931,6 +991,13 @@ fn F() { // CHECK:STDOUT: %E.as.J.impl.G.type: type = fn_type @E.as.J.impl.G [concrete] // CHECK:STDOUT: %E.as.J.impl.G: %E.as.J.impl.G.type = struct_value () [concrete] // CHECK:STDOUT: %J.facet.ee5: %J.type = facet_value %E, (%J.impl_witness) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.c1f: = impl_witness @E.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.742: type = ptr_type %E [concrete] +// CHECK:STDOUT: %pattern_type.88c: type = pattern_type %ptr.742 [concrete] +// CHECK:STDOUT: %E.as.Destroy.impl.Op.type: type = fn_type @E.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %E.as.Destroy.impl.Op: %E.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete] @@ -1005,12 +1072,14 @@ fn F() { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Negate = %Core.Negate // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Negate: type = import_ref Core//prelude/parts/int_literal, Negate, loaded [concrete = constants.%Negate.type] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] @@ -1201,6 +1270,22 @@ fn F() { // CHECK:STDOUT: witness = @E.%J.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @E.as.Destroy.impl: constants.%E as constants.%Destroy.type { +// CHECK:STDOUT: %E.as.Destroy.impl.Op.decl: %E.as.Destroy.impl.Op.type = fn_decl @E.as.Destroy.impl.Op [concrete = constants.%E.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.88c = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.88c = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.742 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%E [concrete = constants.%E] +// CHECK:STDOUT: %self: %ptr.742 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %E.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @E.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @E { // CHECK:STDOUT: impl_decl @E.as.J.impl [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%E [concrete = constants.%E] @@ -1220,6 +1305,9 @@ fn F() { // CHECK:STDOUT: %J.impl_witness_table = impl_witness_table (%impl_witness_assoc_constant, @E.as.J.impl.%E.as.J.impl.F.decl, @E.as.J.impl.%E.as.J.impl.G.decl), @E.as.J.impl [concrete] // CHECK:STDOUT: %J.impl_witness: = impl_witness %J.impl_witness_table [concrete = constants.%J.impl_witness] // CHECK:STDOUT: %impl_witness_assoc_constant: type = impl_witness_assoc_constant constants.%i32 [concrete = constants.%i32] +// CHECK:STDOUT: impl_decl @E.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@E.as.Destroy.impl.%E.as.Destroy.impl.Op.decl), @E.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.c1f] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1278,6 +1366,8 @@ fn F() { // CHECK:STDOUT: return %.loc15_16.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @E.as.Destroy.impl.Op(%self.param: %ptr.742) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @CallBoth(%e.param: %E) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -2295,6 +2385,13 @@ fn F() { // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %E.as.J.impl.F.type.b842fd.2: type = fn_type @E.as.J.impl.F.loc24_21.2 [concrete] // CHECK:STDOUT: %E.as.J.impl.F.b07d12.2: %E.as.J.impl.F.type.b842fd.2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @E.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.742: type = ptr_type %E [concrete] +// CHECK:STDOUT: %pattern_type.88c: type = pattern_type %ptr.742 [concrete] +// CHECK:STDOUT: %E.as.Destroy.impl.Op.type: type = fn_type @E.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %E.as.Destroy.impl.Op: %E.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } @@ -2303,11 +2400,13 @@ fn F() { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -2392,6 +2491,22 @@ fn F() { // CHECK:STDOUT: witness = @E.%J.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @E.as.Destroy.impl: constants.%E as constants.%Destroy.type { +// CHECK:STDOUT: %E.as.Destroy.impl.Op.decl: %E.as.Destroy.impl.Op.type = fn_decl @E.as.Destroy.impl.Op [concrete = constants.%E.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.88c = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.88c = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.742 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%E [concrete = constants.%E] +// CHECK:STDOUT: %self: %ptr.742 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %E.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @E.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @E { // CHECK:STDOUT: impl_decl @E.as.J.impl [concrete] {} { // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%E [concrete = constants.%E] @@ -2411,6 +2526,9 @@ fn F() { // CHECK:STDOUT: %J.impl_witness_table = impl_witness_table (%impl_witness_assoc_constant, @E.as.J.impl.%E.as.J.impl.F.decl.loc24_21.2), @E.as.J.impl [concrete] // CHECK:STDOUT: %J.impl_witness: = impl_witness %J.impl_witness_table [concrete = constants.%J.impl_witness] // CHECK:STDOUT: %impl_witness_assoc_constant: type = impl_witness_assoc_constant constants.%i32 [concrete = constants.%i32] +// CHECK:STDOUT: impl_decl @E.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@E.as.Destroy.impl.%E.as.Destroy.impl.Op.decl), @E.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -2446,6 +2564,8 @@ fn F() { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @E.as.Destroy.impl.Op(%self.param: %ptr.742) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @U(constants.%Self.ccd) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @U(constants.%J.facet.521) {} @@ -2470,11 +2590,11 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %J2.type: type = facet_type <@J2> [concrete] -// CHECK:STDOUT: %Self: %J2.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.541: %J2.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %J2.assoc_type: type = assoc_entity_type @J2 [concrete] // CHECK:STDOUT: %assoc0: %J2.assoc_type = assoc_entity element0, @J2.%U2 [concrete] -// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self [symbolic] -// CHECK:STDOUT: %pattern_type.969: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %Self.as_type.f5c: type = facet_access_type %Self.541 [symbolic] +// CHECK:STDOUT: %pattern_type.969: type = pattern_type %Self.as_type.f5c [symbolic] // CHECK:STDOUT: %J2.F.type: type = fn_type @J2.F [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %J2.F: %J2.F.type = struct_value () [concrete] @@ -2495,6 +2615,13 @@ fn F() { // CHECK:STDOUT: %empty_tuple.type.as.J2.impl.F.type.f405c5.2: type = fn_type @empty_tuple.type.as.J2.impl.F.loc30_33.2 [concrete] // CHECK:STDOUT: %empty_tuple.type.as.J2.impl.F.214a71.2: %empty_tuple.type.as.J2.impl.F.type.f405c5.2 = struct_value () [concrete] // CHECK:STDOUT: %C2: type = class_type @C2 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C2.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.0d6: type = ptr_type %C2 [concrete] +// CHECK:STDOUT: %pattern_type.191: type = pattern_type %ptr.0d6 [concrete] +// CHECK:STDOUT: %C2.as.Destroy.impl.Op.type: type = fn_type @C2.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C2.as.Destroy.impl.Op: %C2.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %J2_where.type.df9: type = facet_type <@J2 where %impl.elem0 = %C2> [concrete] // CHECK:STDOUT: %J2.impl_witness.267: = impl_witness file.%J2.impl_witness_table.loc38 [concrete] @@ -2508,9 +2635,11 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -2561,7 +2690,7 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @J2 { -// CHECK:STDOUT: %Self: %J2.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %J2.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.541] // CHECK:STDOUT: %U2: type = assoc_const_decl @U2 [concrete] { // CHECK:STDOUT: %assoc0: %J2.assoc_type = assoc_entity element0, @J2.%U2 [concrete = constants.%assoc0] // CHECK:STDOUT: } @@ -2573,16 +2702,16 @@ fn F() { // CHECK:STDOUT: %return.patt: = return_slot_pattern [concrete] // CHECK:STDOUT: %return.param_patt: = out_param_pattern %return.patt, call_param2 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %Self.ref.loc19_35: %J2.type = name_ref Self, @J2.%Self [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %self.param: @J2.F.%Self.as_type.loc19_14.1 (%Self.as_type) = value_param call_param0 -// CHECK:STDOUT: %.loc19_14.1: type = splice_block %.loc19_14.2 [symbolic = %Self.as_type.loc19_14.1 (constants.%Self.as_type)] { -// CHECK:STDOUT: %Self.ref.loc19_14: %J2.type = name_ref Self, @J2.%Self [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.as_type.loc19_14.2: type = facet_access_type %Self.ref.loc19_14 [symbolic = %Self.as_type.loc19_14.1 (constants.%Self.as_type)] -// CHECK:STDOUT: %.loc19_14.2: type = converted %Self.ref.loc19_14, %Self.as_type.loc19_14.2 [symbolic = %Self.as_type.loc19_14.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self.ref.loc19_35: %J2.type = name_ref Self, @J2.%Self [symbolic = %Self (constants.%Self.541)] +// CHECK:STDOUT: %self.param: @J2.F.%Self.as_type.loc19_14.1 (%Self.as_type.f5c) = value_param call_param0 +// CHECK:STDOUT: %.loc19_14.1: type = splice_block %.loc19_14.2 [symbolic = %Self.as_type.loc19_14.1 (constants.%Self.as_type.f5c)] { +// CHECK:STDOUT: %Self.ref.loc19_14: %J2.type = name_ref Self, @J2.%Self [symbolic = %Self (constants.%Self.541)] +// CHECK:STDOUT: %Self.as_type.loc19_14.2: type = facet_access_type %Self.ref.loc19_14 [symbolic = %Self.as_type.loc19_14.1 (constants.%Self.as_type.f5c)] +// CHECK:STDOUT: %.loc19_14.2: type = converted %Self.ref.loc19_14, %Self.as_type.loc19_14.2 [symbolic = %Self.as_type.loc19_14.1 (constants.%Self.as_type.f5c)] // CHECK:STDOUT: } -// CHECK:STDOUT: %self: @J2.F.%Self.as_type.loc19_14.1 (%Self.as_type) = bind_name self, %self.param +// CHECK:STDOUT: %self: @J2.F.%Self.as_type.loc19_14.1 (%Self.as_type.f5c) = bind_name self, %self.param // CHECK:STDOUT: %z.param: = value_param call_param1 -// CHECK:STDOUT: %Self.ref.loc19_23: %J2.type = name_ref Self, @J2.%Self [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.ref.loc19_23: %J2.type = name_ref Self, @J2.%Self [symbolic = %Self (constants.%Self.541)] // CHECK:STDOUT: %z: = bind_name z, %z.param // CHECK:STDOUT: %return.param: ref = out_param call_param2 // CHECK:STDOUT: %return: ref = return_slot %return.param @@ -2642,6 +2771,22 @@ fn F() { // CHECK:STDOUT: witness = file.%J2.impl_witness.loc22 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C2.as.Destroy.impl: constants.%C2 as constants.%Destroy.type { +// CHECK:STDOUT: %C2.as.Destroy.impl.Op.decl: %C2.as.Destroy.impl.Op.type = fn_decl @C2.as.Destroy.impl.Op [concrete = constants.%C2.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.191 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.191 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc33: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.0d6 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C2 [concrete = constants.%C2] +// CHECK:STDOUT: %self: %ptr.0d6 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C2.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C2.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C2.as.J2.impl: %C2.ref.loc38_6 as %.loc38_15 { // CHECK:STDOUT: %C2.as.J2.impl.F.decl.loc39_33.1: %C2.as.J2.impl.F.type.05d6a0.1 = fn_decl @C2.as.J2.impl.F.loc39_33.1 [concrete = constants.%C2.as.J2.impl.F.bfa759.1] { // CHECK:STDOUT: %self.patt: %pattern_type.838 = binding_pattern self [concrete] @@ -2685,6 +2830,9 @@ fn F() { // CHECK:STDOUT: %.loc35_10: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc35_11: type = converted %.loc35_10, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: adapt_decl %.loc35_11 [concrete] +// CHECK:STDOUT: impl_decl @C2.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C2.as.Destroy.impl.%C2.as.Destroy.impl.Op.decl), @C2.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: @@ -2693,11 +2841,11 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @J2.F(@J2.%Self: %J2.type) { -// CHECK:STDOUT: %Self: %J2.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] -// CHECK:STDOUT: %Self.as_type.loc19_14.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc19_14.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %Self: %J2.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.541)] +// CHECK:STDOUT: %Self.as_type.loc19_14.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc19_14.1 (constants.%Self.as_type.f5c)] // CHECK:STDOUT: %pattern_type: type = pattern_type %Self.as_type.loc19_14.1 [symbolic = %pattern_type (constants.%pattern_type.969)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%self.param: @J2.F.%Self.as_type.loc19_14.1 (%Self.as_type), %z.param: ) -> ; +// CHECK:STDOUT: fn(%self.param: @J2.F.%Self.as_type.loc19_14.1 (%Self.as_type.f5c), %z.param: ) -> ; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @empty_tuple.type.as.J2.impl.F.loc30_33.1(%self.param: %empty_tuple.type, %z.param: %empty_struct_type) -> %empty_struct_type { @@ -2715,6 +2863,8 @@ fn F() { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C2.as.Destroy.impl.Op(%self.param: %ptr.0d6) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C2.as.J2.impl.F.loc39_33.1(%self.param: %C2, %z.param: %C2) -> %C2 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %self.ref: %C2 = name_ref self, %self @@ -2732,11 +2882,11 @@ fn F() { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @U2(constants.%Self) {} +// CHECK:STDOUT: specific @U2(constants.%Self.541) {} // CHECK:STDOUT: -// CHECK:STDOUT: specific @J2.F(constants.%Self) { -// CHECK:STDOUT: %Self => constants.%Self -// CHECK:STDOUT: %Self.as_type.loc19_14.1 => constants.%Self.as_type +// CHECK:STDOUT: specific @J2.F(constants.%Self.541) { +// CHECK:STDOUT: %Self => constants.%Self.541 +// CHECK:STDOUT: %Self.as_type.loc19_14.1 => constants.%Self.as_type.f5c // CHECK:STDOUT: %pattern_type => constants.%pattern_type.969 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -3109,15 +3259,22 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic] -// CHECK:STDOUT: %pattern_type: type = pattern_type type [concrete] +// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.f2e: type = class_type @C, @C(%T) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %M.type: type = facet_type <@M> [concrete] -// CHECK:STDOUT: %Self: %M.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.bcc: %M.type = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %struct_type.b.86f: type = struct_type {.b: type} [concrete] // CHECK:STDOUT: %M.assoc_type: type = assoc_entity_type @M [concrete] // CHECK:STDOUT: %assoc0: %M.assoc_type = assoc_entity element0, @M.%Z [concrete] @@ -3149,9 +3306,11 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -3162,7 +3321,7 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %C.decl: %C.type = class_decl @C [concrete = constants.%C.generic] { -// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.loc3_9.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc3_9.1 (constants.%T)] // CHECK:STDOUT: } @@ -3218,13 +3377,13 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @M { -// CHECK:STDOUT: %Self: %M.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %M.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.bcc] // CHECK:STDOUT: %Z: %struct_type.b.86f = assoc_const_decl @Z [concrete] { // CHECK:STDOUT: %assoc0: %M.assoc_type = assoc_entity element0, @M.%Z [concrete = constants.%assoc0] // CHECK:STDOUT: } // CHECK:STDOUT: %M.G.decl: %M.G.type = fn_decl @M.G [concrete = constants.%M.G] { -// CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern [concrete] -// CHECK:STDOUT: %return.param_patt: %pattern_type = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.98f = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.98f = out_param_pattern %return.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %return.param: ref type = out_param call_param0 // CHECK:STDOUT: %return: ref type = return_slot %return.param @@ -3242,10 +3401,38 @@ fn F() { // CHECK:STDOUT: assoc_const Z:! %struct_type.b.86f; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc3_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f2e as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc3_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc3_19.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.f2e)] { +// CHECK:STDOUT: %.loc3_19.3: type = specific_constant constants.%C.f2e, @C(constants.%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc3_19.3 [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.M.impl.8b4: %C as %.loc10_17 { // CHECK:STDOUT: %C.as.M.impl.G.decl: %C.as.M.impl.G.type.d92 = fn_decl @C.as.M.impl.G.loc11 [concrete = constants.%C.as.M.impl.G.eac] { -// CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern [concrete] -// CHECK:STDOUT: %return.param_patt: %pattern_type = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.98f = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.98f = out_param_pattern %return.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %return.param: ref type = out_param call_param0 // CHECK:STDOUT: %return: ref type = return_slot %return.param @@ -3259,8 +3446,8 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.M.impl.d97: %C as %.loc16_17 { // CHECK:STDOUT: %C.as.M.impl.G.decl: %C.as.M.impl.G.type.b29 = fn_decl @C.as.M.impl.G.loc17 [concrete = constants.%C.as.M.impl.G.f3b] { -// CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern [concrete] -// CHECK:STDOUT: %return.param_patt: %pattern_type = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.98f = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.98f = out_param_pattern %return.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %return.param: ref type = out_param call_param0 // CHECK:STDOUT: %return: ref type = return_slot %return.param @@ -3278,6 +3465,9 @@ fn F() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -3287,6 +3477,17 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc3_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @M.G(@M.%Self: %M.type) { // CHECK:STDOUT: fn() -> type; // CHECK:STDOUT: } @@ -3323,9 +3524,21 @@ fn F() { // CHECK:STDOUT: %T.loc3_9.1 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @Z(constants.%Self) {} +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @M.G(constants.%Self) {} +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.f2e +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Z(constants.%Self.bcc) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @M.G(constants.%Self.bcc) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%empty_struct_type) { // CHECK:STDOUT: %T.loc3_9.1 => constants.%empty_struct_type @@ -3621,9 +3834,21 @@ fn F() { // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.f2e: type = class_type @C, @C(%T) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.a08: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %ptr.7d2: type = ptr_type %C.f2e [symbolic] +// CHECK:STDOUT: %pattern_type.1d2: type = pattern_type %ptr.7d2 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %.Self: %Z.type = bind_symbolic_name .Self [symbolic_self] // CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self] // CHECK:STDOUT: %Z.lookup_impl_witness: = lookup_impl_witness %.Self, @Z [symbolic_self] @@ -3641,7 +3866,7 @@ fn F() { // CHECK:STDOUT: %Z.facet.f2a: %Z.type = facet_value %D, (%Z.impl_witness.19e) [concrete] // CHECK:STDOUT: %pattern_type.7f8: type = pattern_type %C.131 [concrete] // CHECK:STDOUT: %C.val: %C.131 = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d44: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%D) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.b84: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.131) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e16: %T.as.Destroy.impl.Op.type.b84 = struct_value () [concrete] // CHECK:STDOUT: %ptr.aaa: type = ptr_type %C.131 [concrete] @@ -3714,6 +3939,50 @@ fn F() { // CHECK:STDOUT: assoc_const X:! type; // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%T.loc6_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%T) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%T) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.f2e as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.1d2) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6_19.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = value_param call_param0 +// CHECK:STDOUT: %.loc6_19.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.f2e)] { +// CHECK:STDOUT: %.loc6_19.3: type = specific_constant constants.%C.f2e, @C(constants.%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc6_19.3 [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl @T.as.Z.impl(%T.loc9_14.1: type) { // CHECK:STDOUT: %T.loc9_14.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc9_14.2 (constants.%T)] // CHECK:STDOUT: %C.loc9_45.2: type = class_type @C, @C(%T.loc9_14.2) [symbolic = %C.loc9_45.2 (constants.%C.f2e)] @@ -3735,6 +4004,9 @@ fn F() { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%T) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.a08)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -3745,6 +4017,9 @@ fn F() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -3753,6 +4028,19 @@ fn F() { // CHECK:STDOUT: .Self = constants.%D // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%T.loc6_9.2: type) { +// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic = %T (constants.%T)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%T) [symbolic = %C (constants.%C.f2e)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.7d2)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.1d2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.7d2)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -3790,6 +4078,18 @@ fn F() { // CHECK:STDOUT: %T.loc6_9.1 => constants.%T // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.a08 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%T) { +// CHECK:STDOUT: %T => constants.%T +// CHECK:STDOUT: %C => constants.%C.f2e +// CHECK:STDOUT: %ptr => constants.%ptr.7d2 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.1d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @X(constants.%Z.facet.2a2) {} // CHECK:STDOUT: // CHECK:STDOUT: specific @T.as.Z.impl(constants.%T) { @@ -3818,3 +4118,8 @@ fn F() { // CHECK:STDOUT: // CHECK:STDOUT: specific @X(constants.%Z.facet.f2a) {} // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%D) { +// CHECK:STDOUT: %T => constants.%D +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.d44 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/index/expr_category.carbon b/toolchain/check/testdata/index/expr_category.carbon index 3bd61edb9ba5..e6a26eede54a 100644 --- a/toolchain/check/testdata/index/expr_category.carbon +++ b/toolchain/check/testdata/index/expr_category.carbon @@ -56,6 +56,7 @@ fn ValueBinding(b: array(i32, 3)) { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -84,7 +85,6 @@ fn ValueBinding(b: array(i32, 3)) { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.ac3: = bound_method %int_4.0c1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.1da: = bound_method %int_4.0c1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_4.940: %i32 = int_value 4 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.ba2: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%ptr.235) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.649: %T.as.Destroy.impl.Op.type.ba2 = struct_value () [concrete] // CHECK:STDOUT: %ptr.5d5: type = ptr_type %ptr.235 [concrete] diff --git a/toolchain/check/testdata/index/fail_expr_category.carbon b/toolchain/check/testdata/index/fail_expr_category.carbon index 51c54ef3dd55..476f03907ab1 100644 --- a/toolchain/check/testdata/index/fail_expr_category.carbon +++ b/toolchain/check/testdata/index/fail_expr_category.carbon @@ -64,6 +64,7 @@ fn G(b: array(i32, 3)) { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -80,7 +81,6 @@ fn G(b: array(i32, 3)) { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.ac3: = bound_method %int_4.0c1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.1da: = bound_method %int_4.0c1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_4.940: %i32 = int_value 4 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.1e4: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%array_type) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.f0b: %T.as.Destroy.impl.Op.type.1e4 = struct_value () [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.c51: = specific_function %T.as.Destroy.impl.Op.f0b, @T.as.Destroy.impl.Op(%array_type) [concrete] diff --git a/toolchain/check/testdata/interface/compound_member_access.carbon b/toolchain/check/testdata/interface/compound_member_access.carbon index 61fd653bb5ac..f108cc0791f7 100644 --- a/toolchain/check/testdata/interface/compound_member_access.carbon +++ b/toolchain/check/testdata/interface/compound_member_access.carbon @@ -1210,8 +1210,15 @@ fn Works() { // CHECK:STDOUT: %A.assoc_type: type = assoc_entity_type @A [concrete] // CHECK:STDOUT: %assoc0.d52: %A.assoc_type = assoc_entity element0, @A.%A.G.decl [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %A.impl_witness: = impl_witness file.%A.impl_witness_table [concrete] // CHECK:STDOUT: %C.as.A.impl.G.type: type = fn_type @C.as.A.impl.G [concrete] // CHECK:STDOUT: %C.as.A.impl.G: %C.as.A.impl.G.type = struct_value () [concrete] @@ -1231,26 +1238,21 @@ fn Works() { // CHECK:STDOUT: %type.as.BitAndWith.impl.Op.bound: = bound_method %A.type, %type.as.BitAndWith.impl.Op [concrete] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .BitAndWith = %Core.BitAndWith // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs -// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.BitAndWith: %BitAndWith.type.f2e = import_ref Core//prelude, BitAndWith, loaded [concrete = constants.%BitAndWith.generic] // CHECK:STDOUT: %Core.import_ref.012: %type.as.BitAndWith.impl.Op.type = import_ref Core//prelude, loc13_42, loaded [concrete = constants.%type.as.BitAndWith.impl.Op] // CHECK:STDOUT: %BitAndWith.impl_witness_table = impl_witness_table (%Core.import_ref.012), @type.as.BitAndWith.impl [concrete] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -1283,6 +1285,22 @@ fn Works() { // CHECK:STDOUT: witness = (%A.G.decl) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.A.impl: %C.ref as %A.ref { // CHECK:STDOUT: %C.as.A.impl.G.decl: %C.as.A.impl.G.type = fn_decl @C.as.A.impl.G [concrete = constants.%C.as.A.impl.G] {} {} // CHECK:STDOUT: @@ -1292,8 +1310,11 @@ fn Works() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -1304,6 +1325,8 @@ fn Works() { // CHECK:STDOUT: fn(); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.A.impl.G() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return @@ -1320,8 +1343,8 @@ fn Works() { // CHECK:STDOUT: %A.ref.loc22_15: type = name_ref A, file.%A.decl [concrete = constants.%A.type] // CHECK:STDOUT: %A.ref.loc22_19: type = name_ref A, file.%A.decl [concrete = constants.%A.type] // CHECK:STDOUT: %impl.elem0.loc22: %.2af = impl_witness_access constants.%BitAndWith.impl_witness, element0 [concrete = constants.%type.as.BitAndWith.impl.Op] -// CHECK:STDOUT: %bound_method.loc22_17: = bound_method %A.ref.loc22_15, %impl.elem0.loc22 [concrete = constants.%type.as.BitAndWith.impl.Op.bound] -// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.call.loc22: init type = call %bound_method.loc22_17(%A.ref.loc22_15, %A.ref.loc22_19) [concrete = constants.%A.type] +// CHECK:STDOUT: %bound_method.loc22: = bound_method %A.ref.loc22_15, %impl.elem0.loc22 [concrete = constants.%type.as.BitAndWith.impl.Op.bound] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.call.loc22: init type = call %bound_method.loc22(%A.ref.loc22_15, %A.ref.loc22_19) [concrete = constants.%A.type] // CHECK:STDOUT: %G.ref.loc22: %A.assoc_type = name_ref G, @A.%assoc0 [concrete = constants.%assoc0.d52] // CHECK:STDOUT: %.loc22_12: %A.type = converted %.loc22_7, [concrete = ] // CHECK:STDOUT: %.loc30_6.1: %empty_struct_type = struct_literal () @@ -1359,8 +1382,8 @@ fn Works() { // CHECK:STDOUT: %A.ref.loc38_24: type = name_ref A, file.%A.decl [concrete = constants.%A.type] // CHECK:STDOUT: %A.ref.loc38_28: type = name_ref A, file.%A.decl [concrete = constants.%A.type] // CHECK:STDOUT: %impl.elem0.loc38: %.2af = impl_witness_access constants.%BitAndWith.impl_witness, element0 [concrete = constants.%type.as.BitAndWith.impl.Op] -// CHECK:STDOUT: %bound_method.loc38_26: = bound_method %A.ref.loc38_24, %impl.elem0.loc38 [concrete = constants.%type.as.BitAndWith.impl.Op.bound] -// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.call.loc38: init type = call %bound_method.loc38_26(%A.ref.loc38_24, %A.ref.loc38_28) [concrete = constants.%A.type] +// CHECK:STDOUT: %bound_method.loc38: = bound_method %A.ref.loc38_24, %impl.elem0.loc38 [concrete = constants.%type.as.BitAndWith.impl.Op.bound] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.call.loc38: init type = call %bound_method.loc38(%A.ref.loc38_24, %A.ref.loc38_28) [concrete = constants.%A.type] // CHECK:STDOUT: %.loc38_29.1: type = value_of_initializer %type.as.BitAndWith.impl.Op.call.loc38 [concrete = constants.%A.type] // CHECK:STDOUT: %.loc38_29.2: type = converted %type.as.BitAndWith.impl.Op.call.loc38, %.loc38_29.1 [concrete = constants.%A.type] // CHECK:STDOUT: %A.facet.loc38: %A.type = facet_value constants.%C, (constants.%A.impl_witness) [concrete = constants.%A.facet] @@ -1370,21 +1393,15 @@ fn Works() { // CHECK:STDOUT: %A.ref.loc38_34: type = name_ref A, file.%A.decl [concrete = constants.%A.type] // CHECK:STDOUT: %G.ref.loc38: %A.assoc_type = name_ref G, @A.%assoc0 [concrete = constants.%assoc0.d52] // CHECK:STDOUT: %.loc38_32: %A.type = converted %.loc38_8, [concrete = ] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc38: = bound_method %.loc38_6.2, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc38_6: = bound_method %.loc38_6.2, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound.loc38: = bound_method %.loc38_6.2, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc38: %ptr.019 = addr_of %.loc38_6.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc38: init %empty_tuple.type = call %bound_method.loc38_6(%addr.loc38) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc30: = bound_method %.loc30_6.2, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc30_6: = bound_method %.loc30_6.2, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call.loc38: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound.loc38(%addr.loc38) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound.loc30: = bound_method %.loc30_6.2, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc30: %ptr.019 = addr_of %.loc30_6.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc30: init %empty_tuple.type = call %bound_method.loc30_6(%addr.loc30) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc22: = bound_method %.loc22_5.2, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc22_5: = bound_method %.loc22_5.2, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call.loc30: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound.loc30(%addr.loc30) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound.loc22: = bound_method %.loc22_5.2, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc22: %ptr.019 = addr_of %.loc22_5.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc22: init %empty_tuple.type = call %bound_method.loc22_5(%addr.loc22) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call.loc22: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound.loc22(%addr.loc22) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -1403,6 +1420,13 @@ fn Works() { // CHECK:STDOUT: %A.assoc_type: type = assoc_entity_type @A [concrete] // CHECK:STDOUT: %assoc0.d52: %A.assoc_type = assoc_entity element0, @A.%A.G.decl [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %A.impl_witness: = impl_witness file.%A.impl_witness_table [concrete] @@ -1426,10 +1450,12 @@ fn Works() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .BitAndWith = %Core.BitAndWith // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.BitAndWith: %BitAndWith.type.f2e = import_ref Core//prelude, BitAndWith, loaded [concrete = constants.%BitAndWith.generic] // CHECK:STDOUT: %Core.import_ref.012: %type.as.BitAndWith.impl.Op.type = import_ref Core//prelude, loc13_42, loaded [concrete = constants.%type.as.BitAndWith.impl.Op] // CHECK:STDOUT: %BitAndWith.impl_witness_table = impl_witness_table (%Core.import_ref.012), @type.as.BitAndWith.impl [concrete] @@ -1465,6 +1491,22 @@ fn Works() { // CHECK:STDOUT: witness = (%A.G.decl) // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.A.impl: %C.ref as %A.ref { // CHECK:STDOUT: %C.as.A.impl.G.decl: %C.as.A.impl.G.type = fn_decl @C.as.A.impl.G [concrete = constants.%C.as.A.impl.G] {} {} // CHECK:STDOUT: @@ -1474,6 +1516,9 @@ fn Works() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -1486,6 +1531,8 @@ fn Works() { // CHECK:STDOUT: fn(); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.A.impl.G() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: return diff --git a/toolchain/check/testdata/interface/default_fn.carbon b/toolchain/check/testdata/interface/default_fn.carbon index 3d48eda2cd47..23d25fb6f82e 100644 --- a/toolchain/check/testdata/interface/default_fn.carbon +++ b/toolchain/check/testdata/interface/default_fn.carbon @@ -45,16 +45,18 @@ class C { // CHECK:STDOUT: %C.as.I.impl.F.type: type = fn_type @C.as.I.impl.F [concrete] // CHECK:STDOUT: %C.as.I.impl.F: %C.as.I.impl.F.type = struct_value () [concrete] // CHECK:STDOUT: %I.facet: %I.type = facet_value %C, (%I.impl_witness) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %require_complete.8cb: = require_complete_type %Self.as_type.390 [symbolic] // CHECK:STDOUT: %C.val: %C = struct_value () [concrete] // CHECK:STDOUT: %.e5b: type = fn_type_with_self_type %I.F.type, %I.facet [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -114,6 +116,22 @@ class C { // CHECK:STDOUT: witness = @C.%I.impl_witness // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} // CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} { @@ -122,8 +140,11 @@ class C { // CHECK:STDOUT: } // CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (@C.as.I.impl.%C.as.I.impl.F.decl), @C.as.I.impl [concrete] // CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -157,14 +178,12 @@ class C { // CHECK:STDOUT: %I.ref: type = name_ref I, @C.%I.decl [concrete = constants.%I.type] // CHECK:STDOUT: %F.ref: %I.assoc_type = name_ref F, @I.%assoc0 [concrete = constants.%assoc0.a33] // CHECK:STDOUT: %impl.elem0: %.e5b = impl_witness_access constants.%I.impl_witness, element0 [concrete = constants.%C.as.I.impl.F] -// CHECK:STDOUT: %bound_method.loc21: = bound_method %c.ref, %impl.elem0 +// CHECK:STDOUT: %bound_method: = bound_method %c.ref, %impl.elem0 // CHECK:STDOUT: %.loc21: %C = bind_value %c.ref -// CHECK:STDOUT: %C.as.I.impl.F.call: init %empty_tuple.type = call %bound_method.loc21(%.loc21) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc20: = bound_method %c.var, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.I.impl.F.call: init %empty_tuple.type = call %bound_method(%.loc21) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.019 = addr_of %c.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc20(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -174,6 +193,8 @@ class C { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @I.F(constants.%Self.6ef) { // CHECK:STDOUT: %Self => constants.%Self.6ef // CHECK:STDOUT: %Self.as_type.loc18_16.1 => constants.%Self.as_type.390 diff --git a/toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon b/toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon index fc472ec7931f..3bf41264704d 100644 --- a/toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon +++ b/toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon @@ -208,14 +208,21 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; } // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Interface.type: type = facet_type <@Interface> [concrete] -// CHECK:STDOUT: %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic] -// CHECK:STDOUT: %C: type = class_type @C, @C(%Self) [symbolic] +// CHECK:STDOUT: %Self.719: %Interface.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %C: type = class_type @C, @C(%Self.719) [symbolic] // CHECK:STDOUT: %pattern_type.68b: type = pattern_type %C [symbolic] // CHECK:STDOUT: %U: type = bind_symbolic_name U, 1 [symbolic] // CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] // CHECK:STDOUT: %pattern_type.a32: type = pattern_type %U [symbolic] -// CHECK:STDOUT: %C.F.type: type = fn_type @C.F, @C(%Self) [symbolic] +// CHECK:STDOUT: %C.F.type: type = fn_type @C.F, @C(%Self.719) [symbolic] // CHECK:STDOUT: %C.F: %C.F.type = struct_value () [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%Self.719) [symbolic] +// CHECK:STDOUT: %ptr.134: type = ptr_type %C [symbolic] +// CHECK:STDOUT: %pattern_type.274: type = pattern_type %ptr.134 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%Self.719) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %require_complete.b54: = require_complete_type %U [symbolic] @@ -224,9 +231,11 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -248,7 +257,7 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; } // CHECK:STDOUT: %U.ref.loc20_49: type = name_ref U, %U.loc20 [symbolic = %U.loc14_22.1 (constants.%U)] // CHECK:STDOUT: %self.param.loc20: @C.F.%C (%C) = value_param call_param0 // CHECK:STDOUT: %.loc20_24.1: type = splice_block %Self.ref.loc20 [symbolic = %C (constants.%C)] { -// CHECK:STDOUT: %.loc20_24.2: type = specific_constant constants.%C, @C(constants.%Self) [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %.loc20_24.2: type = specific_constant constants.%C, @C(constants.%Self.719) [symbolic = %C (constants.%C)] // CHECK:STDOUT: %Self.ref.loc20: type = name_ref Self, %.loc20_24.2 [symbolic = %C (constants.%C)] // CHECK:STDOUT: } // CHECK:STDOUT: %self.loc20: @C.F.%C (%C) = bind_name self, %self.param.loc20 @@ -262,7 +271,7 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @Interface { -// CHECK:STDOUT: %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.719] // CHECK:STDOUT: %C.decl: type = class_decl @C [symbolic = constants.%C] {} {} // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -271,9 +280,37 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; } // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@Interface.%Self: %Interface.type) { +// CHECK:STDOUT: %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.719)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%Self) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%Self) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.274) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.274) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc13_11.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.134) = value_param call_param0 +// CHECK:STDOUT: %.loc13_11.2: type = splice_block %Self.ref [symbolic = %C (constants.%C)] { +// CHECK:STDOUT: %.loc13_11.3: type = specific_constant constants.%C, @C(constants.%Self.719) [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc13_11.3 [symbolic = %C (constants.%C)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.134) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(@Interface.%Self: %Interface.type) { // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.719)] // CHECK:STDOUT: %C.F.type: type = fn_type @C.F, @C(%Self) [symbolic = %C.F.type (constants.%C.F.type)] // CHECK:STDOUT: %C.F: @C.%C.F.type (%C.F.type) = struct_value () [symbolic = %C.F (constants.%C.F)] // CHECK:STDOUT: @@ -290,7 +327,7 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; } // CHECK:STDOUT: %U.ref.loc14_41: type = name_ref U, %U.loc14_22.2 [symbolic = %U.loc14_22.1 (constants.%U)] // CHECK:STDOUT: %self.param.loc14: @C.F.%C (%C) = value_param call_param0 // CHECK:STDOUT: %.loc14_16.1: type = splice_block %Self.ref.loc14 [symbolic = %C (constants.%C)] { -// CHECK:STDOUT: %.loc14_16.2: type = specific_constant constants.%C, @C(constants.%Self) [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %.loc14_16.2: type = specific_constant constants.%C, @C(constants.%Self.719) [symbolic = %C (constants.%C)] // CHECK:STDOUT: %Self.ref.loc14: type = name_ref Self, %.loc14_16.2 [symbolic = %C (constants.%C)] // CHECK:STDOUT: } // CHECK:STDOUT: %self.loc14: @C.F.%C (%C) = bind_name self, %self.param.loc14 @@ -301,6 +338,9 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; } // CHECK:STDOUT: %return.param.loc14: ref @C.F.%U.loc14_22.1 (%U) = out_param call_param2 // CHECK:STDOUT: %return.loc14: ref @C.F.%U.loc14_22.1 (%U) = return_slot %return.param.loc14 // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%Self.719) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -312,7 +352,7 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; } // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: generic fn @C.F(@Interface.%Self: %Interface.type, %U.loc14_22.2: type) { -// CHECK:STDOUT: %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.719)] // CHECK:STDOUT: %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C)] // CHECK:STDOUT: %pattern_type.loc14_10: type = pattern_type %C [symbolic = %pattern_type.loc14_10 (constants.%pattern_type.68b)] // CHECK:STDOUT: %U.loc14_22.1: type = bind_symbolic_name U, 1 [symbolic = %U.loc14_22.1 (constants.%U)] @@ -329,18 +369,41 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; } // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @C(constants.%Self) { +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@Interface.%Self: %Interface.type) { +// CHECK:STDOUT: %Self: %Interface.type = bind_symbolic_name Self, 0 [symbolic = %Self (constants.%Self.719)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%Self) [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.134)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.274)] +// CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.134)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C(constants.%Self.719) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Self => constants.%Self.719 // CHECK:STDOUT: %C.F.type => constants.%C.F.type // CHECK:STDOUT: %C.F => constants.%C.F // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @C.F(constants.%Self, constants.%U) { -// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: specific @C.F(constants.%Self.719, constants.%U) { +// CHECK:STDOUT: %Self => constants.%Self.719 // CHECK:STDOUT: %C => constants.%C // CHECK:STDOUT: %pattern_type.loc14_10 => constants.%pattern_type.68b // CHECK:STDOUT: %U.loc14_22.1 => constants.%U // CHECK:STDOUT: %pattern_type.loc14_32 => constants.%pattern_type.a32 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%Self.719) { +// CHECK:STDOUT: %Self => constants.%Self.719 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%Self.719) { +// CHECK:STDOUT: %Self => constants.%Self.719 +// CHECK:STDOUT: %C => constants.%C +// CHECK:STDOUT: %ptr => constants.%ptr.134 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.274 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/interface/generic_method.carbon b/toolchain/check/testdata/interface/generic_method.carbon index 181d26ef51b5..10be5a539a9d 100644 --- a/toolchain/check/testdata/interface/generic_method.carbon +++ b/toolchain/check/testdata/interface/generic_method.carbon @@ -102,10 +102,28 @@ fn CallIndirect() { // CHECK:STDOUT: %A.assoc_type.ed3: type = assoc_entity_type @A, @A(%T.8b3) [symbolic] // CHECK:STDOUT: %assoc0.fcb: %A.assoc_type.ed3 = assoc_entity element0, @A.%A.F.decl [symbolic] // CHECK:STDOUT: %X: type = class_type @X [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.807: = impl_witness @X.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete] +// CHECK:STDOUT: %pattern_type.1c6: type = pattern_type %ptr.d17 [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op.type: type = fn_type @X.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op: %X.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Y: type = class_type @Y [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.621: = impl_witness @Y.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.455: type = ptr_type %Y [concrete] +// CHECK:STDOUT: %pattern_type.0ae: type = pattern_type %ptr.455 [concrete] +// CHECK:STDOUT: %Y.as.Destroy.impl.Op.type: type = fn_type @Y.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Y.as.Destroy.impl.Op: %Y.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Z: type = class_type @Z [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.2a0: = impl_witness @Z.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.fb6: type = ptr_type %Z [concrete] +// CHECK:STDOUT: %pattern_type.f76: type = pattern_type %ptr.fb6 [concrete] +// CHECK:STDOUT: %Z.as.Destroy.impl.Op.type: type = fn_type @Z.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Z.as.Destroy.impl.Op: %Z.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %A.type.91f: type = facet_type <@A, @A(%X)> [concrete] // CHECK:STDOUT: %Self.1bb: %A.type.91f = bind_symbolic_name Self, 1 [symbolic] // CHECK:STDOUT: %A.F.type.13d: type = fn_type @A.F, @A(%X) [concrete] @@ -135,14 +153,8 @@ fn CallIndirect() { // CHECK:STDOUT: %pattern_type.ef1: type = pattern_type %tuple.type.f6b [concrete] // CHECK:STDOUT: %Y.as.A.impl.F.specific_fn: = specific_function %Y.as.A.impl.F, @Y.as.A.impl.F(%Z) [concrete] // CHECK:STDOUT: %Z.val: %Z = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.bc9: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%T.8b3) [symbolic] // CHECK:STDOUT: %T.as.Destroy.impl.Op.46f: %T.as.Destroy.impl.Op.type.bc9 = struct_value () [symbolic] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.f73: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Z) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.6e3: %T.as.Destroy.impl.Op.type.f73 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.fb6: type = ptr_type %Z [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3b7: = specific_function %T.as.Destroy.impl.Op.6e3, @T.as.Destroy.impl.Op(%Z) [concrete] // CHECK:STDOUT: %Destroy.impl_witness.955: = impl_witness imports.%Destroy.impl_witness_table, @T.as.Destroy.impl(%tuple.type.f6b) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.495: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%tuple.type.f6b) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.51a: %T.as.Destroy.impl.Op.type.495 = struct_value () [concrete] @@ -150,7 +162,7 @@ fn CallIndirect() { // CHECK:STDOUT: %complete_type.456: = complete_type_witness %ptr.959 [concrete] // CHECK:STDOUT: %Destroy.facet.1f2: %Destroy.type = facet_value %tuple.type.f6b, (%Destroy.impl_witness.955) [concrete] // CHECK:STDOUT: %.a86: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.1f2 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.8e5: = specific_function %T.as.Destroy.impl.Op.51a, @T.as.Destroy.impl.Op(%tuple.type.f6b) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.51a, @T.as.Destroy.impl.Op(%tuple.type.f6b) [concrete] // CHECK:STDOUT: %T.9c2: %A.type.91f = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %pattern_type.817: type = pattern_type %A.type.91f [concrete] // CHECK:STDOUT: %CallGeneric.type: type = fn_type @CallGeneric [concrete] @@ -276,6 +288,54 @@ fn CallIndirect() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @X.as.Destroy.impl: constants.%X as constants.%Destroy.type { +// CHECK:STDOUT: %X.as.Destroy.impl.Op.decl: %X.as.Destroy.impl.Op.type = fn_decl @X.as.Destroy.impl.Op [concrete = constants.%X.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1c6 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1c6 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.d17 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%X [concrete = constants.%X] +// CHECK:STDOUT: %self: %ptr.d17 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %X.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @X.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Y.as.Destroy.impl: constants.%Y as constants.%Destroy.type { +// CHECK:STDOUT: %Y.as.Destroy.impl.Op.decl: %Y.as.Destroy.impl.Op.type = fn_decl @Y.as.Destroy.impl.Op [concrete = constants.%Y.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.0ae = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.0ae = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc10: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.455 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Y [concrete = constants.%Y] +// CHECK:STDOUT: %self: %ptr.455 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Y.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Y.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Z.as.Destroy.impl: constants.%Z as constants.%Destroy.type { +// CHECK:STDOUT: %Z.as.Destroy.impl.Op.decl: %Z.as.Destroy.impl.Op.type = fn_decl @Z.as.Destroy.impl.Op [concrete = constants.%Z.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f76 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f76 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.fb6 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Z [concrete = constants.%Z] +// CHECK:STDOUT: %self: %ptr.fb6 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Z.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Z.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @Y.as.A.impl: %Y.ref as %A.type { // CHECK:STDOUT: %Y.as.A.impl.F.decl: %Y.as.A.impl.F.type = fn_decl @Y.as.A.impl.F [concrete = constants.%Y.as.A.impl.F] { // CHECK:STDOUT: %U.patt: %pattern_type.98f = symbolic_binding_pattern U, 0 [concrete] @@ -305,6 +365,9 @@ fn CallIndirect() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @X { +// CHECK:STDOUT: impl_decl @X.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@X.as.Destroy.impl.%X.as.Destroy.impl.Op.decl), @X.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.807] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -314,6 +377,9 @@ fn CallIndirect() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Y { +// CHECK:STDOUT: impl_decl @Y.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Y.as.Destroy.impl.%Y.as.Destroy.impl.Op.decl), @Y.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.621] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -323,6 +389,9 @@ fn CallIndirect() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Z { +// CHECK:STDOUT: impl_decl @Z.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Z.as.Destroy.impl.%Z.as.Destroy.impl.Op.decl), @Z.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.2a0] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -345,6 +414,12 @@ fn CallIndirect() { // CHECK:STDOUT: fn(%u.param: @A.F.%U.loc6_8.1 (%U.2cb)) -> @A.F.%tuple.type.loc6_38.2 (%tuple.type.bd2); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @X.as.Destroy.impl.Op(%self.param: %ptr.d17) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Y.as.Destroy.impl.Op(%self.param: %ptr.455) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Z.as.Destroy.impl.Op(%self.param: %ptr.fb6) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @Y.as.A.impl.F(%U.loc16_8.2: type) { // CHECK:STDOUT: %U.loc16_8.1: type = bind_symbolic_name U, 0 [symbolic = %U.loc16_8.1 (constants.%U.8b3)] // CHECK:STDOUT: %pattern_type.loc16_18: type = pattern_type %U.loc16_8.1 [symbolic = %pattern_type.loc16_18 (constants.%pattern_type.7dc)] @@ -400,16 +475,14 @@ fn CallIndirect() { // CHECK:STDOUT: %.loc22_21.6: %Z = bind_value %.loc22_21.5 // CHECK:STDOUT: %Y.as.A.impl.F.call: init %tuple.type.f6b = call %specific_fn(%.loc22_21.6) to %.loc22_22.1 // CHECK:STDOUT: %.loc22_22.2: ref %tuple.type.f6b = temporary %.loc22_22.1, %Y.as.A.impl.F.call -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc22_21: = bound_method %.loc22_21.2, constants.%T.as.Destroy.impl.Op.6e3 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.6e3, @T.as.Destroy.impl.Op(constants.%Z) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.3b7] -// CHECK:STDOUT: %bound_method.loc22_21: = bound_method %.loc22_21.2, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %Z.as.Destroy.impl.Op.bound: = bound_method %.loc22_21.2, constants.%Z.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc22_21: %ptr.fb6 = addr_of %.loc22_21.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc22_21: init %empty_tuple.type = call %bound_method.loc22_21(%addr.loc22_21) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc22_22: = bound_method %.loc22_22.1, constants.%T.as.Destroy.impl.Op.51a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.51a, @T.as.Destroy.impl.Op(constants.%tuple.type.f6b) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.8e5] -// CHECK:STDOUT: %bound_method.loc22_22: = bound_method %.loc22_22.1, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %Z.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Z.as.Destroy.impl.Op.bound(%addr.loc22_21) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc22_22.1, constants.%T.as.Destroy.impl.Op.51a +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.51a, @T.as.Destroy.impl.Op(constants.%tuple.type.f6b) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method: = bound_method %.loc22_22.1, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr.loc22_22: %ptr.959 = addr_of %.loc22_22.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc22_22: init %empty_tuple.type = call %bound_method.loc22_22(%addr.loc22_22) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc22_22) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -452,11 +525,9 @@ fn CallIndirect() { // CHECK:STDOUT: %.loc26_11.6: %Z = bind_value %.loc26_11.5 // CHECK:STDOUT: %.loc26_12.2: init @CallGeneric.%tuple.type (%tuple.type.e28) = call %specific_impl_fn.loc26_4.1(%.loc26_11.6) to %.loc26_12.1 // CHECK:STDOUT: %.loc26_12.3: ref @CallGeneric.%tuple.type (%tuple.type.e28) = temporary %.loc26_12.1, %.loc26_12.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc26_11.2, constants.%T.as.Destroy.impl.Op.6e3 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.6e3, @T.as.Destroy.impl.Op(constants.%Z) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.3b7] -// CHECK:STDOUT: %bound_method.loc26_11: = bound_method %.loc26_11.2, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Z.as.Destroy.impl.Op.bound: = bound_method %.loc26_11.2, constants.%Z.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc26_11: %ptr.fb6 = addr_of %.loc26_11.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc26_11(%addr.loc26_11) +// CHECK:STDOUT: %Z.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Z.as.Destroy.impl.Op.bound(%addr.loc26_11) // CHECK:STDOUT: %impl.elem0.loc26_12.1: @CallGeneric.%.loc26_12.5 (%.efa) = impl_witness_access constants.%Destroy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc26_12.2 (constants.%impl.elem0.305)] // CHECK:STDOUT: %bound_method.loc26_12.1: = bound_method %.loc26_12.1, %impl.elem0.loc26_12.1 // CHECK:STDOUT: %specific_impl_fn.loc26_12.1: = specific_impl_function %impl.elem0.loc26_12.1, @Destroy.Op(constants.%Destroy.facet.1a6) [symbolic = %specific_impl_fn.loc26_12.2 (constants.%specific_impl_fn.52a)] @@ -569,7 +640,7 @@ fn CallIndirect() { // CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.1f2 // CHECK:STDOUT: %.loc26_12.5 => constants.%.a86 // CHECK:STDOUT: %impl.elem0.loc26_12.2 => constants.%T.as.Destroy.impl.Op.51a -// CHECK:STDOUT: %specific_impl_fn.loc26_12.2 => constants.%T.as.Destroy.impl.Op.specific_fn.8e5 +// CHECK:STDOUT: %specific_impl_fn.loc26_12.2 => constants.%T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %ptr => constants.%ptr.959 // CHECK:STDOUT: %require_complete.loc26_12.2 => constants.%complete_type.456 // CHECK:STDOUT: } @@ -607,11 +678,34 @@ fn CallIndirect() { // CHECK:STDOUT: %A.assoc_type.ed3: type = assoc_entity_type @A, @A(%T.8b3) [symbolic] // CHECK:STDOUT: %assoc0.fcb: %A.assoc_type.ed3 = assoc_entity element0, @A.%A.F.decl [symbolic] // CHECK:STDOUT: %X: type = class_type @X [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.807: = impl_witness @X.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete] +// CHECK:STDOUT: %pattern_type.1c6: type = pattern_type %ptr.d17 [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op.type: type = fn_type @X.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op: %X.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Y1: type = class_type @Y1 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.614: = impl_witness @Y1.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.723: type = ptr_type %Y1 [concrete] +// CHECK:STDOUT: %pattern_type.273: type = pattern_type %ptr.723 [concrete] +// CHECK:STDOUT: %Y1.as.Destroy.impl.Op.type: type = fn_type @Y1.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Y1.as.Destroy.impl.Op: %Y1.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Y2: type = class_type @Y2 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.7b0: = impl_witness @Y2.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.23d: type = ptr_type %Y2 [concrete] +// CHECK:STDOUT: %pattern_type.484: type = pattern_type %ptr.23d [concrete] +// CHECK:STDOUT: %Y2.as.Destroy.impl.Op.type: type = fn_type @Y2.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Y2.as.Destroy.impl.Op: %Y2.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Z: type = class_type @Z [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.2a0: = impl_witness @Z.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.fb6: type = ptr_type %Z [concrete] +// CHECK:STDOUT: %pattern_type.f76: type = pattern_type %ptr.fb6 [concrete] +// CHECK:STDOUT: %Z.as.Destroy.impl.Op.type: type = fn_type @Z.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Z.as.Destroy.impl.Op: %Z.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %V1: type = bind_symbolic_name V1, 0 [symbolic] // CHECK:STDOUT: %V2: type = bind_symbolic_name V2, 1 [symbolic] // CHECK:STDOUT: %W: type = bind_symbolic_name W, 2 [symbolic] @@ -637,8 +731,6 @@ fn CallIndirect() { // CHECK:STDOUT: %require_complete.d4d: = require_complete_type %tuple.type.8ae [symbolic] // CHECK:STDOUT: %require_complete.ed4: = require_complete_type %U.753 [symbolic] // CHECK:STDOUT: %tuple.type.as.A.impl.F.specific_fn.7d9: = specific_function %tuple.type.as.A.impl.F.d79, @tuple.type.as.A.impl.F(%V1, %V2, %W, %U.753) [symbolic] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %Destroy.Op.type: type = fn_type @Destroy.Op [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.bc9: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%T.8b3) [symbolic] // CHECK:STDOUT: %T.as.Destroy.impl.Op.46f: %T.as.Destroy.impl.Op.type.bc9 = struct_value () [symbolic] // CHECK:STDOUT: %ptr.ab5: type = ptr_type %tuple.type.8ae [symbolic] @@ -668,10 +760,6 @@ fn CallIndirect() { // CHECK:STDOUT: %pattern_type.0b2: type = pattern_type %tuple.type.415 [concrete] // CHECK:STDOUT: %tuple.type.as.A.impl.F.specific_fn.79b: = specific_function %tuple.type.as.A.impl.F.93b, @tuple.type.as.A.impl.F(%Y1, %Y2, %X, %Z) [concrete] // CHECK:STDOUT: %Z.val: %Z = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.f73: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%Z) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.6e3: %T.as.Destroy.impl.Op.type.f73 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.fb6: type = ptr_type %Z [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3b7: = specific_function %T.as.Destroy.impl.Op.6e3, @T.as.Destroy.impl.Op(%Z) [concrete] // CHECK:STDOUT: %Destroy.impl_witness.c80: = impl_witness imports.%Destroy.impl_witness_table, @T.as.Destroy.impl(%tuple.type.415) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.2a3: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%tuple.type.415) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.66e: %T.as.Destroy.impl.Op.type.2a3 = struct_value () [concrete] @@ -679,7 +767,7 @@ fn CallIndirect() { // CHECK:STDOUT: %complete_type.e23: = complete_type_witness %ptr.ad9 [concrete] // CHECK:STDOUT: %Destroy.facet.2b1: %Destroy.type = facet_value %tuple.type.415, (%Destroy.impl_witness.c80) [concrete] // CHECK:STDOUT: %.1b7: type = fn_type_with_self_type %Destroy.Op.type, %Destroy.facet.2b1 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.ce9: = specific_function %T.as.Destroy.impl.Op.66e, @T.as.Destroy.impl.Op(%tuple.type.415) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.66e, @T.as.Destroy.impl.Op(%tuple.type.415) [concrete] // CHECK:STDOUT: %T.9c2: %A.type.91f = bind_symbolic_name T, 0 [symbolic] // CHECK:STDOUT: %pattern_type.817: type = pattern_type %A.type.91f [concrete] // CHECK:STDOUT: %CallGeneric.type: type = fn_type @CallGeneric [concrete] @@ -817,6 +905,70 @@ fn CallIndirect() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @X.as.Destroy.impl: constants.%X as constants.%Destroy.type { +// CHECK:STDOUT: %X.as.Destroy.impl.Op.decl: %X.as.Destroy.impl.Op.type = fn_decl @X.as.Destroy.impl.Op [concrete = constants.%X.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1c6 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1c6 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc9: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.d17 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%X [concrete = constants.%X] +// CHECK:STDOUT: %self: %ptr.d17 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %X.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @X.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Y1.as.Destroy.impl: constants.%Y1 as constants.%Destroy.type { +// CHECK:STDOUT: %Y1.as.Destroy.impl.Op.decl: %Y1.as.Destroy.impl.Op.type = fn_decl @Y1.as.Destroy.impl.Op [concrete = constants.%Y1.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.273 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.273 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc10: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.723 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Y1 [concrete = constants.%Y1] +// CHECK:STDOUT: %self: %ptr.723 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Y1.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Y1.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Y2.as.Destroy.impl: constants.%Y2 as constants.%Destroy.type { +// CHECK:STDOUT: %Y2.as.Destroy.impl.Op.decl: %Y2.as.Destroy.impl.Op.type = fn_decl @Y2.as.Destroy.impl.Op [concrete = constants.%Y2.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.484 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.484 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.23d = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Y2 [concrete = constants.%Y2] +// CHECK:STDOUT: %self: %ptr.23d = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Y2.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Y2.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @Z.as.Destroy.impl: constants.%Z as constants.%Destroy.type { +// CHECK:STDOUT: %Z.as.Destroy.impl.Op.decl: %Z.as.Destroy.impl.Op.type = fn_decl @Z.as.Destroy.impl.Op [concrete = constants.%Z.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.f76 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.f76 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.fb6 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Z [concrete = constants.%Z] +// CHECK:STDOUT: %self: %ptr.fb6 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Z.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Z.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic impl @tuple.type.as.A.impl(%V1.loc14_14.2: type, %V2.loc14_25.2: type, %W.loc14_36.2: type) { // CHECK:STDOUT: %V1.loc14_14.1: type = bind_symbolic_name V1, 0 [symbolic = %V1.loc14_14.1 (constants.%V1)] // CHECK:STDOUT: %V2.loc14_25.1: type = bind_symbolic_name V2, 1 [symbolic = %V2.loc14_25.1 (constants.%V2)] @@ -864,6 +1016,9 @@ fn CallIndirect() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @X { +// CHECK:STDOUT: impl_decl @X.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@X.as.Destroy.impl.%X.as.Destroy.impl.Op.decl), @X.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.807] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -873,6 +1028,9 @@ fn CallIndirect() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Y1 { +// CHECK:STDOUT: impl_decl @Y1.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Y1.as.Destroy.impl.%Y1.as.Destroy.impl.Op.decl), @Y1.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.614] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -882,6 +1040,9 @@ fn CallIndirect() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Y2 { +// CHECK:STDOUT: impl_decl @Y2.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Y2.as.Destroy.impl.%Y2.as.Destroy.impl.Op.decl), @Y2.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.7b0] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -891,6 +1052,9 @@ fn CallIndirect() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @Z { +// CHECK:STDOUT: impl_decl @Z.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Z.as.Destroy.impl.%Z.as.Destroy.impl.Op.decl), @Z.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.2a0] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -913,6 +1077,14 @@ fn CallIndirect() { // CHECK:STDOUT: fn(%u.param: @A.F.%U.loc6_8.1 (%U.2cb)) -> @A.F.%tuple.type.loc6_38.2 (%tuple.type.bd2); // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @X.as.Destroy.impl.Op(%self.param: %ptr.d17) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Y1.as.Destroy.impl.Op(%self.param: %ptr.723) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Y2.as.Destroy.impl.Op(%self.param: %ptr.23d) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Z.as.Destroy.impl.Op(%self.param: %ptr.fb6) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @tuple.type.as.A.impl.F(@tuple.type.as.A.impl.%V1.loc14_14.2: type, @tuple.type.as.A.impl.%V2.loc14_25.2: type, @tuple.type.as.A.impl.%W.loc14_36.2: type, %U.loc17_8.2: type) { // CHECK:STDOUT: %U.loc17_8.1: type = bind_symbolic_name U, 3 [symbolic = %U.loc17_8.1 (constants.%U.753)] // CHECK:STDOUT: %pattern_type.loc17_18: type = pattern_type %U.loc17_8.1 [symbolic = %pattern_type.loc17_18 (constants.%pattern_type.549)] @@ -983,16 +1155,14 @@ fn CallIndirect() { // CHECK:STDOUT: %.loc24_38.6: %Z = bind_value %.loc24_38.5 // CHECK:STDOUT: %tuple.type.as.A.impl.F.call: init %tuple.type.415 = call %specific_fn(%.loc24_38.6) to %.loc24_39.1 // CHECK:STDOUT: %.loc24_39.2: ref %tuple.type.415 = temporary %.loc24_39.1, %tuple.type.as.A.impl.F.call -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc24_38: = bound_method %.loc24_38.2, constants.%T.as.Destroy.impl.Op.6e3 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.6e3, @T.as.Destroy.impl.Op(constants.%Z) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.3b7] -// CHECK:STDOUT: %bound_method.loc24_38: = bound_method %.loc24_38.2, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %Z.as.Destroy.impl.Op.bound: = bound_method %.loc24_38.2, constants.%Z.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc24_38: %ptr.fb6 = addr_of %.loc24_38.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc24_38: init %empty_tuple.type = call %bound_method.loc24_38(%addr.loc24_38) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc24_39: = bound_method %.loc24_39.1, constants.%T.as.Destroy.impl.Op.66e -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.66e, @T.as.Destroy.impl.Op(constants.%tuple.type.415) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.ce9] -// CHECK:STDOUT: %bound_method.loc24_39: = bound_method %.loc24_39.1, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %Z.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Z.as.Destroy.impl.Op.bound(%addr.loc24_38) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc24_39.1, constants.%T.as.Destroy.impl.Op.66e +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.66e, @T.as.Destroy.impl.Op(constants.%tuple.type.415) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method: = bound_method %.loc24_39.1, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr.loc24_39: %ptr.ad9 = addr_of %.loc24_39.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc24_39: init %empty_tuple.type = call %bound_method.loc24_39(%addr.loc24_39) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc24_39) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -1035,11 +1205,9 @@ fn CallIndirect() { // CHECK:STDOUT: %.loc28_11.6: %Z = bind_value %.loc28_11.5 // CHECK:STDOUT: %.loc28_12.2: init @CallGeneric.%tuple.type (%tuple.type.e28) = call %specific_impl_fn.loc28_4.1(%.loc28_11.6) to %.loc28_12.1 // CHECK:STDOUT: %.loc28_12.3: ref @CallGeneric.%tuple.type (%tuple.type.e28) = temporary %.loc28_12.1, %.loc28_12.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc28_11.2, constants.%T.as.Destroy.impl.Op.6e3 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.6e3, @T.as.Destroy.impl.Op(constants.%Z) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.3b7] -// CHECK:STDOUT: %bound_method.loc28_11: = bound_method %.loc28_11.2, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %Z.as.Destroy.impl.Op.bound: = bound_method %.loc28_11.2, constants.%Z.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc28_11: %ptr.fb6 = addr_of %.loc28_11.2 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc28_11(%addr.loc28_11) +// CHECK:STDOUT: %Z.as.Destroy.impl.Op.call: init %empty_tuple.type = call %Z.as.Destroy.impl.Op.bound(%addr.loc28_11) // CHECK:STDOUT: %impl.elem0.loc28_12.1: @CallGeneric.%.loc28_12.5 (%.efa) = impl_witness_access constants.%Destroy.lookup_impl_witness.1a2, element0 [symbolic = %impl.elem0.loc28_12.2 (constants.%impl.elem0.305)] // CHECK:STDOUT: %bound_method.loc28_12.1: = bound_method %.loc28_12.1, %impl.elem0.loc28_12.1 // CHECK:STDOUT: %specific_impl_fn.loc28_12.1: = specific_impl_function %impl.elem0.loc28_12.1, @Destroy.Op(constants.%Destroy.facet.1a6) [symbolic = %specific_impl_fn.loc28_12.2 (constants.%specific_impl_fn.52a)] @@ -1189,7 +1357,7 @@ fn CallIndirect() { // CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.2b1 // CHECK:STDOUT: %.loc17_24.3 => constants.%.1b7 // CHECK:STDOUT: %impl.elem0.loc17_24.2 => constants.%T.as.Destroy.impl.Op.66e -// CHECK:STDOUT: %specific_impl_fn.loc17_24.2 => constants.%T.as.Destroy.impl.Op.specific_fn.ce9 +// CHECK:STDOUT: %specific_impl_fn.loc17_24.2 => constants.%T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %ptr => constants.%ptr.ad9 // CHECK:STDOUT: %require_complete.loc17_24.2 => constants.%complete_type.e23 // CHECK:STDOUT: } @@ -1226,7 +1394,7 @@ fn CallIndirect() { // CHECK:STDOUT: %Destroy.facet => constants.%Destroy.facet.2b1 // CHECK:STDOUT: %.loc28_12.5 => constants.%.1b7 // CHECK:STDOUT: %impl.elem0.loc28_12.2 => constants.%T.as.Destroy.impl.Op.66e -// CHECK:STDOUT: %specific_impl_fn.loc28_12.2 => constants.%T.as.Destroy.impl.Op.specific_fn.ce9 +// CHECK:STDOUT: %specific_impl_fn.loc28_12.2 => constants.%T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %ptr => constants.%ptr.ad9 // CHECK:STDOUT: %require_complete.loc28_12.2 => constants.%complete_type.e23 // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/interop/cpp/class/class.carbon b/toolchain/check/testdata/interop/cpp/class/class.carbon index 427bc1beba95..fc8fb4ff882e 100644 --- a/toolchain/check/testdata/interop/cpp/class/class.carbon +++ b/toolchain/check/testdata/interop/cpp/class/class.carbon @@ -501,6 +501,13 @@ fn MyF(bar: Cpp.Bar*); // CHECK:STDOUT: %Bar: type = class_type @Bar [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Derived.elem: type = unbound_element_type %Derived, %Bar [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @Derived.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.type: type = fn_type @Derived.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op: %Derived.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.36d: type = struct_type {.base: %Bar} [concrete] // CHECK:STDOUT: %complete_type.fff: = complete_type_witness %struct_type.base.36d [concrete] // CHECK:STDOUT: %MyF.type: type = fn_type @MyF [concrete] @@ -523,10 +530,29 @@ fn MyF(bar: Cpp.Bar*); // CHECK:STDOUT: %MyF.decl: %MyF.type = fn_decl @MyF [concrete = constants.%MyF] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Derived.as.Destroy.impl: constants.%Derived as constants.%Destroy.type { +// CHECK:STDOUT: %Derived.as.Destroy.impl.Op.decl: %Derived.as.Destroy.impl.Op.type = fn_decl @Derived.as.Destroy.impl.Op [concrete = constants.%Derived.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.605 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.605 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc7: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Derived [concrete = constants.%Derived] +// CHECK:STDOUT: %self: %ptr.404 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Derived.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Derived.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Derived { // CHECK:STDOUT: %Cpp.ref: = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp] // CHECK:STDOUT: %Bar.ref: type = name_ref Bar, imports.%Bar.decl [concrete = constants.%Bar] // CHECK:STDOUT: %.loc8: %Derived.elem = base_decl %Bar.ref, element0 [concrete] +// CHECK:STDOUT: impl_decl @Derived.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Derived.as.Destroy.impl.%Derived.as.Destroy.impl.Op.decl), @Derived.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %Bar} [concrete = constants.%struct_type.base.36d] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.base [concrete = constants.%complete_type.fff] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -539,6 +565,8 @@ fn MyF(bar: Cpp.Bar*); // CHECK:STDOUT: extend %Bar.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.as.Destroy.impl.Op(%self.param: %ptr.404) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @MyF() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %Derived.ref: type = name_ref Derived, file.%Derived.decl [concrete = constants.%Derived] diff --git a/toolchain/check/testdata/let/compile_time_bindings.carbon b/toolchain/check/testdata/let/compile_time_bindings.carbon index a90b55aa4717..cd6d6dec565a 100644 --- a/toolchain/check/testdata/let/compile_time_bindings.carbon +++ b/toolchain/check/testdata/let/compile_time_bindings.carbon @@ -165,19 +165,28 @@ impl i32 as Empty { // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete] +// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete] // CHECK:STDOUT: %C.F.type: type = fn_type @C.F [concrete] // CHECK:STDOUT: %C.F: %C.F.type = struct_value () [concrete] // CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -189,10 +198,26 @@ impl i32 as Empty { // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %C.F.decl: %C.F.type = fn_decl @C.F [concrete = constants.%C.F] { -// CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern [concrete] -// CHECK:STDOUT: %return.param_patt: %pattern_type = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.cb1 = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.cb1 = out_param_pattern %return.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %.loc5_14.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc5_14.2: type = converted %.loc5_14.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] @@ -200,7 +225,7 @@ impl i32 as Empty { // CHECK:STDOUT: %return: ref %empty_tuple.type = return_slot %return.param // CHECK:STDOUT: } // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %x.patt: %pattern_type = binding_pattern x [concrete] +// CHECK:STDOUT: %x.patt: %pattern_type.cb1 = binding_pattern x [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %.loc10_17.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc10_12.1: type = splice_block %.loc10_12.3 [concrete = constants.%empty_tuple.type] { @@ -210,6 +235,9 @@ impl i32 as Empty { // CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple] // CHECK:STDOUT: %.loc10_17.2: %empty_tuple.type = converted %.loc10_17.1, %empty_tuple [concrete = constants.%empty_tuple] // CHECK:STDOUT: %x: %empty_tuple.type = bind_name x, %.loc10_17.2 +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -226,24 +254,35 @@ impl i32 as Empty { // CHECK:STDOUT: return %x.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_let_before.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete] +// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete] // CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] // CHECK:STDOUT: %C.F.type: type = fn_type @C.F [concrete] // CHECK:STDOUT: %C.F: %C.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -255,9 +294,25 @@ impl i32 as Empty { // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %x.patt: %pattern_type = binding_pattern x [concrete] +// CHECK:STDOUT: %x.patt: %pattern_type.cb1 = binding_pattern x [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: %.loc9_17.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc9_12.1: type = splice_block %.loc9_12.3 [concrete = constants.%empty_tuple.type] { @@ -268,14 +323,17 @@ impl i32 as Empty { // CHECK:STDOUT: %.loc9_17.2: %empty_tuple.type = converted %.loc9_17.1, %empty_tuple [concrete = constants.%empty_tuple] // CHECK:STDOUT: %x: %empty_tuple.type = bind_name x, %.loc9_17.2 // CHECK:STDOUT: %C.F.decl: %C.F.type = fn_decl @C.F [concrete = constants.%C.F] { -// CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern [concrete] -// CHECK:STDOUT: %return.param_patt: %pattern_type = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.cb1 = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.cb1 = out_param_pattern %return.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %.loc10_14.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc10_14.2: type = converted %.loc10_14.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] // CHECK:STDOUT: %return.param: ref %empty_tuple.type = out_param call_param0 // CHECK:STDOUT: %return: ref %empty_tuple.type = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -292,6 +350,8 @@ impl i32 as Empty { // CHECK:STDOUT: return %x.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_multiple_lets.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -308,6 +368,13 @@ impl i32 as Empty { // CHECK:STDOUT: %ptr.7fe: type = ptr_type %tuple.type.2d5 [concrete] // CHECK:STDOUT: %pattern_type.8c1: type = pattern_type %tuple.type.2d5 [concrete] // CHECK:STDOUT: %tuple.7e4: %tuple.type.2d5 = tuple_value (%empty_tuple, %empty_tuple, %empty_tuple) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %tuple.type.bcd: type = tuple_type (%empty_tuple.type, %empty_tuple.type) [concrete] @@ -319,7 +386,6 @@ impl i32 as Empty { // CHECK:STDOUT: %tuple.f41: %tuple.type.9fb = tuple_value (%empty_tuple) [concrete] // CHECK:STDOUT: %tuple.elem0.eaf: %empty_tuple.type = tuple_access %c, element0 [symbolic] // CHECK:STDOUT: %tuple.elem1: %empty_tuple.type = tuple_access %c, element1 [symbolic] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.073: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%tuple.type.2d5) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.dce: %T.as.Destroy.impl.Op.type.073 = struct_value () [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.234: = specific_function %T.as.Destroy.impl.Op.dce, @T.as.Destroy.impl.Op(%tuple.type.2d5) [concrete] @@ -354,6 +420,22 @@ impl i32 as Empty { // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %a.patt: %pattern_type.cb1 = binding_pattern a [concrete] @@ -403,6 +485,9 @@ impl i32 as Empty { // CHECK:STDOUT: %tuple: %tuple.type.2d5 = tuple_value (%.loc22_37.2, %.loc22_37.3, %.loc22_37.4) [concrete = constants.%tuple.7e4] // CHECK:STDOUT: %.loc22_37.5: %tuple.type.2d5 = converted %.loc22_37.1, %tuple [concrete = constants.%tuple.7e4] // CHECK:STDOUT: %d: %tuple.type.2d5 = bind_name d, %.loc22_37.5 +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -562,6 +647,8 @@ impl i32 as Empty { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: specific @C.F(constants.%b) { // CHECK:STDOUT: %b.loc10_8.1 => constants.%b // CHECK:STDOUT: } @@ -571,18 +658,27 @@ impl i32 as Empty { // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %empty_tuple.type [concrete] +// CHECK:STDOUT: %pattern_type.cb1: type = pattern_type %empty_tuple.type [concrete] // CHECK:STDOUT: %C.F.type: type = fn_type @C.F [concrete] // CHECK:STDOUT: %C.F: %C.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -594,10 +690,26 @@ impl i32 as Empty { // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %C.F.decl: %C.F.type = fn_decl @C.F [concrete = constants.%C.F] { -// CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern [concrete] -// CHECK:STDOUT: %return.param_patt: %pattern_type = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.cb1 = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.cb1 = out_param_pattern %return.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %.loc5_14.1: %empty_tuple.type = tuple_literal () // CHECK:STDOUT: %.loc5_14.2: type = converted %.loc5_14.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] @@ -605,8 +717,11 @@ impl i32 as Empty { // CHECK:STDOUT: %return: ref %empty_tuple.type = return_slot %return.param // CHECK:STDOUT: } // CHECK:STDOUT: name_binding_decl { -// CHECK:STDOUT: %x.patt: %pattern_type = binding_pattern x [concrete] +// CHECK:STDOUT: %x.patt: %pattern_type.cb1 = binding_pattern x [concrete] // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -623,6 +738,8 @@ impl i32 as Empty { // CHECK:STDOUT: return %x.ref // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- use_in_function.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { @@ -908,6 +1025,13 @@ impl i32 as Empty { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %I.F.type: type = fn_type @I.F [concrete] // CHECK:STDOUT: %I.F: %I.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @I.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.9fe: type = ptr_type %I [concrete] +// CHECK:STDOUT: %pattern_type.21d: type = pattern_type %ptr.9fe [concrete] +// CHECK:STDOUT: %I.as.Destroy.impl.Op.type: type = fn_type @I.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %I.as.Destroy.impl.Op: %I.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } @@ -915,10 +1039,12 @@ impl i32 as Empty { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -930,6 +1056,22 @@ impl i32 as Empty { // CHECK:STDOUT: %I.decl: type = class_decl @I [concrete = constants.%I] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @I.as.Destroy.impl: constants.%I as constants.%Destroy.type { +// CHECK:STDOUT: %I.as.Destroy.impl.Op.decl: %I.as.Destroy.impl.Op.type = fn_decl @I.as.Destroy.impl.Op [concrete = constants.%I.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.21d = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.21d = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.9fe = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%I [concrete = constants.%I] +// CHECK:STDOUT: %self: %ptr.9fe = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %I.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @I.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @I { // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %T.patt: %pattern_type.98f = binding_pattern T [concrete] @@ -945,6 +1087,9 @@ impl i32 as Empty { // CHECK:STDOUT: %return.param: ref = out_param call_param0 // CHECK:STDOUT: %return: ref = return_slot %return.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @I.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@I.as.Destroy.impl.%I.as.Destroy.impl.Op.decl), @I.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -957,6 +1102,8 @@ impl i32 as Empty { // CHECK:STDOUT: // CHECK:STDOUT: fn @I.F() -> ; // CHECK:STDOUT: +// CHECK:STDOUT: fn @I.as.Destroy.impl.Op(%self.param: %ptr.9fe) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_return_in_package_scope.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/namespace/fail_not_top_level.carbon b/toolchain/check/testdata/namespace/fail_not_top_level.carbon index c7638308deb3..8152d0645c57 100644 --- a/toolchain/check/testdata/namespace/fail_not_top_level.carbon +++ b/toolchain/check/testdata/namespace/fail_not_top_level.carbon @@ -49,19 +49,28 @@ interface I { // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %F.type.1cc: type = fn_type @F.loc30 [concrete] // CHECK:STDOUT: %F.f49: %F.type.1cc = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %I.type.733: type = facet_type <@I.loc33> [concrete] -// CHECK:STDOUT: %Self: %I.type.733 = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Self.826: %I.type.733 = bind_symbolic_name Self, 0 [symbolic] // CHECK:STDOUT: %I.type.d37: type = fn_type @I.loc39 [concrete] // CHECK:STDOUT: %I: %I.type.d37 = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -78,7 +87,7 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: interface @I.loc33 { -// CHECK:STDOUT: %Self: %I.type.733 = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Self: %I.type.733 = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826] // CHECK:STDOUT: %N: = namespace [concrete] { // CHECK:STDOUT: .I = %I.decl // CHECK:STDOUT: } @@ -90,11 +99,30 @@ interface I { // CHECK:STDOUT: witness = () // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc24: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %N: = namespace [concrete] { // CHECK:STDOUT: .F = %F.decl // CHECK:STDOUT: } // CHECK:STDOUT: %F.decl: %F.type.1cc = fn_decl @F.loc30 [concrete = constants.%F.f49] {} {} +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -123,6 +151,8 @@ interface I { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: generic fn @I.loc39(@I.loc33.%Self: %I.type.733) { // CHECK:STDOUT: !definition: // CHECK:STDOUT: @@ -132,5 +162,5 @@ interface I { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: specific @I.loc39(constants.%Self) {} +// CHECK:STDOUT: specific @I.loc39(constants.%Self.826) {} // CHECK:STDOUT: diff --git a/toolchain/check/testdata/namespace/merging_with_indirections.carbon b/toolchain/check/testdata/namespace/merging_with_indirections.carbon index 9036deff7597..d3f39cf3ce67 100644 --- a/toolchain/check/testdata/namespace/merging_with_indirections.carbon +++ b/toolchain/check/testdata/namespace/merging_with_indirections.carbon @@ -49,15 +49,24 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %A: type = class_type @A [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @A.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.a87: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.ba7: type = pattern_type %ptr.a87 [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -72,7 +81,26 @@ fn Run() { // CHECK:STDOUT: %A.decl: type = class_decl @A [concrete = constants.%A] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: constants.%A as constants.%Destroy.type { +// CHECK:STDOUT: %A.as.Destroy.impl.Op.decl: %A.as.Destroy.impl.Op.type = fn_decl @A.as.Destroy.impl.Op [concrete = constants.%A.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.ba7 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.ba7 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.a87 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: %ptr.a87 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %A.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @A.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A { +// CHECK:STDOUT: impl_decl @A.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@A.as.Destroy.impl.%A.as.Destroy.impl.Op.decl), @A.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -81,14 +109,23 @@ fn Run() { // CHECK:STDOUT: .Self = constants.%A // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op(%self.param: %ptr.a87) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- b.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @B.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.958: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.533: type = pattern_type %ptr.958 [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op.type: type = fn_type @B.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %B.as.Destroy.impl.Op: %B.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %A: type = class_type @A [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %A [concrete] +// CHECK:STDOUT: %pattern_type.045: type = pattern_type %A [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %A.val: %A = struct_value () [concrete] @@ -102,9 +139,11 @@ fn Run() { // CHECK:STDOUT: } // CHECK:STDOUT: %Other.A: type = import_ref Other//a, A, loaded [concrete = constants.%A] // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Other.import_ref.8f2: = import_ref Other//a, loc5_14, loaded [concrete = constants.%complete_type] // CHECK:STDOUT: %Other.import_ref.ca8 = import_ref Other//a, inst19 [no loc], unloaded // CHECK:STDOUT: } @@ -123,8 +162,8 @@ fn Run() { // CHECK:STDOUT: } // CHECK:STDOUT: %B.decl: type = class_decl @B [concrete = constants.%B] {} {} // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { -// CHECK:STDOUT: %return.patt: %pattern_type = return_slot_pattern [concrete] -// CHECK:STDOUT: %return.param_patt: %pattern_type = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.045 = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.045 = out_param_pattern %return.patt, call_param0 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %NS1.ref: = name_ref NS1, imports.%NS1 [concrete = imports.%NS1] // CHECK:STDOUT: %A.ref: type = name_ref A, imports.%Other.A [concrete = constants.%A] @@ -133,7 +172,26 @@ fn Run() { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.Destroy.impl: constants.%B as constants.%Destroy.type { +// CHECK:STDOUT: %B.as.Destroy.impl.Op.decl: %B.as.Destroy.impl.Op.type = fn_decl @B.as.Destroy.impl.Op [concrete = constants.%B.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.533 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.533 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.958 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: %ptr.958 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %B.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @B.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @B { +// CHECK:STDOUT: impl_decl @B.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@B.as.Destroy.impl.%B.as.Destroy.impl.Op.decl), @B.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -149,6 +207,8 @@ fn Run() { // CHECK:STDOUT: .Self = imports.%Other.import_ref.ca8 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.Destroy.impl.Op(%self.param: %ptr.958) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() -> %return.param: %A { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc8_27.1: %empty_struct_type = struct_literal () @@ -167,13 +227,13 @@ fn Run() { // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %A: type = class_type @A [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.272: type = pattern_type %A [concrete] // CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.d74: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%A) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.478: %T.as.Destroy.impl.Op.type.d74 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.90d: = impl_witness imports.%Destroy.impl_witness_table.8a3 [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op.type: type = fn_type @A.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %A.as.Destroy.impl.Op: %A.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.07e: type = ptr_type %A [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.478, @T.as.Destroy.impl.Op(%A) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -189,8 +249,8 @@ fn Run() { // CHECK:STDOUT: import Other//a // CHECK:STDOUT: } // CHECK:STDOUT: %Other.F: %F.type = import_ref Other//b, F, loaded [concrete = constants.%F] -// CHECK:STDOUT: %Other.import_ref.8db: = import_ref Other//b, inst31 [indirect], loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Other.import_ref.bbd = import_ref Other//b, inst32 [indirect], unloaded +// CHECK:STDOUT: %Other.import_ref.8db: = import_ref Other//b, inst70 [indirect], loaded [concrete = constants.%complete_type] +// CHECK:STDOUT: %Other.import_ref.bbd = import_ref Other//b, inst71 [indirect], unloaded // CHECK:STDOUT: %Other.NS1: = import_ref Other//b, NS1, loaded // CHECK:STDOUT: %NS1.b9a: = namespace %Other.NS1, [concrete] { // CHECK:STDOUT: .A = %Other.A @@ -199,6 +259,11 @@ fn Run() { // CHECK:STDOUT: } // CHECK:STDOUT: %Other.A: type = import_ref Other//a, A, loaded [concrete = constants.%A] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Other.import_ref.af3: = import_ref Other//a, loc5_13, loaded [concrete = constants.%Destroy.impl_witness.90d] +// CHECK:STDOUT: %Other.import_ref.a85: type = import_ref Other//a, inst19 [no loc], loaded [concrete = constants.%A] +// CHECK:STDOUT: %Other.import_ref.cb9: type = import_ref Other//a, inst22 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Other.import_ref.788: %A.as.Destroy.impl.Op.type = import_ref Other//a, loc5_13, loaded [concrete = constants.%A.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.8a3 = impl_witness_table (%Other.import_ref.788), @A.as.Destroy.impl [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -212,6 +277,11 @@ fn Run() { // CHECK:STDOUT: %Run.decl: %Run.type = fn_decl @Run [concrete = constants.%Run] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @A.as.Destroy.impl: imports.%Other.import_ref.a85 as imports.%Other.import_ref.cb9 [from "a.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%Other.import_ref.af3 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @A [from "b.carbon"] { // CHECK:STDOUT: complete_type_witness = imports.%Other.import_ref.8db // CHECK:STDOUT: @@ -243,23 +313,19 @@ fn Run() { // CHECK:STDOUT: %.loc13: ref %A = splice_block %a.ref {} // CHECK:STDOUT: %F.call.loc13: init %A = call %F.ref.loc13() to %.loc13 // CHECK:STDOUT: assign %a.ref, %F.call.loc13 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13: = bound_method %.loc13, constants.%T.as.Destroy.impl.Op.478 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.478, @T.as.Destroy.impl.Op(constants.%A) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc13: = bound_method %.loc13, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %A.as.Destroy.impl.Op.bound.loc13: = bound_method %.loc13, constants.%A.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc13: %ptr.07e = addr_of %.loc13 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc13: init %empty_tuple.type = call %bound_method.loc13(%addr.loc13) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10: = bound_method %a.var, constants.%T.as.Destroy.impl.Op.478 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.478, @T.as.Destroy.impl.Op(constants.%A) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc10: = bound_method %a.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %A.as.Destroy.impl.Op.call.loc13: init %empty_tuple.type = call %A.as.Destroy.impl.Op.bound.loc13(%addr.loc13) +// CHECK:STDOUT: %A.as.Destroy.impl.Op.bound.loc10: = bound_method %a.var, constants.%A.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc10: %ptr.07e = addr_of %a.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10: init %empty_tuple.type = call %bound_method.loc10(%addr.loc10) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7: = bound_method %.loc7_11.1, constants.%T.as.Destroy.impl.Op.478 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.478, @T.as.Destroy.impl.Op(constants.%A) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc7: = bound_method %.loc7_11.1, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %A.as.Destroy.impl.Op.call.loc10: init %empty_tuple.type = call %A.as.Destroy.impl.Op.bound.loc10(%addr.loc10) +// CHECK:STDOUT: %A.as.Destroy.impl.Op.bound.loc7: = bound_method %.loc7_11.1, constants.%A.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc7: %ptr.07e = addr_of %.loc7_11.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7: init %empty_tuple.type = call %bound_method.loc7(%addr.loc7) +// CHECK:STDOUT: %A.as.Destroy.impl.Op.call.loc7: init %empty_tuple.type = call %A.as.Destroy.impl.Op.bound.loc7(%addr.loc7) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @F [from "b.carbon"]; // CHECK:STDOUT: +// CHECK:STDOUT: fn @A.as.Destroy.impl.Op = "no_op" [from "a.carbon"]; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/namespace/shadow.carbon b/toolchain/check/testdata/namespace/shadow.carbon index 298113d6b683..e470813cce5a 100644 --- a/toolchain/check/testdata/namespace/shadow.carbon +++ b/toolchain/check/testdata/namespace/shadow.carbon @@ -52,6 +52,7 @@ fn N.M.B() -> i32 { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -64,7 +65,6 @@ fn N.M.B() -> i32 { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.956, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] // CHECK:STDOUT: %bound_method: = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] diff --git a/toolchain/check/testdata/operators/builtin/assignment.carbon b/toolchain/check/testdata/operators/builtin/assignment.carbon index 0aca5157e23b..12ded42768ce 100644 --- a/toolchain/check/testdata/operators/builtin/assignment.carbon +++ b/toolchain/check/testdata/operators/builtin/assignment.carbon @@ -46,6 +46,7 @@ fn Main() { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -101,7 +102,6 @@ fn Main() { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.491: = bound_method %int_10.64f, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.5ba: = bound_method %int_10.64f, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_10.265: %i32 = int_value 10 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.ba2: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%ptr.235) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.649: %T.as.Destroy.impl.Op.type.ba2 = struct_value () [concrete] // CHECK:STDOUT: %ptr.5d5: type = ptr_type %ptr.235 [concrete] diff --git a/toolchain/check/testdata/operators/builtin/fail_and_or_not_in_function.carbon b/toolchain/check/testdata/operators/builtin/fail_and_or_not_in_function.carbon index 1026663aaf79..f99d7abd3a68 100644 --- a/toolchain/check/testdata/operators/builtin/fail_and_or_not_in_function.carbon +++ b/toolchain/check/testdata/operators/builtin/fail_and_or_not_in_function.carbon @@ -168,6 +168,13 @@ fn F() { // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C: type = class_type @C, @C(%B.7dd) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%B.7dd) [symbolic] +// CHECK:STDOUT: %ptr.1a8: type = ptr_type %C [symbolic] +// CHECK:STDOUT: %pattern_type.926: type = pattern_type %ptr.1a8 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%B.7dd) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %B.d97: type = class_type @B [concrete] @@ -175,12 +182,43 @@ fn F() { // CHECK:STDOUT: %false: bool = bool_literal false [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(.inst27.loc4_14: bool) { +// CHECK:STDOUT: %B: bool = bind_symbolic_name B, 0 [symbolic = %B (constants.%B.7dd)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%B) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%B) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.926) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.926) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_24.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.1a8) = value_param call_param0 +// CHECK:STDOUT: %.loc4_24.2: type = splice_block %Self.ref [symbolic = %C (constants.%C)] { +// CHECK:STDOUT: %.loc4_24.3: type = specific_constant constants.%C, @C(constants.%B.7dd) [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_24.3 [symbolic = %C (constants.%C)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.1a8) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(.inst27.loc4_14: bool) { // CHECK:STDOUT: %B: bool = bind_symbolic_name B, 0 [symbolic = %B (constants.%B.7dd)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%B.7dd) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -203,9 +241,32 @@ fn F() { // CHECK:STDOUT: .C = // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(.inst27.loc4_14: bool) { +// CHECK:STDOUT: %B: bool = bind_symbolic_name B, 0 [symbolic = %B (constants.%B.7dd)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%B) [symbolic = %C (constants.%C)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.1a8)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.926)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.1a8)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(); // CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%B.7dd) { // CHECK:STDOUT: %B => constants.%B.7dd // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%B.7dd) { +// CHECK:STDOUT: %B => constants.%B.7dd +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%B.7dd) { +// CHECK:STDOUT: %B => constants.%B.7dd +// CHECK:STDOUT: %C => constants.%C +// CHECK:STDOUT: %ptr => constants.%ptr.1a8 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.926 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/operators/builtin/fail_assignment_to_non_assignable.carbon b/toolchain/check/testdata/operators/builtin/fail_assignment_to_non_assignable.carbon index 447f4f7d4e0e..b37d5d77f21d 100644 --- a/toolchain/check/testdata/operators/builtin/fail_assignment_to_non_assignable.carbon +++ b/toolchain/check/testdata/operators/builtin/fail_assignment_to_non_assignable.carbon @@ -80,6 +80,7 @@ fn Main() { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -118,7 +119,6 @@ fn Main() { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.491: = bound_method %int_10.64f, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.5ba: = bound_method %int_10.64f, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_10.265: %i32 = int_value 10 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(%i32) [concrete] diff --git a/toolchain/check/testdata/operators/builtin/fail_redundant_compound_access.carbon b/toolchain/check/testdata/operators/builtin/fail_redundant_compound_access.carbon index e15f748dedbc..7a3bbf6fa841 100644 --- a/toolchain/check/testdata/operators/builtin/fail_redundant_compound_access.carbon +++ b/toolchain/check/testdata/operators/builtin/fail_redundant_compound_access.carbon @@ -44,6 +44,7 @@ fn Main() { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -62,7 +63,6 @@ fn Main() { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.b30: = bound_method %int_3.1ba, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.047: = bound_method %int_3.1ba, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_3.822: %i32 = int_value 3 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] diff --git a/toolchain/check/testdata/operators/builtin/fail_type_mismatch_assignment.carbon b/toolchain/check/testdata/operators/builtin/fail_type_mismatch_assignment.carbon index b2aefa0ba6f1..61ec8ebfb789 100644 --- a/toolchain/check/testdata/operators/builtin/fail_type_mismatch_assignment.carbon +++ b/toolchain/check/testdata/operators/builtin/fail_type_mismatch_assignment.carbon @@ -40,6 +40,7 @@ fn Main() { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -53,7 +54,6 @@ fn Main() { // CHECK:STDOUT: %bound_method: = bound_method %int_3.1ba, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_3.822: %i32 = int_value 3 [concrete] // CHECK:STDOUT: %float: f64 = float_literal 5.6000000000000005 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] diff --git a/toolchain/check/testdata/operators/overloaded/add.carbon b/toolchain/check/testdata/operators/overloaded/add.carbon index 565a7ee1f0dc..b1f1d25ff695 100644 --- a/toolchain/check/testdata/operators/overloaded/add.carbon +++ b/toolchain/check/testdata/operators/overloaded/add.carbon @@ -43,6 +43,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %AddWith.type.ffb: type = facet_type <@AddWith, @AddWith(%C)> [concrete] // CHECK:STDOUT: %AddWith.Op.type.45e: type = fn_type @AddWith.Op, @AddWith(%C) [concrete] @@ -53,7 +54,6 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %AddAssignWith.type.393: type = facet_type <@AddAssignWith, @AddAssignWith(%C)> [concrete] // CHECK:STDOUT: %AddAssignWith.Op.type.5af: type = fn_type @AddAssignWith.Op, @AddAssignWith(%C) [concrete] // CHECK:STDOUT: %AddAssignWith.impl_witness: = impl_witness file.%AddAssignWith.impl_witness_table [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %C.as.AddAssignWith.impl.Op.type: type = fn_type @C.as.AddAssignWith.impl.Op [concrete] // CHECK:STDOUT: %C.as.AddAssignWith.impl.Op: %C.as.AddAssignWith.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %AddAssignWith.facet: %AddAssignWith.type.393 = facet_value %C, (%AddAssignWith.impl_witness) [concrete] @@ -69,9 +69,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %a.ref: %C = name_ref a, %a // CHECK:STDOUT: %b.ref: %C = name_ref b, %b // CHECK:STDOUT: %impl.elem1: %.268 = impl_witness_access constants.%AddWith.impl_witness, element1 [concrete = constants.%C.as.AddWith.impl.Op] -// CHECK:STDOUT: %bound_method.loc32: = bound_method %a.ref, %impl.elem1 +// CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem1 // CHECK:STDOUT: -// CHECK:STDOUT: %C.as.AddWith.impl.Op.call: init %C = call %bound_method.loc32(%a.ref, %b.ref) to %.loc30 +// CHECK:STDOUT: %C.as.AddWith.impl.Op.call: init %C = call %bound_method(%a.ref, %b.ref) to %.loc30 // CHECK:STDOUT: // CHECK:STDOUT: return %C.as.AddWith.impl.Op.call to %return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/operators/overloaded/bit_and.carbon b/toolchain/check/testdata/operators/overloaded/bit_and.carbon index d9fd2adfd4bd..f513734a8581 100644 --- a/toolchain/check/testdata/operators/overloaded/bit_and.carbon +++ b/toolchain/check/testdata/operators/overloaded/bit_and.carbon @@ -43,6 +43,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %BitAndWith.type.e40: type = facet_type <@BitAndWith, @BitAndWith(%C)> [concrete] // CHECK:STDOUT: %BitAndWith.Op.type.914: type = fn_type @BitAndWith.Op, @BitAndWith(%C) [concrete] @@ -53,7 +54,6 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %BitAndAssignWith.type.e85: type = facet_type <@BitAndAssignWith, @BitAndAssignWith(%C)> [concrete] // CHECK:STDOUT: %BitAndAssignWith.Op.type.73d: type = fn_type @BitAndAssignWith.Op, @BitAndAssignWith(%C) [concrete] // CHECK:STDOUT: %BitAndAssignWith.impl_witness: = impl_witness file.%BitAndAssignWith.impl_witness_table [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %C.as.BitAndAssignWith.impl.Op.type: type = fn_type @C.as.BitAndAssignWith.impl.Op [concrete] // CHECK:STDOUT: %C.as.BitAndAssignWith.impl.Op: %C.as.BitAndAssignWith.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %BitAndAssignWith.facet: %BitAndAssignWith.type.e85 = facet_value %C, (%BitAndAssignWith.impl_witness) [concrete] @@ -69,9 +69,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %a.ref: %C = name_ref a, %a // CHECK:STDOUT: %b.ref: %C = name_ref b, %b // CHECK:STDOUT: %impl.elem1: %.04a = impl_witness_access constants.%BitAndWith.impl_witness, element1 [concrete = constants.%C.as.BitAndWith.impl.Op] -// CHECK:STDOUT: %bound_method.loc32: = bound_method %a.ref, %impl.elem1 +// CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem1 // CHECK:STDOUT: -// CHECK:STDOUT: %C.as.BitAndWith.impl.Op.call: init %C = call %bound_method.loc32(%a.ref, %b.ref) to %.loc30 +// CHECK:STDOUT: %C.as.BitAndWith.impl.Op.call: init %C = call %bound_method(%a.ref, %b.ref) to %.loc30 // CHECK:STDOUT: // CHECK:STDOUT: return %C.as.BitAndWith.impl.Op.call to %return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/operators/overloaded/bit_complement.carbon b/toolchain/check/testdata/operators/overloaded/bit_complement.carbon index fe122c636beb..d631b5ae96f8 100644 --- a/toolchain/check/testdata/operators/overloaded/bit_complement.carbon +++ b/toolchain/check/testdata/operators/overloaded/bit_complement.carbon @@ -50,9 +50,9 @@ fn TestOp(a: C) -> C { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %C = name_ref a, %a // CHECK:STDOUT: %impl.elem1: %.18b = impl_witness_access constants.%BitComplement.impl_witness, element1 [concrete = constants.%C.as.BitComplement.impl.Op] -// CHECK:STDOUT: %bound_method.loc29: = bound_method %a.ref, %impl.elem1 +// CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem1 // CHECK:STDOUT: -// CHECK:STDOUT: %C.as.BitComplement.impl.Op.call: init %C = call %bound_method.loc29(%a.ref) to %.loc27 +// CHECK:STDOUT: %C.as.BitComplement.impl.Op.call: init %C = call %bound_method(%a.ref) to %.loc27 // CHECK:STDOUT: // CHECK:STDOUT: return %C.as.BitComplement.impl.Op.call to %return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/operators/overloaded/bit_or.carbon b/toolchain/check/testdata/operators/overloaded/bit_or.carbon index 964c7585e481..2762913817e6 100644 --- a/toolchain/check/testdata/operators/overloaded/bit_or.carbon +++ b/toolchain/check/testdata/operators/overloaded/bit_or.carbon @@ -43,6 +43,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %BitOrWith.type.502: type = facet_type <@BitOrWith, @BitOrWith(%C)> [concrete] // CHECK:STDOUT: %BitOrWith.Op.type.501: type = fn_type @BitOrWith.Op, @BitOrWith(%C) [concrete] @@ -53,7 +54,6 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %BitOrAssignWith.type.3e6: type = facet_type <@BitOrAssignWith, @BitOrAssignWith(%C)> [concrete] // CHECK:STDOUT: %BitOrAssignWith.Op.type.efc: type = fn_type @BitOrAssignWith.Op, @BitOrAssignWith(%C) [concrete] // CHECK:STDOUT: %BitOrAssignWith.impl_witness: = impl_witness file.%BitOrAssignWith.impl_witness_table [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %C.as.BitOrAssignWith.impl.Op.type: type = fn_type @C.as.BitOrAssignWith.impl.Op [concrete] // CHECK:STDOUT: %C.as.BitOrAssignWith.impl.Op: %C.as.BitOrAssignWith.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %BitOrAssignWith.facet: %BitOrAssignWith.type.3e6 = facet_value %C, (%BitOrAssignWith.impl_witness) [concrete] @@ -69,9 +69,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %a.ref: %C = name_ref a, %a // CHECK:STDOUT: %b.ref: %C = name_ref b, %b // CHECK:STDOUT: %impl.elem1: %.b8d = impl_witness_access constants.%BitOrWith.impl_witness, element1 [concrete = constants.%C.as.BitOrWith.impl.Op] -// CHECK:STDOUT: %bound_method.loc32: = bound_method %a.ref, %impl.elem1 +// CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem1 // CHECK:STDOUT: -// CHECK:STDOUT: %C.as.BitOrWith.impl.Op.call: init %C = call %bound_method.loc32(%a.ref, %b.ref) to %.loc30 +// CHECK:STDOUT: %C.as.BitOrWith.impl.Op.call: init %C = call %bound_method(%a.ref, %b.ref) to %.loc30 // CHECK:STDOUT: // CHECK:STDOUT: return %C.as.BitOrWith.impl.Op.call to %return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/operators/overloaded/bit_xor.carbon b/toolchain/check/testdata/operators/overloaded/bit_xor.carbon index 0e657ec540c1..dad2c9b0fc74 100644 --- a/toolchain/check/testdata/operators/overloaded/bit_xor.carbon +++ b/toolchain/check/testdata/operators/overloaded/bit_xor.carbon @@ -43,6 +43,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %BitXorWith.type.f9b: type = facet_type <@BitXorWith, @BitXorWith(%C)> [concrete] // CHECK:STDOUT: %BitXorWith.Op.type.502: type = fn_type @BitXorWith.Op, @BitXorWith(%C) [concrete] @@ -53,7 +54,6 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %BitXorAssignWith.type.57a: type = facet_type <@BitXorAssignWith, @BitXorAssignWith(%C)> [concrete] // CHECK:STDOUT: %BitXorAssignWith.Op.type.ad0: type = fn_type @BitXorAssignWith.Op, @BitXorAssignWith(%C) [concrete] // CHECK:STDOUT: %BitXorAssignWith.impl_witness: = impl_witness file.%BitXorAssignWith.impl_witness_table [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %C.as.BitXorAssignWith.impl.Op.type: type = fn_type @C.as.BitXorAssignWith.impl.Op [concrete] // CHECK:STDOUT: %C.as.BitXorAssignWith.impl.Op: %C.as.BitXorAssignWith.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %BitXorAssignWith.facet: %BitXorAssignWith.type.57a = facet_value %C, (%BitXorAssignWith.impl_witness) [concrete] @@ -69,9 +69,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %a.ref: %C = name_ref a, %a // CHECK:STDOUT: %b.ref: %C = name_ref b, %b // CHECK:STDOUT: %impl.elem1: %.c60 = impl_witness_access constants.%BitXorWith.impl_witness, element1 [concrete = constants.%C.as.BitXorWith.impl.Op] -// CHECK:STDOUT: %bound_method.loc32: = bound_method %a.ref, %impl.elem1 +// CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem1 // CHECK:STDOUT: -// CHECK:STDOUT: %C.as.BitXorWith.impl.Op.call: init %C = call %bound_method.loc32(%a.ref, %b.ref) to %.loc30 +// CHECK:STDOUT: %C.as.BitXorWith.impl.Op.call: init %C = call %bound_method(%a.ref, %b.ref) to %.loc30 // CHECK:STDOUT: // CHECK:STDOUT: return %C.as.BitXorWith.impl.Op.call to %return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/operators/overloaded/dec.carbon b/toolchain/check/testdata/operators/overloaded/dec.carbon index 4ac838ea9434..f1b4451f524e 100644 --- a/toolchain/check/testdata/operators/overloaded/dec.carbon +++ b/toolchain/check/testdata/operators/overloaded/dec.carbon @@ -33,12 +33,12 @@ fn TestOp() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Dec.type: type = facet_type <@Dec> [concrete] // CHECK:STDOUT: %Dec.Op.type: type = fn_type @Dec.Op [concrete] // CHECK:STDOUT: %Dec.impl_witness: = impl_witness file.%Dec.impl_witness_table [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %C.as.Dec.impl.Op.type: type = fn_type @C.as.Dec.impl.Op [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %C.as.Dec.impl.Op: %C.as.Dec.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Dec.facet: %Dec.type = facet_value %C, (%Dec.impl_witness) [concrete] // CHECK:STDOUT: %.859: type = fn_type_with_self_type %Dec.Op.type, %Dec.facet [concrete] @@ -52,9 +52,9 @@ fn TestOp() { // CHECK:STDOUT: // CHECK:STDOUT: %c.ref: ref %C = name_ref c, %c // CHECK:STDOUT: %impl.elem0: %.859 = impl_witness_access constants.%Dec.impl_witness, element0 [concrete = constants.%C.as.Dec.impl.Op] -// CHECK:STDOUT: %bound_method.loc28: = bound_method %c.ref, %impl.elem0 +// CHECK:STDOUT: %bound_method: = bound_method %c.ref, %impl.elem0 // CHECK:STDOUT: %addr.loc28: %ptr.019 = addr_of %c.ref -// CHECK:STDOUT: %C.as.Dec.impl.Op.call: init %empty_tuple.type = call %bound_method.loc28(%addr.loc28) +// CHECK:STDOUT: %C.as.Dec.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc28) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/operators/overloaded/div.carbon b/toolchain/check/testdata/operators/overloaded/div.carbon index 9239b6ef1680..f7e4a904670f 100644 --- a/toolchain/check/testdata/operators/overloaded/div.carbon +++ b/toolchain/check/testdata/operators/overloaded/div.carbon @@ -43,6 +43,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %DivWith.type.ead: type = facet_type <@DivWith, @DivWith(%C)> [concrete] // CHECK:STDOUT: %DivWith.Op.type.c4b: type = fn_type @DivWith.Op, @DivWith(%C) [concrete] @@ -53,7 +54,6 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %DivAssignWith.type.08b: type = facet_type <@DivAssignWith, @DivAssignWith(%C)> [concrete] // CHECK:STDOUT: %DivAssignWith.Op.type.629: type = fn_type @DivAssignWith.Op, @DivAssignWith(%C) [concrete] // CHECK:STDOUT: %DivAssignWith.impl_witness: = impl_witness file.%DivAssignWith.impl_witness_table [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %C.as.DivAssignWith.impl.Op.type: type = fn_type @C.as.DivAssignWith.impl.Op [concrete] // CHECK:STDOUT: %C.as.DivAssignWith.impl.Op: %C.as.DivAssignWith.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %DivAssignWith.facet: %DivAssignWith.type.08b = facet_value %C, (%DivAssignWith.impl_witness) [concrete] @@ -69,9 +69,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %a.ref: %C = name_ref a, %a // CHECK:STDOUT: %b.ref: %C = name_ref b, %b // CHECK:STDOUT: %impl.elem1: %.bb6 = impl_witness_access constants.%DivWith.impl_witness, element1 [concrete = constants.%C.as.DivWith.impl.Op] -// CHECK:STDOUT: %bound_method.loc32: = bound_method %a.ref, %impl.elem1 +// CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem1 // CHECK:STDOUT: -// CHECK:STDOUT: %C.as.DivWith.impl.Op.call: init %C = call %bound_method.loc32(%a.ref, %b.ref) to %.loc30 +// CHECK:STDOUT: %C.as.DivWith.impl.Op.call: init %C = call %bound_method(%a.ref, %b.ref) to %.loc30 // CHECK:STDOUT: // CHECK:STDOUT: return %C.as.DivWith.impl.Op.call to %return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/operators/overloaded/eq.carbon b/toolchain/check/testdata/operators/overloaded/eq.carbon index eb63988cad87..0dcff4ffcadb 100644 --- a/toolchain/check/testdata/operators/overloaded/eq.carbon +++ b/toolchain/check/testdata/operators/overloaded/eq.carbon @@ -85,6 +85,13 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %EqWith.type.c2e: type = generic_interface_type @EqWith [concrete] @@ -112,11 +119,13 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .EqWith = %Core.EqWith // CHECK:STDOUT: .Bool = %Core.Bool // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.EqWith: %EqWith.type.c2e = import_ref Core//prelude/operators/comparison, EqWith, loaded [concrete = constants.%EqWith.generic] // CHECK:STDOUT: %Core.Bool: %Bool.type = import_ref Core//prelude/types/bool, Bool, loaded [concrete = constants.%Bool] // CHECK:STDOUT: } @@ -181,6 +190,22 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.EqWith.impl: %C.ref.loc6_6 as %EqWith.type { // CHECK:STDOUT: %C.as.EqWith.impl.Equal.decl: %C.as.EqWith.impl.Equal.type = fn_decl @C.as.EqWith.impl.Equal [concrete = constants.%C.as.EqWith.impl.Equal] { // CHECK:STDOUT: %self.patt: %pattern_type.c48 = binding_pattern self [concrete] @@ -231,6 +256,9 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -239,6 +267,8 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.EqWith.impl.Equal(%self.param: %C, %other.param: %C) -> bool; // CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.EqWith.impl.NotEqual(%self.param: %C, %other.param: %C) -> bool; @@ -271,6 +301,13 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.510: type = pattern_type %D [concrete] @@ -287,11 +324,13 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Bool = %Core.Bool // CHECK:STDOUT: .EqWith = %Core.EqWith // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Bool: %Bool.type = import_ref Core//prelude/types/bool, Bool, loaded [concrete = constants.%Bool] // CHECK:STDOUT: %Core.EqWith: %EqWith.type.c2e = import_ref Core//prelude/operators/comparison, EqWith, loaded [concrete = constants.%EqWith.generic] // CHECK:STDOUT: } @@ -347,7 +386,26 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -356,6 +414,8 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: .Self = constants.%D // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @TestEqual(%a.param: %D, %b.param: %D) -> bool { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %D = name_ref a, %a @@ -374,9 +434,21 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %EqWith.type.c2e: type = generic_interface_type @EqWith [concrete] // CHECK:STDOUT: %EqWith.generic: %EqWith.type.c2e = struct_value () [concrete] // CHECK:STDOUT: %pattern_type.831: type = pattern_type bool [concrete] @@ -398,11 +470,13 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .EqWith = %Core.EqWith // CHECK:STDOUT: .Bool = %Core.Bool // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.EqWith: %EqWith.type.c2e = import_ref Core//prelude/operators/comparison, EqWith, loaded [concrete = constants.%EqWith.generic] // CHECK:STDOUT: %Core.Bool: %Bool.type = import_ref Core//prelude/types/bool, Bool, loaded [concrete = constants.%Bool] // CHECK:STDOUT: } @@ -469,6 +543,38 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.EqWith.impl: %C.ref.loc7_6 as %EqWith.type { // CHECK:STDOUT: %C.as.EqWith.impl.Equal.decl: %C.as.EqWith.impl.Equal.type = fn_decl @C.as.EqWith.impl.Equal [concrete = constants.%C.as.EqWith.impl.Equal] { // CHECK:STDOUT: %self.patt: %pattern_type.c48 = binding_pattern self [concrete] @@ -519,6 +625,9 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -528,6 +637,9 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -536,6 +648,10 @@ fn TestLhsBad(a: D, b: C) -> bool { // CHECK:STDOUT: .Self = constants.%D // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.EqWith.impl.Equal(%self.param: %C, %other.param: %C) -> bool; // CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.EqWith.impl.NotEqual(%self.param: %C, %other.param: %C) -> bool; diff --git a/toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon b/toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon index 8782d30d4bd4..56a27d23f838 100644 --- a/toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon +++ b/toolchain/check/testdata/operators/overloaded/fail_assign_non_ref.carbon @@ -49,16 +49,20 @@ fn TestAddAssignNonRef(a: C, b: C) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %Inc.type: type = facet_type <@Inc> [concrete] -// CHECK:STDOUT: %Inc.Op.type: type = fn_type @Inc.Op [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] -// CHECK:STDOUT: %Inc.impl_witness: = impl_witness file.%Inc.impl_witness_table [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] -// CHECK:STDOUT: %C.as.Inc.impl.Op.type: type = fn_type @C.as.Inc.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %Inc.type: type = facet_type <@Inc> [concrete] +// CHECK:STDOUT: %Inc.Op.type: type = fn_type @Inc.Op [concrete] +// CHECK:STDOUT: %Inc.impl_witness: = impl_witness file.%Inc.impl_witness_table [concrete] +// CHECK:STDOUT: %C.as.Inc.impl.Op.type: type = fn_type @C.as.Inc.impl.Op [concrete] // CHECK:STDOUT: %C.as.Inc.impl.Op: %C.as.Inc.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Inc.facet: %Inc.type = facet_value %C, (%Inc.impl_witness) [concrete] // CHECK:STDOUT: %AddAssignWith.type.fc6: type = generic_interface_type @AddAssignWith [concrete] @@ -73,10 +77,6 @@ fn TestAddAssignNonRef(a: C, b: C) { // CHECK:STDOUT: %TestIncNonRef.type: type = fn_type @TestIncNonRef [concrete] // CHECK:STDOUT: %TestIncNonRef: %TestIncNonRef.type = struct_value () [concrete] // CHECK:STDOUT: %.bc7: type = fn_type_with_self_type %Inc.Op.type, %Inc.facet [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: %TestAddAssignNonRef.type: type = fn_type @TestAddAssignNonRef [concrete] // CHECK:STDOUT: %TestAddAssignNonRef: %TestAddAssignNonRef.type = struct_value () [concrete] // CHECK:STDOUT: %.e2d: type = fn_type_with_self_type %AddAssignWith.Op.type.5af, %AddAssignWith.facet [concrete] @@ -84,15 +84,15 @@ fn TestAddAssignNonRef(a: C, b: C) { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Inc = %Core.Inc // CHECK:STDOUT: .AddAssignWith = %Core.AddAssignWith -// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Inc: type = import_ref Core//prelude/operators/arithmetic, Inc, loaded [concrete = constants.%Inc.type] // CHECK:STDOUT: %Core.AddAssignWith: %AddAssignWith.type.fc6 = import_ref Core//prelude/operators/arithmetic, AddAssignWith, loaded [concrete = constants.%AddAssignWith.generic] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -143,6 +143,22 @@ fn TestAddAssignNonRef(a: C, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc17: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.Inc.impl: %C.ref as %Inc.ref { // CHECK:STDOUT: %C.as.Inc.impl.Op.decl: %C.as.Inc.impl.Op.type = fn_decl @C.as.Inc.impl.Op [concrete = constants.%C.as.Inc.impl.Op] { // CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] @@ -189,14 +205,19 @@ fn TestAddAssignNonRef(a: C, b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.Inc.impl.Op(%self.param: %ptr.019); // CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.AddAssignWith.impl.Op(%self.param: %ptr.019, %other.param: %C); @@ -205,15 +226,13 @@ fn TestAddAssignNonRef(a: C, b: C) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %C = name_ref a, %a // CHECK:STDOUT: %impl.elem0: %.bc7 = impl_witness_access constants.%Inc.impl_witness, element0 [concrete = constants.%C.as.Inc.impl.Op] -// CHECK:STDOUT: %bound_method.loc34_3: = bound_method %a.ref, %impl.elem0 +// CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem0 // CHECK:STDOUT: %.loc34: ref %C = temporary_storage // CHECK:STDOUT: %addr.loc34_5.1: %ptr.019 = addr_of %.loc34 -// CHECK:STDOUT: %C.as.Inc.impl.Op.call: init %empty_tuple.type = call %bound_method.loc34_3(%addr.loc34_5.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc34, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc34_5: = bound_method %.loc34, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.Inc.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc34_5.1) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc34, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc34_5.2: %ptr.019 = addr_of %.loc34 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc34_5(%addr.loc34_5.2) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr.loc34_5.2) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -222,15 +241,13 @@ fn TestAddAssignNonRef(a: C, b: C) { // CHECK:STDOUT: %a.ref: %C = name_ref a, %a // CHECK:STDOUT: %b.ref: %C = name_ref b, %b // CHECK:STDOUT: %impl.elem0: %.e2d = impl_witness_access constants.%AddAssignWith.impl_witness, element0 [concrete = constants.%C.as.AddAssignWith.impl.Op] -// CHECK:STDOUT: %bound_method.loc45_5: = bound_method %a.ref, %impl.elem0 +// CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem0 // CHECK:STDOUT: %.loc45: ref %C = temporary_storage // CHECK:STDOUT: %addr.loc45_3.1: %ptr.019 = addr_of %.loc45 -// CHECK:STDOUT: %C.as.AddAssignWith.impl.Op.call: init %empty_tuple.type = call %bound_method.loc45_5(%addr.loc45_3.1, %b.ref) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc45, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc45_3: = bound_method %.loc45, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.AddAssignWith.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc45_3.1, %b.ref) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %.loc45, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc45_3.2: %ptr.019 = addr_of %.loc45 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc45_3(%addr.loc45_3.2) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr.loc45_3.2) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/operators/overloaded/fail_no_impl.carbon b/toolchain/check/testdata/operators/overloaded/fail_no_impl.carbon index 4c465f21b589..1cf01294d70b 100644 --- a/toolchain/check/testdata/operators/overloaded/fail_no_impl.carbon +++ b/toolchain/check/testdata/operators/overloaded/fail_no_impl.carbon @@ -50,11 +50,18 @@ fn TestRef(b: C) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %TestUnary.type: type = fn_type @TestUnary [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %TestUnary: %TestUnary.type = struct_value () [concrete] // CHECK:STDOUT: %Negate.type: type = facet_type <@Negate> [concrete] // CHECK:STDOUT: %AddWith.type.e05: type = generic_interface_type @AddWith [concrete] @@ -67,28 +74,23 @@ fn TestRef(b: C) { // CHECK:STDOUT: %AddAssignWith.type.fc6: type = generic_interface_type @AddAssignWith [concrete] // CHECK:STDOUT: %AddAssignWith.generic: %AddAssignWith.type.fc6 = struct_value () [concrete] // CHECK:STDOUT: %Inc.type: type = facet_type <@Inc> [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.153: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.5d7: %T.as.Destroy.impl.Op.type.153 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(%C) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Negate = %Core.Negate // CHECK:STDOUT: .AddWith = %Core.AddWith // CHECK:STDOUT: .AddAssignWith = %Core.AddAssignWith // CHECK:STDOUT: .Inc = %Core.Inc -// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// 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.AddWith: %AddWith.type.e05 = import_ref Core//prelude/operators/arithmetic, AddWith, loaded [concrete = constants.%AddWith.generic] // CHECK:STDOUT: %Core.AddAssignWith: %AddAssignWith.type.fc6 = import_ref Core//prelude/operators/arithmetic, AddAssignWith, loaded [concrete = constants.%AddAssignWith.generic] // CHECK:STDOUT: %Core.Inc: type = import_ref Core//prelude/operators/arithmetic, Inc, loaded [concrete = constants.%Inc.type] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -142,15 +144,36 @@ fn TestRef(b: C) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc17: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] -// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type // CHECK:STDOUT: // CHECK:STDOUT: !members: // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @TestUnary(%a.param: %C) -> %return.param: %C { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %C = name_ref a, %a @@ -180,11 +203,9 @@ fn TestRef(b: C) { // CHECK:STDOUT: %a.ref.loc41: ref %C = name_ref a, %a // CHECK:STDOUT: %b.ref: %C = name_ref b, %b // CHECK:STDOUT: %a.ref.loc46: ref %C = name_ref a, %a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %a.var, constants.%T.as.Destroy.impl.Op.5d7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5d7, @T.as.Destroy.impl.Op(constants.%C) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %a.var, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %C.as.Destroy.impl.Op.bound: = bound_method %a.var, constants.%C.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.019 = addr_of %a.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %C.as.Destroy.impl.Op.call: init %empty_tuple.type = call %C.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/operators/overloaded/implicit_as.carbon b/toolchain/check/testdata/operators/overloaded/implicit_as.carbon index 31c5b5e3e849..7dda20240a30 100644 --- a/toolchain/check/testdata/operators/overloaded/implicit_as.carbon +++ b/toolchain/check/testdata/operators/overloaded/implicit_as.carbon @@ -47,6 +47,13 @@ fn Test() { // CHECK:STDOUT: %i32.builtin: type = int_type signed, %int_32 [concrete] // CHECK:STDOUT: %complete_type.f8a: = complete_type_witness %i32.builtin [concrete] // CHECK:STDOUT: %X.elem: type = unbound_element_type %X, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.807: = impl_witness @X.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete] +// CHECK:STDOUT: %pattern_type.1c6: type = pattern_type %ptr.d17 [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op.type: type = fn_type @X.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op: %X.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete] // CHECK:STDOUT: %complete_type.54b: = complete_type_witness %struct_type.n [concrete] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] @@ -82,24 +89,19 @@ fn Test() { // CHECK:STDOUT: %.2ea: type = fn_type_with_self_type %ImplicitAs.Convert.type.1b6, %ImplicitAs.facet.bf9 [concrete] // CHECK:STDOUT: %Source.specific_fn.cc7: = specific_function %Source, @Source(%i32) [concrete] // CHECK:STDOUT: %.9b4: type = fn_type_with_self_type %ImplicitAs.Convert.type.665, %ImplicitAs.facet.d80 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.9e1: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%X) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.33a: %T.as.Destroy.impl.Op.type.9e1 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.33a, @T.as.Destroy.impl.Op(%X) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] -// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -165,6 +167,22 @@ fn Test() { // CHECK:STDOUT: %Test.decl: %Test.type = fn_decl @Test [concrete = constants.%Test] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @X.as.Destroy.impl: constants.%X as constants.%Destroy.type { +// CHECK:STDOUT: %X.as.Destroy.impl.Op.decl: %X.as.Destroy.impl.Op.type = fn_decl @X.as.Destroy.impl.Op [concrete = constants.%X.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1c6 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1c6 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.d17 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%X [concrete = constants.%X] +// CHECK:STDOUT: %self: %ptr.d17 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %X.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @X.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @i32.as.ImplicitAs.impl: %i32 as %ImplicitAs.type { // CHECK:STDOUT: %i32.as.ImplicitAs.impl.Convert.decl: %i32.as.ImplicitAs.impl.Convert.type = fn_decl @i32.as.ImplicitAs.impl.Convert [concrete = constants.%i32.as.ImplicitAs.impl.Convert] { // CHECK:STDOUT: %self.patt: %pattern_type.7ce = binding_pattern self [concrete] @@ -215,6 +233,9 @@ fn Test() { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc16: %X.elem = field_decl n, element0 [concrete] +// CHECK:STDOUT: impl_decl @X.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@X.as.Destroy.impl.%X.as.Destroy.impl.Op.decl), @X.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.807] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete = constants.%struct_type.n] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n [concrete = constants.%complete_type.54b] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -224,6 +245,8 @@ fn Test() { // CHECK:STDOUT: .n = %.loc16 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @X.as.Destroy.impl.Op(%self.param: %ptr.d17) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @i32.as.ImplicitAs.impl.Convert(%self.param: %i32) -> %return.param: %X { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %self.ref: %i32 = name_ref self, %self @@ -277,10 +300,10 @@ fn Test() { // CHECK:STDOUT: %.loc34_20.1: ref %X = temporary_storage // CHECK:STDOUT: %Source.call.loc34: init %X = call %Source.specific_fn.loc34() to %.loc34_20.1 // CHECK:STDOUT: %impl.elem0.loc34: %.2ea = impl_witness_access constants.%ImplicitAs.impl_witness.b30, element0 [concrete = constants.%X.as.ImplicitAs.impl.Convert] -// CHECK:STDOUT: %bound_method.loc34_20.1: = bound_method %Source.call.loc34, %impl.elem0.loc34 +// CHECK:STDOUT: %bound_method.loc34: = bound_method %Source.call.loc34, %impl.elem0.loc34 // CHECK:STDOUT: %.loc34_20.2: ref %X = temporary %.loc34_20.1, %Source.call.loc34 // CHECK:STDOUT: %.loc34_20.3: %X = bind_value %.loc34_20.2 -// CHECK:STDOUT: %X.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc34_20.1(%.loc34_20.3) +// CHECK:STDOUT: %X.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc34(%.loc34_20.3) // CHECK:STDOUT: %.loc34_20.4: %i32 = value_of_initializer %X.as.ImplicitAs.impl.Convert.call // CHECK:STDOUT: %.loc34_20.5: %i32 = converted %Source.call.loc34, %.loc34_20.4 // CHECK:STDOUT: %Sink_i32.call: init %empty_tuple.type = call %Sink_i32.ref(%.loc34_20.5) @@ -291,25 +314,21 @@ fn Test() { // CHECK:STDOUT: %Source.specific_fn.loc35: = specific_function %Source.ref.loc35, @Source(constants.%i32) [concrete = constants.%Source.specific_fn.cc7] // CHECK:STDOUT: %Source.call.loc35: init %i32 = call %Source.specific_fn.loc35() // CHECK:STDOUT: %impl.elem0.loc35: %.9b4 = impl_witness_access constants.%ImplicitAs.impl_witness.aa3, element0 [concrete = constants.%i32.as.ImplicitAs.impl.Convert] -// CHECK:STDOUT: %bound_method.loc35_20.1: = bound_method %Source.call.loc35, %impl.elem0.loc35 +// CHECK:STDOUT: %bound_method.loc35: = bound_method %Source.call.loc35, %impl.elem0.loc35 // CHECK:STDOUT: %.loc35_20.1: ref %X = temporary_storage // CHECK:STDOUT: %.loc35_20.2: %i32 = value_of_initializer %Source.call.loc35 // CHECK:STDOUT: %.loc35_20.3: %i32 = converted %Source.call.loc35, %.loc35_20.2 -// CHECK:STDOUT: %i32.as.ImplicitAs.impl.Convert.call: init %X = call %bound_method.loc35_20.1(%.loc35_20.3) to %.loc35_20.1 +// CHECK:STDOUT: %i32.as.ImplicitAs.impl.Convert.call: init %X = call %bound_method.loc35(%.loc35_20.3) to %.loc35_20.1 // CHECK:STDOUT: %.loc35_20.4: init %X = converted %Source.call.loc35, %i32.as.ImplicitAs.impl.Convert.call // CHECK:STDOUT: %.loc35_20.5: ref %X = temporary %.loc35_20.1, %.loc35_20.4 // CHECK:STDOUT: %.loc35_20.6: %X = bind_value %.loc35_20.5 // CHECK:STDOUT: %Sink_X.call: init %empty_tuple.type = call %Sink_X.ref(%.loc35_20.6) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc35: = bound_method %.loc35_20.1, constants.%T.as.Destroy.impl.Op.33a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.33a, @T.as.Destroy.impl.Op(constants.%X) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc35_20.2: = bound_method %.loc35_20.1, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %X.as.Destroy.impl.Op.bound.loc35: = bound_method %.loc35_20.1, constants.%X.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc35: %ptr.d17 = addr_of %.loc35_20.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc35: init %empty_tuple.type = call %bound_method.loc35_20.2(%addr.loc35) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc34: = bound_method %.loc34_20.1, constants.%T.as.Destroy.impl.Op.33a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.33a, @T.as.Destroy.impl.Op(constants.%X) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc34_20.2: = bound_method %.loc34_20.1, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %X.as.Destroy.impl.Op.call.loc35: init %empty_tuple.type = call %X.as.Destroy.impl.Op.bound.loc35(%addr.loc35) +// CHECK:STDOUT: %X.as.Destroy.impl.Op.bound.loc34: = bound_method %.loc34_20.1, constants.%X.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc34: %ptr.d17 = addr_of %.loc34_20.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc34: init %empty_tuple.type = call %bound_method.loc34_20.2(%addr.loc34) +// CHECK:STDOUT: %X.as.Destroy.impl.Op.call.loc34: init %empty_tuple.type = call %X.as.Destroy.impl.Op.bound.loc34(%addr.loc34) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/operators/overloaded/inc.carbon b/toolchain/check/testdata/operators/overloaded/inc.carbon index 611b41f5b552..7eac14b016a6 100644 --- a/toolchain/check/testdata/operators/overloaded/inc.carbon +++ b/toolchain/check/testdata/operators/overloaded/inc.carbon @@ -33,12 +33,12 @@ fn TestOp() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Inc.type: type = facet_type <@Inc> [concrete] // CHECK:STDOUT: %Inc.Op.type: type = fn_type @Inc.Op [concrete] // CHECK:STDOUT: %Inc.impl_witness: = impl_witness file.%Inc.impl_witness_table [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %C.as.Inc.impl.Op.type: type = fn_type @C.as.Inc.impl.Op [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %C.as.Inc.impl.Op: %C.as.Inc.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %Inc.facet: %Inc.type = facet_value %C, (%Inc.impl_witness) [concrete] // CHECK:STDOUT: %.bc7: type = fn_type_with_self_type %Inc.Op.type, %Inc.facet [concrete] @@ -52,9 +52,9 @@ fn TestOp() { // CHECK:STDOUT: // CHECK:STDOUT: %c.ref: ref %C = name_ref c, %c // CHECK:STDOUT: %impl.elem0: %.bc7 = impl_witness_access constants.%Inc.impl_witness, element0 [concrete = constants.%C.as.Inc.impl.Op] -// CHECK:STDOUT: %bound_method.loc28: = bound_method %c.ref, %impl.elem0 +// CHECK:STDOUT: %bound_method: = bound_method %c.ref, %impl.elem0 // CHECK:STDOUT: %addr.loc28: %ptr.019 = addr_of %c.ref -// CHECK:STDOUT: %C.as.Inc.impl.Op.call: init %empty_tuple.type = call %bound_method.loc28(%addr.loc28) +// CHECK:STDOUT: %C.as.Inc.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc28) // CHECK:STDOUT: // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/operators/overloaded/index_with_prelude.carbon b/toolchain/check/testdata/operators/overloaded/index_with_prelude.carbon index 852fcafd85fe..3dbd648c1fbe 100644 --- a/toolchain/check/testdata/operators/overloaded/index_with_prelude.carbon +++ b/toolchain/check/testdata/operators/overloaded/index_with_prelude.carbon @@ -85,10 +85,27 @@ let x: i32 = c[0]; // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %ElementType.e6b: type = class_type @ElementType [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b20: = impl_witness @ElementType.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e72: type = ptr_type %ElementType.e6b [concrete] +// CHECK:STDOUT: %pattern_type.b78: type = pattern_type %ptr.e72 [concrete] +// CHECK:STDOUT: %ElementType.as.Destroy.impl.Op.type: type = fn_type @ElementType.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %ElementType.as.Destroy.impl.Op: %ElementType.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %SubscriptType.8ee: type = class_type @SubscriptType [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.63e: = impl_witness @SubscriptType.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.627: type = ptr_type %SubscriptType.8ee [concrete] +// CHECK:STDOUT: %pattern_type.17d: type = pattern_type %ptr.627 [concrete] +// CHECK:STDOUT: %SubscriptType.as.Destroy.impl.Op.type: type = fn_type @SubscriptType.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %SubscriptType.as.Destroy.impl.Op: %SubscriptType.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %IndexWith.type.504: type = generic_interface_type @IndexWith [concrete] // CHECK:STDOUT: %IndexWith.generic: %IndexWith.type.504 = struct_value () [concrete] // CHECK:STDOUT: %IndexWith.type.e80: type = facet_type <@IndexWith, @IndexWith(%SubscriptType.8ee, %ElementType.e6b)> [concrete] @@ -108,10 +125,12 @@ let x: i32 = c[0]; // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .IndexWith = %Core.IndexWith // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.IndexWith: %IndexWith.type.504 = import_ref Core//prelude/operators/index, IndexWith, loaded [concrete = constants.%IndexWith.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -168,6 +187,54 @@ let x: i32 = c[0]; // CHECK:STDOUT: %x: %ElementType.e6b = bind_name x, %.loc16_25.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @ElementType.as.Destroy.impl: constants.%ElementType.e6b as constants.%Destroy.type { +// CHECK:STDOUT: %ElementType.as.Destroy.impl.Op.decl: %ElementType.as.Destroy.impl.Op.type = fn_decl @ElementType.as.Destroy.impl.Op [concrete = constants.%ElementType.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.b78 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.b78 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e72 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%ElementType.e6b [concrete = constants.%ElementType.e6b] +// CHECK:STDOUT: %self: %ptr.e72 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %ElementType.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @ElementType.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @SubscriptType.as.Destroy.impl: constants.%SubscriptType.8ee as constants.%Destroy.type { +// CHECK:STDOUT: %SubscriptType.as.Destroy.impl.Op.decl: %SubscriptType.as.Destroy.impl.Op.type = fn_decl @SubscriptType.as.Destroy.impl.Op [concrete = constants.%SubscriptType.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.17d = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.17d = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.627 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SubscriptType.8ee [concrete = constants.%SubscriptType.8ee] +// CHECK:STDOUT: %self: %ptr.627 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %SubscriptType.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @SubscriptType.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.IndexWith.impl: %C.ref as %IndexWith.type { // CHECK:STDOUT: %C.as.IndexWith.impl.At.decl: %C.as.IndexWith.impl.At.type = fn_decl @C.as.IndexWith.impl.At [concrete = constants.%C.as.IndexWith.impl.At] { // CHECK:STDOUT: %self.patt: %pattern_type.c48 = binding_pattern self [concrete] @@ -196,6 +263,9 @@ let x: i32 = c[0]; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -205,6 +275,9 @@ let x: i32 = c[0]; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @ElementType { +// CHECK:STDOUT: impl_decl @ElementType.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@ElementType.as.Destroy.impl.%ElementType.as.Destroy.impl.Op.decl), @ElementType.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b20] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -214,6 +287,9 @@ let x: i32 = c[0]; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @SubscriptType { +// CHECK:STDOUT: impl_decl @SubscriptType.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@SubscriptType.as.Destroy.impl.%SubscriptType.as.Destroy.impl.Op.decl), @SubscriptType.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.63e] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -222,6 +298,12 @@ let x: i32 = c[0]; // CHECK:STDOUT: .Self = constants.%SubscriptType.8ee // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ElementType.as.Destroy.impl.Op(%self.param: %ptr.e72) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @SubscriptType.as.Destroy.impl.Op(%self.param: %ptr.627) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.IndexWith.impl.At(%self.param: %C, %subscript.param: %SubscriptType.8ee) -> %return.param: %ElementType.e6b { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc10_13.1: %empty_struct_type = struct_literal () @@ -432,10 +514,27 @@ let x: i32 = c[0]; // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %ElementType.e6b: type = class_type @ElementType [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b20: = impl_witness @ElementType.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.e72: type = ptr_type %ElementType.e6b [concrete] +// CHECK:STDOUT: %pattern_type.b78: type = pattern_type %ptr.e72 [concrete] +// CHECK:STDOUT: %ElementType.as.Destroy.impl.Op.type: type = fn_type @ElementType.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %ElementType.as.Destroy.impl.Op: %ElementType.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %SubscriptType.8ee: type = class_type @SubscriptType [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.63e: = impl_witness @SubscriptType.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.627: type = ptr_type %SubscriptType.8ee [concrete] +// CHECK:STDOUT: %pattern_type.17d: type = pattern_type %ptr.627 [concrete] +// CHECK:STDOUT: %SubscriptType.as.Destroy.impl.Op.type: type = fn_type @SubscriptType.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %SubscriptType.as.Destroy.impl.Op: %SubscriptType.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %IndexWith.type.504: type = generic_interface_type @IndexWith [concrete] // CHECK:STDOUT: %IndexWith.generic: %IndexWith.type.504 = struct_value () [concrete] // CHECK:STDOUT: %IndexWith.type.e80: type = facet_type <@IndexWith, @IndexWith(%SubscriptType.8ee, %ElementType.e6b)> [concrete] @@ -457,11 +556,13 @@ let x: i32 = c[0]; // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .IndexWith = %Core.IndexWith // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.IndexWith: %IndexWith.type.504 = import_ref Core//prelude/operators/index, IndexWith, loaded [concrete = constants.%IndexWith.generic] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/operators/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } @@ -508,6 +609,54 @@ let x: i32 = c[0]; // CHECK:STDOUT: %x: %ElementType.e6b = bind_name x, %.loc22_25.2 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @ElementType.as.Destroy.impl: constants.%ElementType.e6b as constants.%Destroy.type { +// CHECK:STDOUT: %ElementType.as.Destroy.impl.Op.decl: %ElementType.as.Destroy.impl.Op.type = fn_decl @ElementType.as.Destroy.impl.Op [concrete = constants.%ElementType.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.b78 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.b78 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e72 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%ElementType.e6b [concrete = constants.%ElementType.e6b] +// CHECK:STDOUT: %self: %ptr.e72 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %ElementType.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @ElementType.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @SubscriptType.as.Destroy.impl: constants.%SubscriptType.8ee as constants.%Destroy.type { +// CHECK:STDOUT: %SubscriptType.as.Destroy.impl.Op.decl: %SubscriptType.as.Destroy.impl.Op.type = fn_decl @SubscriptType.as.Destroy.impl.Op [concrete = constants.%SubscriptType.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.17d = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.17d = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.627 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%SubscriptType.8ee [concrete = constants.%SubscriptType.8ee] +// CHECK:STDOUT: %self: %ptr.627 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %SubscriptType.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @SubscriptType.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.IndexWith.impl: %C.ref as %IndexWith.type { // CHECK:STDOUT: %C.as.IndexWith.impl.At.decl: %C.as.IndexWith.impl.At.type = fn_decl @C.as.IndexWith.impl.At [concrete = constants.%C.as.IndexWith.impl.At] { // CHECK:STDOUT: %self.patt: %pattern_type.c48 = binding_pattern self [concrete] @@ -536,6 +685,9 @@ let x: i32 = c[0]; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -545,6 +697,9 @@ let x: i32 = c[0]; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @ElementType { +// CHECK:STDOUT: impl_decl @ElementType.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@ElementType.as.Destroy.impl.%ElementType.as.Destroy.impl.Op.decl), @ElementType.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.b20] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -554,6 +709,9 @@ let x: i32 = c[0]; // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @SubscriptType { +// CHECK:STDOUT: impl_decl @SubscriptType.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@SubscriptType.as.Destroy.impl.%SubscriptType.as.Destroy.impl.Op.decl), @SubscriptType.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.63e] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -562,6 +720,12 @@ let x: i32 = c[0]; // CHECK:STDOUT: .Self = constants.%SubscriptType.8ee // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ElementType.as.Destroy.impl.Op(%self.param: %ptr.e72) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @SubscriptType.as.Destroy.impl.Op(%self.param: %ptr.627) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.IndexWith.impl.At(%self.param: %C, %subscript.param: %SubscriptType.8ee) -> %return.param: %ElementType.e6b { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc10_13.1: %empty_struct_type = struct_literal () @@ -587,6 +751,13 @@ let x: i32 = c[0]; // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] @@ -603,11 +774,13 @@ let x: i32 = c[0]; // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .IndexWith = %Core.IndexWith // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/types/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %Core.IndexWith: %IndexWith.type.504 = import_ref Core//prelude/operators/index, IndexWith, loaded [concrete = constants.%IndexWith.generic] // CHECK:STDOUT: } @@ -641,7 +814,26 @@ let x: i32 = c[0]; // CHECK:STDOUT: %x: %i32 = bind_name x, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -650,6 +842,8 @@ let x: i32 = c[0]; // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc6: %empty_struct_type = struct_literal () diff --git a/toolchain/check/testdata/operators/overloaded/left_shift.carbon b/toolchain/check/testdata/operators/overloaded/left_shift.carbon index b8a72447e05e..2c319d73624f 100644 --- a/toolchain/check/testdata/operators/overloaded/left_shift.carbon +++ b/toolchain/check/testdata/operators/overloaded/left_shift.carbon @@ -43,6 +43,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %LeftShiftWith.type.f92: type = facet_type <@LeftShiftWith, @LeftShiftWith(%C)> [concrete] // CHECK:STDOUT: %LeftShiftWith.Op.type.097: type = fn_type @LeftShiftWith.Op, @LeftShiftWith(%C) [concrete] @@ -53,7 +54,6 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %LeftShiftAssignWith.type.56d: type = facet_type <@LeftShiftAssignWith, @LeftShiftAssignWith(%C)> [concrete] // CHECK:STDOUT: %LeftShiftAssignWith.Op.type.30f: type = fn_type @LeftShiftAssignWith.Op, @LeftShiftAssignWith(%C) [concrete] // CHECK:STDOUT: %LeftShiftAssignWith.impl_witness: = impl_witness file.%LeftShiftAssignWith.impl_witness_table [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %C.as.LeftShiftAssignWith.impl.Op.type: type = fn_type @C.as.LeftShiftAssignWith.impl.Op [concrete] // CHECK:STDOUT: %C.as.LeftShiftAssignWith.impl.Op: %C.as.LeftShiftAssignWith.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %LeftShiftAssignWith.facet: %LeftShiftAssignWith.type.56d = facet_value %C, (%LeftShiftAssignWith.impl_witness) [concrete] @@ -69,9 +69,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %a.ref: %C = name_ref a, %a // CHECK:STDOUT: %b.ref: %C = name_ref b, %b // CHECK:STDOUT: %impl.elem1: %.cd9 = impl_witness_access constants.%LeftShiftWith.impl_witness, element1 [concrete = constants.%C.as.LeftShiftWith.impl.Op] -// CHECK:STDOUT: %bound_method.loc32: = bound_method %a.ref, %impl.elem1 +// CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem1 // CHECK:STDOUT: -// CHECK:STDOUT: %C.as.LeftShiftWith.impl.Op.call: init %C = call %bound_method.loc32(%a.ref, %b.ref) to %.loc30 +// CHECK:STDOUT: %C.as.LeftShiftWith.impl.Op.call: init %C = call %bound_method(%a.ref, %b.ref) to %.loc30 // CHECK:STDOUT: // CHECK:STDOUT: return %C.as.LeftShiftWith.impl.Op.call to %return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/operators/overloaded/mod.carbon b/toolchain/check/testdata/operators/overloaded/mod.carbon index aa4c44117338..cdce4ac62e07 100644 --- a/toolchain/check/testdata/operators/overloaded/mod.carbon +++ b/toolchain/check/testdata/operators/overloaded/mod.carbon @@ -43,6 +43,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %ModWith.type.4d0: type = facet_type <@ModWith, @ModWith(%C)> [concrete] // CHECK:STDOUT: %ModWith.Op.type.140: type = fn_type @ModWith.Op, @ModWith(%C) [concrete] @@ -53,7 +54,6 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %ModAssignWith.type.8eb: type = facet_type <@ModAssignWith, @ModAssignWith(%C)> [concrete] // CHECK:STDOUT: %ModAssignWith.Op.type.dd0: type = fn_type @ModAssignWith.Op, @ModAssignWith(%C) [concrete] // CHECK:STDOUT: %ModAssignWith.impl_witness: = impl_witness file.%ModAssignWith.impl_witness_table [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %C.as.ModAssignWith.impl.Op.type: type = fn_type @C.as.ModAssignWith.impl.Op [concrete] // CHECK:STDOUT: %C.as.ModAssignWith.impl.Op: %C.as.ModAssignWith.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ModAssignWith.facet: %ModAssignWith.type.8eb = facet_value %C, (%ModAssignWith.impl_witness) [concrete] @@ -69,9 +69,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %a.ref: %C = name_ref a, %a // CHECK:STDOUT: %b.ref: %C = name_ref b, %b // CHECK:STDOUT: %impl.elem1: %.f08 = impl_witness_access constants.%ModWith.impl_witness, element1 [concrete = constants.%C.as.ModWith.impl.Op] -// CHECK:STDOUT: %bound_method.loc32: = bound_method %a.ref, %impl.elem1 +// CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem1 // CHECK:STDOUT: -// CHECK:STDOUT: %C.as.ModWith.impl.Op.call: init %C = call %bound_method.loc32(%a.ref, %b.ref) to %.loc30 +// CHECK:STDOUT: %C.as.ModWith.impl.Op.call: init %C = call %bound_method(%a.ref, %b.ref) to %.loc30 // CHECK:STDOUT: // CHECK:STDOUT: return %C.as.ModWith.impl.Op.call to %return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/operators/overloaded/mul.carbon b/toolchain/check/testdata/operators/overloaded/mul.carbon index 310afcdc8a36..479e5adf4e54 100644 --- a/toolchain/check/testdata/operators/overloaded/mul.carbon +++ b/toolchain/check/testdata/operators/overloaded/mul.carbon @@ -43,6 +43,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %MulWith.type.3ed: type = facet_type <@MulWith, @MulWith(%C)> [concrete] // CHECK:STDOUT: %MulWith.Op.type.2c9: type = fn_type @MulWith.Op, @MulWith(%C) [concrete] @@ -53,7 +54,6 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %MulAssignWith.type.a15: type = facet_type <@MulAssignWith, @MulAssignWith(%C)> [concrete] // CHECK:STDOUT: %MulAssignWith.Op.type.5c8: type = fn_type @MulAssignWith.Op, @MulAssignWith(%C) [concrete] // CHECK:STDOUT: %MulAssignWith.impl_witness: = impl_witness file.%MulAssignWith.impl_witness_table [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %C.as.MulAssignWith.impl.Op.type: type = fn_type @C.as.MulAssignWith.impl.Op [concrete] // CHECK:STDOUT: %C.as.MulAssignWith.impl.Op: %C.as.MulAssignWith.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %MulAssignWith.facet: %MulAssignWith.type.a15 = facet_value %C, (%MulAssignWith.impl_witness) [concrete] @@ -69,9 +69,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %a.ref: %C = name_ref a, %a // CHECK:STDOUT: %b.ref: %C = name_ref b, %b // CHECK:STDOUT: %impl.elem1: %.6ce = impl_witness_access constants.%MulWith.impl_witness, element1 [concrete = constants.%C.as.MulWith.impl.Op] -// CHECK:STDOUT: %bound_method.loc32: = bound_method %a.ref, %impl.elem1 +// CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem1 // CHECK:STDOUT: -// CHECK:STDOUT: %C.as.MulWith.impl.Op.call: init %C = call %bound_method.loc32(%a.ref, %b.ref) to %.loc30 +// CHECK:STDOUT: %C.as.MulWith.impl.Op.call: init %C = call %bound_method(%a.ref, %b.ref) to %.loc30 // CHECK:STDOUT: // CHECK:STDOUT: return %C.as.MulWith.impl.Op.call to %return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/operators/overloaded/negate.carbon b/toolchain/check/testdata/operators/overloaded/negate.carbon index 6aa1c99605e9..66ed8539749e 100644 --- a/toolchain/check/testdata/operators/overloaded/negate.carbon +++ b/toolchain/check/testdata/operators/overloaded/negate.carbon @@ -50,9 +50,9 @@ fn TestOp(a: C) -> C { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %C = name_ref a, %a // CHECK:STDOUT: %impl.elem1: %.26d = impl_witness_access constants.%Negate.impl_witness, element1 [concrete = constants.%C.as.Negate.impl.Op] -// CHECK:STDOUT: %bound_method.loc29: = bound_method %a.ref, %impl.elem1 +// CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem1 // CHECK:STDOUT: -// CHECK:STDOUT: %C.as.Negate.impl.Op.call: init %C = call %bound_method.loc29(%a.ref) to %.loc27 +// CHECK:STDOUT: %C.as.Negate.impl.Op.call: init %C = call %bound_method(%a.ref) to %.loc27 // CHECK:STDOUT: // CHECK:STDOUT: return %C.as.Negate.impl.Op.call to %return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/operators/overloaded/ordered.carbon b/toolchain/check/testdata/operators/overloaded/ordered.carbon index 87ccea8099ec..9b16bf78dd8b 100644 --- a/toolchain/check/testdata/operators/overloaded/ordered.carbon +++ b/toolchain/check/testdata/operators/overloaded/ordered.carbon @@ -83,6 +83,13 @@ fn TestGreaterEqual(a: D, b: D) -> bool { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %OrderedWith.type.270: type = generic_interface_type @OrderedWith [concrete] @@ -122,11 +129,13 @@ fn TestGreaterEqual(a: D, b: D) -> bool { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .OrderedWith = %Core.OrderedWith // CHECK:STDOUT: .Bool = %Core.Bool // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.OrderedWith: %OrderedWith.type.270 = import_ref Core//prelude/operators/comparison, OrderedWith, loaded [concrete = constants.%OrderedWith.generic] // CHECK:STDOUT: %Core.Bool: %Bool.type = import_ref Core//prelude/types/bool, Bool, loaded [concrete = constants.%Bool] // CHECK:STDOUT: } @@ -233,6 +242,22 @@ fn TestGreaterEqual(a: D, b: D) -> bool { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.OrderedWith.impl: %C.ref.loc6_6 as %OrderedWith.type { // CHECK:STDOUT: %C.as.OrderedWith.impl.Less.decl: %C.as.OrderedWith.impl.Less.type = fn_decl @C.as.OrderedWith.impl.Less [concrete = constants.%C.as.OrderedWith.impl.Less] { // CHECK:STDOUT: %self.patt: %pattern_type.c48 = binding_pattern self [concrete] @@ -325,6 +350,9 @@ fn TestGreaterEqual(a: D, b: D) -> bool { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -333,6 +361,8 @@ fn TestGreaterEqual(a: D, b: D) -> bool { // CHECK:STDOUT: .Self = constants.%C // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.OrderedWith.impl.Less(%self.param: %C, %other.param: %C) -> bool; // CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.OrderedWith.impl.LessOrEquivalent(%self.param: %C, %other.param: %C) -> bool; @@ -393,6 +423,13 @@ fn TestGreaterEqual(a: D, b: D) -> bool { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.510: type = pattern_type %D [concrete] @@ -413,11 +450,13 @@ fn TestGreaterEqual(a: D, b: D) -> bool { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .Bool = %Core.Bool // CHECK:STDOUT: .OrderedWith = %Core.OrderedWith // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.Bool: %Bool.type = import_ref Core//prelude/types/bool, Bool, loaded [concrete = constants.%Bool] // CHECK:STDOUT: %Core.OrderedWith: %OrderedWith.type.270 = import_ref Core//prelude/operators/comparison, OrderedWith, loaded [concrete = constants.%OrderedWith.generic] // CHECK:STDOUT: } @@ -515,7 +554,26 @@ fn TestGreaterEqual(a: D, b: D) -> bool { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @D { +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -524,6 +582,8 @@ fn TestGreaterEqual(a: D, b: D) -> bool { // CHECK:STDOUT: .Self = constants.%D // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @TestLess(%a.param: %D, %b.param: %D) -> bool { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %a.ref: %D = name_ref a, %a diff --git a/toolchain/check/testdata/operators/overloaded/right_shift.carbon b/toolchain/check/testdata/operators/overloaded/right_shift.carbon index 421c677328eb..57932132d02f 100644 --- a/toolchain/check/testdata/operators/overloaded/right_shift.carbon +++ b/toolchain/check/testdata/operators/overloaded/right_shift.carbon @@ -43,6 +43,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %RightShiftWith.type.bd6: type = facet_type <@RightShiftWith, @RightShiftWith(%C)> [concrete] // CHECK:STDOUT: %RightShiftWith.Op.type.19b: type = fn_type @RightShiftWith.Op, @RightShiftWith(%C) [concrete] @@ -53,7 +54,6 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %RightShiftAssignWith.type.cd0: type = facet_type <@RightShiftAssignWith, @RightShiftAssignWith(%C)> [concrete] // CHECK:STDOUT: %RightShiftAssignWith.Op.type.ae9: type = fn_type @RightShiftAssignWith.Op, @RightShiftAssignWith(%C) [concrete] // CHECK:STDOUT: %RightShiftAssignWith.impl_witness: = impl_witness file.%RightShiftAssignWith.impl_witness_table [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %C.as.RightShiftAssignWith.impl.Op.type: type = fn_type @C.as.RightShiftAssignWith.impl.Op [concrete] // CHECK:STDOUT: %C.as.RightShiftAssignWith.impl.Op: %C.as.RightShiftAssignWith.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %RightShiftAssignWith.facet: %RightShiftAssignWith.type.cd0 = facet_value %C, (%RightShiftAssignWith.impl_witness) [concrete] @@ -69,9 +69,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %a.ref: %C = name_ref a, %a // CHECK:STDOUT: %b.ref: %C = name_ref b, %b // CHECK:STDOUT: %impl.elem1: %.982 = impl_witness_access constants.%RightShiftWith.impl_witness, element1 [concrete = constants.%C.as.RightShiftWith.impl.Op] -// CHECK:STDOUT: %bound_method.loc32: = bound_method %a.ref, %impl.elem1 +// CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem1 // CHECK:STDOUT: -// CHECK:STDOUT: %C.as.RightShiftWith.impl.Op.call: init %C = call %bound_method.loc32(%a.ref, %b.ref) to %.loc30 +// CHECK:STDOUT: %C.as.RightShiftWith.impl.Op.call: init %C = call %bound_method(%a.ref, %b.ref) to %.loc30 // CHECK:STDOUT: // CHECK:STDOUT: return %C.as.RightShiftWith.impl.Op.call to %return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/operators/overloaded/sub.carbon b/toolchain/check/testdata/operators/overloaded/sub.carbon index 6120f324e20e..f62cda203e52 100644 --- a/toolchain/check/testdata/operators/overloaded/sub.carbon +++ b/toolchain/check/testdata/operators/overloaded/sub.carbon @@ -43,6 +43,7 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %SubWith.type.d29: type = facet_type <@SubWith, @SubWith(%C)> [concrete] // CHECK:STDOUT: %SubWith.Op.type.fc0: type = fn_type @SubWith.Op, @SubWith(%C) [concrete] @@ -53,7 +54,6 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %SubAssignWith.type.df6: type = facet_type <@SubAssignWith, @SubAssignWith(%C)> [concrete] // CHECK:STDOUT: %SubAssignWith.Op.type.ffe: type = fn_type @SubAssignWith.Op, @SubAssignWith(%C) [concrete] // CHECK:STDOUT: %SubAssignWith.impl_witness: = impl_witness file.%SubAssignWith.impl_witness_table [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %C.as.SubAssignWith.impl.Op.type: type = fn_type @C.as.SubAssignWith.impl.Op [concrete] // CHECK:STDOUT: %C.as.SubAssignWith.impl.Op: %C.as.SubAssignWith.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %SubAssignWith.facet: %SubAssignWith.type.df6 = facet_value %C, (%SubAssignWith.impl_witness) [concrete] @@ -69,9 +69,9 @@ fn TestAssign(a: C*, b: C) { // CHECK:STDOUT: %a.ref: %C = name_ref a, %a // CHECK:STDOUT: %b.ref: %C = name_ref b, %b // CHECK:STDOUT: %impl.elem1: %.71c = impl_witness_access constants.%SubWith.impl_witness, element1 [concrete = constants.%C.as.SubWith.impl.Op] -// CHECK:STDOUT: %bound_method.loc32: = bound_method %a.ref, %impl.elem1 +// CHECK:STDOUT: %bound_method: = bound_method %a.ref, %impl.elem1 // CHECK:STDOUT: -// CHECK:STDOUT: %C.as.SubWith.impl.Op.call: init %C = call %bound_method.loc32(%a.ref, %b.ref) to %.loc30 +// CHECK:STDOUT: %C.as.SubWith.impl.Op.call: init %C = call %bound_method(%a.ref, %b.ref) to %.loc30 // CHECK:STDOUT: // CHECK:STDOUT: return %C.as.SubWith.impl.Op.call to %return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/package_expr/syntax.carbon b/toolchain/check/testdata/package_expr/syntax.carbon index 9c09cb040de3..56f2228d0adb 100644 --- a/toolchain/check/testdata/package_expr/syntax.carbon +++ b/toolchain/check/testdata/package_expr/syntax.carbon @@ -145,6 +145,7 @@ fn Main() { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -163,7 +164,6 @@ fn Main() { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.ab5: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.9a1: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] @@ -272,6 +272,13 @@ fn Main() { // CHECK:STDOUT: %C.Foo.type: type = fn_type @C.Foo [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %C.Foo: %C.Foo.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.691: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.c45: type = pattern_type %ptr.691 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %Main.type: type = fn_type @Main [concrete] @@ -280,9 +287,11 @@ fn Main() { // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -299,8 +308,27 @@ fn Main() { // CHECK:STDOUT: %Main.decl: %Main.type = fn_decl @Main [concrete = constants.%Main] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.c45 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.c45 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.691 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.691 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %C.Foo.decl: %C.Foo.type = fn_decl @C.Foo [concrete = constants.%C.Foo] {} {} +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -315,6 +343,8 @@ fn Main() { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.691) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Main() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %package.ref: = name_ref package, package [concrete = package] diff --git a/toolchain/check/testdata/packages/raw_core.carbon b/toolchain/check/testdata/packages/raw_core.carbon index c6ecb3b61261..627b5851ca1e 100644 --- a/toolchain/check/testdata/packages/raw_core.carbon +++ b/toolchain/check/testdata/packages/raw_core.carbon @@ -200,6 +200,13 @@ var c: r#Core = {.n = 0 as Core.Int(32)}; // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Core.elem: type = unbound_element_type %Core, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.987: = impl_witness @Core.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.4bf: type = ptr_type %Core [concrete] +// CHECK:STDOUT: %pattern_type.c58: type = pattern_type %ptr.4bf [concrete] +// CHECK:STDOUT: %Core.as.Destroy.impl.Op.type: type = fn_type @Core.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %Core.as.Destroy.impl.Op: %Core.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete] // CHECK:STDOUT: %complete_type.54b: = complete_type_witness %struct_type.n [concrete] // CHECK:STDOUT: %pattern_type.c8a: type = pattern_type %Core [concrete] @@ -227,11 +234,13 @@ var c: r#Core = {.n = 0 as Core.Int(32)}; // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: .As = %Core.As // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.As: %As.type.90f = import_ref Core//prelude/parts/as, As, loaded [concrete = constants.%As.generic] // CHECK:STDOUT: %Core.import_ref.78a: @Core.IntLiteral.as.As.impl.%Core.IntLiteral.as.As.impl.Convert.type (%Core.IntLiteral.as.As.impl.Convert.type.062) = import_ref Core//prelude/parts/int, loc25_39, loaded [symbolic = @Core.IntLiteral.as.As.impl.%Core.IntLiteral.as.As.impl.Convert (constants.%Core.IntLiteral.as.As.impl.Convert.527)] // CHECK:STDOUT: %As.impl_witness_table.eb4 = impl_witness_table (%Core.import_ref.78a), @Core.IntLiteral.as.As.impl [concrete] @@ -254,12 +263,31 @@ var c: r#Core = {.n = 0 as Core.Int(32)}; // CHECK:STDOUT: %c: ref %Core = bind_name c, %c.var [concrete = %c.var] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @Core.as.Destroy.impl: constants.%Core as constants.%Destroy.type { +// CHECK:STDOUT: %Core.as.Destroy.impl.Op.decl: %Core.as.Destroy.impl.Op.type = fn_decl @Core.as.Destroy.impl.Op [concrete = constants.%Core.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.c58 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.c58 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc2: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.4bf = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Core [concrete = constants.%Core] +// CHECK:STDOUT: %self: %ptr.4bf = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %Core.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @Core.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @Core { // CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] // CHECK:STDOUT: %Int.ref: %Int.type = name_ref Int, imports.%Core.Int [concrete = constants.%Int.generic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc3: %Core.elem = field_decl n, element0 [concrete] +// CHECK:STDOUT: impl_decl @Core.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@Core.as.Destroy.impl.%Core.as.Destroy.impl.Op.decl), @Core.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.987] // CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete = constants.%struct_type.n] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n [concrete = constants.%complete_type.54b] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -269,6 +297,8 @@ var c: r#Core = {.n = 0 as Core.Int(32)}; // CHECK:STDOUT: .n = %.loc3 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @Core.as.Destroy.impl.Op(%self.param: %ptr.4bf) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] diff --git a/toolchain/check/testdata/pointer/address_of_deref.carbon b/toolchain/check/testdata/pointer/address_of_deref.carbon index e48531e484a3..2cb8992f0cc9 100644 --- a/toolchain/check/testdata/pointer/address_of_deref.carbon +++ b/toolchain/check/testdata/pointer/address_of_deref.carbon @@ -33,6 +33,7 @@ fn F() -> i32 { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -46,7 +47,6 @@ fn F() -> i32 { // CHECK:STDOUT: %bound_method: = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(%i32) [concrete] diff --git a/toolchain/check/testdata/pointer/address_of_lvalue.carbon b/toolchain/check/testdata/pointer/address_of_lvalue.carbon index 9df60117b2ad..8ce7a1953da3 100644 --- a/toolchain/check/testdata/pointer/address_of_lvalue.carbon +++ b/toolchain/check/testdata/pointer/address_of_lvalue.carbon @@ -44,6 +44,7 @@ fn F() { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -70,7 +71,6 @@ fn F() { // CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] // CHECK:STDOUT: %tuple: %tuple.type.d07 = tuple_value (%int_1.5d2, %int_2.ef8) [concrete] // CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.ba2: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%ptr.235) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.649: %T.as.Destroy.impl.Op.type.ba2 = struct_value () [concrete] // CHECK:STDOUT: %ptr.5d5: type = ptr_type %ptr.235 [concrete] diff --git a/toolchain/check/testdata/pointer/arrow.carbon b/toolchain/check/testdata/pointer/arrow.carbon index 45e7eedfc493..756d85a2c1bc 100644 --- a/toolchain/check/testdata/pointer/arrow.carbon +++ b/toolchain/check/testdata/pointer/arrow.carbon @@ -37,18 +37,25 @@ fn Foo(ptr: C*) { // CHECK:STDOUT: %C.Member: %C.Member.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %ptr.019 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.field: type = struct_type {.field: %ptr.019} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.field [concrete] -// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] // CHECK:STDOUT: %Foo.type: type = fn_type @Foo [concrete] // CHECK:STDOUT: %Foo: %Foo.type = struct_value () [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -72,6 +79,22 @@ fn Foo(ptr: C*) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %C.Member.decl: %C.Member.type = fn_decl @C.Member [concrete = constants.%C.Member] { // CHECK:STDOUT: %self.patt: %pattern_type.c48 = binding_pattern self [concrete] @@ -84,6 +107,9 @@ fn Foo(ptr: C*) { // CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] // CHECK:STDOUT: %ptr: type = ptr_type %C.ref [concrete = constants.%ptr.019] // CHECK:STDOUT: %.loc17: %C.elem = field_decl field, element0 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %struct_type.field: type = struct_type {.field: %ptr.019} [concrete = constants.%struct_type.field] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.field [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -97,6 +123,8 @@ fn Foo(ptr: C*) { // CHECK:STDOUT: // CHECK:STDOUT: fn @C.Member(%self.param: %C); // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Foo(%ptr.param: %ptr.019) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %ptr.ref.loc21: %ptr.019 = name_ref ptr, %ptr.loc20_8 diff --git a/toolchain/check/testdata/pointer/basic.carbon b/toolchain/check/testdata/pointer/basic.carbon index 358a34d4f63d..da499ce98e51 100644 --- a/toolchain/check/testdata/pointer/basic.carbon +++ b/toolchain/check/testdata/pointer/basic.carbon @@ -35,6 +35,7 @@ fn F() -> i32 { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -49,7 +50,6 @@ fn F() -> i32 { // CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] // CHECK:STDOUT: %pattern_type.fe8: type = pattern_type %ptr.235 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.ba2: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%ptr.235) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.649: %T.as.Destroy.impl.Op.type.ba2 = struct_value () [concrete] // CHECK:STDOUT: %ptr.5d5: type = ptr_type %ptr.235 [concrete] diff --git a/toolchain/check/testdata/pointer/import.carbon b/toolchain/check/testdata/pointer/import.carbon index a45f7c52044b..5aa019d25794 100644 --- a/toolchain/check/testdata/pointer/import.carbon +++ b/toolchain/check/testdata/pointer/import.carbon @@ -50,9 +50,9 @@ var a: i32* = a_ref; // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.956, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] // CHECK:STDOUT: %bound_method: = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete] -// CHECK:STDOUT: %pattern_type.fe8: type = pattern_type %ptr [concrete] -// CHECK:STDOUT: %addr: %ptr = addr_of file.%a_orig.var [concrete] +// CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] +// CHECK:STDOUT: %pattern_type.fe8: type = pattern_type %ptr.235 [concrete] +// CHECK:STDOUT: %addr: %ptr.235 = addr_of file.%a_orig.var [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -89,13 +89,13 @@ var a: i32* = a_ref; // CHECK:STDOUT: %a_ref.patt: %pattern_type.fe8 = binding_pattern a_ref [concrete] // CHECK:STDOUT: %a_ref.var_patt: %pattern_type.fe8 = var_pattern %a_ref.patt [concrete] // CHECK:STDOUT: } -// CHECK:STDOUT: %a_ref.var: ref %ptr = var %a_ref.var_patt [concrete] -// CHECK:STDOUT: %.loc5: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %a_ref.var: ref %ptr.235 = var %a_ref.var_patt [concrete] +// CHECK:STDOUT: %.loc5: type = splice_block %ptr [concrete = constants.%ptr.235] { // CHECK:STDOUT: %int_32.loc5: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %ptr: type = ptr_type %i32.loc5 [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr: type = ptr_type %i32.loc5 [concrete = constants.%ptr.235] // CHECK:STDOUT: } -// CHECK:STDOUT: %a_ref: ref %ptr = bind_name a_ref, %a_ref.var [concrete = %a_ref.var] +// CHECK:STDOUT: %a_ref: ref %ptr.235 = bind_name a_ref, %a_ref.var [concrete = %a_ref.var] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { @@ -109,7 +109,7 @@ var a: i32* = a_ref; // CHECK:STDOUT: %.loc4: init %i32 = converted %int_0, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_0.6a9] // CHECK:STDOUT: assign file.%a_orig.var, %.loc4 // CHECK:STDOUT: %a_orig.ref: ref %i32 = name_ref a_orig, file.%a_orig [concrete = file.%a_orig.var] -// CHECK:STDOUT: %addr: %ptr = addr_of %a_orig.ref [concrete = constants.%addr] +// CHECK:STDOUT: %addr: %ptr.235 = addr_of %a_orig.ref [concrete = constants.%addr] // CHECK:STDOUT: assign file.%a_ref.var, %addr // CHECK:STDOUT: return // CHECK:STDOUT: } @@ -121,13 +121,13 @@ var a: i32* = a_ref; // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete] -// CHECK:STDOUT: %pattern_type.f6a: type = pattern_type %ptr [concrete] +// CHECK:STDOUT: %ptr.9e1: type = ptr_type %i32 [concrete] +// CHECK:STDOUT: %pattern_type.f6a: type = pattern_type %ptr.9e1 [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Implicit.a_orig = import_ref Implicit//default, a_orig, unloaded -// CHECK:STDOUT: %Implicit.a_ref: ref %ptr = import_ref Implicit//default, a_ref, loaded [concrete = %a_ref.var] +// CHECK:STDOUT: %Implicit.a_ref: ref %ptr.9e1 = import_ref Implicit//default, a_ref, loaded [concrete = %a_ref.var] // CHECK:STDOUT: %Core.ece: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: import Core//prelude @@ -136,7 +136,7 @@ var a: i32* = a_ref; // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %a_ref.patt: %pattern_type.f6a = binding_pattern a_ref [concrete] // CHECK:STDOUT: %a_ref.var_patt: %pattern_type.f6a = var_pattern %a_ref.patt [concrete] -// CHECK:STDOUT: %a_ref.var: ref %ptr = var %a_ref.var_patt [concrete] +// CHECK:STDOUT: %a_ref.var: ref %ptr.9e1 = var %a_ref.var_patt [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -153,19 +153,19 @@ var a: i32* = a_ref; // CHECK:STDOUT: %a.patt: %pattern_type.f6a = binding_pattern a [concrete] // CHECK:STDOUT: %a.var_patt: %pattern_type.f6a = var_pattern %a.patt [concrete] // CHECK:STDOUT: } -// CHECK:STDOUT: %a.var: ref %ptr = var %a.var_patt [concrete] -// CHECK:STDOUT: %.loc4: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %a.var: ref %ptr.9e1 = var %a.var_patt [concrete] +// CHECK:STDOUT: %.loc4: type = splice_block %ptr [concrete = constants.%ptr.9e1] { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete = constants.%ptr] +// CHECK:STDOUT: %ptr: type = ptr_type %i32 [concrete = constants.%ptr.9e1] // CHECK:STDOUT: } -// CHECK:STDOUT: %a: ref %ptr = bind_name a, %a.var [concrete = %a.var] +// CHECK:STDOUT: %a: ref %ptr.9e1 = bind_name a, %a.var [concrete = %a.var] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %a_ref.ref: ref %ptr = name_ref a_ref, imports.%Implicit.a_ref [concrete = imports.%a_ref.var] -// CHECK:STDOUT: %.loc4: %ptr = bind_value %a_ref.ref +// CHECK:STDOUT: %a_ref.ref: ref %ptr.9e1 = name_ref a_ref, imports.%Implicit.a_ref [concrete = imports.%a_ref.var] +// CHECK:STDOUT: %.loc4: %ptr.9e1 = bind_value %a_ref.ref // CHECK:STDOUT: assign file.%a.var, %.loc4 // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/check/testdata/return/fail_return_with_returned_var.carbon b/toolchain/check/testdata/return/fail_return_with_returned_var.carbon index 5eb999e1a835..3dcd7641ecb7 100644 --- a/toolchain/check/testdata/return/fail_return_with_returned_var.carbon +++ b/toolchain/check/testdata/return/fail_return_with_returned_var.carbon @@ -53,6 +53,8 @@ fn G() -> C { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -66,13 +68,17 @@ fn G() -> C { // CHECK:STDOUT: %bound_method.b6e: = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.e6a, @T.as.Destroy.impl.Op(%i32) [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %i32 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a.b.501: type = struct_type {.a: %i32, .b: %i32} [concrete] // CHECK:STDOUT: %complete_type.705: = complete_type_witness %struct_type.a.b.501 [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] @@ -132,6 +138,22 @@ fn G() -> C { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc27: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %int_32.loc27_18: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc27_18: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -139,6 +161,9 @@ fn G() -> C { // CHECK:STDOUT: %int_32.loc27_30: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc27_30: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc27_28: %C.elem = field_decl b, element1 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete = constants.%struct_type.a.b.501] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a.b [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -178,6 +203,8 @@ fn G() -> C { // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @G() -> %return.param: %C { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { diff --git a/toolchain/check/testdata/return/fail_returned_var_shadow.carbon b/toolchain/check/testdata/return/fail_returned_var_shadow.carbon index 9f6fe323a9ad..50caa57037a1 100644 --- a/toolchain/check/testdata/return/fail_returned_var_shadow.carbon +++ b/toolchain/check/testdata/return/fail_returned_var_shadow.carbon @@ -61,6 +61,7 @@ fn DifferentScopes() -> i32 { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -77,7 +78,6 @@ fn DifferentScopes() -> i32 { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.ab5: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.9a1: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] diff --git a/toolchain/check/testdata/return/import_convert_function.carbon b/toolchain/check/testdata/return/import_convert_function.carbon index 51879464f39b..4b8f5345167f 100644 --- a/toolchain/check/testdata/return/import_convert_function.carbon +++ b/toolchain/check/testdata/return/import_convert_function.carbon @@ -60,10 +60,22 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.506: type = class_type @C, @C(%N.51e) [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.1ba: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%N.51e) [symbolic] +// CHECK:STDOUT: %ptr.128: type = ptr_type %C.506 [symbolic] +// CHECK:STDOUT: %pattern_type.d64: type = pattern_type %ptr.128 [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%N.51e) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] // CHECK:STDOUT: %D.elem: type = unbound_element_type %D, %i32 [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.73d: = impl_witness @D.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.n.m.de8: type = struct_type {.n: %i32, .m: %i32} [concrete] // CHECK:STDOUT: %complete_type.ea0: = complete_type_witness %struct_type.n.m.de8 [concrete] // CHECK:STDOUT: %pattern_type.510: type = pattern_type %D [concrete] @@ -94,11 +106,6 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %pattern_type.f33: type = pattern_type %C.c8d [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.type.cd0: type = fn_type @C.as.ImplicitAs.impl.Convert.loc8 [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.b95: %C.as.ImplicitAs.impl.Convert.type.cd0 = struct_value () [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.548: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%D) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.2d4: %T.as.Destroy.impl.Op.type.548 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(%D) [concrete] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.ab5: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.9a1: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] @@ -167,16 +174,16 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -351,6 +358,50 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %ImplicitAs.impl_witness.loc15: = impl_witness %ImplicitAs.impl_witness_table.loc15 [concrete = constants.%ImplicitAs.impl_witness.217] // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%N.loc4_9.2: %i32) { +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.51e)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%N) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.1ba)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%N) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.506 as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.d64) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.d64) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4_18.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.128) = value_param call_param0 +// CHECK:STDOUT: %.loc4_18.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.506)] { +// CHECK:STDOUT: %.loc4_18.3: type = specific_constant constants.%C.506, @C(constants.%N.51e) [symbolic = %C (constants.%C.506)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc4_18.3 [symbolic = %C (constants.%C.506)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.128) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: constants.%D as constants.%Destroy.type { +// CHECK:STDOUT: %D.as.Destroy.impl.Op.decl: %D.as.Destroy.impl.Op.type = fn_decl @D.as.Destroy.impl.Op [concrete = constants.%D.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.a94 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.a94 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc5: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.19c = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%D [concrete = constants.%D] +// CHECK:STDOUT: %self: %ptr.19c = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %D.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @D.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.ImplicitAs.impl.6d8: %C as %ImplicitAs.type { // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.decl: %C.as.ImplicitAs.impl.Convert.type.cd0 = fn_decl @C.as.ImplicitAs.impl.Convert.loc8 [concrete = constants.%C.as.ImplicitAs.impl.Convert.b95] { // CHECK:STDOUT: %self.patt: %pattern_type.f33 = binding_pattern self [concrete] @@ -533,6 +584,9 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%N.51e) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.1ba)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -549,6 +603,9 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %int_32.loc5_30: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc5_30: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc5_28: %D.elem = field_decl m, element1 [concrete] +// CHECK:STDOUT: impl_decl @D.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@D.as.Destroy.impl.%D.as.Destroy.impl.Op.decl), @D.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.73d] // CHECK:STDOUT: %struct_type.n.m: type = struct_type {.n: %i32, .m: %i32} [concrete = constants.%struct_type.n.m.de8] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.n.m [concrete = constants.%complete_type.ea0] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -559,6 +616,19 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: .m = %.loc5_28 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%N.loc4_9.2: %i32) { +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.51e)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%N) [symbolic = %C (constants.%C.506)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.128)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.d64)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.128)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op(%self.param: %ptr.19c) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @Make() -> %return.param: %D { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %int_0.loc6_31: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] @@ -590,11 +660,9 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make] // CHECK:STDOUT: %.loc8: ref %D = splice_block %return {} // CHECK:STDOUT: %Make.call: init %D = call %Make.ref() to %.loc8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc8, constants.%T.as.Destroy.impl.Op.2d4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc8, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound: = bound_method %.loc8, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.19c = addr_of %.loc8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %Make.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -603,11 +671,9 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make] // CHECK:STDOUT: %.loc9: ref %D = splice_block %return {} // CHECK:STDOUT: %Make.call: init %D = call %Make.ref() to %.loc9 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc9, constants.%T.as.Destroy.impl.Op.2d4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc9, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound: = bound_method %.loc9, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.19c = addr_of %.loc9 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %Make.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -616,11 +682,9 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make] // CHECK:STDOUT: %.loc10: ref %D = splice_block %return {} // CHECK:STDOUT: %Make.call: init %D = call %Make.ref() to %.loc10 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc10, constants.%T.as.Destroy.impl.Op.2d4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc10, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound: = bound_method %.loc10, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.19c = addr_of %.loc10 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %Make.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -629,11 +693,9 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make] // CHECK:STDOUT: %.loc11: ref %D = splice_block %return {} // CHECK:STDOUT: %Make.call: init %D = call %Make.ref() to %.loc11 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc11, constants.%T.as.Destroy.impl.Op.2d4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc11, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound: = bound_method %.loc11, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.19c = addr_of %.loc11 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %Make.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -642,11 +704,9 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make] // CHECK:STDOUT: %.loc12: ref %D = splice_block %return {} // CHECK:STDOUT: %Make.call: init %D = call %Make.ref() to %.loc12 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc12, constants.%T.as.Destroy.impl.Op.2d4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc12, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound: = bound_method %.loc12, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.19c = addr_of %.loc12 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %Make.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -655,11 +715,9 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make] // CHECK:STDOUT: %.loc13: ref %D = splice_block %return {} // CHECK:STDOUT: %Make.call: init %D = call %Make.ref() to %.loc13 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc13, constants.%T.as.Destroy.impl.Op.2d4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc13, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound: = bound_method %.loc13, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.19c = addr_of %.loc13 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %Make.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -668,11 +726,9 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make] // CHECK:STDOUT: %.loc14: ref %D = splice_block %return {} // CHECK:STDOUT: %Make.call: init %D = call %Make.ref() to %.loc14 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc14, constants.%T.as.Destroy.impl.Op.2d4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc14, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound: = bound_method %.loc14, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.19c = addr_of %.loc14 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %Make.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -681,11 +737,9 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make] // CHECK:STDOUT: %.loc15: ref %D = splice_block %return {} // CHECK:STDOUT: %Make.call: init %D = call %Make.ref() to %.loc15 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %.loc15, constants.%T.as.Destroy.impl.Op.2d4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.2d4, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method: = bound_method %.loc15, %T.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound: = bound_method %.loc15, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr: %ptr.19c = addr_of %.loc15 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound(%addr) // CHECK:STDOUT: return %Make.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -693,6 +747,18 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %N.loc4_9.1 => constants.%N.51e // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%N.51e) { +// CHECK:STDOUT: %N => constants.%N.51e +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.1ba +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%N.51e) { +// CHECK:STDOUT: %N => constants.%N.51e +// CHECK:STDOUT: %C => constants.%C.506 +// CHECK:STDOUT: %ptr => constants.%ptr.128 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d64 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%int_0.6a9) { // CHECK:STDOUT: %N.loc4_9.1 => constants.%int_0.6a9 // CHECK:STDOUT: @@ -762,11 +828,13 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %N.51e: %i32 = bind_symbolic_name N, 0 [symbolic] +// CHECK:STDOUT: %C.17a: type = class_type @C, @C(%N.51e) [symbolic] // CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] // CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -783,7 +851,11 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %C.val.452: %C.b00 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.5f9: type = facet_type <@ImplicitAs, @ImplicitAs(%D)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.334: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%D) [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.9f3: = impl_witness imports.%Destroy.impl_witness_table.bc6, @C.as.Destroy.impl(%N.51e) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%N.51e) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.9e5: type = ptr_type %C.17a [symbolic] +// CHECK:STDOUT: %pattern_type.572: type = pattern_type %ptr.9e5 [symbolic] // CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] // CHECK:STDOUT: %C.674: type = class_type @C, @C(%int_1.5d2) [concrete] // CHECK:STDOUT: %int_2.ef8: %i32 = int_value 2 [concrete] @@ -803,14 +875,15 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.a9c: type = fn_type_with_self_type %ImplicitAs.Convert.type.334, %ImplicitAs.facet.014 [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.type.971: type = fn_type @C.as.ImplicitAs.impl.Convert.1 [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.bf9: %C.as.ImplicitAs.impl.Convert.type.971 = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.69c: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%D) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.f5a: %T.as.Destroy.impl.Op.type.69c = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.d5a: = impl_witness imports.%Destroy.impl_witness_table.787 [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op.type: type = fn_type @D.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.f29: type = ptr_type %D [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.bd1: = specific_function %T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(%D) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.94c: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.b00) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.ae6: %T.as.Destroy.impl.Op.type.94c = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.749: = impl_witness imports.%Destroy.impl_witness_table.bc6, @C.as.Destroy.impl(%int_0.6a9) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a98: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.b00) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.c0c: %T.as.Destroy.impl.Op.type.a98 = struct_value () [concrete] // CHECK:STDOUT: %ptr.697: type = ptr_type %C.b00 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.e42: = specific_function %T.as.Destroy.impl.Op.ae6, @T.as.Destroy.impl.Op(%C.b00) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.364: = specific_function %T.as.Destroy.impl.Op.c0c, @T.as.Destroy.impl.Op(%C.b00) [concrete] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.ab5: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.9a1: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] @@ -820,10 +893,11 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.7d6: type = fn_type_with_self_type %ImplicitAs.Convert.type.334, %ImplicitAs.facet.b8a [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.type.bdd: type = fn_type @C.as.ImplicitAs.impl.Convert.2 [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.c82: %C.as.ImplicitAs.impl.Convert.type.bdd = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.b6b: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.674) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.ad8: %T.as.Destroy.impl.Op.type.b6b = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.bda: = impl_witness imports.%Destroy.impl_witness_table.bc6, @C.as.Destroy.impl(%int_1.5d2) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.286: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.674) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.60a: %T.as.Destroy.impl.Op.type.286 = struct_value () [concrete] // CHECK:STDOUT: %ptr.625: type = ptr_type %C.674 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.6b6: = specific_function %T.as.Destroy.impl.Op.ad8, @T.as.Destroy.impl.Op(%C.674) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.b9a: = specific_function %T.as.Destroy.impl.Op.60a, @T.as.Destroy.impl.Op(%C.674) [concrete] // CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.ef9: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.b92: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] @@ -833,10 +907,11 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.987: type = fn_type_with_self_type %ImplicitAs.Convert.type.334, %ImplicitAs.facet.d55 [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.type.4c1: type = fn_type @C.as.ImplicitAs.impl.Convert.3 [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.08c: %C.as.ImplicitAs.impl.Convert.type.4c1 = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a31: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.681) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.404: %T.as.Destroy.impl.Op.type.a31 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.b08: = impl_witness imports.%Destroy.impl_witness_table.bc6, @C.as.Destroy.impl(%int_2.ef8) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.fb8: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.681) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.912: %T.as.Destroy.impl.Op.type.fb8 = struct_value () [concrete] // CHECK:STDOUT: %ptr.3bd: type = ptr_type %C.681 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.822: = specific_function %T.as.Destroy.impl.Op.404, @T.as.Destroy.impl.Op(%C.681) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.60f: = specific_function %T.as.Destroy.impl.Op.912, @T.as.Destroy.impl.Op(%C.681) [concrete] // CHECK:STDOUT: %int_3.1ba: Core.IntLiteral = int_value 3 [concrete] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.b30: = bound_method %int_3.1ba, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.047: = bound_method %int_3.1ba, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] @@ -846,10 +921,11 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.efa: type = fn_type_with_self_type %ImplicitAs.Convert.type.334, %ImplicitAs.facet.aa1 [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.type.f89: type = fn_type @C.as.ImplicitAs.impl.Convert.4 [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.2dd: %C.as.ImplicitAs.impl.Convert.type.f89 = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.100: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.7ac) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.9cf: %T.as.Destroy.impl.Op.type.100 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.38d: = impl_witness imports.%Destroy.impl_witness_table.bc6, @C.as.Destroy.impl(%int_3.822) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.895: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.7ac) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.459: %T.as.Destroy.impl.Op.type.895 = struct_value () [concrete] // CHECK:STDOUT: %ptr.2b1: type = ptr_type %C.7ac [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.694: = specific_function %T.as.Destroy.impl.Op.9cf, @T.as.Destroy.impl.Op(%C.7ac) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.f58: = specific_function %T.as.Destroy.impl.Op.459, @T.as.Destroy.impl.Op(%C.7ac) [concrete] // CHECK:STDOUT: %int_4.0c1: Core.IntLiteral = int_value 4 [concrete] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.ac3: = bound_method %int_4.0c1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.1da: = bound_method %int_4.0c1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] @@ -859,10 +935,11 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.26e: type = fn_type_with_self_type %ImplicitAs.Convert.type.334, %ImplicitAs.facet.750 [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.type.2ce: type = fn_type @C.as.ImplicitAs.impl.Convert.5 [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.009: %C.as.ImplicitAs.impl.Convert.type.2ce = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.86c: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.89d) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.6b4: %T.as.Destroy.impl.Op.type.86c = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.897: = impl_witness imports.%Destroy.impl_witness_table.bc6, @C.as.Destroy.impl(%int_4.940) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.d94: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.89d) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.aa1: %T.as.Destroy.impl.Op.type.d94 = struct_value () [concrete] // CHECK:STDOUT: %ptr.c28b: type = ptr_type %C.89d [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.357: = specific_function %T.as.Destroy.impl.Op.6b4, @T.as.Destroy.impl.Op(%C.89d) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.c1b: = specific_function %T.as.Destroy.impl.Op.aa1, @T.as.Destroy.impl.Op(%C.89d) [concrete] // CHECK:STDOUT: %int_5.64b: Core.IntLiteral = int_value 5 [concrete] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.4e6: = bound_method %int_5.64b, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.a25: = bound_method %int_5.64b, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] @@ -872,10 +949,11 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.eaf: type = fn_type_with_self_type %ImplicitAs.Convert.type.334, %ImplicitAs.facet.8cc [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.type.e9d: type = fn_type @C.as.ImplicitAs.impl.Convert.6 [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.b66: %C.as.ImplicitAs.impl.Convert.type.e9d = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.4df: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.f0a) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.985: %T.as.Destroy.impl.Op.type.4df = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.0c6: = impl_witness imports.%Destroy.impl_witness_table.bc6, @C.as.Destroy.impl(%int_5.0f6) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.03d: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.f0a) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.928: %T.as.Destroy.impl.Op.type.03d = struct_value () [concrete] // CHECK:STDOUT: %ptr.24c: type = ptr_type %C.f0a [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.a66: = specific_function %T.as.Destroy.impl.Op.985, @T.as.Destroy.impl.Op(%C.f0a) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.cdb: = specific_function %T.as.Destroy.impl.Op.928, @T.as.Destroy.impl.Op(%C.f0a) [concrete] // CHECK:STDOUT: %int_6.462: Core.IntLiteral = int_value 6 [concrete] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.ce9: = bound_method %int_6.462, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.efa: = bound_method %int_6.462, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] @@ -885,10 +963,11 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.874: type = fn_type_with_self_type %ImplicitAs.Convert.type.334, %ImplicitAs.facet.a69 [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.type.4b8: type = fn_type @C.as.ImplicitAs.impl.Convert.7 [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.f59: %C.as.ImplicitAs.impl.Convert.type.4b8 = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.32d: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.c60) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.ca5: %T.as.Destroy.impl.Op.type.32d = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.3a0: = impl_witness imports.%Destroy.impl_witness_table.bc6, @C.as.Destroy.impl(%int_6.e56) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.d47: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.c60) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.180: %T.as.Destroy.impl.Op.type.d47 = struct_value () [concrete] // CHECK:STDOUT: %ptr.b5e: type = ptr_type %C.c60 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.8d0: = specific_function %T.as.Destroy.impl.Op.ca5, @T.as.Destroy.impl.Op(%C.c60) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.659: = specific_function %T.as.Destroy.impl.Op.180, @T.as.Destroy.impl.Op(%C.c60) [concrete] // CHECK:STDOUT: %int_7.29f: Core.IntLiteral = int_value 7 [concrete] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.208: = bound_method %int_7.29f, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.3bd: = bound_method %int_7.29f, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] @@ -898,10 +977,11 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.79b: type = fn_type_with_self_type %ImplicitAs.Convert.type.334, %ImplicitAs.facet.cca [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.type.c7e: type = fn_type @C.as.ImplicitAs.impl.Convert.8 [concrete] // CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.6c1: %C.as.ImplicitAs.impl.Convert.type.c7e = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.986: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.304) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.6fc: %T.as.Destroy.impl.Op.type.986 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.4f0: = impl_witness imports.%Destroy.impl_witness_table.bc6, @C.as.Destroy.impl(%int_7.0b1) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.4d0: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%C.304) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.7c1: %T.as.Destroy.impl.Op.type.4d0 = struct_value () [concrete] // CHECK:STDOUT: %ptr.dc3: type = ptr_type %C.304 [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.a08: = specific_function %T.as.Destroy.impl.Op.6fc, @T.as.Destroy.impl.Op(%C.304) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.078: = specific_function %T.as.Destroy.impl.Op.7c1, @T.as.Destroy.impl.Op(%C.304) [concrete] // CHECK:STDOUT: %Make.type: type = fn_type @Make [concrete] // CHECK:STDOUT: %Make: %Make.type = struct_value () [concrete] // CHECK:STDOUT: } @@ -923,16 +1003,26 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %P.D: type = import_ref P//library, D, loaded [concrete = constants.%D] // CHECK:STDOUT: %P.import_ref.a7d: = import_ref P//library, loc5_35, loaded [concrete = constants.%complete_type.ea0] -// CHECK:STDOUT: %P.import_ref.cab = import_ref P//library, inst57 [no loc], unloaded +// CHECK:STDOUT: %P.import_ref.cab = import_ref P//library, inst107 [no loc], unloaded // CHECK:STDOUT: %P.import_ref.a52 = import_ref P//library, loc5_16, unloaded // CHECK:STDOUT: %P.import_ref.b4a = import_ref P//library, loc5_28, unloaded // CHECK:STDOUT: %P.C: %C.type = import_ref P//library, C, loaded [concrete = constants.%C.generic] -// CHECK:STDOUT: %P.import_ref.1b7: %i32 = import_ref P//library, loc4_9, loaded [symbolic = @C.%N (constants.%N.51e)] +// CHECK:STDOUT: %P.import_ref.1b7f13.1: %i32 = import_ref P//library, loc4_9, loaded [symbolic = @C.%N (constants.%N.51e)] // CHECK:STDOUT: %P.import_ref.8f2: = import_ref P//library, loc4_19, loaded [concrete = constants.%complete_type.357] // CHECK:STDOUT: %P.import_ref.f65 = import_ref P//library, inst51 [no loc], unloaded // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %P.import_ref.f49 = import_ref P//library, loc4_18, unloaded +// CHECK:STDOUT: %P.import_ref.1b7f13.2: %i32 = import_ref P//library, loc4_9, loaded [symbolic = @C.%N (constants.%N.51e)] +// CHECK:STDOUT: %P.import_ref.d6f: type = import_ref P//library, inst51 [no loc], loaded [symbolic = constants.%C.17a] +// CHECK:STDOUT: %P.import_ref.cb9298.1: type = import_ref P//library, inst54 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %P.import_ref.4f7 = import_ref P//library, loc4_18, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.bc6 = impl_witness_table (%P.import_ref.4f7), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %P.import_ref.1b7f13.3: %i32 = import_ref P//library, loc4_9, loaded [symbolic = @C.%N (constants.%N.51e)] +// CHECK:STDOUT: %P.import_ref.7ba: = import_ref P//library, loc5_9, loaded [concrete = constants.%Destroy.impl_witness.d5a] +// CHECK:STDOUT: %P.import_ref.4aa: type = import_ref P//library, inst107 [no loc], loaded [concrete = constants.%D] +// CHECK:STDOUT: %P.import_ref.cb9298.2: type = import_ref P//library, inst54 [no loc], loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %P.import_ref.708: = import_ref P//library, loc8_33, loaded [concrete = constants.%ImplicitAs.impl_witness.f53] // CHECK:STDOUT: %P.import_ref.d2c: type = import_ref P//library, loc8_9, loaded [concrete = constants.%C.b00] // CHECK:STDOUT: %P.import_ref.b769fa.1: type = import_ref P//library, loc8_31, loaded [concrete = constants.%ImplicitAs.type.5f9] @@ -960,6 +1050,8 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %P.import_ref.e36: %C.as.ImplicitAs.impl.Convert.type.971 = import_ref P//library, loc8_65, loaded [concrete = constants.%C.as.ImplicitAs.impl.Convert.bf9] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.f4b = impl_witness_table (%P.import_ref.e36), @C.as.ImplicitAs.impl.284 [concrete] // CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %P.import_ref.8ca: %D.as.Destroy.impl.Op.type = import_ref P//library, loc5_9, loaded [concrete = constants.%D.as.Destroy.impl.Op] +// CHECK:STDOUT: %Destroy.impl_witness_table.787 = impl_witness_table (%P.import_ref.8ca), @D.as.Destroy.impl [concrete] // CHECK:STDOUT: %P.import_ref.38e: %C.as.ImplicitAs.impl.Convert.type.bdd = import_ref P//library, loc9_65, loaded [concrete = constants.%C.as.ImplicitAs.impl.Convert.c82] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.297 = impl_witness_table (%P.import_ref.38e), @C.as.ImplicitAs.impl.628 [concrete] // CHECK:STDOUT: %P.import_ref.5ab: %C.as.ImplicitAs.impl.Convert.type.4c1 = import_ref P//library, loc10_65, loaded [concrete = constants.%C.as.ImplicitAs.impl.Convert.08c] @@ -1004,6 +1096,25 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(imports.%P.import_ref.1b7f13.2: %i32) [from "library.carbon"] { +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.51e)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.bc6, @C.as.Destroy.impl(%N) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.9f3)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%N) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%P.import_ref.d6f as imports.%P.import_ref.cb9298.1 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%P.import_ref.f49 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @D.as.Destroy.impl: imports.%P.import_ref.4aa as imports.%P.import_ref.cb9298.2 [from "library.carbon"] { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: witness = imports.%P.import_ref.7ba +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: impl @C.as.ImplicitAs.impl.284: imports.%P.import_ref.d2c as imports.%P.import_ref.b769fa.1 [from "library.carbon"] { // CHECK:STDOUT: !members: // CHECK:STDOUT: witness = imports.%P.import_ref.708 @@ -1053,7 +1164,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: .m = imports.%P.import_ref.b4a // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic class @C(imports.%P.import_ref.1b7: %i32) [from "library.carbon"] { +// CHECK:STDOUT: generic class @C(imports.%P.import_ref.1b7f13.1: %i32) [from "library.carbon"] { // CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.51e)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: @@ -1089,19 +1200,17 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc7_24.4: ref %C.b00 = temporary %.loc7_24.2, %.loc7_24.3 // CHECK:STDOUT: %.loc7_26.1: ref %C.b00 = converted %.loc7_24.1, %.loc7_24.4 // CHECK:STDOUT: %impl.elem0.loc7_35: %.a9c = impl_witness_access constants.%ImplicitAs.impl_witness.f53, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.bf9] -// CHECK:STDOUT: %bound_method.loc7_35.1: = bound_method %.loc7_26.1, %impl.elem0.loc7_35 +// CHECK:STDOUT: %bound_method.loc7_35: = bound_method %.loc7_26.1, %impl.elem0.loc7_35 // CHECK:STDOUT: %.loc7_35.1: ref %D = temporary_storage // CHECK:STDOUT: %.loc7_26.2: %C.b00 = bind_value %.loc7_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc7: init %D = call %bound_method.loc7_35.1(%.loc7_26.2) to %.loc7_35.1 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc7: init %D = call %bound_method.loc7_35(%.loc7_26.2) to %.loc7_35.1 // CHECK:STDOUT: %.loc7_35.2: init %D = converted %.loc7_26.1, %C.as.ImplicitAs.impl.Convert.call.loc7 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_35.1: = bound_method %.loc7_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc7_35.2: = bound_method %.loc7_35.1, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc7_35.1: = bound_method %.loc7_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc7_35.1: %ptr.f29 = addr_of %.loc7_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_35.1: init %empty_tuple.type = call %bound_method.loc7_35.2(%addr.loc7_35.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.1: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.ae6 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.ae6, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.e42] -// CHECK:STDOUT: %bound_method.loc7_24.1: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc7_35.1: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc7_35.1(%addr.loc7_35.1) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.1: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.c0c +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.c0c, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.364] +// CHECK:STDOUT: %bound_method.loc7_24.1: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.1 // CHECK:STDOUT: %addr.loc7_24.1: %ptr.697 = addr_of %.loc7_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_24.1: init %empty_tuple.type = call %bound_method.loc7_24.1(%addr.loc7_24.1) // CHECK:STDOUT: return %.loc7_35.2 to %return @@ -1128,29 +1237,25 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc8_24.4: ref %C.674 = temporary %.loc8_24.2, %.loc8_24.3 // CHECK:STDOUT: %.loc8_26.1: ref %C.674 = converted %.loc8_24.1, %.loc8_24.4 // CHECK:STDOUT: %impl.elem0.loc8_35: %.7d6 = impl_witness_access constants.%ImplicitAs.impl_witness.fcb, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.c82] -// CHECK:STDOUT: %bound_method.loc8_35.1: = bound_method %.loc8_26.1, %impl.elem0.loc8_35 +// CHECK:STDOUT: %bound_method.loc8_35: = bound_method %.loc8_26.1, %impl.elem0.loc8_35 // CHECK:STDOUT: %.loc8_35.1: ref %D = temporary_storage // CHECK:STDOUT: %.loc8_26.2: %C.674 = bind_value %.loc8_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc8: init %D = call %bound_method.loc8_35.1(%.loc8_26.2) to %.loc8_35.1 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc8: init %D = call %bound_method.loc8_35(%.loc8_26.2) to %.loc8_35.1 // CHECK:STDOUT: %.loc8_35.2: init %D = converted %.loc8_26.1, %C.as.ImplicitAs.impl.Convert.call.loc8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_35.1: = bound_method %.loc8_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc8_35.2: = bound_method %.loc8_35.1, %T.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc8_35.1: = bound_method %.loc8_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc8_35.1: %ptr.f29 = addr_of %.loc8_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_35.1: init %empty_tuple.type = call %bound_method.loc8_35.2(%addr.loc8_35.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.1: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.ad8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.4: = specific_function constants.%T.as.Destroy.impl.Op.ad8, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6b6] -// CHECK:STDOUT: %bound_method.loc8_24.1: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.4 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc8_35.1: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc8_35.1(%addr.loc8_35.1) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.1: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.60a +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.60a, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.b9a] +// CHECK:STDOUT: %bound_method.loc8_24.1: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.2 // CHECK:STDOUT: %addr.loc8_24.1: %ptr.625 = addr_of %.loc8_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_24.1: init %empty_tuple.type = call %bound_method.loc8_24.1(%addr.loc8_24.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_35.2: = bound_method %.loc7_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.5: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc7_35.3: = bound_method %.loc7_35.1, %T.as.Destroy.impl.Op.specific_fn.5 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc7_35.2: = bound_method %.loc7_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc7_35.2: %ptr.f29 = addr_of %.loc7_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_35.2: init %empty_tuple.type = call %bound_method.loc7_35.3(%addr.loc7_35.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.2: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.ae6 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.6: = specific_function constants.%T.as.Destroy.impl.Op.ae6, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.e42] -// CHECK:STDOUT: %bound_method.loc7_24.2: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.6 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc7_35.2: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc7_35.2(%addr.loc7_35.2) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.2: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.c0c +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%T.as.Destroy.impl.Op.c0c, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.364] +// CHECK:STDOUT: %bound_method.loc7_24.2: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.3 // CHECK:STDOUT: %addr.loc7_24.2: %ptr.697 = addr_of %.loc7_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_24.2: init %empty_tuple.type = call %bound_method.loc7_24.2(%addr.loc7_24.2) // CHECK:STDOUT: return %.loc8_35.2 to %return @@ -1177,39 +1282,33 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc9_24.4: ref %C.681 = temporary %.loc9_24.2, %.loc9_24.3 // CHECK:STDOUT: %.loc9_26.1: ref %C.681 = converted %.loc9_24.1, %.loc9_24.4 // CHECK:STDOUT: %impl.elem0.loc9_35: %.987 = impl_witness_access constants.%ImplicitAs.impl_witness.746, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.08c] -// CHECK:STDOUT: %bound_method.loc9_35.1: = bound_method %.loc9_26.1, %impl.elem0.loc9_35 +// CHECK:STDOUT: %bound_method.loc9_35: = bound_method %.loc9_26.1, %impl.elem0.loc9_35 // CHECK:STDOUT: %.loc9_35.1: ref %D = temporary_storage // CHECK:STDOUT: %.loc9_26.2: %C.681 = bind_value %.loc9_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc9: init %D = call %bound_method.loc9_35.1(%.loc9_26.2) to %.loc9_35.1 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc9: init %D = call %bound_method.loc9_35(%.loc9_26.2) to %.loc9_35.1 // CHECK:STDOUT: %.loc9_35.2: init %D = converted %.loc9_26.1, %C.as.ImplicitAs.impl.Convert.call.loc9 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_35.1: = bound_method %.loc9_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.7: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc9_35.2: = bound_method %.loc9_35.1, %T.as.Destroy.impl.Op.specific_fn.7 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc9_35.1: = bound_method %.loc9_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc9_35.1: %ptr.f29 = addr_of %.loc9_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9_35.1: init %empty_tuple.type = call %bound_method.loc9_35.2(%addr.loc9_35.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_24.1: = bound_method %.loc9_24.2, constants.%T.as.Destroy.impl.Op.404 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.8: = specific_function constants.%T.as.Destroy.impl.Op.404, @T.as.Destroy.impl.Op(constants.%C.681) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.822] -// CHECK:STDOUT: %bound_method.loc9_24.1: = bound_method %.loc9_24.2, %T.as.Destroy.impl.Op.specific_fn.8 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc9_35.1: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc9_35.1(%addr.loc9_35.1) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_24.1: = bound_method %.loc9_24.2, constants.%T.as.Destroy.impl.Op.912 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.4: = specific_function constants.%T.as.Destroy.impl.Op.912, @T.as.Destroy.impl.Op(constants.%C.681) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.60f] +// CHECK:STDOUT: %bound_method.loc9_24.1: = bound_method %.loc9_24.2, %T.as.Destroy.impl.Op.specific_fn.4 // CHECK:STDOUT: %addr.loc9_24.1: %ptr.3bd = addr_of %.loc9_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9_24.1: init %empty_tuple.type = call %bound_method.loc9_24.1(%addr.loc9_24.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_35.2: = bound_method %.loc8_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.9: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc8_35.3: = bound_method %.loc8_35.1, %T.as.Destroy.impl.Op.specific_fn.9 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc8_35.2: = bound_method %.loc8_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc8_35.2: %ptr.f29 = addr_of %.loc8_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_35.2: init %empty_tuple.type = call %bound_method.loc8_35.3(%addr.loc8_35.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.2: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.ad8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.10: = specific_function constants.%T.as.Destroy.impl.Op.ad8, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6b6] -// CHECK:STDOUT: %bound_method.loc8_24.2: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.10 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc8_35.2: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc8_35.2(%addr.loc8_35.2) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.2: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.60a +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.5: = specific_function constants.%T.as.Destroy.impl.Op.60a, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.b9a] +// CHECK:STDOUT: %bound_method.loc8_24.2: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.5 // CHECK:STDOUT: %addr.loc8_24.2: %ptr.625 = addr_of %.loc8_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_24.2: init %empty_tuple.type = call %bound_method.loc8_24.2(%addr.loc8_24.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_35.3: = bound_method %.loc7_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.11: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc7_35.4: = bound_method %.loc7_35.1, %T.as.Destroy.impl.Op.specific_fn.11 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc7_35.3: = bound_method %.loc7_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc7_35.3: %ptr.f29 = addr_of %.loc7_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_35.3: init %empty_tuple.type = call %bound_method.loc7_35.4(%addr.loc7_35.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.3: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.ae6 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.12: = specific_function constants.%T.as.Destroy.impl.Op.ae6, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.e42] -// CHECK:STDOUT: %bound_method.loc7_24.3: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.12 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc7_35.3: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc7_35.3(%addr.loc7_35.3) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.3: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.c0c +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.6: = specific_function constants.%T.as.Destroy.impl.Op.c0c, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.364] +// CHECK:STDOUT: %bound_method.loc7_24.3: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.6 // CHECK:STDOUT: %addr.loc7_24.3: %ptr.697 = addr_of %.loc7_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_24.3: init %empty_tuple.type = call %bound_method.loc7_24.3(%addr.loc7_24.3) // CHECK:STDOUT: return %.loc9_35.2 to %return @@ -1236,49 +1335,41 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc10_24.4: ref %C.7ac = temporary %.loc10_24.2, %.loc10_24.3 // CHECK:STDOUT: %.loc10_26.1: ref %C.7ac = converted %.loc10_24.1, %.loc10_24.4 // CHECK:STDOUT: %impl.elem0.loc10_35: %.efa = impl_witness_access constants.%ImplicitAs.impl_witness.f79, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.2dd] -// CHECK:STDOUT: %bound_method.loc10_35.1: = bound_method %.loc10_26.1, %impl.elem0.loc10_35 +// CHECK:STDOUT: %bound_method.loc10_35: = bound_method %.loc10_26.1, %impl.elem0.loc10_35 // CHECK:STDOUT: %.loc10_35.1: ref %D = temporary_storage // CHECK:STDOUT: %.loc10_26.2: %C.7ac = bind_value %.loc10_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc10: init %D = call %bound_method.loc10_35.1(%.loc10_26.2) to %.loc10_35.1 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc10: init %D = call %bound_method.loc10_35(%.loc10_26.2) to %.loc10_35.1 // CHECK:STDOUT: %.loc10_35.2: init %D = converted %.loc10_26.1, %C.as.ImplicitAs.impl.Convert.call.loc10 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_35.1: = bound_method %.loc10_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.13: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc10_35.2: = bound_method %.loc10_35.1, %T.as.Destroy.impl.Op.specific_fn.13 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc10_35.1: = bound_method %.loc10_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc10_35.1: %ptr.f29 = addr_of %.loc10_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10_35.1: init %empty_tuple.type = call %bound_method.loc10_35.2(%addr.loc10_35.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_24.1: = bound_method %.loc10_24.2, constants.%T.as.Destroy.impl.Op.9cf -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.14: = specific_function constants.%T.as.Destroy.impl.Op.9cf, @T.as.Destroy.impl.Op(constants.%C.7ac) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.694] -// CHECK:STDOUT: %bound_method.loc10_24.1: = bound_method %.loc10_24.2, %T.as.Destroy.impl.Op.specific_fn.14 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc10_35.1: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc10_35.1(%addr.loc10_35.1) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_24.1: = bound_method %.loc10_24.2, constants.%T.as.Destroy.impl.Op.459 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.7: = specific_function constants.%T.as.Destroy.impl.Op.459, @T.as.Destroy.impl.Op(constants.%C.7ac) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.f58] +// CHECK:STDOUT: %bound_method.loc10_24.1: = bound_method %.loc10_24.2, %T.as.Destroy.impl.Op.specific_fn.7 // CHECK:STDOUT: %addr.loc10_24.1: %ptr.2b1 = addr_of %.loc10_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10_24.1: init %empty_tuple.type = call %bound_method.loc10_24.1(%addr.loc10_24.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_35.2: = bound_method %.loc9_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.15: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc9_35.3: = bound_method %.loc9_35.1, %T.as.Destroy.impl.Op.specific_fn.15 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc9_35.2: = bound_method %.loc9_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc9_35.2: %ptr.f29 = addr_of %.loc9_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9_35.2: init %empty_tuple.type = call %bound_method.loc9_35.3(%addr.loc9_35.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_24.2: = bound_method %.loc9_24.2, constants.%T.as.Destroy.impl.Op.404 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.16: = specific_function constants.%T.as.Destroy.impl.Op.404, @T.as.Destroy.impl.Op(constants.%C.681) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.822] -// CHECK:STDOUT: %bound_method.loc9_24.2: = bound_method %.loc9_24.2, %T.as.Destroy.impl.Op.specific_fn.16 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc9_35.2: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc9_35.2(%addr.loc9_35.2) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_24.2: = bound_method %.loc9_24.2, constants.%T.as.Destroy.impl.Op.912 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.8: = specific_function constants.%T.as.Destroy.impl.Op.912, @T.as.Destroy.impl.Op(constants.%C.681) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.60f] +// CHECK:STDOUT: %bound_method.loc9_24.2: = bound_method %.loc9_24.2, %T.as.Destroy.impl.Op.specific_fn.8 // CHECK:STDOUT: %addr.loc9_24.2: %ptr.3bd = addr_of %.loc9_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9_24.2: init %empty_tuple.type = call %bound_method.loc9_24.2(%addr.loc9_24.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_35.3: = bound_method %.loc8_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.17: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc8_35.4: = bound_method %.loc8_35.1, %T.as.Destroy.impl.Op.specific_fn.17 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc8_35.3: = bound_method %.loc8_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc8_35.3: %ptr.f29 = addr_of %.loc8_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_35.3: init %empty_tuple.type = call %bound_method.loc8_35.4(%addr.loc8_35.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.3: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.ad8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.18: = specific_function constants.%T.as.Destroy.impl.Op.ad8, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6b6] -// CHECK:STDOUT: %bound_method.loc8_24.3: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.18 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc8_35.3: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc8_35.3(%addr.loc8_35.3) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.3: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.60a +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.9: = specific_function constants.%T.as.Destroy.impl.Op.60a, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.b9a] +// CHECK:STDOUT: %bound_method.loc8_24.3: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.9 // CHECK:STDOUT: %addr.loc8_24.3: %ptr.625 = addr_of %.loc8_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_24.3: init %empty_tuple.type = call %bound_method.loc8_24.3(%addr.loc8_24.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_35.4: = bound_method %.loc7_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.19: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc7_35.5: = bound_method %.loc7_35.1, %T.as.Destroy.impl.Op.specific_fn.19 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc7_35.4: = bound_method %.loc7_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc7_35.4: %ptr.f29 = addr_of %.loc7_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_35.4: init %empty_tuple.type = call %bound_method.loc7_35.5(%addr.loc7_35.4) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.4: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.ae6 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.20: = specific_function constants.%T.as.Destroy.impl.Op.ae6, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.e42] -// CHECK:STDOUT: %bound_method.loc7_24.4: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.20 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc7_35.4: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc7_35.4(%addr.loc7_35.4) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.4: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.c0c +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.10: = specific_function constants.%T.as.Destroy.impl.Op.c0c, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.364] +// CHECK:STDOUT: %bound_method.loc7_24.4: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.10 // CHECK:STDOUT: %addr.loc7_24.4: %ptr.697 = addr_of %.loc7_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_24.4: init %empty_tuple.type = call %bound_method.loc7_24.4(%addr.loc7_24.4) // CHECK:STDOUT: return %.loc10_35.2 to %return @@ -1305,59 +1396,49 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc11_24.4: ref %C.89d = temporary %.loc11_24.2, %.loc11_24.3 // CHECK:STDOUT: %.loc11_26.1: ref %C.89d = converted %.loc11_24.1, %.loc11_24.4 // CHECK:STDOUT: %impl.elem0.loc11_35: %.26e = impl_witness_access constants.%ImplicitAs.impl_witness.16c, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.009] -// CHECK:STDOUT: %bound_method.loc11_35.1: = bound_method %.loc11_26.1, %impl.elem0.loc11_35 +// CHECK:STDOUT: %bound_method.loc11_35: = bound_method %.loc11_26.1, %impl.elem0.loc11_35 // CHECK:STDOUT: %.loc11_35.1: ref %D = temporary_storage // CHECK:STDOUT: %.loc11_26.2: %C.89d = bind_value %.loc11_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc11: init %D = call %bound_method.loc11_35.1(%.loc11_26.2) to %.loc11_35.1 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc11: init %D = call %bound_method.loc11_35(%.loc11_26.2) to %.loc11_35.1 // CHECK:STDOUT: %.loc11_35.2: init %D = converted %.loc11_26.1, %C.as.ImplicitAs.impl.Convert.call.loc11 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc11_35.1: = bound_method %.loc11_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.21: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc11_35.2: = bound_method %.loc11_35.1, %T.as.Destroy.impl.Op.specific_fn.21 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc11_35.1: = bound_method %.loc11_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc11_35.1: %ptr.f29 = addr_of %.loc11_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc11_35.1: init %empty_tuple.type = call %bound_method.loc11_35.2(%addr.loc11_35.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc11_24.1: = bound_method %.loc11_24.2, constants.%T.as.Destroy.impl.Op.6b4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.22: = specific_function constants.%T.as.Destroy.impl.Op.6b4, @T.as.Destroy.impl.Op(constants.%C.89d) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.357] -// CHECK:STDOUT: %bound_method.loc11_24.1: = bound_method %.loc11_24.2, %T.as.Destroy.impl.Op.specific_fn.22 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc11_35.1: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc11_35.1(%addr.loc11_35.1) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc11_24.1: = bound_method %.loc11_24.2, constants.%T.as.Destroy.impl.Op.aa1 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.11: = specific_function constants.%T.as.Destroy.impl.Op.aa1, @T.as.Destroy.impl.Op(constants.%C.89d) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.c1b] +// CHECK:STDOUT: %bound_method.loc11_24.1: = bound_method %.loc11_24.2, %T.as.Destroy.impl.Op.specific_fn.11 // CHECK:STDOUT: %addr.loc11_24.1: %ptr.c28b = addr_of %.loc11_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc11_24.1: init %empty_tuple.type = call %bound_method.loc11_24.1(%addr.loc11_24.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_35.2: = bound_method %.loc10_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.23: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc10_35.3: = bound_method %.loc10_35.1, %T.as.Destroy.impl.Op.specific_fn.23 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc10_35.2: = bound_method %.loc10_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc10_35.2: %ptr.f29 = addr_of %.loc10_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10_35.2: init %empty_tuple.type = call %bound_method.loc10_35.3(%addr.loc10_35.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_24.2: = bound_method %.loc10_24.2, constants.%T.as.Destroy.impl.Op.9cf -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.24: = specific_function constants.%T.as.Destroy.impl.Op.9cf, @T.as.Destroy.impl.Op(constants.%C.7ac) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.694] -// CHECK:STDOUT: %bound_method.loc10_24.2: = bound_method %.loc10_24.2, %T.as.Destroy.impl.Op.specific_fn.24 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc10_35.2: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc10_35.2(%addr.loc10_35.2) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_24.2: = bound_method %.loc10_24.2, constants.%T.as.Destroy.impl.Op.459 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.12: = specific_function constants.%T.as.Destroy.impl.Op.459, @T.as.Destroy.impl.Op(constants.%C.7ac) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.f58] +// CHECK:STDOUT: %bound_method.loc10_24.2: = bound_method %.loc10_24.2, %T.as.Destroy.impl.Op.specific_fn.12 // CHECK:STDOUT: %addr.loc10_24.2: %ptr.2b1 = addr_of %.loc10_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10_24.2: init %empty_tuple.type = call %bound_method.loc10_24.2(%addr.loc10_24.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_35.3: = bound_method %.loc9_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.25: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc9_35.4: = bound_method %.loc9_35.1, %T.as.Destroy.impl.Op.specific_fn.25 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc9_35.3: = bound_method %.loc9_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc9_35.3: %ptr.f29 = addr_of %.loc9_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9_35.3: init %empty_tuple.type = call %bound_method.loc9_35.4(%addr.loc9_35.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_24.3: = bound_method %.loc9_24.2, constants.%T.as.Destroy.impl.Op.404 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.26: = specific_function constants.%T.as.Destroy.impl.Op.404, @T.as.Destroy.impl.Op(constants.%C.681) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.822] -// CHECK:STDOUT: %bound_method.loc9_24.3: = bound_method %.loc9_24.2, %T.as.Destroy.impl.Op.specific_fn.26 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc9_35.3: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc9_35.3(%addr.loc9_35.3) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_24.3: = bound_method %.loc9_24.2, constants.%T.as.Destroy.impl.Op.912 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.13: = specific_function constants.%T.as.Destroy.impl.Op.912, @T.as.Destroy.impl.Op(constants.%C.681) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.60f] +// CHECK:STDOUT: %bound_method.loc9_24.3: = bound_method %.loc9_24.2, %T.as.Destroy.impl.Op.specific_fn.13 // CHECK:STDOUT: %addr.loc9_24.3: %ptr.3bd = addr_of %.loc9_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9_24.3: init %empty_tuple.type = call %bound_method.loc9_24.3(%addr.loc9_24.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_35.4: = bound_method %.loc8_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.27: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc8_35.5: = bound_method %.loc8_35.1, %T.as.Destroy.impl.Op.specific_fn.27 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc8_35.4: = bound_method %.loc8_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc8_35.4: %ptr.f29 = addr_of %.loc8_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_35.4: init %empty_tuple.type = call %bound_method.loc8_35.5(%addr.loc8_35.4) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.4: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.ad8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.28: = specific_function constants.%T.as.Destroy.impl.Op.ad8, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6b6] -// CHECK:STDOUT: %bound_method.loc8_24.4: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.28 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc8_35.4: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc8_35.4(%addr.loc8_35.4) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.4: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.60a +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.14: = specific_function constants.%T.as.Destroy.impl.Op.60a, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.b9a] +// CHECK:STDOUT: %bound_method.loc8_24.4: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.14 // CHECK:STDOUT: %addr.loc8_24.4: %ptr.625 = addr_of %.loc8_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_24.4: init %empty_tuple.type = call %bound_method.loc8_24.4(%addr.loc8_24.4) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_35.5: = bound_method %.loc7_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.29: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc7_35.6: = bound_method %.loc7_35.1, %T.as.Destroy.impl.Op.specific_fn.29 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc7_35.5: = bound_method %.loc7_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc7_35.5: %ptr.f29 = addr_of %.loc7_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_35.5: init %empty_tuple.type = call %bound_method.loc7_35.6(%addr.loc7_35.5) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.5: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.ae6 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.30: = specific_function constants.%T.as.Destroy.impl.Op.ae6, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.e42] -// CHECK:STDOUT: %bound_method.loc7_24.5: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.30 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc7_35.5: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc7_35.5(%addr.loc7_35.5) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.5: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.c0c +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.15: = specific_function constants.%T.as.Destroy.impl.Op.c0c, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.364] +// CHECK:STDOUT: %bound_method.loc7_24.5: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.15 // CHECK:STDOUT: %addr.loc7_24.5: %ptr.697 = addr_of %.loc7_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_24.5: init %empty_tuple.type = call %bound_method.loc7_24.5(%addr.loc7_24.5) // CHECK:STDOUT: return %.loc11_35.2 to %return @@ -1384,69 +1465,57 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc12_24.4: ref %C.f0a = temporary %.loc12_24.2, %.loc12_24.3 // CHECK:STDOUT: %.loc12_26.1: ref %C.f0a = converted %.loc12_24.1, %.loc12_24.4 // CHECK:STDOUT: %impl.elem0.loc12_35: %.eaf = impl_witness_access constants.%ImplicitAs.impl_witness.aa9, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.b66] -// CHECK:STDOUT: %bound_method.loc12_35.1: = bound_method %.loc12_26.1, %impl.elem0.loc12_35 +// CHECK:STDOUT: %bound_method.loc12_35: = bound_method %.loc12_26.1, %impl.elem0.loc12_35 // CHECK:STDOUT: %.loc12_35.1: ref %D = temporary_storage // CHECK:STDOUT: %.loc12_26.2: %C.f0a = bind_value %.loc12_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc12: init %D = call %bound_method.loc12_35.1(%.loc12_26.2) to %.loc12_35.1 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc12: init %D = call %bound_method.loc12_35(%.loc12_26.2) to %.loc12_35.1 // CHECK:STDOUT: %.loc12_35.2: init %D = converted %.loc12_26.1, %C.as.ImplicitAs.impl.Convert.call.loc12 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_35.1: = bound_method %.loc12_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.31: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc12_35.2: = bound_method %.loc12_35.1, %T.as.Destroy.impl.Op.specific_fn.31 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc12_35.1: = bound_method %.loc12_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc12_35.1: %ptr.f29 = addr_of %.loc12_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_35.1: init %empty_tuple.type = call %bound_method.loc12_35.2(%addr.loc12_35.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_24.1: = bound_method %.loc12_24.2, constants.%T.as.Destroy.impl.Op.985 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.32: = specific_function constants.%T.as.Destroy.impl.Op.985, @T.as.Destroy.impl.Op(constants.%C.f0a) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.a66] -// CHECK:STDOUT: %bound_method.loc12_24.1: = bound_method %.loc12_24.2, %T.as.Destroy.impl.Op.specific_fn.32 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc12_35.1: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc12_35.1(%addr.loc12_35.1) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_24.1: = bound_method %.loc12_24.2, constants.%T.as.Destroy.impl.Op.928 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.16: = specific_function constants.%T.as.Destroy.impl.Op.928, @T.as.Destroy.impl.Op(constants.%C.f0a) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.cdb] +// CHECK:STDOUT: %bound_method.loc12_24.1: = bound_method %.loc12_24.2, %T.as.Destroy.impl.Op.specific_fn.16 // CHECK:STDOUT: %addr.loc12_24.1: %ptr.24c = addr_of %.loc12_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_24.1: init %empty_tuple.type = call %bound_method.loc12_24.1(%addr.loc12_24.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc11_35.2: = bound_method %.loc11_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.33: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc11_35.3: = bound_method %.loc11_35.1, %T.as.Destroy.impl.Op.specific_fn.33 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc11_35.2: = bound_method %.loc11_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc11_35.2: %ptr.f29 = addr_of %.loc11_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc11_35.2: init %empty_tuple.type = call %bound_method.loc11_35.3(%addr.loc11_35.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc11_24.2: = bound_method %.loc11_24.2, constants.%T.as.Destroy.impl.Op.6b4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.34: = specific_function constants.%T.as.Destroy.impl.Op.6b4, @T.as.Destroy.impl.Op(constants.%C.89d) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.357] -// CHECK:STDOUT: %bound_method.loc11_24.2: = bound_method %.loc11_24.2, %T.as.Destroy.impl.Op.specific_fn.34 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc11_35.2: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc11_35.2(%addr.loc11_35.2) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc11_24.2: = bound_method %.loc11_24.2, constants.%T.as.Destroy.impl.Op.aa1 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.17: = specific_function constants.%T.as.Destroy.impl.Op.aa1, @T.as.Destroy.impl.Op(constants.%C.89d) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.c1b] +// CHECK:STDOUT: %bound_method.loc11_24.2: = bound_method %.loc11_24.2, %T.as.Destroy.impl.Op.specific_fn.17 // CHECK:STDOUT: %addr.loc11_24.2: %ptr.c28b = addr_of %.loc11_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc11_24.2: init %empty_tuple.type = call %bound_method.loc11_24.2(%addr.loc11_24.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_35.3: = bound_method %.loc10_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.35: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc10_35.4: = bound_method %.loc10_35.1, %T.as.Destroy.impl.Op.specific_fn.35 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc10_35.3: = bound_method %.loc10_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc10_35.3: %ptr.f29 = addr_of %.loc10_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10_35.3: init %empty_tuple.type = call %bound_method.loc10_35.4(%addr.loc10_35.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_24.3: = bound_method %.loc10_24.2, constants.%T.as.Destroy.impl.Op.9cf -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.36: = specific_function constants.%T.as.Destroy.impl.Op.9cf, @T.as.Destroy.impl.Op(constants.%C.7ac) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.694] -// CHECK:STDOUT: %bound_method.loc10_24.3: = bound_method %.loc10_24.2, %T.as.Destroy.impl.Op.specific_fn.36 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc10_35.3: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc10_35.3(%addr.loc10_35.3) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_24.3: = bound_method %.loc10_24.2, constants.%T.as.Destroy.impl.Op.459 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.18: = specific_function constants.%T.as.Destroy.impl.Op.459, @T.as.Destroy.impl.Op(constants.%C.7ac) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.f58] +// CHECK:STDOUT: %bound_method.loc10_24.3: = bound_method %.loc10_24.2, %T.as.Destroy.impl.Op.specific_fn.18 // CHECK:STDOUT: %addr.loc10_24.3: %ptr.2b1 = addr_of %.loc10_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10_24.3: init %empty_tuple.type = call %bound_method.loc10_24.3(%addr.loc10_24.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_35.4: = bound_method %.loc9_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.37: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc9_35.5: = bound_method %.loc9_35.1, %T.as.Destroy.impl.Op.specific_fn.37 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc9_35.4: = bound_method %.loc9_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc9_35.4: %ptr.f29 = addr_of %.loc9_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9_35.4: init %empty_tuple.type = call %bound_method.loc9_35.5(%addr.loc9_35.4) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_24.4: = bound_method %.loc9_24.2, constants.%T.as.Destroy.impl.Op.404 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.38: = specific_function constants.%T.as.Destroy.impl.Op.404, @T.as.Destroy.impl.Op(constants.%C.681) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.822] -// CHECK:STDOUT: %bound_method.loc9_24.4: = bound_method %.loc9_24.2, %T.as.Destroy.impl.Op.specific_fn.38 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc9_35.4: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc9_35.4(%addr.loc9_35.4) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_24.4: = bound_method %.loc9_24.2, constants.%T.as.Destroy.impl.Op.912 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.19: = specific_function constants.%T.as.Destroy.impl.Op.912, @T.as.Destroy.impl.Op(constants.%C.681) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.60f] +// CHECK:STDOUT: %bound_method.loc9_24.4: = bound_method %.loc9_24.2, %T.as.Destroy.impl.Op.specific_fn.19 // CHECK:STDOUT: %addr.loc9_24.4: %ptr.3bd = addr_of %.loc9_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9_24.4: init %empty_tuple.type = call %bound_method.loc9_24.4(%addr.loc9_24.4) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_35.5: = bound_method %.loc8_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.39: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc8_35.6: = bound_method %.loc8_35.1, %T.as.Destroy.impl.Op.specific_fn.39 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc8_35.5: = bound_method %.loc8_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc8_35.5: %ptr.f29 = addr_of %.loc8_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_35.5: init %empty_tuple.type = call %bound_method.loc8_35.6(%addr.loc8_35.5) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.5: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.ad8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.40: = specific_function constants.%T.as.Destroy.impl.Op.ad8, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6b6] -// CHECK:STDOUT: %bound_method.loc8_24.5: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.40 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc8_35.5: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc8_35.5(%addr.loc8_35.5) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.5: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.60a +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.20: = specific_function constants.%T.as.Destroy.impl.Op.60a, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.b9a] +// CHECK:STDOUT: %bound_method.loc8_24.5: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.20 // CHECK:STDOUT: %addr.loc8_24.5: %ptr.625 = addr_of %.loc8_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_24.5: init %empty_tuple.type = call %bound_method.loc8_24.5(%addr.loc8_24.5) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_35.6: = bound_method %.loc7_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.41: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc7_35.7: = bound_method %.loc7_35.1, %T.as.Destroy.impl.Op.specific_fn.41 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc7_35.6: = bound_method %.loc7_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc7_35.6: %ptr.f29 = addr_of %.loc7_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_35.6: init %empty_tuple.type = call %bound_method.loc7_35.7(%addr.loc7_35.6) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.6: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.ae6 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.42: = specific_function constants.%T.as.Destroy.impl.Op.ae6, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.e42] -// CHECK:STDOUT: %bound_method.loc7_24.6: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.42 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc7_35.6: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc7_35.6(%addr.loc7_35.6) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.6: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.c0c +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.21: = specific_function constants.%T.as.Destroy.impl.Op.c0c, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.364] +// CHECK:STDOUT: %bound_method.loc7_24.6: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.21 // CHECK:STDOUT: %addr.loc7_24.6: %ptr.697 = addr_of %.loc7_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_24.6: init %empty_tuple.type = call %bound_method.loc7_24.6(%addr.loc7_24.6) // CHECK:STDOUT: return %.loc12_35.2 to %return @@ -1473,79 +1542,65 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc13_24.4: ref %C.c60 = temporary %.loc13_24.2, %.loc13_24.3 // CHECK:STDOUT: %.loc13_26.1: ref %C.c60 = converted %.loc13_24.1, %.loc13_24.4 // CHECK:STDOUT: %impl.elem0.loc13_35: %.874 = impl_witness_access constants.%ImplicitAs.impl_witness.e4d, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.f59] -// CHECK:STDOUT: %bound_method.loc13_35.1: = bound_method %.loc13_26.1, %impl.elem0.loc13_35 +// CHECK:STDOUT: %bound_method.loc13_35: = bound_method %.loc13_26.1, %impl.elem0.loc13_35 // CHECK:STDOUT: %.loc13_35.1: ref %D = temporary_storage // CHECK:STDOUT: %.loc13_26.2: %C.c60 = bind_value %.loc13_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc13: init %D = call %bound_method.loc13_35.1(%.loc13_26.2) to %.loc13_35.1 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc13: init %D = call %bound_method.loc13_35(%.loc13_26.2) to %.loc13_35.1 // CHECK:STDOUT: %.loc13_35.2: init %D = converted %.loc13_26.1, %C.as.ImplicitAs.impl.Convert.call.loc13 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13_35.1: = bound_method %.loc13_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.43: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc13_35.2: = bound_method %.loc13_35.1, %T.as.Destroy.impl.Op.specific_fn.43 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc13_35.1: = bound_method %.loc13_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc13_35.1: %ptr.f29 = addr_of %.loc13_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc13_35.1: init %empty_tuple.type = call %bound_method.loc13_35.2(%addr.loc13_35.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13_24.1: = bound_method %.loc13_24.2, constants.%T.as.Destroy.impl.Op.ca5 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.44: = specific_function constants.%T.as.Destroy.impl.Op.ca5, @T.as.Destroy.impl.Op(constants.%C.c60) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.8d0] -// CHECK:STDOUT: %bound_method.loc13_24.1: = bound_method %.loc13_24.2, %T.as.Destroy.impl.Op.specific_fn.44 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc13_35.1: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc13_35.1(%addr.loc13_35.1) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13_24.1: = bound_method %.loc13_24.2, constants.%T.as.Destroy.impl.Op.180 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.22: = specific_function constants.%T.as.Destroy.impl.Op.180, @T.as.Destroy.impl.Op(constants.%C.c60) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.659] +// CHECK:STDOUT: %bound_method.loc13_24.1: = bound_method %.loc13_24.2, %T.as.Destroy.impl.Op.specific_fn.22 // CHECK:STDOUT: %addr.loc13_24.1: %ptr.b5e = addr_of %.loc13_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc13_24.1: init %empty_tuple.type = call %bound_method.loc13_24.1(%addr.loc13_24.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_35.2: = bound_method %.loc12_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.45: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc12_35.3: = bound_method %.loc12_35.1, %T.as.Destroy.impl.Op.specific_fn.45 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc12_35.2: = bound_method %.loc12_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc12_35.2: %ptr.f29 = addr_of %.loc12_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_35.2: init %empty_tuple.type = call %bound_method.loc12_35.3(%addr.loc12_35.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_24.2: = bound_method %.loc12_24.2, constants.%T.as.Destroy.impl.Op.985 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.46: = specific_function constants.%T.as.Destroy.impl.Op.985, @T.as.Destroy.impl.Op(constants.%C.f0a) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.a66] -// CHECK:STDOUT: %bound_method.loc12_24.2: = bound_method %.loc12_24.2, %T.as.Destroy.impl.Op.specific_fn.46 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc12_35.2: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc12_35.2(%addr.loc12_35.2) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_24.2: = bound_method %.loc12_24.2, constants.%T.as.Destroy.impl.Op.928 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.23: = specific_function constants.%T.as.Destroy.impl.Op.928, @T.as.Destroy.impl.Op(constants.%C.f0a) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.cdb] +// CHECK:STDOUT: %bound_method.loc12_24.2: = bound_method %.loc12_24.2, %T.as.Destroy.impl.Op.specific_fn.23 // CHECK:STDOUT: %addr.loc12_24.2: %ptr.24c = addr_of %.loc12_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_24.2: init %empty_tuple.type = call %bound_method.loc12_24.2(%addr.loc12_24.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc11_35.3: = bound_method %.loc11_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.47: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc11_35.4: = bound_method %.loc11_35.1, %T.as.Destroy.impl.Op.specific_fn.47 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc11_35.3: = bound_method %.loc11_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc11_35.3: %ptr.f29 = addr_of %.loc11_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc11_35.3: init %empty_tuple.type = call %bound_method.loc11_35.4(%addr.loc11_35.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc11_24.3: = bound_method %.loc11_24.2, constants.%T.as.Destroy.impl.Op.6b4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.48: = specific_function constants.%T.as.Destroy.impl.Op.6b4, @T.as.Destroy.impl.Op(constants.%C.89d) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.357] -// CHECK:STDOUT: %bound_method.loc11_24.3: = bound_method %.loc11_24.2, %T.as.Destroy.impl.Op.specific_fn.48 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc11_35.3: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc11_35.3(%addr.loc11_35.3) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc11_24.3: = bound_method %.loc11_24.2, constants.%T.as.Destroy.impl.Op.aa1 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.24: = specific_function constants.%T.as.Destroy.impl.Op.aa1, @T.as.Destroy.impl.Op(constants.%C.89d) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.c1b] +// CHECK:STDOUT: %bound_method.loc11_24.3: = bound_method %.loc11_24.2, %T.as.Destroy.impl.Op.specific_fn.24 // CHECK:STDOUT: %addr.loc11_24.3: %ptr.c28b = addr_of %.loc11_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc11_24.3: init %empty_tuple.type = call %bound_method.loc11_24.3(%addr.loc11_24.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_35.4: = bound_method %.loc10_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.49: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc10_35.5: = bound_method %.loc10_35.1, %T.as.Destroy.impl.Op.specific_fn.49 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc10_35.4: = bound_method %.loc10_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc10_35.4: %ptr.f29 = addr_of %.loc10_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10_35.4: init %empty_tuple.type = call %bound_method.loc10_35.5(%addr.loc10_35.4) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_24.4: = bound_method %.loc10_24.2, constants.%T.as.Destroy.impl.Op.9cf -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.50: = specific_function constants.%T.as.Destroy.impl.Op.9cf, @T.as.Destroy.impl.Op(constants.%C.7ac) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.694] -// CHECK:STDOUT: %bound_method.loc10_24.4: = bound_method %.loc10_24.2, %T.as.Destroy.impl.Op.specific_fn.50 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc10_35.4: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc10_35.4(%addr.loc10_35.4) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_24.4: = bound_method %.loc10_24.2, constants.%T.as.Destroy.impl.Op.459 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.25: = specific_function constants.%T.as.Destroy.impl.Op.459, @T.as.Destroy.impl.Op(constants.%C.7ac) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.f58] +// CHECK:STDOUT: %bound_method.loc10_24.4: = bound_method %.loc10_24.2, %T.as.Destroy.impl.Op.specific_fn.25 // CHECK:STDOUT: %addr.loc10_24.4: %ptr.2b1 = addr_of %.loc10_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10_24.4: init %empty_tuple.type = call %bound_method.loc10_24.4(%addr.loc10_24.4) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_35.5: = bound_method %.loc9_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.51: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc9_35.6: = bound_method %.loc9_35.1, %T.as.Destroy.impl.Op.specific_fn.51 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc9_35.5: = bound_method %.loc9_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc9_35.5: %ptr.f29 = addr_of %.loc9_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9_35.5: init %empty_tuple.type = call %bound_method.loc9_35.6(%addr.loc9_35.5) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_24.5: = bound_method %.loc9_24.2, constants.%T.as.Destroy.impl.Op.404 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.52: = specific_function constants.%T.as.Destroy.impl.Op.404, @T.as.Destroy.impl.Op(constants.%C.681) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.822] -// CHECK:STDOUT: %bound_method.loc9_24.5: = bound_method %.loc9_24.2, %T.as.Destroy.impl.Op.specific_fn.52 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc9_35.5: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc9_35.5(%addr.loc9_35.5) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_24.5: = bound_method %.loc9_24.2, constants.%T.as.Destroy.impl.Op.912 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.26: = specific_function constants.%T.as.Destroy.impl.Op.912, @T.as.Destroy.impl.Op(constants.%C.681) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.60f] +// CHECK:STDOUT: %bound_method.loc9_24.5: = bound_method %.loc9_24.2, %T.as.Destroy.impl.Op.specific_fn.26 // CHECK:STDOUT: %addr.loc9_24.5: %ptr.3bd = addr_of %.loc9_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9_24.5: init %empty_tuple.type = call %bound_method.loc9_24.5(%addr.loc9_24.5) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_35.6: = bound_method %.loc8_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.53: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc8_35.7: = bound_method %.loc8_35.1, %T.as.Destroy.impl.Op.specific_fn.53 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc8_35.6: = bound_method %.loc8_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc8_35.6: %ptr.f29 = addr_of %.loc8_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_35.6: init %empty_tuple.type = call %bound_method.loc8_35.7(%addr.loc8_35.6) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.6: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.ad8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.54: = specific_function constants.%T.as.Destroy.impl.Op.ad8, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6b6] -// CHECK:STDOUT: %bound_method.loc8_24.6: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.54 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc8_35.6: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc8_35.6(%addr.loc8_35.6) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.6: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.60a +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.27: = specific_function constants.%T.as.Destroy.impl.Op.60a, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.b9a] +// CHECK:STDOUT: %bound_method.loc8_24.6: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.27 // CHECK:STDOUT: %addr.loc8_24.6: %ptr.625 = addr_of %.loc8_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_24.6: init %empty_tuple.type = call %bound_method.loc8_24.6(%addr.loc8_24.6) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_35.7: = bound_method %.loc7_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.55: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc7_35.8: = bound_method %.loc7_35.1, %T.as.Destroy.impl.Op.specific_fn.55 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc7_35.7: = bound_method %.loc7_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc7_35.7: %ptr.f29 = addr_of %.loc7_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_35.7: init %empty_tuple.type = call %bound_method.loc7_35.8(%addr.loc7_35.7) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.7: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.ae6 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.56: = specific_function constants.%T.as.Destroy.impl.Op.ae6, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.e42] -// CHECK:STDOUT: %bound_method.loc7_24.7: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.56 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc7_35.7: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc7_35.7(%addr.loc7_35.7) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.7: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.c0c +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.28: = specific_function constants.%T.as.Destroy.impl.Op.c0c, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.364] +// CHECK:STDOUT: %bound_method.loc7_24.7: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.28 // CHECK:STDOUT: %addr.loc7_24.7: %ptr.697 = addr_of %.loc7_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_24.7: init %empty_tuple.type = call %bound_method.loc7_24.7(%addr.loc7_24.7) // CHECK:STDOUT: return %.loc13_35.2 to %return @@ -1572,89 +1627,73 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc14_24.4: ref %C.304 = temporary %.loc14_24.2, %.loc14_24.3 // CHECK:STDOUT: %.loc14_26.1: ref %C.304 = converted %.loc14_24.1, %.loc14_24.4 // CHECK:STDOUT: %impl.elem0.loc14_35: %.79b = impl_witness_access constants.%ImplicitAs.impl_witness.0ca, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.6c1] -// CHECK:STDOUT: %bound_method.loc14_35.1: = bound_method %.loc14_26.1, %impl.elem0.loc14_35 +// CHECK:STDOUT: %bound_method.loc14_35: = bound_method %.loc14_26.1, %impl.elem0.loc14_35 // CHECK:STDOUT: %.loc14_35.1: ref %D = temporary_storage // CHECK:STDOUT: %.loc14_26.2: %C.304 = bind_value %.loc14_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc14: init %D = call %bound_method.loc14_35.1(%.loc14_26.2) to %.loc14_35.1 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc14: init %D = call %bound_method.loc14_35(%.loc14_26.2) to %.loc14_35.1 // CHECK:STDOUT: %.loc14_35.2: init %D = converted %.loc14_26.1, %C.as.ImplicitAs.impl.Convert.call.loc14 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc14_35.1: = bound_method %.loc14_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.57: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc14_35.2: = bound_method %.loc14_35.1, %T.as.Destroy.impl.Op.specific_fn.57 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc14_35.1: = bound_method %.loc14_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc14_35.1: %ptr.f29 = addr_of %.loc14_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc14_35.1: init %empty_tuple.type = call %bound_method.loc14_35.2(%addr.loc14_35.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc14_24.1: = bound_method %.loc14_24.2, constants.%T.as.Destroy.impl.Op.6fc -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.58: = specific_function constants.%T.as.Destroy.impl.Op.6fc, @T.as.Destroy.impl.Op(constants.%C.304) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.a08] -// CHECK:STDOUT: %bound_method.loc14_24.1: = bound_method %.loc14_24.2, %T.as.Destroy.impl.Op.specific_fn.58 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc14_35.1: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc14_35.1(%addr.loc14_35.1) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc14_24.1: = bound_method %.loc14_24.2, constants.%T.as.Destroy.impl.Op.7c1 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.29: = specific_function constants.%T.as.Destroy.impl.Op.7c1, @T.as.Destroy.impl.Op(constants.%C.304) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.078] +// CHECK:STDOUT: %bound_method.loc14_24.1: = bound_method %.loc14_24.2, %T.as.Destroy.impl.Op.specific_fn.29 // CHECK:STDOUT: %addr.loc14_24.1: %ptr.dc3 = addr_of %.loc14_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc14_24.1: init %empty_tuple.type = call %bound_method.loc14_24.1(%addr.loc14_24.1) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13_35.2: = bound_method %.loc13_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.59: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc13_35.3: = bound_method %.loc13_35.1, %T.as.Destroy.impl.Op.specific_fn.59 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc13_35.2: = bound_method %.loc13_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc13_35.2: %ptr.f29 = addr_of %.loc13_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc13_35.2: init %empty_tuple.type = call %bound_method.loc13_35.3(%addr.loc13_35.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13_24.2: = bound_method %.loc13_24.2, constants.%T.as.Destroy.impl.Op.ca5 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.60: = specific_function constants.%T.as.Destroy.impl.Op.ca5, @T.as.Destroy.impl.Op(constants.%C.c60) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.8d0] -// CHECK:STDOUT: %bound_method.loc13_24.2: = bound_method %.loc13_24.2, %T.as.Destroy.impl.Op.specific_fn.60 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc13_35.2: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc13_35.2(%addr.loc13_35.2) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13_24.2: = bound_method %.loc13_24.2, constants.%T.as.Destroy.impl.Op.180 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.30: = specific_function constants.%T.as.Destroy.impl.Op.180, @T.as.Destroy.impl.Op(constants.%C.c60) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.659] +// CHECK:STDOUT: %bound_method.loc13_24.2: = bound_method %.loc13_24.2, %T.as.Destroy.impl.Op.specific_fn.30 // CHECK:STDOUT: %addr.loc13_24.2: %ptr.b5e = addr_of %.loc13_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc13_24.2: init %empty_tuple.type = call %bound_method.loc13_24.2(%addr.loc13_24.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_35.3: = bound_method %.loc12_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.61: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc12_35.4: = bound_method %.loc12_35.1, %T.as.Destroy.impl.Op.specific_fn.61 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc12_35.3: = bound_method %.loc12_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc12_35.3: %ptr.f29 = addr_of %.loc12_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_35.3: init %empty_tuple.type = call %bound_method.loc12_35.4(%addr.loc12_35.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_24.3: = bound_method %.loc12_24.2, constants.%T.as.Destroy.impl.Op.985 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.62: = specific_function constants.%T.as.Destroy.impl.Op.985, @T.as.Destroy.impl.Op(constants.%C.f0a) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.a66] -// CHECK:STDOUT: %bound_method.loc12_24.3: = bound_method %.loc12_24.2, %T.as.Destroy.impl.Op.specific_fn.62 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc12_35.3: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc12_35.3(%addr.loc12_35.3) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_24.3: = bound_method %.loc12_24.2, constants.%T.as.Destroy.impl.Op.928 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.31: = specific_function constants.%T.as.Destroy.impl.Op.928, @T.as.Destroy.impl.Op(constants.%C.f0a) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.cdb] +// CHECK:STDOUT: %bound_method.loc12_24.3: = bound_method %.loc12_24.2, %T.as.Destroy.impl.Op.specific_fn.31 // CHECK:STDOUT: %addr.loc12_24.3: %ptr.24c = addr_of %.loc12_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_24.3: init %empty_tuple.type = call %bound_method.loc12_24.3(%addr.loc12_24.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc11_35.4: = bound_method %.loc11_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.63: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc11_35.5: = bound_method %.loc11_35.1, %T.as.Destroy.impl.Op.specific_fn.63 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc11_35.4: = bound_method %.loc11_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc11_35.4: %ptr.f29 = addr_of %.loc11_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc11_35.4: init %empty_tuple.type = call %bound_method.loc11_35.5(%addr.loc11_35.4) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc11_24.4: = bound_method %.loc11_24.2, constants.%T.as.Destroy.impl.Op.6b4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.64: = specific_function constants.%T.as.Destroy.impl.Op.6b4, @T.as.Destroy.impl.Op(constants.%C.89d) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.357] -// CHECK:STDOUT: %bound_method.loc11_24.4: = bound_method %.loc11_24.2, %T.as.Destroy.impl.Op.specific_fn.64 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc11_35.4: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc11_35.4(%addr.loc11_35.4) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc11_24.4: = bound_method %.loc11_24.2, constants.%T.as.Destroy.impl.Op.aa1 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.32: = specific_function constants.%T.as.Destroy.impl.Op.aa1, @T.as.Destroy.impl.Op(constants.%C.89d) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.c1b] +// CHECK:STDOUT: %bound_method.loc11_24.4: = bound_method %.loc11_24.2, %T.as.Destroy.impl.Op.specific_fn.32 // CHECK:STDOUT: %addr.loc11_24.4: %ptr.c28b = addr_of %.loc11_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc11_24.4: init %empty_tuple.type = call %bound_method.loc11_24.4(%addr.loc11_24.4) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_35.5: = bound_method %.loc10_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.65: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc10_35.6: = bound_method %.loc10_35.1, %T.as.Destroy.impl.Op.specific_fn.65 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc10_35.5: = bound_method %.loc10_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc10_35.5: %ptr.f29 = addr_of %.loc10_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10_35.5: init %empty_tuple.type = call %bound_method.loc10_35.6(%addr.loc10_35.5) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_24.5: = bound_method %.loc10_24.2, constants.%T.as.Destroy.impl.Op.9cf -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.66: = specific_function constants.%T.as.Destroy.impl.Op.9cf, @T.as.Destroy.impl.Op(constants.%C.7ac) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.694] -// CHECK:STDOUT: %bound_method.loc10_24.5: = bound_method %.loc10_24.2, %T.as.Destroy.impl.Op.specific_fn.66 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc10_35.5: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc10_35.5(%addr.loc10_35.5) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_24.5: = bound_method %.loc10_24.2, constants.%T.as.Destroy.impl.Op.459 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.33: = specific_function constants.%T.as.Destroy.impl.Op.459, @T.as.Destroy.impl.Op(constants.%C.7ac) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.f58] +// CHECK:STDOUT: %bound_method.loc10_24.5: = bound_method %.loc10_24.2, %T.as.Destroy.impl.Op.specific_fn.33 // CHECK:STDOUT: %addr.loc10_24.5: %ptr.2b1 = addr_of %.loc10_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10_24.5: init %empty_tuple.type = call %bound_method.loc10_24.5(%addr.loc10_24.5) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_35.6: = bound_method %.loc9_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.67: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc9_35.7: = bound_method %.loc9_35.1, %T.as.Destroy.impl.Op.specific_fn.67 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc9_35.6: = bound_method %.loc9_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc9_35.6: %ptr.f29 = addr_of %.loc9_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9_35.6: init %empty_tuple.type = call %bound_method.loc9_35.7(%addr.loc9_35.6) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_24.6: = bound_method %.loc9_24.2, constants.%T.as.Destroy.impl.Op.404 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.68: = specific_function constants.%T.as.Destroy.impl.Op.404, @T.as.Destroy.impl.Op(constants.%C.681) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.822] -// CHECK:STDOUT: %bound_method.loc9_24.6: = bound_method %.loc9_24.2, %T.as.Destroy.impl.Op.specific_fn.68 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc9_35.6: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc9_35.6(%addr.loc9_35.6) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_24.6: = bound_method %.loc9_24.2, constants.%T.as.Destroy.impl.Op.912 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.34: = specific_function constants.%T.as.Destroy.impl.Op.912, @T.as.Destroy.impl.Op(constants.%C.681) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.60f] +// CHECK:STDOUT: %bound_method.loc9_24.6: = bound_method %.loc9_24.2, %T.as.Destroy.impl.Op.specific_fn.34 // CHECK:STDOUT: %addr.loc9_24.6: %ptr.3bd = addr_of %.loc9_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9_24.6: init %empty_tuple.type = call %bound_method.loc9_24.6(%addr.loc9_24.6) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_35.7: = bound_method %.loc8_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.69: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc8_35.8: = bound_method %.loc8_35.1, %T.as.Destroy.impl.Op.specific_fn.69 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc8_35.7: = bound_method %.loc8_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc8_35.7: %ptr.f29 = addr_of %.loc8_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_35.7: init %empty_tuple.type = call %bound_method.loc8_35.8(%addr.loc8_35.7) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.7: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.ad8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.70: = specific_function constants.%T.as.Destroy.impl.Op.ad8, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6b6] -// CHECK:STDOUT: %bound_method.loc8_24.7: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.70 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc8_35.7: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc8_35.7(%addr.loc8_35.7) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.7: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.60a +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.35: = specific_function constants.%T.as.Destroy.impl.Op.60a, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.b9a] +// CHECK:STDOUT: %bound_method.loc8_24.7: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.35 // CHECK:STDOUT: %addr.loc8_24.7: %ptr.625 = addr_of %.loc8_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_24.7: init %empty_tuple.type = call %bound_method.loc8_24.7(%addr.loc8_24.7) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_35.8: = bound_method %.loc7_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.71: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc7_35.9: = bound_method %.loc7_35.1, %T.as.Destroy.impl.Op.specific_fn.71 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc7_35.8: = bound_method %.loc7_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc7_35.8: %ptr.f29 = addr_of %.loc7_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_35.8: init %empty_tuple.type = call %bound_method.loc7_35.9(%addr.loc7_35.8) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.8: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.ae6 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.72: = specific_function constants.%T.as.Destroy.impl.Op.ae6, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.e42] -// CHECK:STDOUT: %bound_method.loc7_24.8: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.72 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc7_35.8: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc7_35.8(%addr.loc7_35.8) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.8: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.c0c +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.36: = specific_function constants.%T.as.Destroy.impl.Op.c0c, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.364] +// CHECK:STDOUT: %bound_method.loc7_24.8: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.36 // CHECK:STDOUT: %addr.loc7_24.8: %ptr.697 = addr_of %.loc7_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_24.8: init %empty_tuple.type = call %bound_method.loc7_24.8(%addr.loc7_24.8) // CHECK:STDOUT: return %.loc14_35.2 to %return @@ -1664,96 +1703,91 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, imports.%P.Make [concrete = constants.%Make] // CHECK:STDOUT: %.loc6_15: ref %D = splice_block %return {} // CHECK:STDOUT: %Make.call: init %D = call %Make.ref() to %.loc6_15 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc6: = bound_method %.loc6_15, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.73: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc6: = bound_method %.loc6_15, %T.as.Destroy.impl.Op.specific_fn.73 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc6: = bound_method %.loc6_15, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc6: %ptr.f29 = addr_of %.loc6_15 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc6: init %empty_tuple.type = call %bound_method.loc6(%addr.loc6) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc14_35.2: = bound_method %.loc14_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.74: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc14_35.3: = bound_method %.loc14_35.1, %T.as.Destroy.impl.Op.specific_fn.74 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc6: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc6(%addr.loc6) +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc14_35.2: = bound_method %.loc14_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc14_35.2: %ptr.f29 = addr_of %.loc14_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc14_35.2: init %empty_tuple.type = call %bound_method.loc14_35.3(%addr.loc14_35.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc14_24.2: = bound_method %.loc14_24.2, constants.%T.as.Destroy.impl.Op.6fc -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.75: = specific_function constants.%T.as.Destroy.impl.Op.6fc, @T.as.Destroy.impl.Op(constants.%C.304) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.a08] -// CHECK:STDOUT: %bound_method.loc14_24.2: = bound_method %.loc14_24.2, %T.as.Destroy.impl.Op.specific_fn.75 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc14_35.2: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc14_35.2(%addr.loc14_35.2) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc14_24.2: = bound_method %.loc14_24.2, constants.%T.as.Destroy.impl.Op.7c1 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.37: = specific_function constants.%T.as.Destroy.impl.Op.7c1, @T.as.Destroy.impl.Op(constants.%C.304) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.078] +// CHECK:STDOUT: %bound_method.loc14_24.2: = bound_method %.loc14_24.2, %T.as.Destroy.impl.Op.specific_fn.37 // CHECK:STDOUT: %addr.loc14_24.2: %ptr.dc3 = addr_of %.loc14_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc14_24.2: init %empty_tuple.type = call %bound_method.loc14_24.2(%addr.loc14_24.2) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13_35.3: = bound_method %.loc13_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.76: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc13_35.4: = bound_method %.loc13_35.1, %T.as.Destroy.impl.Op.specific_fn.76 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc13_35.3: = bound_method %.loc13_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc13_35.3: %ptr.f29 = addr_of %.loc13_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc13_35.3: init %empty_tuple.type = call %bound_method.loc13_35.4(%addr.loc13_35.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13_24.3: = bound_method %.loc13_24.2, constants.%T.as.Destroy.impl.Op.ca5 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.77: = specific_function constants.%T.as.Destroy.impl.Op.ca5, @T.as.Destroy.impl.Op(constants.%C.c60) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.8d0] -// CHECK:STDOUT: %bound_method.loc13_24.3: = bound_method %.loc13_24.2, %T.as.Destroy.impl.Op.specific_fn.77 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc13_35.3: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc13_35.3(%addr.loc13_35.3) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc13_24.3: = bound_method %.loc13_24.2, constants.%T.as.Destroy.impl.Op.180 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.38: = specific_function constants.%T.as.Destroy.impl.Op.180, @T.as.Destroy.impl.Op(constants.%C.c60) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.659] +// CHECK:STDOUT: %bound_method.loc13_24.3: = bound_method %.loc13_24.2, %T.as.Destroy.impl.Op.specific_fn.38 // CHECK:STDOUT: %addr.loc13_24.3: %ptr.b5e = addr_of %.loc13_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc13_24.3: init %empty_tuple.type = call %bound_method.loc13_24.3(%addr.loc13_24.3) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_35.4: = bound_method %.loc12_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.78: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc12_35.5: = bound_method %.loc12_35.1, %T.as.Destroy.impl.Op.specific_fn.78 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc12_35.4: = bound_method %.loc12_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc12_35.4: %ptr.f29 = addr_of %.loc12_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_35.4: init %empty_tuple.type = call %bound_method.loc12_35.5(%addr.loc12_35.4) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_24.4: = bound_method %.loc12_24.2, constants.%T.as.Destroy.impl.Op.985 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.79: = specific_function constants.%T.as.Destroy.impl.Op.985, @T.as.Destroy.impl.Op(constants.%C.f0a) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.a66] -// CHECK:STDOUT: %bound_method.loc12_24.4: = bound_method %.loc12_24.2, %T.as.Destroy.impl.Op.specific_fn.79 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc12_35.4: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc12_35.4(%addr.loc12_35.4) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc12_24.4: = bound_method %.loc12_24.2, constants.%T.as.Destroy.impl.Op.928 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.39: = specific_function constants.%T.as.Destroy.impl.Op.928, @T.as.Destroy.impl.Op(constants.%C.f0a) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.cdb] +// CHECK:STDOUT: %bound_method.loc12_24.4: = bound_method %.loc12_24.2, %T.as.Destroy.impl.Op.specific_fn.39 // CHECK:STDOUT: %addr.loc12_24.4: %ptr.24c = addr_of %.loc12_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc12_24.4: init %empty_tuple.type = call %bound_method.loc12_24.4(%addr.loc12_24.4) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc11_35.5: = bound_method %.loc11_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.80: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc11_35.6: = bound_method %.loc11_35.1, %T.as.Destroy.impl.Op.specific_fn.80 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc11_35.5: = bound_method %.loc11_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc11_35.5: %ptr.f29 = addr_of %.loc11_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc11_35.5: init %empty_tuple.type = call %bound_method.loc11_35.6(%addr.loc11_35.5) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc11_24.5: = bound_method %.loc11_24.2, constants.%T.as.Destroy.impl.Op.6b4 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.81: = specific_function constants.%T.as.Destroy.impl.Op.6b4, @T.as.Destroy.impl.Op(constants.%C.89d) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.357] -// CHECK:STDOUT: %bound_method.loc11_24.5: = bound_method %.loc11_24.2, %T.as.Destroy.impl.Op.specific_fn.81 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc11_35.5: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc11_35.5(%addr.loc11_35.5) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc11_24.5: = bound_method %.loc11_24.2, constants.%T.as.Destroy.impl.Op.aa1 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.40: = specific_function constants.%T.as.Destroy.impl.Op.aa1, @T.as.Destroy.impl.Op(constants.%C.89d) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.c1b] +// CHECK:STDOUT: %bound_method.loc11_24.5: = bound_method %.loc11_24.2, %T.as.Destroy.impl.Op.specific_fn.40 // CHECK:STDOUT: %addr.loc11_24.5: %ptr.c28b = addr_of %.loc11_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc11_24.5: init %empty_tuple.type = call %bound_method.loc11_24.5(%addr.loc11_24.5) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_35.6: = bound_method %.loc10_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.82: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc10_35.7: = bound_method %.loc10_35.1, %T.as.Destroy.impl.Op.specific_fn.82 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc10_35.6: = bound_method %.loc10_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc10_35.6: %ptr.f29 = addr_of %.loc10_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10_35.6: init %empty_tuple.type = call %bound_method.loc10_35.7(%addr.loc10_35.6) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_24.6: = bound_method %.loc10_24.2, constants.%T.as.Destroy.impl.Op.9cf -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.83: = specific_function constants.%T.as.Destroy.impl.Op.9cf, @T.as.Destroy.impl.Op(constants.%C.7ac) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.694] -// CHECK:STDOUT: %bound_method.loc10_24.6: = bound_method %.loc10_24.2, %T.as.Destroy.impl.Op.specific_fn.83 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc10_35.6: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc10_35.6(%addr.loc10_35.6) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc10_24.6: = bound_method %.loc10_24.2, constants.%T.as.Destroy.impl.Op.459 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.41: = specific_function constants.%T.as.Destroy.impl.Op.459, @T.as.Destroy.impl.Op(constants.%C.7ac) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.f58] +// CHECK:STDOUT: %bound_method.loc10_24.6: = bound_method %.loc10_24.2, %T.as.Destroy.impl.Op.specific_fn.41 // CHECK:STDOUT: %addr.loc10_24.6: %ptr.2b1 = addr_of %.loc10_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc10_24.6: init %empty_tuple.type = call %bound_method.loc10_24.6(%addr.loc10_24.6) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_35.7: = bound_method %.loc9_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.84: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc9_35.8: = bound_method %.loc9_35.1, %T.as.Destroy.impl.Op.specific_fn.84 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc9_35.7: = bound_method %.loc9_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc9_35.7: %ptr.f29 = addr_of %.loc9_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9_35.7: init %empty_tuple.type = call %bound_method.loc9_35.8(%addr.loc9_35.7) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_24.7: = bound_method %.loc9_24.2, constants.%T.as.Destroy.impl.Op.404 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.85: = specific_function constants.%T.as.Destroy.impl.Op.404, @T.as.Destroy.impl.Op(constants.%C.681) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.822] -// CHECK:STDOUT: %bound_method.loc9_24.7: = bound_method %.loc9_24.2, %T.as.Destroy.impl.Op.specific_fn.85 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc9_35.7: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc9_35.7(%addr.loc9_35.7) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc9_24.7: = bound_method %.loc9_24.2, constants.%T.as.Destroy.impl.Op.912 +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.42: = specific_function constants.%T.as.Destroy.impl.Op.912, @T.as.Destroy.impl.Op(constants.%C.681) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.60f] +// CHECK:STDOUT: %bound_method.loc9_24.7: = bound_method %.loc9_24.2, %T.as.Destroy.impl.Op.specific_fn.42 // CHECK:STDOUT: %addr.loc9_24.7: %ptr.3bd = addr_of %.loc9_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc9_24.7: init %empty_tuple.type = call %bound_method.loc9_24.7(%addr.loc9_24.7) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_35.8: = bound_method %.loc8_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.86: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc8_35.9: = bound_method %.loc8_35.1, %T.as.Destroy.impl.Op.specific_fn.86 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc8_35.8: = bound_method %.loc8_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc8_35.8: %ptr.f29 = addr_of %.loc8_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_35.8: init %empty_tuple.type = call %bound_method.loc8_35.9(%addr.loc8_35.8) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.8: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.ad8 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.87: = specific_function constants.%T.as.Destroy.impl.Op.ad8, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.6b6] -// CHECK:STDOUT: %bound_method.loc8_24.8: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.87 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc8_35.8: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc8_35.8(%addr.loc8_35.8) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc8_24.8: = bound_method %.loc8_24.2, constants.%T.as.Destroy.impl.Op.60a +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.43: = specific_function constants.%T.as.Destroy.impl.Op.60a, @T.as.Destroy.impl.Op(constants.%C.674) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.b9a] +// CHECK:STDOUT: %bound_method.loc8_24.8: = bound_method %.loc8_24.2, %T.as.Destroy.impl.Op.specific_fn.43 // CHECK:STDOUT: %addr.loc8_24.8: %ptr.625 = addr_of %.loc8_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc8_24.8: init %empty_tuple.type = call %bound_method.loc8_24.8(%addr.loc8_24.8) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_35.9: = bound_method %.loc7_35.1, constants.%T.as.Destroy.impl.Op.f5a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.88: = specific_function constants.%T.as.Destroy.impl.Op.f5a, @T.as.Destroy.impl.Op(constants.%D) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.bd1] -// CHECK:STDOUT: %bound_method.loc7_35.10: = bound_method %.loc7_35.1, %T.as.Destroy.impl.Op.specific_fn.88 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.bound.loc7_35.9: = bound_method %.loc7_35.1, constants.%D.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc7_35.9: %ptr.f29 = addr_of %.loc7_35.1 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_35.9: init %empty_tuple.type = call %bound_method.loc7_35.10(%addr.loc7_35.9) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.9: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.ae6 -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.89: = specific_function constants.%T.as.Destroy.impl.Op.ae6, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.e42] -// CHECK:STDOUT: %bound_method.loc7_24.9: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.89 +// CHECK:STDOUT: %D.as.Destroy.impl.Op.call.loc7_35.9: init %empty_tuple.type = call %D.as.Destroy.impl.Op.bound.loc7_35.9(%addr.loc7_35.9) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc7_24.9: = bound_method %.loc7_24.2, constants.%T.as.Destroy.impl.Op.c0c +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.44: = specific_function constants.%T.as.Destroy.impl.Op.c0c, @T.as.Destroy.impl.Op(constants.%C.b00) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.364] +// CHECK:STDOUT: %bound_method.loc7_24.9: = bound_method %.loc7_24.2, %T.as.Destroy.impl.Op.specific_fn.44 // CHECK:STDOUT: %addr.loc7_24.9: %ptr.697 = addr_of %.loc7_24.2 // CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc7_24.9: init %empty_tuple.type = call %bound_method.loc7_24.9(%addr.loc7_24.9) // CHECK:STDOUT: return %Make.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(imports.%P.import_ref.1b7f13.3: %i32) [from "library.carbon"] { +// CHECK:STDOUT: %N: %i32 = bind_symbolic_name N, 0 [symbolic = %N (constants.%N.51e)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%N) [symbolic = %C (constants.%C.17a)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.9e5)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.572)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.ImplicitAs.impl.Convert.1 [from "library.carbon"]; // CHECK:STDOUT: +// CHECK:STDOUT: fn @D.as.Destroy.impl.Op = "no_op" [from "library.carbon"]; +// CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.ImplicitAs.impl.Convert.2 [from "library.carbon"]; // CHECK:STDOUT: // CHECK:STDOUT: fn @C.as.ImplicitAs.impl.Convert.3 [from "library.carbon"]; @@ -1780,6 +1814,18 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%N.51e) { +// CHECK:STDOUT: %N => constants.%N.51e +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.9f3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%N.51e) { +// CHECK:STDOUT: %N => constants.%N.51e +// CHECK:STDOUT: %C => constants.%C.17a +// CHECK:STDOUT: %ptr => constants.%ptr.9e5 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.572 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%int_1.5d2) { // CHECK:STDOUT: %N => constants.%int_1.5d2 // CHECK:STDOUT: @@ -1822,3 +1868,43 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: !definition: // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%int_0.6a9) { +// CHECK:STDOUT: %N => constants.%int_0.6a9 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.749 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%int_1.5d2) { +// CHECK:STDOUT: %N => constants.%int_1.5d2 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.bda +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%int_2.ef8) { +// CHECK:STDOUT: %N => constants.%int_2.ef8 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.b08 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%int_3.822) { +// CHECK:STDOUT: %N => constants.%int_3.822 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.38d +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%int_4.940) { +// CHECK:STDOUT: %N => constants.%int_4.940 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.897 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%int_5.0f6) { +// CHECK:STDOUT: %N => constants.%int_5.0f6 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.0c6 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%int_6.e56) { +// CHECK:STDOUT: %N => constants.%int_6.e56 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.3a0 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%int_7.0b1) { +// CHECK:STDOUT: %N => constants.%int_7.0b1 +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.4f0 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/return/returned_var.carbon b/toolchain/check/testdata/return/returned_var.carbon index 2db77585d2b5..0148364644ab 100644 --- a/toolchain/check/testdata/return/returned_var.carbon +++ b/toolchain/check/testdata/return/returned_var.carbon @@ -37,6 +37,13 @@ fn G() -> i32 { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %i32 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.edd: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a.b.501: type = struct_type {.a: %i32, .b: %i32} [concrete] // CHECK:STDOUT: %complete_type.705: = complete_type_witness %struct_type.a.b.501 [concrete] // CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] @@ -72,7 +79,6 @@ fn G() -> i32 { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.d04: = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.b6e: = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] @@ -82,16 +88,16 @@ fn G() -> i32 { // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int -// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -122,6 +128,22 @@ fn G() -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %int_32.loc16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] @@ -129,6 +151,9 @@ fn G() -> i32 { // CHECK:STDOUT: %int_32.loc17: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc17: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc17: %C.elem = field_decl b, element1 [concrete] +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.edd] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete = constants.%struct_type.a.b.501] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a.b [concrete = constants.%complete_type.705] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -139,6 +164,8 @@ fn G() -> i32 { // CHECK:STDOUT: .b = %.loc17 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() -> %return.param: %C { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { diff --git a/toolchain/check/testdata/return/returned_var_scope.carbon b/toolchain/check/testdata/return/returned_var_scope.carbon index 49967ccb5fd7..dbba017c9ee8 100644 --- a/toolchain/check/testdata/return/returned_var_scope.carbon +++ b/toolchain/check/testdata/return/returned_var_scope.carbon @@ -48,6 +48,7 @@ fn EnclosingButAfter(b: bool) -> i32 { // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -64,7 +65,6 @@ fn EnclosingButAfter(b: bool) -> i32 { // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.ab5: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.956 [concrete] // CHECK:STDOUT: %bound_method.9a1: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] // CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.a17: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%i32) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.e6a: %T.as.Destroy.impl.Op.type.a17 = struct_value () [concrete] // CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] diff --git a/toolchain/check/testdata/struct/import.carbon b/toolchain/check/testdata/struct/import.carbon index 4e43ed1cb1cc..a32f05ae24b4 100644 --- a/toolchain/check/testdata/struct/import.carbon +++ b/toolchain/check/testdata/struct/import.carbon @@ -71,6 +71,8 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] // CHECK:STDOUT: %ImplicitAs.type.205: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] // CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.f06: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9 = struct_value () [symbolic] @@ -105,6 +107,11 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] // CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %C.775: type = class_type @C, @C(%S) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.d9c: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%S) [symbolic] +// CHECK:STDOUT: %ptr.e4c: type = ptr_type %C.775 [symbolic] +// CHECK:STDOUT: %pattern_type.d5f: type = pattern_type %ptr.e4c [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%S) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] @@ -127,6 +134,7 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { // CHECK:STDOUT: .Int = %Core.Int // CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } @@ -134,6 +142,7 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: %Core.import_ref.a5b: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.0f9) = import_ref Core//prelude/parts/int, loc16_39, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.f06)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.a2f = impl_witness_table (%Core.import_ref.a5b), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -216,12 +225,43 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(@C.%S.loc8_9.2: %struct_type.a.b.501) { +// CHECK:STDOUT: %S: %struct_type.a.b.501 = bind_symbolic_name S, 0 [symbolic = %S (constants.%S)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table, @C.as.Destroy.impl(%S) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.d9c)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%S) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: constants.%C.775 as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = fn_decl @C.as.Destroy.impl.Op [symbolic = @C.as.Destroy.impl.%C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] { +// CHECK:STDOUT: %self.patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.d5f) = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @C.as.Destroy.impl.Op.%pattern_type (%pattern_type.d5f) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc8_33.1: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.e4c) = value_param call_param0 +// CHECK:STDOUT: %.loc8_33.2: type = splice_block %Self.ref [symbolic = %C (constants.%C.775)] { +// CHECK:STDOUT: %.loc8_33.3: type = specific_constant constants.%C.775, @C(constants.%S) [symbolic = %C (constants.%C.775)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc8_33.3 [symbolic = %C (constants.%C.775)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @C.as.Destroy.impl.Op.%ptr (%ptr.e4c) = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: generic class @C(%S.loc8_9.2: %struct_type.a.b.501) { // CHECK:STDOUT: %S.loc8_9.1: %struct_type.a.b.501 = bind_symbolic_name S, 0 [symbolic = %S.loc8_9.1 (constants.%S)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: // CHECK:STDOUT: class { +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table, @C.as.Destroy.impl(constants.%S) [symbolic = @C.as.Destroy.impl.%Destroy.impl_witness (constants.%Destroy.impl_witness.d9c)] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -231,6 +271,17 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(@C.%S.loc8_9.2: %struct_type.a.b.501) { +// CHECK:STDOUT: %S: %struct_type.a.b.501 = bind_symbolic_name S, 0 [symbolic = %S (constants.%S)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%S) [symbolic = %C (constants.%C.775)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.e4c)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.d5f)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @C.as.Destroy.impl.Op.%ptr (%ptr.e4c)) = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F() -> %C.c8f; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { @@ -291,6 +342,18 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %S.loc8_9.1 => constants.%S // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%S) { +// CHECK:STDOUT: %S => constants.%S +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.d9c +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%S) { +// CHECK:STDOUT: %S => constants.%S +// CHECK:STDOUT: %C => constants.%C.775 +// CHECK:STDOUT: %ptr => constants.%ptr.e4c +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d5f +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%struct.ed5) { // CHECK:STDOUT: %S.loc8_9.1 => constants.%struct.ed5 // CHECK:STDOUT: } @@ -298,15 +361,28 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: --- implicit.impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] +// CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %ImplicitAs.type.595: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.595 = struct_value () [concrete] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9a6: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.458: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9a6 = struct_value () [symbolic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %struct_type.a.b.5ca: type = struct_type {.a: %i32, .b: %i32} [concrete] +// CHECK:STDOUT: %S: %struct_type.a.b.5ca = bind_symbolic_name S, 0 [symbolic] +// CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] +// CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %C.720: type = class_type @C, @C(%S) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.abc: = impl_witness imports.%Destroy.impl_witness_table.2ab, @C.as.Destroy.impl(%S) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%S) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.9e0: type = ptr_type %C.720 [symbolic] +// CHECK:STDOUT: %pattern_type.d77: type = pattern_type %ptr.9e0 [symbolic] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %i32} [concrete] // CHECK:STDOUT: %pattern_type.b54: type = pattern_type %struct_type.a [concrete] // CHECK:STDOUT: %.c27: ref %i32 = struct_access imports.%a_ref.var, element0 [concrete] @@ -324,12 +400,6 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %tuple.elem0.aa5: ref %i32 = tuple_access %.e5f, element0 [concrete] // CHECK:STDOUT: %.dfe: ref %i32 = struct_access imports.%b_ref.var, element1 [concrete] // CHECK:STDOUT: %.607: ref %i32 = struct_access file.%b.var, element1 [concrete] -// CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] -// CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] -// CHECK:STDOUT: %struct_type.a.b.5ca: type = struct_type {.a: %i32, .b: %i32} [concrete] -// CHECK:STDOUT: %S: %struct_type.a.b.5ca = bind_symbolic_name S, 0 [symbolic] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: %struct_type.a.b.cfd: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [concrete] @@ -365,8 +435,19 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Implicit.import_ref.773: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9a6) = import_ref Implicit//default, inst117 [indirect], loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.458)] +// CHECK:STDOUT: %Implicit.import_ref.773: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9a6) = import_ref Implicit//default, inst149 [indirect], loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.458)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.1ad = impl_witness_table (%Implicit.import_ref.773), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %Implicit.import_ref.48d = import_ref Implicit//default, loc8_33, unloaded +// CHECK:STDOUT: %Implicit.import_ref.c81f8f.1: %struct_type.a.b.5ca = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] +// CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc8_34, loaded [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst488 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.c81f8f.2: %struct_type.a.b.5ca = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] +// CHECK:STDOUT: %Implicit.import_ref.4cf: type = import_ref Implicit//default, inst488 [no loc], loaded [symbolic = constants.%C.720] +// CHECK:STDOUT: %Implicit.import_ref.cb9: type = import_ref Implicit//default, inst108 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Implicit.import_ref.7f2ca0.1 = import_ref Implicit//default, loc8_33, unloaded +// CHECK:STDOUT: %Implicit.import_ref.7f2ca0.2 = import_ref Implicit//default, loc8_33, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.2ab = impl_witness_table (%Implicit.import_ref.7f2ca0.2), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Implicit.import_ref.c81f8f.3: %struct_type.a.b.5ca = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] // CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] // CHECK:STDOUT: %a_ref.patt: %pattern_type.b54 = binding_pattern a_ref [concrete] // CHECK:STDOUT: %a_ref.var_patt: %pattern_type.b54 = var_pattern %a_ref.patt [concrete] @@ -374,9 +455,6 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %b_ref.patt: %pattern_type.020 = binding_pattern b_ref [concrete] // CHECK:STDOUT: %b_ref.var_patt: %pattern_type.020 = var_pattern %b_ref.patt [concrete] // CHECK:STDOUT: %b_ref.var: ref %struct_type.a.d.9db = var %b_ref.var_patt [concrete] -// CHECK:STDOUT: %Implicit.import_ref.c81: %struct_type.a.b.5ca = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] -// CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc8_34, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst456 [no loc], unloaded // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.595 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -454,7 +532,22 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %c: ref %C.a8a = bind_name c, %c.var [concrete = %c.var] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic class @C(imports.%Implicit.import_ref.c81: %struct_type.a.b.5ca) [from "implicit.carbon"] { +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(imports.%Implicit.import_ref.c81f8f.2: %struct_type.a.b.5ca) [from "implicit.carbon"] { +// CHECK:STDOUT: %S: %struct_type.a.b.5ca = bind_symbolic_name S, 0 [symbolic = %S (constants.%S)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.2ab, @C.as.Destroy.impl(%S) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.abc)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%S) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%Implicit.import_ref.4cf as imports.%Implicit.import_ref.cb9 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = imports.%Implicit.import_ref.7f2ca0.1 +// CHECK:STDOUT: witness = imports.%Implicit.import_ref.48d +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @C(imports.%Implicit.import_ref.c81f8f.1: %struct_type.a.b.5ca) [from "implicit.carbon"] { // CHECK:STDOUT: %S: %struct_type.a.b.5ca = bind_symbolic_name S, 0 [symbolic = %S (constants.%S)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: @@ -467,6 +560,17 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(imports.%Implicit.import_ref.c81f8f.3: %struct_type.a.b.5ca) [from "implicit.carbon"] { +// CHECK:STDOUT: %S: %struct_type.a.b.5ca = bind_symbolic_name S, 0 [symbolic = %S (constants.%S)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%S) [symbolic = %C (constants.%C.720)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.9e0)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.d77)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F [from "implicit.carbon"]; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { @@ -511,6 +615,18 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %S => constants.%S // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%S) { +// CHECK:STDOUT: %S => constants.%S +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.abc +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%S) { +// CHECK:STDOUT: %S => constants.%S +// CHECK:STDOUT: %C => constants.%C.720 +// CHECK:STDOUT: %ptr => constants.%ptr.9e0 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d77 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%struct) { // CHECK:STDOUT: %S => constants.%struct // CHECK:STDOUT: @@ -520,14 +636,21 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: --- fail_bad_type.impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { -// CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] -// CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %struct_type.a.b: type = struct_type {.a: %i32, .b: %i32} [concrete] // CHECK:STDOUT: %S: %struct_type.a.b = bind_symbolic_name S, 0 [symbolic] +// CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] +// CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %C.720: type = class_type @C, @C(%S) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.abc: = impl_witness imports.%Destroy.impl_witness_table.2ab, @C.as.Destroy.impl(%S) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%S) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.9e0: type = ptr_type %C.720 [symbolic] +// CHECK:STDOUT: %pattern_type.d77: type = pattern_type %ptr.9e0 [symbolic] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: %struct_type.c.d: type = struct_type {.c: Core.IntLiteral, .d: Core.IntLiteral} [concrete] @@ -548,9 +671,17 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Implicit.import_ref.c81: %struct_type.a.b = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] +// CHECK:STDOUT: %Implicit.import_ref.48d = import_ref Implicit//default, loc8_33, unloaded +// CHECK:STDOUT: %Implicit.import_ref.c81f8f.1: %struct_type.a.b = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] // CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc8_34, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst456 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst488 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.c81f8f.2: %struct_type.a.b = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] +// CHECK:STDOUT: %Implicit.import_ref.4cf: type = import_ref Implicit//default, inst488 [no loc], loaded [symbolic = constants.%C.720] +// CHECK:STDOUT: %Implicit.import_ref.cb9: type = import_ref Implicit//default, inst108 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Implicit.import_ref.7f2ca0.1 = import_ref Implicit//default, loc8_33, unloaded +// CHECK:STDOUT: %Implicit.import_ref.7f2ca0.2 = import_ref Implicit//default, loc8_33, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.2ab = impl_witness_table (%Implicit.import_ref.7f2ca0.2), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Implicit.import_ref.c81f8f.3: %struct_type.a.b = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -579,7 +710,22 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %c_bad: = bind_name c_bad, [concrete = ] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic class @C(imports.%Implicit.import_ref.c81: %struct_type.a.b) [from "implicit.carbon"] { +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(imports.%Implicit.import_ref.c81f8f.2: %struct_type.a.b) [from "implicit.carbon"] { +// CHECK:STDOUT: %S: %struct_type.a.b = bind_symbolic_name S, 0 [symbolic = %S (constants.%S)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.2ab, @C.as.Destroy.impl(%S) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.abc)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%S) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%Implicit.import_ref.4cf as imports.%Implicit.import_ref.cb9 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = imports.%Implicit.import_ref.7f2ca0.1 +// CHECK:STDOUT: witness = imports.%Implicit.import_ref.48d +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @C(imports.%Implicit.import_ref.c81f8f.1: %struct_type.a.b) [from "implicit.carbon"] { // CHECK:STDOUT: %S: %struct_type.a.b = bind_symbolic_name S, 0 [symbolic = %S (constants.%S)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: @@ -592,6 +738,17 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(imports.%Implicit.import_ref.c81f8f.3: %struct_type.a.b) [from "implicit.carbon"] { +// CHECK:STDOUT: %S: %struct_type.a.b = bind_symbolic_name S, 0 [symbolic = %S (constants.%S)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%S) [symbolic = %C (constants.%C.720)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.9e0)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.d77)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F [from "implicit.carbon"]; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { @@ -607,6 +764,18 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %S => constants.%S // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%S) { +// CHECK:STDOUT: %S => constants.%S +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.abc +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%S) { +// CHECK:STDOUT: %S => constants.%S +// CHECK:STDOUT: %C => constants.%C.720 +// CHECK:STDOUT: %ptr => constants.%ptr.9e0 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d77 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%struct) { // CHECK:STDOUT: %S => constants.%struct // CHECK:STDOUT: @@ -616,19 +785,26 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: --- fail_bad_value.impl.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] // CHECK:STDOUT: %To: Core.IntLiteral = bind_symbolic_name To, 0 [symbolic] // CHECK:STDOUT: %ImplicitAs.type.595: type = generic_interface_type @ImplicitAs [concrete] // CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.595 = struct_value () [concrete] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9a6: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.458: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9a6 = struct_value () [symbolic] -// CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] -// CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] -// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] -// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %struct_type.a.b.5ca: type = struct_type {.a: %i32, .b: %i32} [concrete] // CHECK:STDOUT: %S: %struct_type.a.b.5ca = bind_symbolic_name S, 0 [symbolic] +// CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] +// CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %C.720: type = class_type @C, @C(%S) [symbolic] +// CHECK:STDOUT: %Destroy.impl_witness.abc: = impl_witness imports.%Destroy.impl_witness_table.2ab, @C.as.Destroy.impl(%S) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%S) [symbolic] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [symbolic] +// CHECK:STDOUT: %ptr.9e0: type = ptr_type %C.720 [symbolic] +// CHECK:STDOUT: %pattern_type.d77: type = pattern_type %ptr.9e0 [symbolic] // CHECK:STDOUT: %int_3.1ba: Core.IntLiteral = int_value 3 [concrete] // CHECK:STDOUT: %int_4.0c1: Core.IntLiteral = int_value 4 [concrete] // CHECK:STDOUT: %struct_type.a.b.cfd: type = struct_type {.a: Core.IntLiteral, .b: Core.IntLiteral} [concrete] @@ -667,11 +843,19 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } -// CHECK:STDOUT: %Implicit.import_ref.773: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9a6) = import_ref Implicit//default, inst117 [indirect], loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.458)] +// CHECK:STDOUT: %Implicit.import_ref.773: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9a6) = import_ref Implicit//default, inst149 [indirect], loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.458)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.1ad = impl_witness_table (%Implicit.import_ref.773), @Core.IntLiteral.as.ImplicitAs.impl [concrete] -// CHECK:STDOUT: %Implicit.import_ref.c81: %struct_type.a.b.5ca = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] +// CHECK:STDOUT: %Implicit.import_ref.48d = import_ref Implicit//default, loc8_33, unloaded +// CHECK:STDOUT: %Implicit.import_ref.c81f8f.1: %struct_type.a.b.5ca = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] // CHECK:STDOUT: %Implicit.import_ref.8f2: = import_ref Implicit//default, loc8_34, loaded [concrete = constants.%complete_type.357] -// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst456 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.b8b = import_ref Implicit//default, inst488 [no loc], unloaded +// CHECK:STDOUT: %Implicit.import_ref.c81f8f.2: %struct_type.a.b.5ca = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] +// CHECK:STDOUT: %Implicit.import_ref.4cf: type = import_ref Implicit//default, inst488 [no loc], loaded [symbolic = constants.%C.720] +// CHECK:STDOUT: %Implicit.import_ref.cb9: type = import_ref Implicit//default, inst108 [no loc], loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: %Implicit.import_ref.7f2ca0.1 = import_ref Implicit//default, loc8_33, unloaded +// CHECK:STDOUT: %Implicit.import_ref.7f2ca0.2 = import_ref Implicit//default, loc8_33, unloaded +// CHECK:STDOUT: %Destroy.impl_witness_table.2ab = impl_witness_table (%Implicit.import_ref.7f2ca0.2), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Implicit.import_ref.c81f8f.3: %struct_type.a.b.5ca = import_ref Implicit//default, loc8_9, loaded [symbolic = @C.%S (constants.%S)] // CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.595 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] // CHECK:STDOUT: } // CHECK:STDOUT: @@ -718,7 +902,22 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %c_bad: ref %C.5a7 = bind_name c_bad, %c_bad.var [concrete = %c_bad.var] // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: generic class @C(imports.%Implicit.import_ref.c81: %struct_type.a.b.5ca) [from "implicit.carbon"] { +// CHECK:STDOUT: generic impl @C.as.Destroy.impl(imports.%Implicit.import_ref.c81f8f.2: %struct_type.a.b.5ca) [from "implicit.carbon"] { +// CHECK:STDOUT: %S: %struct_type.a.b.5ca = bind_symbolic_name S, 0 [symbolic = %S (constants.%S)] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness imports.%Destroy.impl_witness_table.2ab, @C.as.Destroy.impl(%S) [symbolic = %Destroy.impl_witness (constants.%Destroy.impl_witness.abc)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op, @C.as.Destroy.impl(%S) [symbolic = %C.as.Destroy.impl.Op.type (constants.%C.as.Destroy.impl.Op.type)] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: @C.as.Destroy.impl.%C.as.Destroy.impl.Op.type (%C.as.Destroy.impl.Op.type) = struct_value () [symbolic = %C.as.Destroy.impl.Op (constants.%C.as.Destroy.impl.Op)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: imports.%Implicit.import_ref.4cf as imports.%Implicit.import_ref.cb9 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = imports.%Implicit.import_ref.7f2ca0.1 +// CHECK:STDOUT: witness = imports.%Implicit.import_ref.48d +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @C(imports.%Implicit.import_ref.c81f8f.1: %struct_type.a.b.5ca) [from "implicit.carbon"] { // CHECK:STDOUT: %S: %struct_type.a.b.5ca = bind_symbolic_name S, 0 [symbolic = %S (constants.%S)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: @@ -731,6 +930,17 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: generic fn @C.as.Destroy.impl.Op(imports.%Implicit.import_ref.c81f8f.3: %struct_type.a.b.5ca) [from "implicit.carbon"] { +// CHECK:STDOUT: %S: %struct_type.a.b.5ca = bind_symbolic_name S, 0 [symbolic = %S (constants.%S)] +// CHECK:STDOUT: %C: type = class_type @C, @C(%S) [symbolic = %C (constants.%C.720)] +// CHECK:STDOUT: %ptr: type = ptr_type %C [symbolic = %ptr (constants.%ptr.9e0)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %ptr [symbolic = %pattern_type (constants.%pattern_type.d77)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn = "no_op"; +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: fn @F [from "implicit.carbon"]; // CHECK:STDOUT: // CHECK:STDOUT: fn @__global_init() { @@ -747,6 +957,18 @@ var c_bad: C({.a = 3, .b = 4}) = F(); // CHECK:STDOUT: %S => constants.%S // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl(constants.%S) { +// CHECK:STDOUT: %S => constants.%S +// CHECK:STDOUT: %Destroy.impl_witness => constants.%Destroy.impl_witness.abc +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @C.as.Destroy.impl.Op(constants.%S) { +// CHECK:STDOUT: %S => constants.%S +// CHECK:STDOUT: %C => constants.%C.720 +// CHECK:STDOUT: %ptr => constants.%ptr.9e0 +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.d77 +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: specific @C(constants.%struct.8e6) { // CHECK:STDOUT: %S => constants.%struct.8e6 // CHECK:STDOUT: diff --git a/toolchain/check/testdata/tuple/import.carbon b/toolchain/check/testdata/tuple/import.carbon index 53a55b552e88..b3bd105567c4 100644 --- a/toolchain/check/testdata/tuple/import.carbon +++ b/toolchain/check/testdata/tuple/import.carbon @@ -66,6 +66,9 @@ var c_bad: C((3, 4)) = F(); // CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.458: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9a6 = struct_value () [symbolic] // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %tuple.type.c2c: type = tuple_type (%i32, %i32) [concrete] +// CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] +// CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %tuple.type.85c: type = tuple_type (type) [concrete] // CHECK:STDOUT: %tuple.type.dd4: type = tuple_type (%i32) [concrete] // CHECK:STDOUT: %pattern_type.2e8: type = pattern_type %tuple.type.dd4 [concrete] @@ -74,7 +77,6 @@ var c_bad: C((3, 4)) = F(); // CHECK:STDOUT: %tuple.type.24b: type = tuple_type (type, type) [concrete] // CHECK:STDOUT: %tuple.type.58c: type = tuple_type (%tuple.type.8c7, %tuple.type.24b) [concrete] // CHECK:STDOUT: %tuple.type.154: type = tuple_type (%tuple.type.dd4, %i32) [concrete] -// CHECK:STDOUT: %tuple.type.c2c: type = tuple_type (%i32, %i32) [concrete] // CHECK:STDOUT: %tuple.type.cfa: type = tuple_type (%tuple.type.154, %tuple.type.c2c) [concrete] // CHECK:STDOUT: %pattern_type.ab9: type = pattern_type %tuple.type.cfa [concrete] // CHECK:STDOUT: %tuple.elem0.693: ref %tuple.type.154 = tuple_access imports.%b_ref.var, element0 [concrete] @@ -90,8 +92,6 @@ var c_bad: C((3, 4)) = F(); // CHECK:STDOUT: %tuple.elem0.790: ref %i32 = tuple_access %tuple.elem1.4f3, element0 [concrete] // CHECK:STDOUT: %tuple.elem1.282: ref %i32 = tuple_access %tuple.elem1.92b, element1 [concrete] // CHECK:STDOUT: %tuple.elem1.822: ref %i32 = tuple_access %tuple.elem1.4f3, element1 [concrete] -// CHECK:STDOUT: %C.type: type = generic_class_type @C [concrete] -// CHECK:STDOUT: %C.generic: %C.type = struct_value () [concrete] // CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] // CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] // CHECK:STDOUT: %tuple.type.f94: type = tuple_type (Core.IntLiteral, Core.IntLiteral) [concrete] @@ -121,7 +121,7 @@ var c_bad: C((3, 4)) = F(); // CHECK:STDOUT: %Implicit.b_ref: ref %tuple.type.cfa = import_ref Implicit//default, b_ref, loaded [concrete = %b_ref.var] // CHECK:STDOUT: %Implicit.C: %C.type = import_ref Implicit//default, C, loaded [concrete = constants.%C.generic] // CHECK:STDOUT: %Implicit.F: %F.type = import_ref Implicit//default, F, loaded [concrete = constants.%F] -// CHECK:STDOUT: %Implicit.import_ref.773: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9a6) = import_ref Implicit//default, inst119 [indirect], loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.458)] +// CHECK:STDOUT: %Implicit.import_ref.773: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.9a6) = import_ref Implicit//default, inst151 [indirect], loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.458)] // CHECK:STDOUT: %ImplicitAs.impl_witness_table.1ad = impl_witness_table (%Implicit.import_ref.773), @Core.IntLiteral.as.ImplicitAs.impl [concrete] // CHECK:STDOUT: %a_ref.patt: %pattern_type.2e8 = binding_pattern a_ref [concrete] // CHECK:STDOUT: %a_ref.var_patt: %pattern_type.2e8 = var_pattern %a_ref.patt [concrete] diff --git a/toolchain/check/testdata/var/fail_not_copyable.carbon b/toolchain/check/testdata/var/fail_not_copyable.carbon index 8515c9b6bb7f..70ba862b5aed 100644 --- a/toolchain/check/testdata/var/fail_not_copyable.carbon +++ b/toolchain/check/testdata/var/fail_not_copyable.carbon @@ -36,23 +36,25 @@ fn F(x: X) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %X: type = class_type @X [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness.807: = impl_witness @X.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete] +// CHECK:STDOUT: %pattern_type.1c6: type = pattern_type %ptr.d17 [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op.type: type = fn_type @X.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %X.as.Destroy.impl.Op: %X.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.019: type = pattern_type %X [concrete] // CHECK:STDOUT: %F.type: type = fn_type @F [concrete] -// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %F: %F.type = struct_value () [concrete] // CHECK:STDOUT: %ptr.a45: type = ptr_type String [concrete] // CHECK:STDOUT: %pattern_type.b05: type = pattern_type String [concrete] // CHECK:STDOUT: %str: String = string_literal "hello" [concrete] -// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.type.9e1: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(%X) [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.33a: %T.as.Destroy.impl.Op.type.9e1 = struct_value () [concrete] -// CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.d1f: = specific_function %T.as.Destroy.impl.Op.33a, @T.as.Destroy.impl.Op(%X) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.type.051: type = fn_type @T.as.Destroy.impl.Op, @T.as.Destroy.impl(String) [concrete] // CHECK:STDOUT: %T.as.Destroy.impl.Op.5ef: %T.as.Destroy.impl.Op.type.051 = struct_value () [concrete] -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.93f: = specific_function %T.as.Destroy.impl.Op.5ef, @T.as.Destroy.impl.Op(String) [concrete] +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function %T.as.Destroy.impl.Op.5ef, @T.as.Destroy.impl.Op(String) [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { @@ -82,7 +84,26 @@ fn F(x: X) { // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @X.as.Destroy.impl: constants.%X as constants.%Destroy.type { +// CHECK:STDOUT: %X.as.Destroy.impl.Op.decl: %X.as.Destroy.impl.Op.type = fn_decl @X.as.Destroy.impl.Op [concrete = constants.%X.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.1c6 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1c6 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.d17 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%X [concrete = constants.%X] +// CHECK:STDOUT: %self: %ptr.d17 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %X.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @X.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @X { +// CHECK:STDOUT: impl_decl @X.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@X.as.Destroy.impl.%X.as.Destroy.impl.Op.decl), @X.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness.807] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -91,6 +112,8 @@ fn F(x: X) { // CHECK:STDOUT: .Self = constants.%X // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: fn @X.as.Destroy.impl.Op(%self.param: %ptr.d17) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: fn @F(%x.param: %X) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { @@ -110,16 +133,14 @@ fn F(x: X) { // CHECK:STDOUT: assign %y.var, // CHECK:STDOUT: %X.ref.loc32: type = name_ref X, file.%X.decl [concrete = constants.%X] // CHECK:STDOUT: %y: ref %X = bind_name y, %y.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc32: = bound_method %y.var, constants.%T.as.Destroy.impl.Op.33a -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%T.as.Destroy.impl.Op.33a, @T.as.Destroy.impl.Op(constants.%X) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.d1f] -// CHECK:STDOUT: %bound_method.loc32: = bound_method %y.var, %T.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %X.as.Destroy.impl.Op.bound: = bound_method %y.var, constants.%X.as.Destroy.impl.Op // CHECK:STDOUT: %addr.loc32: %ptr.d17 = addr_of %y.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc32: init %empty_tuple.type = call %bound_method.loc32(%addr.loc32) -// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound.loc25: = bound_method %s.var, constants.%T.as.Destroy.impl.Op.5ef -// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%T.as.Destroy.impl.Op.5ef, @T.as.Destroy.impl.Op(String) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn.93f] -// CHECK:STDOUT: %bound_method.loc25: = bound_method %s.var, %T.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %X.as.Destroy.impl.Op.call: init %empty_tuple.type = call %X.as.Destroy.impl.Op.bound(%addr.loc32) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.bound: = bound_method %s.var, constants.%T.as.Destroy.impl.Op.5ef +// CHECK:STDOUT: %T.as.Destroy.impl.Op.specific_fn: = specific_function constants.%T.as.Destroy.impl.Op.5ef, @T.as.Destroy.impl.Op(String) [concrete = constants.%T.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method: = bound_method %s.var, %T.as.Destroy.impl.Op.specific_fn // CHECK:STDOUT: %addr.loc25: %ptr.a45 = addr_of %s.var -// CHECK:STDOUT: %T.as.Destroy.impl.Op.call.loc25: init %empty_tuple.type = call %bound_method.loc25(%addr.loc25) +// CHECK:STDOUT: %T.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc25) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/var/var_pattern.carbon b/toolchain/check/testdata/var/var_pattern.carbon index 4916df7b924c..7c1fbdb056f5 100644 --- a/toolchain/check/testdata/var/var_pattern.carbon +++ b/toolchain/check/testdata/var/var_pattern.carbon @@ -822,18 +822,27 @@ fn G() { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %C: type = class_type @C [concrete] -// CHECK:STDOUT: %pattern_type: type = pattern_type %C [concrete] +// CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %C.F.type: type = fn_type @C.F [concrete] // CHECK:STDOUT: %C.F: %C.F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness @C.%Destroy.impl_witness_table [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op.type: type = fn_type @C.as.Destroy.impl.Op [concrete] +// CHECK:STDOUT: %C.as.Destroy.impl.Op: %C.as.Destroy.impl.Op.type = struct_value () [concrete] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: imports { // CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy // CHECK:STDOUT: import Core//prelude // CHECK:STDOUT: import Core//prelude/... // CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -845,16 +854,35 @@ fn G() { // CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.Destroy.impl: constants.%C as constants.%Destroy.type { +// CHECK:STDOUT: %C.as.Destroy.impl.Op.decl: %C.as.Destroy.impl.Op.type = fn_decl @C.as.Destroy.impl.Op [concrete = constants.%C.as.Destroy.impl.Op] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc4: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: %ptr.019 = bind_name self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Op = %C.as.Destroy.impl.Op.decl +// CHECK:STDOUT: witness = @C.%Destroy.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: class @C { // CHECK:STDOUT: %C.F.decl: %C.F.type = fn_decl @C.F [concrete = constants.%C.F] { -// CHECK:STDOUT: %self.patt: %pattern_type = binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: %pattern_type = ref_param_pattern %self.patt, call_param0 [concrete] -// CHECK:STDOUT: %self.var_patt: %pattern_type = var_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %self.patt: %pattern_type.c48 = binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.c48 = ref_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %self.var_patt: %pattern_type.c48 = var_pattern %self.param_patt [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %self.param: ref %C = ref_param call_param0 // CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] // CHECK:STDOUT: %self: ref %C = bind_name self, %self.param // CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @C.as.Destroy.impl [concrete] {} {} +// CHECK:STDOUT: %Destroy.impl_witness_table = impl_witness_table (@C.as.Destroy.impl.%C.as.Destroy.impl.Op.decl), @C.as.Destroy.impl [concrete] +// CHECK:STDOUT: %Destroy.impl_witness: = impl_witness %Destroy.impl_witness_table [concrete = constants.%Destroy.impl_witness] // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete = constants.%complete_type] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -866,6 +894,8 @@ fn G() { // CHECK:STDOUT: // CHECK:STDOUT: fn @C.F(%self.param: %C); // CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.Destroy.impl.Op(%self.param: %ptr.019) = "no_op"; +// CHECK:STDOUT: // CHECK:STDOUT: --- nested_match.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/driver/compile_subcommand.cpp b/toolchain/driver/compile_subcommand.cpp index 8fb3e0144a69..ef5227093c67 100644 --- a/toolchain/driver/compile_subcommand.cpp +++ b/toolchain/driver/compile_subcommand.cpp @@ -282,6 +282,19 @@ Whether to use the implicit prelude import. Enabled by default. arg_b.Default(true); arg_b.Set(&prelude_import); }); + b.AddFlag( + { + .name = "gen-implicit-type-impls", + .help = R"""( +Whether to generate standard `impl`s for types, such as `Core.Destroy`. This +only controls generation of the `impl`; code which expects the `impl` is +expected to fail. Enabled by default. +)""", + }, + [&](auto& arg_b) { + arg_b.Default(true); + arg_b.Set(&gen_implicit_type_impls); + }); b.AddFlag( { .name = "custom-core", @@ -999,6 +1012,7 @@ auto CompileSubcommand::Run(DriverEnv& driver_env) -> DriverResult { CARBON_VLOG_TO(driver_env.vlog_stream, "*** Check::CheckParseTrees ***\n"); Check::CheckParseTreesOptions options; options.prelude_import = options_.prelude_import; + options.gen_implicit_type_impls = options_.gen_implicit_type_impls; options.vlog_stream = driver_env.vlog_stream; options.fuzzing = driver_env.fuzzing; if (options.vlog_stream || options_.dump_sem_ir || options_.dump_raw_sem_ir) { diff --git a/toolchain/driver/compile_subcommand.h b/toolchain/driver/compile_subcommand.h index f1bd598f4eeb..87b65c317629 100644 --- a/toolchain/driver/compile_subcommand.h +++ b/toolchain/driver/compile_subcommand.h @@ -60,6 +60,7 @@ struct CompileOptions { bool preorder_parse_tree = false; bool builtin_sem_ir = false; bool prelude_import = false; + bool gen_implicit_type_impls = false; bool include_debug_info = true; bool run_llvm_verifier = true; diff --git a/toolchain/language_server/testdata/document_symbol/nested.carbon b/toolchain/language_server/testdata/document_symbol/nested.carbon index 675602eb815c..61ab2fa09b42 100644 --- a/toolchain/language_server/testdata/document_symbol/nested.carbon +++ b/toolchain/language_server/testdata/document_symbol/nested.carbon @@ -29,13 +29,29 @@ class A { // --- AUTOUPDATE-SPLIT -// CHECK:STDOUT: Content-Length: 145{{\r}} +// CHECK:STDOUT: Content-Length: 506{{\r}} // CHECK:STDOUT: {{\r}} // CHECK:STDOUT: { // CHECK:STDOUT: "jsonrpc": "2.0", // CHECK:STDOUT: "method": "textDocument/publishDiagnostics", // CHECK:STDOUT: "params": { -// CHECK:STDOUT: "diagnostics": [], +// CHECK:STDOUT: "diagnostics": [ +// CHECK:STDOUT: { +// CHECK:STDOUT: "message": "`Core.Destroy` implicitly referenced here, but package `Core` not found", +// CHECK:STDOUT: "range": { +// CHECK:STDOUT: "end": { +// CHECK:STDOUT: "character": 10, +// CHECK:STDOUT: "line": 1 +// CHECK:STDOUT: }, +// CHECK:STDOUT: "start": { +// CHECK:STDOUT: "character": 0, +// CHECK:STDOUT: "line": 0 +// CHECK:STDOUT: } +// CHECK:STDOUT: }, +// CHECK:STDOUT: "severity": 1, +// CHECK:STDOUT: "source": "carbon" +// CHECK:STDOUT: } +// CHECK:STDOUT: ], // CHECK:STDOUT: "uri": "file:///class.carbon" // CHECK:STDOUT: } // CHECK:STDOUT: }Content-Length: 1495{{\r}} diff --git a/toolchain/testing/testdata/min_prelude/none.carbon b/toolchain/testing/testdata/min_prelude/none.carbon index 38f2f696c475..e27d59f5298c 100644 --- a/toolchain/testing/testdata/min_prelude/none.carbon +++ b/toolchain/testing/testdata/min_prelude/none.carbon @@ -2,7 +2,7 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -// EXTRA-ARGS: --no-prelude-import --exclude-dump-file-prefix=min_prelude/ +// EXTRA-ARGS: --no-prelude-import --no-gen-implicit-type-impls --exclude-dump-file-prefix=min_prelude/ // --- min_prelude/none.carbon