diff --git a/toolchain/check/handle_function.cpp b/toolchain/check/handle_function.cpp index 89817a395c67..edf7fe85d961 100644 --- a/toolchain/check/handle_function.cpp +++ b/toolchain/check/handle_function.cpp @@ -95,14 +95,10 @@ static auto DiagnoseModifiers(Context& context, is_definition); CheckMethodModifiersOnFunction(context, introducer, parent_scope_inst_id, parent_scope_inst); - RequireDefaultFinalOnlyInInterfaces(context, introducer, parent_scope_id); - - if (introducer.modifier_set.HasAnyOf(KeywordModifierSet::Interface)) { - // TODO: Once we are saving the modifiers for a function, add check that - // the function may only be defined if it is marked `default` or `final`. - context.TODO(introducer.modifier_node_id(ModifierOrder::Decl), - "interface modifier"); - } + RequireDefaultFinalOnlyInInterfaces(context, introducer, parent_scope_id, + is_definition); + // TODO: add check that functions in interfaces may only be defined if they + // are marked `default` or `final`. if (!self_param_id.has_value() && introducer.modifier_set.HasAnyOf(KeywordModifierSet::Method)) { @@ -135,6 +131,16 @@ static auto GetEvaluationMode(const KeywordModifierSet& modifier_set) .Default(SemIR::Function::EvaluationMode::None); } +// Returns the implementation modifier as an enum. +static auto GetInterfaceModifier(const KeywordModifierSet& modifier_set) + -> SemIR::Function::InterfaceModifier { + using enum SemIR::Function::InterfaceModifier; + return modifier_set.ToEnum() + .Case(KeywordModifierSet::Default, Default) + .Case(KeywordModifierSet::Final, Final) + .Default(None); +} + // Tries to merge new_function into prev_function_id. Since new_function won't // have a definition even if one is upcoming, set is_definition to indicate the // planned result. @@ -545,6 +551,7 @@ static auto BuildFunctionDecl(Context& context, bool is_extern = introducer.modifier_set.HasAnyOf(KeywordModifierSet::Extern); auto virtual_modifier = GetVirtualModifier(introducer.modifier_set); auto evaluation_mode = GetEvaluationMode(introducer.modifier_set); + auto interface_modifier = GetInterfaceModifier(introducer.modifier_set); // Add the function declaration. SemIR::FunctionDecl function_decl = {SemIR::TypeId::None, @@ -565,6 +572,7 @@ static auto BuildFunctionDecl(Context& context, .return_pattern_id = return_pattern_id, .virtual_modifier = virtual_modifier, .evaluation_mode = evaluation_mode, + .interface_modifier = interface_modifier, .self_param_id = self_param_id}}; if (is_definition) { function_info.definition_id = decl_id; diff --git a/toolchain/check/handle_let_and_var.cpp b/toolchain/check/handle_let_and_var.cpp index 359ca8103b2b..a920aac16ffd 100644 --- a/toolchain/check/handle_let_and_var.cpp +++ b/toolchain/check/handle_let_and_var.cpp @@ -326,7 +326,8 @@ auto HandleParseNode(Context& context, Parse::LetDeclId node_id) -> bool { // constant. We use this rather than `LimitModifiersOnDecl` to get a more // specific error. RequireDefaultFinalOnlyInInterfaces(context, decl_info.introducer, - SemIR::NameScopeId::None); + SemIR::NameScopeId::None, + /*is_definition=*/false); if (decl_info.init_id.has_value()) { LocalPatternMatch(context, decl_info.pattern_id, decl_info.init_id); diff --git a/toolchain/check/impl.cpp b/toolchain/check/impl.cpp index 3e6e5de4d0bd..4289da779879 100644 --- a/toolchain/check/impl.cpp +++ b/toolchain/check/impl.cpp @@ -712,13 +712,33 @@ auto FinishImplWitness(Context& context, const SemIR::Impl& impl) -> void { auto lookup_result = LookupNameInExactScope(context, SemIR::LocId(decl_id), fn.name_id, impl.scope_id, impl_scope); + using InterfaceModifier = SemIR::Function::InterfaceModifier; if (lookup_result.is_found()) { + if (fn.interface_modifier == InterfaceModifier::Final) { + CARBON_DIAGNOSTIC(ImplFinalFunction, Error, + "attempted to implement `{0}`, which is final in " + "interface `{1}`", + SemIR::NameId, SemIR::NameId); + auto builder = + context.emitter().Build(impl.definition_id, ImplFinalFunction, + fn.name_id, interface.name_id); + NoteAssociatedFunction(context, builder, fn_type->function_id); + builder.Emit(); + witness_value = SemIR::ErrorInst::InstId; + break; + } used_decl_ids.push_back(lookup_result.target_inst_id()); witness_value = CheckAssociatedFunctionImplementation( context, *fn_type, context.generics().GetSelfSpecific(impl.generic_id), lookup_result.target_inst_id(), /*defer_thunk_definition=*/true); + break; + } + + if (fn.interface_modifier != InterfaceModifier::None) { + witness_value = decl_id; + break; } else { CARBON_DIAGNOSTIC( ImplMissingFunction, Error, diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index 037f489baf2d..9c3a3a526fe7 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -2392,7 +2392,8 @@ static auto ImportFunctionDecl(ImportContext& context, .return_pattern_id = SemIR::InstId::None, .virtual_modifier = import_function.virtual_modifier, .virtual_index = import_function.virtual_index, - .evaluation_mode = import_function.evaluation_mode}}); + .evaluation_mode = import_function.evaluation_mode, + .interface_modifier = import_function.interface_modifier}}); // Directly add the function type constant. Don't use `GetFunctionType` // because that will evaluate the function type, which we can't do if the diff --git a/toolchain/check/modifiers.cpp b/toolchain/check/modifiers.cpp index fd940fcf0cc1..cdbfe1ddd40d 100644 --- a/toolchain/check/modifiers.cpp +++ b/toolchain/check/modifiers.cpp @@ -225,18 +225,29 @@ auto RestrictExternModifierOnDecl(Context& context, auto RequireDefaultFinalOnlyInInterfaces(Context& context, DeclIntroducerState& introducer, - SemIR::NameScopeId parent_scope_id) - -> void { - if (context.name_scopes().InstIs( + SemIR::NameScopeId parent_scope_id, + bool is_definition) -> void { + // Both `default` and `final` allowed in an interface definition. + if (!context.name_scopes().InstIs( parent_scope_id)) { - // Both `default` and `final` allowed in an interface definition. + CARBON_DIAGNOSTIC(ModifierRequiresInterface, Error, + "`{0}` not allowed; requires interface scope", + Lex::TokenKind); + ForbidModifiersOnDecl(context, ModifierRequiresInterface, introducer, + KeywordModifierSet::Interface); return; } - CARBON_DIAGNOSTIC(ModifierRequiresInterface, Error, - "`{0}` not allowed; requires interface scope", - Lex::TokenKind); - ForbidModifiersOnDecl(context, ModifierRequiresInterface, introducer, - KeywordModifierSet::Interface); + + // TODO: remove and check that final/default declarations have a definition by + // the end of the file. + if (!is_definition) { + CARBON_DIAGNOSTIC( + ModifierFinalRequiresDefaultImpl, Error, + "TODO: `{0}` modifier currently requires an inline definition", + Lex::TokenKind); + ForbidModifiersOnDecl(context, ModifierFinalRequiresDefaultImpl, introducer, + KeywordModifierSet::Interface); + } } } // namespace Carbon::Check diff --git a/toolchain/check/modifiers.h b/toolchain/check/modifiers.h index 961cfba3210d..394840bfeedd 100644 --- a/toolchain/check/modifiers.h +++ b/toolchain/check/modifiers.h @@ -55,8 +55,8 @@ auto RestrictExternModifierOnDecl(Context& context, // `parent_scope_id` may be None for a declaration in a block scope. auto RequireDefaultFinalOnlyInInterfaces(Context& context, DeclIntroducerState& introducer, - SemIR::NameScopeId parent_scope_id) - -> void; + SemIR::NameScopeId parent_scope_id, + bool is_definition) -> void; } // namespace Carbon::Check diff --git a/toolchain/check/testdata/impl/impl_inside_interface.carbon b/toolchain/check/testdata/impl/impl_inside_interface.carbon index b954ba2d463a..aca593b06b76 100644 --- a/toolchain/check/testdata/impl/impl_inside_interface.carbon +++ b/toolchain/check/testdata/impl/impl_inside_interface.carbon @@ -10,47 +10,23 @@ // TIP: To dump output, run: // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/impl_inside_interface.carbon -// --- fail_todo_impl_in_interface_definition.carbon +// --- impl_in_interface_definition.carbon library "[[@TEST_NAME]]"; -// This test uses many unsupported features, and is expected to change. interface I { - // CHECK:STDERR: fail_todo_impl_in_interface_definition.carbon:[[@LINE+4]]:3: error: semantics TODO: `interface modifier` [SemanticsTodo] - // CHECK:STDERR: default fn F() { - // CHECK:STDERR: ^~~~~~~ - // CHECK:STDERR: default fn F() { class C {} - // CHECK:STDERR: fail_todo_impl_in_interface_definition.carbon:[[@LINE+7]]:5: error: missing implementation of F in impl of interface I [ImplMissingFunction] - // CHECK:STDERR: impl C as I {} - // CHECK:STDERR: ^~~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_impl_in_interface_definition.carbon:[[@LINE-5]]:3: note: associated function F declared here [AssociatedFunctionHere] - // CHECK:STDERR: default fn F() { - // CHECK:STDERR: ^~~~~~~~~~~~~~~~ - // CHECK:STDERR: impl C as I {} } } -// --- fail_todo_impl_in_interface_definition_with_associated.carbon +// --- impl_in_interface_definition_with_associated.carbon library "[[@TEST_NAME]]"; -// This test uses many unsupported features, and is expected to change. interface I { let U: type; - // CHECK:STDERR: fail_todo_impl_in_interface_definition_with_associated.carbon:[[@LINE+4]]:3: error: semantics TODO: `interface modifier` [SemanticsTodo] - // CHECK:STDERR: default fn F() { - // CHECK:STDERR: ^~~~~~~ - // CHECK:STDERR: default fn F() { class C {} - // CHECK:STDERR: fail_todo_impl_in_interface_definition_with_associated.carbon:[[@LINE+7]]:5: error: missing implementation of F in impl of interface I [ImplMissingFunction] - // CHECK:STDERR: impl C as I where .U = C {} - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~ - // CHECK:STDERR: fail_todo_impl_in_interface_definition_with_associated.carbon:[[@LINE-5]]:3: note: associated function F declared here [AssociatedFunctionHere] - // CHECK:STDERR: default fn F() { - // CHECK:STDERR: ^~~~~~~~~~~~~~~~ - // CHECK:STDERR: impl C as I where .U = C {} } } diff --git a/toolchain/check/testdata/interface/fail_todo_define_default_fn_inline.carbon b/toolchain/check/testdata/interface/fail_todo_define_default_fn_inline.carbon deleted file mode 100644 index a3cced1bc30b..000000000000 --- a/toolchain/check/testdata/interface/fail_todo_define_default_fn_inline.carbon +++ /dev/null @@ -1,137 +0,0 @@ -// 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-FILE: toolchain/testing/testdata/min_prelude/int.carbon -// TODO: Add ranges and switch to "--dump-sem-ir-ranges=only". -// EXTRA-ARGS: --dump-sem-ir-ranges=if-present -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interface/fail_todo_define_default_fn_inline.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interface/fail_todo_define_default_fn_inline.carbon - -interface Interface { - // CHECK:STDERR: fail_todo_define_default_fn_inline.carbon:[[@LINE+4]]:3: error: semantics TODO: `interface modifier` [SemanticsTodo] - // CHECK:STDERR: default fn F() {} - // CHECK:STDERR: ^~~~~~~ - // CHECK:STDERR: - default fn F() {} - - // CHECK:STDERR: fail_todo_define_default_fn_inline.carbon:[[@LINE+4]]:3: error: semantics TODO: `interface modifier` [SemanticsTodo] - // CHECK:STDERR: default fn G(a: i32, b: i32) -> i32 = "int.sadd"; - // CHECK:STDERR: ^~~~~~~ - // CHECK:STDERR: - default fn G(a: i32, b: i32) -> i32 = "int.sadd"; -} - -// CHECK:STDOUT: --- fail_todo_define_default_fn_inline.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %Interface.type: type = facet_type <@Interface> [concrete] -// CHECK:STDOUT: %Self: %Interface.type = symbolic_binding Self, 0 [symbolic] -// CHECK:STDOUT: %Interface.WithSelf.F.type: type = fn_type @Interface.WithSelf.F, @Interface.WithSelf(%Self) [symbolic] -// CHECK:STDOUT: %Interface.WithSelf.F: %Interface.WithSelf.F.type = struct_value () [symbolic] -// CHECK:STDOUT: %Interface.assoc_type: type = assoc_entity_type @Interface [concrete] -// CHECK:STDOUT: %assoc0: %Interface.assoc_type = assoc_entity element0, @Interface.WithSelf.%Interface.WithSelf.F.decl [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: %pattern_type.6b6: type = pattern_type %i32 [concrete] -// CHECK:STDOUT: %a.param_patt: %pattern_type.6b6 = value_param_pattern [concrete] -// CHECK:STDOUT: %a.patt: %pattern_type.6b6 = at_binding_pattern a, %a.param_patt [concrete] -// CHECK:STDOUT: %b.param_patt: %pattern_type.6b6 = value_param_pattern [concrete] -// CHECK:STDOUT: %b.patt: %pattern_type.6b6 = at_binding_pattern b, %b.param_patt [concrete] -// CHECK:STDOUT: %.795: Core.Form = init_form %i32 [concrete] -// CHECK:STDOUT: %return.param_patt: %pattern_type.6b6 = out_param_pattern [concrete] -// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %return.param_patt, %i32 [concrete] -// CHECK:STDOUT: %Interface.WithSelf.G.type: type = fn_type @Interface.WithSelf.G, @Interface.WithSelf(%Self) [symbolic] -// CHECK:STDOUT: %Interface.WithSelf.G: %Interface.WithSelf.G.type = struct_value () [symbolic] -// CHECK:STDOUT: %assoc1: %Interface.assoc_type = assoc_entity element1, @Interface.WithSelf.%Interface.WithSelf.G.decl [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { -// 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: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .Core = imports.%Core -// CHECK:STDOUT: .Interface = %Interface.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %Core.import = import Core -// CHECK:STDOUT: %Interface.decl: type = interface_decl @Interface [concrete = constants.%Interface.type] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @Interface { -// CHECK:STDOUT: %Self: %Interface.type = symbolic_binding Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: %Interface.WithSelf.decl = interface_with_self_decl @Interface [concrete] -// CHECK:STDOUT: -// CHECK:STDOUT: !with Self: -// CHECK:STDOUT: %Interface.WithSelf.F.decl: @Interface.WithSelf.%Interface.WithSelf.F.type (%Interface.WithSelf.F.type) = fn_decl @Interface.WithSelf.F [symbolic = @Interface.WithSelf.%Interface.WithSelf.F (constants.%Interface.WithSelf.F)] {} {} -// CHECK:STDOUT: %assoc0: %Interface.assoc_type = assoc_entity element0, %Interface.WithSelf.F.decl [concrete = constants.%assoc0] -// CHECK:STDOUT: %Interface.WithSelf.G.decl: @Interface.WithSelf.%Interface.WithSelf.G.type (%Interface.WithSelf.G.type) = fn_decl @Interface.WithSelf.G [symbolic = @Interface.WithSelf.%Interface.WithSelf.G (constants.%Interface.WithSelf.G)] { -// CHECK:STDOUT: %a.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%a.param_patt] -// CHECK:STDOUT: %a.patt: %pattern_type.6b6 = at_binding_pattern a, %a.param_patt [concrete = constants.%a.patt] -// CHECK:STDOUT: %b.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%b.param_patt] -// CHECK:STDOUT: %b.patt: %pattern_type.6b6 = at_binding_pattern b, %b.param_patt [concrete = constants.%b.patt] -// CHECK:STDOUT: %return.param_patt: %pattern_type.6b6 = out_param_pattern [concrete = constants.%return.param_patt] -// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %return.param_patt, %i32.loc26_35 [concrete = constants.%return.patt] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %i32.loc26_35: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %.loc26: Core.Form = init_form %i32.loc26_35 [concrete = constants.%.795] -// CHECK:STDOUT: %a.param: %i32 = value_param call_param0 -// CHECK:STDOUT: %i32.loc26_19: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %a: %i32 = wrapper_binding a, %a.param -// CHECK:STDOUT: %b.param: %i32 = value_param call_param1 -// CHECK:STDOUT: %i32.loc26_27: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %b: %i32 = wrapper_binding b, %b.param -// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param2 -// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param -// CHECK:STDOUT: } -// CHECK:STDOUT: %assoc1: %Interface.assoc_type = assoc_entity element1, %Interface.WithSelf.G.decl [concrete = constants.%assoc1] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: .F = @Interface.WithSelf.%assoc0 -// CHECK:STDOUT: .G = @Interface.WithSelf.%assoc1 -// CHECK:STDOUT: witness = (@Interface.WithSelf.%Interface.WithSelf.F.decl, @Interface.WithSelf.%Interface.WithSelf.G.decl) -// CHECK:STDOUT: -// CHECK:STDOUT: !requires: -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @Interface.WithSelf.F(@Interface.%Self: %Interface.type) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: -// CHECK:STDOUT: fn() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @Interface.WithSelf.G(@Interface.%Self: %Interface.type) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%a.param: %i32, %b.param: %i32) -> out %return.param: %i32 = "int.sadd"; -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @Interface.WithSelf(constants.%Self) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %Self => constants.%Self -// CHECK:STDOUT: %Interface.WithSelf.F.type => constants.%Interface.WithSelf.F.type -// CHECK:STDOUT: %Interface.WithSelf.F => constants.%Interface.WithSelf.F -// CHECK:STDOUT: %Interface.WithSelf.G.type => constants.%Interface.WithSelf.G.type -// CHECK:STDOUT: %Interface.WithSelf.G => constants.%Interface.WithSelf.G -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @Interface.WithSelf.F(constants.%Self) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @Interface.WithSelf.G(constants.%Self) {} -// CHECK:STDOUT: 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 deleted file mode 100644 index 7b6483a3c8ce..000000000000 --- a/toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon +++ /dev/null @@ -1,398 +0,0 @@ -// 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-FILE: toolchain/testing/testdata/min_prelude/int.carbon -// TODO: Add ranges and switch to "--dump-sem-ir-ranges=only". -// EXTRA-ARGS: --dump-sem-ir-ranges=if-present -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interface/fail_todo_define_default_fn_out_of_line.carbon - -// --- fail_todo_define_default_fn_out_of_line.carbon - -interface Interface { - // CHECK:STDERR: fail_todo_define_default_fn_out_of_line.carbon:[[@LINE+4]]:3: error: semantics TODO: `interface modifier` [SemanticsTodo] - // CHECK:STDERR: default fn F(); - // CHECK:STDERR: ^~~~~~~ - // CHECK:STDERR: - default fn F(); - - // CHECK:STDERR: fail_todo_define_default_fn_out_of_line.carbon:[[@LINE+4]]:3: error: semantics TODO: `interface modifier` [SemanticsTodo] - // CHECK:STDERR: default fn G(a: i32, b: i32) -> i32; - // CHECK:STDERR: ^~~~~~~ - // CHECK:STDERR: - default fn G(a: i32, b: i32) -> i32; -} - -fn Interface.F() {} - -fn Interface.G(a: i32, b: i32) -> i32 = "int.sadd"; - -// --- dependent_return_type.carbon - -library "dependent_return_type.carbon"; - -// Ensure that a dependent return type matches between an interface definition -// and an out-of-line member. This requires `Self` to be properly reintroduced -// into the list of generic parameters. - -interface Interface { - // TODO: This should be - // default fn F(self, generic U: type, u: U*) -> U*; - // rather than a class member, but we don't currently accept that due to the - // TODOs above. - class C { - fn F(self, generic U: type, u: U*) -> U*; - } -} - -// TODO: This should be -// fn Interface.F(self, generic U: type, u: U*) -> U* { return u; } -fn Interface.C.F(unused self, generic U: type, u: U*) -> U* { return u; } - - -// CHECK:STDOUT: --- fail_todo_define_default_fn_out_of_line.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %Interface.type: type = facet_type <@Interface> [concrete] -// CHECK:STDOUT: %Self: %Interface.type = symbolic_binding Self, 0 [symbolic] -// CHECK:STDOUT: %Interface.WithSelf.F.type: type = fn_type @Interface.WithSelf.F, @Interface.WithSelf(%Self) [symbolic] -// CHECK:STDOUT: %Interface.WithSelf.F: %Interface.WithSelf.F.type = struct_value () [symbolic] -// CHECK:STDOUT: %Interface.assoc_type: type = assoc_entity_type @Interface [concrete] -// CHECK:STDOUT: %assoc0: %Interface.assoc_type = assoc_entity element0, @Interface.WithSelf.%Interface.WithSelf.F.decl [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: %pattern_type.6b6: type = pattern_type %i32 [concrete] -// CHECK:STDOUT: %a.param_patt: %pattern_type.6b6 = value_param_pattern [concrete] -// CHECK:STDOUT: %a.patt: %pattern_type.6b6 = at_binding_pattern a, %a.param_patt [concrete] -// CHECK:STDOUT: %b.param_patt: %pattern_type.6b6 = value_param_pattern [concrete] -// CHECK:STDOUT: %b.patt: %pattern_type.6b6 = at_binding_pattern b, %b.param_patt [concrete] -// CHECK:STDOUT: %.795: Core.Form = init_form %i32 [concrete] -// CHECK:STDOUT: %return.param_patt: %pattern_type.6b6 = out_param_pattern [concrete] -// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %return.param_patt, %i32 [concrete] -// CHECK:STDOUT: %Interface.WithSelf.G.type: type = fn_type @Interface.WithSelf.G, @Interface.WithSelf(%Self) [symbolic] -// CHECK:STDOUT: %Interface.WithSelf.G: %Interface.WithSelf.G.type = struct_value () [symbolic] -// CHECK:STDOUT: %assoc1: %Interface.assoc_type = assoc_entity element1, @Interface.WithSelf.%Interface.WithSelf.G.decl [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { -// 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: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .Core = imports.%Core -// CHECK:STDOUT: .Interface = %Interface.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %Core.import = import Core -// CHECK:STDOUT: %Interface.decl: type = interface_decl @Interface [concrete = constants.%Interface.type] {} {} -// CHECK:STDOUT: %Interface.WithSelf.F.decl: %Interface.WithSelf.F.type = fn_decl @Interface.WithSelf.F [symbolic = constants.%Interface.WithSelf.F] {} {} -// CHECK:STDOUT: %Interface.WithSelf.G.decl: %Interface.WithSelf.G.type = fn_decl @Interface.WithSelf.G [symbolic = constants.%Interface.WithSelf.G] { -// CHECK:STDOUT: %a.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%a.param_patt] -// CHECK:STDOUT: %a.patt: %pattern_type.6b6 = at_binding_pattern a, %a.param_patt [concrete = constants.%a.patt] -// CHECK:STDOUT: %b.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%b.param_patt] -// CHECK:STDOUT: %b.patt: %pattern_type.6b6 = at_binding_pattern b, %b.param_patt [concrete = constants.%b.patt] -// CHECK:STDOUT: %return.param_patt: %pattern_type.6b6 = out_param_pattern [concrete = constants.%return.param_patt] -// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %return.param_patt, %i32.loc18_35 [concrete = constants.%return.patt] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %i32.loc18_35: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %.loc18: Core.Form = init_form %i32.loc18_35 [concrete = constants.%.795] -// CHECK:STDOUT: %a.param.loc18: %i32 = value_param call_param0 -// CHECK:STDOUT: %i32.loc18_19: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %a.loc18: %i32 = wrapper_binding a, %a.param.loc18 -// CHECK:STDOUT: %b.param.loc18: %i32 = value_param call_param1 -// CHECK:STDOUT: %i32.loc18_27: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %b.loc18: %i32 = wrapper_binding b, %b.param.loc18 -// CHECK:STDOUT: %return.param.loc18: ref %i32 = out_param call_param2 -// CHECK:STDOUT: %return.loc18: ref %i32 = return_slot %return.param.loc18 -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @Interface { -// CHECK:STDOUT: %Self: %Interface.type = symbolic_binding Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: %Interface.WithSelf.decl = interface_with_self_decl @Interface [concrete] -// CHECK:STDOUT: -// CHECK:STDOUT: !with Self: -// CHECK:STDOUT: %Interface.WithSelf.F.decl: @Interface.WithSelf.%Interface.WithSelf.F.type (%Interface.WithSelf.F.type) = fn_decl @Interface.WithSelf.F [symbolic = @Interface.WithSelf.%Interface.WithSelf.F (constants.%Interface.WithSelf.F)] {} {} -// CHECK:STDOUT: %assoc0: %Interface.assoc_type = assoc_entity element0, %Interface.WithSelf.F.decl [concrete = constants.%assoc0] -// CHECK:STDOUT: %Interface.WithSelf.G.decl: @Interface.WithSelf.%Interface.WithSelf.G.type (%Interface.WithSelf.G.type) = fn_decl @Interface.WithSelf.G [symbolic = @Interface.WithSelf.%Interface.WithSelf.G (constants.%Interface.WithSelf.G)] { -// CHECK:STDOUT: %a.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%a.param_patt] -// CHECK:STDOUT: %a.patt: %pattern_type.6b6 = at_binding_pattern a, %a.param_patt [concrete = constants.%a.patt] -// CHECK:STDOUT: %b.param_patt: %pattern_type.6b6 = value_param_pattern [concrete = constants.%b.param_patt] -// CHECK:STDOUT: %b.patt: %pattern_type.6b6 = at_binding_pattern b, %b.param_patt [concrete = constants.%b.patt] -// CHECK:STDOUT: %return.param_patt: %pattern_type.6b6 = out_param_pattern [concrete = constants.%return.param_patt] -// CHECK:STDOUT: %return.patt: %pattern_type.6b6 = return_slot_pattern %return.param_patt, %i32.loc18_35 [concrete = constants.%return.patt] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %i32.loc13_35: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %.loc13: Core.Form = init_form %i32.loc13_35 [concrete = constants.%.795] -// CHECK:STDOUT: %a.param.loc13: %i32 = value_param call_param0 -// CHECK:STDOUT: %i32.loc13_19: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %a.loc13: %i32 = wrapper_binding a, %a.param.loc13 -// CHECK:STDOUT: %b.param.loc13: %i32 = value_param call_param1 -// CHECK:STDOUT: %i32.loc13_27: type = type_literal constants.%i32 [concrete = constants.%i32] -// CHECK:STDOUT: %b.loc13: %i32 = wrapper_binding b, %b.param.loc13 -// CHECK:STDOUT: %return.param.loc13: ref %i32 = out_param call_param2 -// CHECK:STDOUT: %return.loc13: ref %i32 = return_slot %return.param.loc13 -// CHECK:STDOUT: } -// CHECK:STDOUT: %assoc1: %Interface.assoc_type = assoc_entity element1, %Interface.WithSelf.G.decl [concrete = constants.%assoc1] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: .F = @Interface.WithSelf.%assoc0 -// CHECK:STDOUT: .G = @Interface.WithSelf.%assoc1 -// CHECK:STDOUT: witness = (@Interface.WithSelf.%Interface.WithSelf.F.decl, @Interface.WithSelf.%Interface.WithSelf.G.decl) -// CHECK:STDOUT: -// CHECK:STDOUT: !requires: -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @Interface.WithSelf.F(@Interface.%Self: %Interface.type) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: -// CHECK:STDOUT: fn() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @Interface.WithSelf.G(@Interface.%Self: %Interface.type) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%a.param.loc18: %i32, %b.param.loc18: %i32) -> out %return.param.loc18: %i32 = "int.sadd"; -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @Interface.WithSelf(constants.%Self) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @Interface.WithSelf.F(constants.%Self) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @Interface.WithSelf.G(constants.%Self) {} -// CHECK:STDOUT: -// CHECK:STDOUT: --- dependent_return_type.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %Interface.type: type = facet_type <@Interface> [concrete] -// CHECK:STDOUT: %Self.3ce: %Interface.type = symbolic_binding Self, 0 [symbolic] -// CHECK:STDOUT: %C: type = class_type @C, @C(%Self.3ce) [symbolic] -// CHECK:STDOUT: %pattern_type.f25: type = pattern_type %C [symbolic] -// CHECK:STDOUT: %self.param_patt.f45: %pattern_type.f25 = value_param_pattern [symbolic] -// CHECK:STDOUT: %self.patt.134: %pattern_type.f25 = at_binding_pattern self, %self.param_patt.f45 [symbolic] -// CHECK:STDOUT: %type: type = facet_type [concrete] -// CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self] -// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] -// CHECK:STDOUT: %U.patt.014: %pattern_type.98f = symbolic_binding_pattern U, 1 [symbolic] -// CHECK:STDOUT: %U.091: type = symbolic_binding U, 1 [symbolic] -// CHECK:STDOUT: %ptr.18e: type = ptr_type %U.091 [symbolic] -// CHECK:STDOUT: %pattern_type.423: type = pattern_type %ptr.18e [symbolic] -// CHECK:STDOUT: %u.param_patt: %pattern_type.423 = value_param_pattern [symbolic] -// CHECK:STDOUT: %u.patt: %pattern_type.423 = at_binding_pattern u, %u.param_patt [symbolic] -// CHECK:STDOUT: %.6d8: Core.Form = init_form %ptr.18e [symbolic] -// CHECK:STDOUT: %return.param_patt.534: %pattern_type.423 = out_param_pattern [symbolic] -// CHECK:STDOUT: %return.patt.669: %pattern_type.423 = return_slot_pattern %return.param_patt.534, %ptr.18e [symbolic] -// CHECK:STDOUT: %C.F.type: type = fn_type @C.F, @C(%Self.3ce) [symbolic] -// CHECK:STDOUT: %C.F: %C.F.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.f37: = require_complete_type %C [symbolic] -// CHECK:STDOUT: %require_complete.56d: = require_complete_type %ptr.18e [symbolic] -// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] -// CHECK:STDOUT: %Copy.lookup_impl_witness.088: = lookup_impl_witness %ptr.18e, @Copy [symbolic] -// CHECK:STDOUT: %.ddf: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%U.091) [symbolic] -// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.18e, (%Copy.lookup_impl_witness.088) [symbolic] -// CHECK:STDOUT: %Copy.WithSelf.Op.type.da6: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet) [symbolic] -// CHECK:STDOUT: %.a56: type = fn_type_with_self_type %Copy.WithSelf.Op.type.da6, %Copy.facet [symbolic] -// CHECK:STDOUT: %impl.elem0.fbe: %.a56 = impl_witness_access %Copy.lookup_impl_witness.088, element0 [symbolic] -// CHECK:STDOUT: %specific_impl_fn.16d: = specific_impl_function %impl.elem0.fbe, @Copy.WithSelf.Op(%Copy.facet) [symbolic] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: imports { -// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { -// CHECK:STDOUT: .Copy = %Core.Copy -// CHECK:STDOUT: import Core//prelude -// CHECK:STDOUT: import Core//prelude/... -// CHECK:STDOUT: } -// CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/parts/copy, Copy, loaded [concrete = constants.%Copy.type] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .Core = imports.%Core -// CHECK:STDOUT: .Interface = %Interface.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %Core.import = import Core -// CHECK:STDOUT: %Interface.decl: type = interface_decl @Interface [concrete = constants.%Interface.type] {} {} -// CHECK:STDOUT: %C.F.decl: %C.F.type = fn_decl @C.F [symbolic = constants.%C.F] { -// CHECK:STDOUT: %self.param_patt.loc20: @C.F.%pattern_type.loc14_10 (%pattern_type.f25) = value_param_pattern [symbolic = %self.param_patt.loc14 (constants.%self.param_patt.f45)] -// CHECK:STDOUT: %self.patt.loc20: @C.F.%pattern_type.loc14_10 (%pattern_type.f25) = at_binding_pattern self, %self.param_patt.loc20 [symbolic = %self.patt.loc14 (constants.%self.patt.134)] -// CHECK:STDOUT: %U.patt.loc20: %pattern_type.98f = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc14 (constants.%U.patt.014)] -// CHECK:STDOUT: %u.param_patt.loc20: @C.F.%pattern_type.loc14_34 (%pattern_type.423) = value_param_pattern [symbolic = %u.param_patt.loc14 (constants.%u.param_patt)] -// CHECK:STDOUT: %u.patt.loc20: @C.F.%pattern_type.loc14_34 (%pattern_type.423) = at_binding_pattern u, %u.param_patt.loc20 [symbolic = %u.patt.loc14 (constants.%u.patt)] -// CHECK:STDOUT: %return.param_patt.loc20: @C.F.%pattern_type.loc14_34 (%pattern_type.423) = out_param_pattern [symbolic = %return.param_patt.loc14 (constants.%return.param_patt.534)] -// CHECK:STDOUT: %return.patt.loc20: @C.F.%pattern_type.loc14_34 (%pattern_type.423) = return_slot_pattern %return.param_patt.loc20, %ptr.loc20_59 [symbolic = %return.patt.loc14 (constants.%return.patt.669)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %U.ref.loc20_58: type = name_ref U, %U.loc20 [symbolic = %U.loc14_25.1 (constants.%U.091)] -// CHECK:STDOUT: %ptr.loc20_59: type = ptr_type %U.ref.loc20_58 [symbolic = %ptr.loc14_37.1 (constants.%ptr.18e)] -// CHECK:STDOUT: %.loc20_59: Core.Form = init_form %ptr.loc20_59 [symbolic = %.loc14_44.1 (constants.%.6d8)] -// CHECK:STDOUT: %self.param.loc20: @C.F.%C (%C) = value_param call_param0 -// CHECK:STDOUT: %.loc20_25.1: type = splice_block %Self.ref.loc20 [symbolic = %C (constants.%C)] { -// CHECK:STDOUT: %.loc20_25.2: type = specific_constant constants.%C, @C(constants.%Self.3ce) [symbolic = %C (constants.%C)] -// CHECK:STDOUT: %Self.ref.loc20: type = name_ref Self, %.loc20_25.2 [symbolic = %C (constants.%C)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self.loc20: @C.F.%C (%C) = wrapper_binding self, %self.param.loc20 -// CHECK:STDOUT: %.loc20_42.1: type = splice_block %.loc20_42.2 [concrete = type] { -// CHECK:STDOUT: %.Self.frozen.loc20: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen] -// CHECK:STDOUT: %.loc20_42.2: type = type_literal type [concrete = type] -// CHECK:STDOUT: } -// CHECK:STDOUT: %U.loc20: type = symbolic_binding U, 1 [symbolic = %U.loc14_25.1 (constants.%U.091)] -// CHECK:STDOUT: %u.param.loc20: @C.F.%ptr.loc14_37.1 (%ptr.18e) = value_param call_param1 -// CHECK:STDOUT: %.loc20_52: type = splice_block %ptr.loc20_52 [symbolic = %ptr.loc14_37.1 (constants.%ptr.18e)] { -// CHECK:STDOUT: %U.ref.loc20_51: type = name_ref U, %U.loc20 [symbolic = %U.loc14_25.1 (constants.%U.091)] -// CHECK:STDOUT: %ptr.loc20_52: type = ptr_type %U.ref.loc20_51 [symbolic = %ptr.loc14_37.1 (constants.%ptr.18e)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %u.loc20: @C.F.%ptr.loc14_37.1 (%ptr.18e) = wrapper_binding u, %u.param.loc20 -// CHECK:STDOUT: %return.param.loc20: ref @C.F.%ptr.loc14_37.1 (%ptr.18e) = out_param call_param2 -// CHECK:STDOUT: %return.loc20: ref @C.F.%ptr.loc14_37.1 (%ptr.18e) = return_slot %return.param.loc20 -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @Interface { -// CHECK:STDOUT: %Self: %Interface.type = symbolic_binding Self, 0 [symbolic = constants.%Self.3ce] -// CHECK:STDOUT: %Interface.WithSelf.decl = interface_with_self_decl @Interface [concrete] -// CHECK:STDOUT: -// CHECK:STDOUT: !with Self: -// CHECK:STDOUT: %C.decl: type = class_decl @C [symbolic = @Interface.WithSelf.%C (constants.%C)] {} {} -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: .C = @Interface.WithSelf.%C.decl -// CHECK:STDOUT: witness = () -// CHECK:STDOUT: -// CHECK:STDOUT: !requires: -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic class @C(@Interface.%Self: %Interface.type) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %Self: %Interface.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self.3ce)] -// 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: -// CHECK:STDOUT: class { -// CHECK:STDOUT: %C.F.decl: @C.%C.F.type (%C.F.type) = fn_decl @C.F [symbolic = @C.%C.F (constants.%C.F)] { -// CHECK:STDOUT: %self.param_patt.loc20: @C.F.%pattern_type.loc14_10 (%pattern_type.f25) = value_param_pattern [symbolic = %self.param_patt.loc14 (constants.%self.param_patt.f45)] -// CHECK:STDOUT: %self.patt.loc20: @C.F.%pattern_type.loc14_10 (%pattern_type.f25) = at_binding_pattern self, %self.param_patt.loc20 [symbolic = %self.patt.loc14 (constants.%self.patt.134)] -// CHECK:STDOUT: %U.patt.loc20: %pattern_type.98f = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc14 (constants.%U.patt.014)] -// CHECK:STDOUT: %u.param_patt.loc20: @C.F.%pattern_type.loc14_34 (%pattern_type.423) = value_param_pattern [symbolic = %u.param_patt.loc14 (constants.%u.param_patt)] -// CHECK:STDOUT: %u.patt.loc20: @C.F.%pattern_type.loc14_34 (%pattern_type.423) = at_binding_pattern u, %u.param_patt.loc20 [symbolic = %u.patt.loc14 (constants.%u.patt)] -// CHECK:STDOUT: %return.param_patt.loc20: @C.F.%pattern_type.loc14_34 (%pattern_type.423) = out_param_pattern [symbolic = %return.param_patt.loc14 (constants.%return.param_patt.534)] -// CHECK:STDOUT: %return.patt.loc20: @C.F.%pattern_type.loc14_34 (%pattern_type.423) = return_slot_pattern %return.param_patt.loc20, %ptr.loc20_59 [symbolic = %return.patt.loc14 (constants.%return.patt.669)] -// CHECK:STDOUT: } { -// CHECK:STDOUT: %U.ref.loc14_43: type = name_ref U, %U.loc14_25.2 [symbolic = %U.loc14_25.1 (constants.%U.091)] -// CHECK:STDOUT: %ptr.loc14_44: type = ptr_type %U.ref.loc14_43 [symbolic = %ptr.loc14_37.1 (constants.%ptr.18e)] -// CHECK:STDOUT: %.loc14_44.2: Core.Form = init_form %ptr.loc14_44 [symbolic = %.loc14_44.1 (constants.%.6d8)] -// CHECK:STDOUT: %self.param.loc14: @C.F.%C (%C) = value_param call_param0 -// CHECK:STDOUT: %.loc14_10.1: type = splice_block %Self.ref.loc14 [symbolic = %C (constants.%C)] { -// CHECK:STDOUT: %.loc14_10.2: type = specific_constant constants.%C, @C(constants.%Self.3ce) [symbolic = %C (constants.%C)] -// CHECK:STDOUT: %Self.ref.loc14: type = name_ref Self, %.loc14_10.2 [symbolic = %C (constants.%C)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self.loc14: @C.F.%C (%C) = wrapper_binding self, %self.param.loc14 -// CHECK:STDOUT: %.loc14_27.1: type = splice_block %.loc14_27.2 [concrete = type] { -// CHECK:STDOUT: %.Self.frozen.loc14: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen] -// CHECK:STDOUT: %.loc14_27.2: type = type_literal type [concrete = type] -// CHECK:STDOUT: } -// CHECK:STDOUT: %U.loc14_25.2: type = symbolic_binding U, 1 [symbolic = %U.loc14_25.1 (constants.%U.091)] -// CHECK:STDOUT: %u.param.loc14: @C.F.%ptr.loc14_37.1 (%ptr.18e) = value_param call_param1 -// CHECK:STDOUT: %.loc14_37: type = splice_block %ptr.loc14_37.2 [symbolic = %ptr.loc14_37.1 (constants.%ptr.18e)] { -// CHECK:STDOUT: %U.ref.loc14_36: type = name_ref U, %U.loc14_25.2 [symbolic = %U.loc14_25.1 (constants.%U.091)] -// CHECK:STDOUT: %ptr.loc14_37.2: type = ptr_type %U.ref.loc14_36 [symbolic = %ptr.loc14_37.1 (constants.%ptr.18e)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %u.loc14: @C.F.%ptr.loc14_37.1 (%ptr.18e) = wrapper_binding u, %u.param.loc14 -// CHECK:STDOUT: %return.param.loc14: ref @C.F.%ptr.loc14_37.1 (%ptr.18e) = out_param call_param2 -// CHECK:STDOUT: %return.loc14: ref @C.F.%ptr.loc14_37.1 (%ptr.18e) = return_slot %return.param.loc14 -// CHECK:STDOUT: } -// 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: -// CHECK:STDOUT: .Self = constants.%C -// CHECK:STDOUT: .F = %C.F.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @C.F(@Interface.%Self: %Interface.type, %U.loc14_25.2: type) { -// CHECK:STDOUT: %Self: %Interface.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self.3ce)] -// 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.f25)] -// CHECK:STDOUT: %self.param_patt.loc14: @C.F.%pattern_type.loc14_10 (%pattern_type.f25) = value_param_pattern [symbolic = %self.param_patt.loc14 (constants.%self.param_patt.f45)] -// CHECK:STDOUT: %self.patt.loc14: @C.F.%pattern_type.loc14_10 (%pattern_type.f25) = at_binding_pattern self, %self.param_patt.loc14 [symbolic = %self.patt.loc14 (constants.%self.patt.134)] -// CHECK:STDOUT: %U.patt.loc14: %pattern_type.98f = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc14 (constants.%U.patt.014)] -// CHECK:STDOUT: %U.loc14_25.1: type = symbolic_binding U, 1 [symbolic = %U.loc14_25.1 (constants.%U.091)] -// CHECK:STDOUT: %ptr.loc14_37.1: type = ptr_type %U.loc14_25.1 [symbolic = %ptr.loc14_37.1 (constants.%ptr.18e)] -// CHECK:STDOUT: %pattern_type.loc14_34: type = pattern_type %ptr.loc14_37.1 [symbolic = %pattern_type.loc14_34 (constants.%pattern_type.423)] -// CHECK:STDOUT: %u.param_patt.loc14: @C.F.%pattern_type.loc14_34 (%pattern_type.423) = value_param_pattern [symbolic = %u.param_patt.loc14 (constants.%u.param_patt)] -// CHECK:STDOUT: %u.patt.loc14: @C.F.%pattern_type.loc14_34 (%pattern_type.423) = at_binding_pattern u, %u.param_patt.loc14 [symbolic = %u.patt.loc14 (constants.%u.patt)] -// CHECK:STDOUT: %.loc14_44.1: Core.Form = init_form %ptr.loc14_37.1 [symbolic = %.loc14_44.1 (constants.%.6d8)] -// CHECK:STDOUT: %return.param_patt.loc14: @C.F.%pattern_type.loc14_34 (%pattern_type.423) = out_param_pattern [symbolic = %return.param_patt.loc14 (constants.%return.param_patt.534)] -// CHECK:STDOUT: %return.patt.loc14: @C.F.%pattern_type.loc14_34 (%pattern_type.423) = return_slot_pattern %return.param_patt.loc14, %ptr.loc14_37.1 [symbolic = %return.patt.loc14 (constants.%return.patt.669)] -// CHECK:STDOUT: -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete.loc20_25: = require_complete_type %C [symbolic = %require_complete.loc20_25 (constants.%require_complete.f37)] -// CHECK:STDOUT: %require_complete.loc20_49: = require_complete_type %ptr.loc14_37.1 [symbolic = %require_complete.loc20_49 (constants.%require_complete.56d)] -// CHECK:STDOUT: %.loc20_70.3: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%U.loc14_25.1) [symbolic = %.loc20_70.3 (constants.%.ddf)] -// CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc14_37.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.088)] -// CHECK:STDOUT: %Copy.facet.loc20_70.3: %Copy.type = facet_value %ptr.loc14_37.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet.loc20_70.3 (constants.%Copy.facet)] -// CHECK:STDOUT: %Copy.WithSelf.Op.type: type = fn_type @Copy.WithSelf.Op, @Copy.WithSelf(%Copy.facet.loc20_70.3) [symbolic = %Copy.WithSelf.Op.type (constants.%Copy.WithSelf.Op.type.da6)] -// CHECK:STDOUT: %.loc20_70.4: type = fn_type_with_self_type %Copy.WithSelf.Op.type, %Copy.facet.loc20_70.3 [symbolic = %.loc20_70.4 (constants.%.a56)] -// CHECK:STDOUT: %impl.elem0.loc20_70.2: @C.F.%.loc20_70.4 (%.a56) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc20_70.2 (constants.%impl.elem0.fbe)] -// CHECK:STDOUT: %specific_impl_fn.loc20_70.2: = specific_impl_function %impl.elem0.loc20_70.2, @Copy.WithSelf.Op(%Copy.facet.loc20_70.3) [symbolic = %specific_impl_fn.loc20_70.2 (constants.%specific_impl_fn.16d)] -// CHECK:STDOUT: -// CHECK:STDOUT: fn(%self.param.loc20: @C.F.%C (%C), %u.param.loc20: @C.F.%ptr.loc14_37.1 (%ptr.18e)) -> out %return.param.loc20: @C.F.%ptr.loc14_37.1 (%ptr.18e) { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: %u.ref: @C.F.%ptr.loc14_37.1 (%ptr.18e) = name_ref u, %u.loc20 -// CHECK:STDOUT: %impl.elem0.loc20_70.1: @C.F.%.loc20_70.4 (%.a56) = impl_witness_access constants.%Copy.lookup_impl_witness.088, element0 [symbolic = %impl.elem0.loc20_70.2 (constants.%impl.elem0.fbe)] -// CHECK:STDOUT: %bound_method.loc20_70.1: = bound_method %u.ref, %impl.elem0.loc20_70.1 -// CHECK:STDOUT: %Copy.facet.loc20_70.1: %Copy.type = facet_value constants.%ptr.18e, (constants.%Copy.lookup_impl_witness.088) [symbolic = %Copy.facet.loc20_70.3 (constants.%Copy.facet)] -// CHECK:STDOUT: %.loc20_70.1: %Copy.type = converted constants.%ptr.18e, %Copy.facet.loc20_70.1 [symbolic = %Copy.facet.loc20_70.3 (constants.%Copy.facet)] -// CHECK:STDOUT: %Copy.facet.loc20_70.2: %Copy.type = facet_value constants.%ptr.18e, (constants.%Copy.lookup_impl_witness.088) [symbolic = %Copy.facet.loc20_70.3 (constants.%Copy.facet)] -// CHECK:STDOUT: %.loc20_70.2: %Copy.type = converted constants.%ptr.18e, %Copy.facet.loc20_70.2 [symbolic = %Copy.facet.loc20_70.3 (constants.%Copy.facet)] -// CHECK:STDOUT: %specific_impl_fn.loc20_70.1: = specific_impl_function %impl.elem0.loc20_70.1, @Copy.WithSelf.Op(constants.%Copy.facet) [symbolic = %specific_impl_fn.loc20_70.2 (constants.%specific_impl_fn.16d)] -// CHECK:STDOUT: %bound_method.loc20_70.2: = bound_method %u.ref, %specific_impl_fn.loc20_70.1 -// CHECK:STDOUT: %Copy.WithSelf.Op.call: init @C.F.%ptr.loc14_37.1 (%ptr.18e) = call %bound_method.loc20_70.2(%u.ref) -// CHECK:STDOUT: return %Copy.WithSelf.Op.call -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @Interface.WithSelf(constants.%Self.3ce) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @C(constants.%Self.3ce) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %Self => constants.%Self.3ce -// 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.3ce, constants.%U.091) { -// CHECK:STDOUT: %Self => constants.%Self.3ce -// CHECK:STDOUT: %C => constants.%C -// CHECK:STDOUT: %pattern_type.loc14_10 => constants.%pattern_type.f25 -// CHECK:STDOUT: %self.param_patt.loc14 => constants.%self.param_patt.f45 -// CHECK:STDOUT: %self.patt.loc14 => constants.%self.patt.134 -// CHECK:STDOUT: %U.patt.loc14 => constants.%U.patt.014 -// CHECK:STDOUT: %U.loc14_25.1 => constants.%U.091 -// CHECK:STDOUT: %ptr.loc14_37.1 => constants.%ptr.18e -// CHECK:STDOUT: %pattern_type.loc14_34 => constants.%pattern_type.423 -// CHECK:STDOUT: %u.param_patt.loc14 => constants.%u.param_patt -// CHECK:STDOUT: %u.patt.loc14 => constants.%u.patt -// CHECK:STDOUT: %.loc14_44.1 => constants.%.6d8 -// CHECK:STDOUT: %return.param_patt.loc14 => constants.%return.param_patt.534 -// CHECK:STDOUT: %return.patt.loc14 => constants.%return.patt.669 -// CHECK:STDOUT: } -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/interface/fail_todo_modifiers.carbon b/toolchain/check/testdata/interface/fail_todo_modifiers.carbon deleted file mode 100644 index ceaca3857975..000000000000 --- a/toolchain/check/testdata/interface/fail_todo_modifiers.carbon +++ /dev/null @@ -1,98 +0,0 @@ -// 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-FILE: toolchain/testing/testdata/min_prelude/none.carbon -// TODO: Add ranges and switch to "--dump-sem-ir-ranges=only". -// EXTRA-ARGS: --dump-sem-ir-ranges=if-present -// -// AUTOUPDATE -// TIP: To test this file alone, run: -// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interface/fail_todo_modifiers.carbon -// TIP: To dump output, run: -// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interface/fail_todo_modifiers.carbon - -interface Modifiers { - // CHECK:STDERR: fail_todo_modifiers.carbon:[[@LINE+4]]:3: error: semantics TODO: `interface modifier` [SemanticsTodo] - // CHECK:STDERR: final fn Final() { } - // CHECK:STDERR: ^~~~~ - // CHECK:STDERR: - final fn Final() { } - // CHECK:STDERR: fail_todo_modifiers.carbon:[[@LINE+4]]:3: error: semantics TODO: `interface modifier` [SemanticsTodo] - // CHECK:STDERR: default fn Default() { } - // CHECK:STDERR: ^~~~~~~ - // CHECK:STDERR: - default fn Default() { } -} - -// CHECK:STDOUT: --- fail_todo_modifiers.carbon -// CHECK:STDOUT: -// CHECK:STDOUT: constants { -// CHECK:STDOUT: %Modifiers.type: type = facet_type <@Modifiers> [concrete] -// CHECK:STDOUT: %Self: %Modifiers.type = symbolic_binding Self, 0 [symbolic] -// CHECK:STDOUT: %Modifiers.WithSelf.Final.type: type = fn_type @Modifiers.WithSelf.Final, @Modifiers.WithSelf(%Self) [symbolic] -// CHECK:STDOUT: %Modifiers.WithSelf.Final: %Modifiers.WithSelf.Final.type = struct_value () [symbolic] -// CHECK:STDOUT: %Modifiers.assoc_type: type = assoc_entity_type @Modifiers [concrete] -// CHECK:STDOUT: %assoc0: %Modifiers.assoc_type = assoc_entity element0, @Modifiers.WithSelf.%Modifiers.WithSelf.Final.decl [concrete] -// CHECK:STDOUT: %Modifiers.WithSelf.Default.type: type = fn_type @Modifiers.WithSelf.Default, @Modifiers.WithSelf(%Self) [symbolic] -// CHECK:STDOUT: %Modifiers.WithSelf.Default: %Modifiers.WithSelf.Default.type = struct_value () [symbolic] -// CHECK:STDOUT: %assoc1: %Modifiers.assoc_type = assoc_entity element1, @Modifiers.WithSelf.%Modifiers.WithSelf.Default.decl [concrete] -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: file { -// CHECK:STDOUT: package: = namespace [concrete] { -// CHECK:STDOUT: .Modifiers = %Modifiers.decl -// CHECK:STDOUT: } -// CHECK:STDOUT: %Modifiers.decl: type = interface_decl @Modifiers [concrete = constants.%Modifiers.type] {} {} -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: interface @Modifiers { -// CHECK:STDOUT: %Self: %Modifiers.type = symbolic_binding Self, 0 [symbolic = constants.%Self] -// CHECK:STDOUT: %Modifiers.WithSelf.decl = interface_with_self_decl @Modifiers [concrete] -// CHECK:STDOUT: -// CHECK:STDOUT: !with Self: -// CHECK:STDOUT: %Modifiers.WithSelf.Final.decl: @Modifiers.WithSelf.%Modifiers.WithSelf.Final.type (%Modifiers.WithSelf.Final.type) = fn_decl @Modifiers.WithSelf.Final [symbolic = @Modifiers.WithSelf.%Modifiers.WithSelf.Final (constants.%Modifiers.WithSelf.Final)] {} {} -// CHECK:STDOUT: %assoc0: %Modifiers.assoc_type = assoc_entity element0, %Modifiers.WithSelf.Final.decl [concrete = constants.%assoc0] -// CHECK:STDOUT: %Modifiers.WithSelf.Default.decl: @Modifiers.WithSelf.%Modifiers.WithSelf.Default.type (%Modifiers.WithSelf.Default.type) = fn_decl @Modifiers.WithSelf.Default [symbolic = @Modifiers.WithSelf.%Modifiers.WithSelf.Default (constants.%Modifiers.WithSelf.Default)] {} {} -// CHECK:STDOUT: %assoc1: %Modifiers.assoc_type = assoc_entity element1, %Modifiers.WithSelf.Default.decl [concrete = constants.%assoc1] -// CHECK:STDOUT: -// CHECK:STDOUT: !members: -// CHECK:STDOUT: .Self = %Self -// CHECK:STDOUT: .Final = @Modifiers.WithSelf.%assoc0 -// CHECK:STDOUT: .Default = @Modifiers.WithSelf.%assoc1 -// CHECK:STDOUT: witness = (@Modifiers.WithSelf.%Modifiers.WithSelf.Final.decl, @Modifiers.WithSelf.%Modifiers.WithSelf.Default.decl) -// CHECK:STDOUT: -// CHECK:STDOUT: !requires: -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @Modifiers.WithSelf.Final(@Modifiers.%Self: %Modifiers.type) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: -// CHECK:STDOUT: fn() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: generic fn @Modifiers.WithSelf.Default(@Modifiers.%Self: %Modifiers.type) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: -// CHECK:STDOUT: fn() { -// CHECK:STDOUT: !entry: -// CHECK:STDOUT: return -// CHECK:STDOUT: } -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @Modifiers.WithSelf(constants.%Self) { -// CHECK:STDOUT: !definition: -// CHECK:STDOUT: %Self => constants.%Self -// CHECK:STDOUT: %Modifiers.WithSelf.Final.type => constants.%Modifiers.WithSelf.Final.type -// CHECK:STDOUT: %Modifiers.WithSelf.Final => constants.%Modifiers.WithSelf.Final -// CHECK:STDOUT: %Modifiers.WithSelf.Default.type => constants.%Modifiers.WithSelf.Default.type -// CHECK:STDOUT: %Modifiers.WithSelf.Default => constants.%Modifiers.WithSelf.Default -// CHECK:STDOUT: } -// CHECK:STDOUT: -// CHECK:STDOUT: specific @Modifiers.WithSelf.Final(constants.%Self) {} -// CHECK:STDOUT: -// CHECK:STDOUT: specific @Modifiers.WithSelf.Default(constants.%Self) {} -// CHECK:STDOUT: diff --git a/toolchain/check/testdata/interface/modifiers.carbon b/toolchain/check/testdata/interface/modifiers.carbon new file mode 100644 index 000000000000..0d72a2de3b96 --- /dev/null +++ b/toolchain/check/testdata/interface/modifiers.carbon @@ -0,0 +1,1305 @@ +// 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-FILE: toolchain/testing/testdata/min_prelude/convert.carbon +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interface/modifiers.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interface/modifiers.carbon + +// --- default_interfaces.carbon + +library "[[@TEST_NAME]]"; + +//@dump-sem-ir-begin +interface DefaultFn { + default fn F() {} +} + +interface DefaultMethod { + default fn M(unused self) {} +} + +fn CallFn(generic d: DefaultFn) { + d.F(); +} + +fn CallMethod[T: DefaultMethod](t: T) { + t.M(); +} +//@dump-sem-ir-end + +// --- final_interfaces.carbon + +library "[[@TEST_NAME]]"; + +//@dump-sem-ir-begin +interface FinalFn { + final fn F() {} +} + +interface FinalMethod { + final fn M(unused self) {} +} + +fn CallFn(generic d: FinalFn) { + d.F(); +} + +fn CallMethod[T: FinalMethod](t: T) { + t.M(); +} +//@dump-sem-ir-end + +// --- default_function.carbon + +library "[[@TEST_NAME]]"; +import library "default_interfaces"; + +//@dump-sem-ir-begin +class C { + impl as DefaultFn {} +} + +fn F() { + CallFn(C); +} +//@dump-sem-ir-end + +// --- default_method.carbon + +library "[[@TEST_NAME]]"; +import library "default_interfaces"; + +//@dump-sem-ir-begin +class C { + impl as DefaultMethod {} +} + +fn F() { + let c: C = {}; + CallMethod(c); +} +//@dump-sem-ir-end + +// --- default_function_overridden.carbon + +library "[[@TEST_NAME]]"; +import library "default_interfaces"; + +//@dump-sem-ir-begin +class C { + fn G() { } + impl as DefaultFn { + fn F() { C.G(); } + } +} + +fn F() { + CallFn(C); +} +//@dump-sem-ir-end + +// --- default_method_overridden.carbon + +library "[[@TEST_NAME]]"; +import library "default_interfaces"; + +//@dump-sem-ir-begin +class C { + fn G(unused self) { } + impl as DefaultMethod { + fn M(self) { self.G(); } + } +} + +fn F() { + let c: C = {}; + CallMethod(c); +} +//@dump-sem-ir-end + +// --- final_function.carbon + +library "[[@TEST_NAME]]"; +import library "final_interfaces"; + +//@dump-sem-ir-begin +class C { + impl as FinalFn {} +} + +fn F() { + CallFn(C); +} +//@dump-sem-ir-end + +// --- final_method.carbon + +library "[[@TEST_NAME]]"; +import library "final_interfaces"; + +//@dump-sem-ir-begin +class C { + impl as FinalMethod {} +} + +fn F() { + let c: C = {}; + CallMethod(c); +} +//@dump-sem-ir-end + +// --- todo_fail_inline_definition_without_modifier.carbon + +interface I { + // TODO: diagnose non-default or non-final interface members with definitions. + fn F() {} +} + +// --- fail_todo_deferred_modifiers.carbon + +library "[[@TEST_NAME]]"; + +interface Modifiers { + // CHECK:STDERR: fail_todo_deferred_modifiers.carbon:[[@LINE+4]]:3: error: TODO: `default` modifier currently requires an inline definition [ModifierFinalRequiresDefaultImpl] + // CHECK:STDERR: default fn DefaultFunction(); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + default fn DefaultFunction(); + // CHECK:STDERR: fail_todo_deferred_modifiers.carbon:[[@LINE+4]]:3: error: TODO: `default` modifier currently requires an inline definition [ModifierFinalRequiresDefaultImpl] + // CHECK:STDERR: default fn DefaultMethod(self); + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + default fn DefaultMethod(self); + + // CHECK:STDERR: fail_todo_deferred_modifiers.carbon:[[@LINE+4]]:3: error: TODO: `final` modifier currently requires an inline definition [ModifierFinalRequiresDefaultImpl] + // CHECK:STDERR: final fn FinalFunction(); + // CHECK:STDERR: ^~~~~ + // CHECK:STDERR: + final fn FinalFunction(); + // CHECK:STDERR: fail_todo_deferred_modifiers.carbon:[[@LINE+4]]:3: error: TODO: `final` modifier currently requires an inline definition [ModifierFinalRequiresDefaultImpl] + // CHECK:STDERR: final fn FinalMethod(self); + // CHECK:STDERR: ^~~~~ + // CHECK:STDERR: + final fn FinalMethod(self); +} + +// --- fail_impl_final.carbon + +library "[[@TEST_NAME]]"; +import library "final_interfaces"; + +class C { + // CHECK:STDERR: fail_impl_final.carbon:[[@LINE+8]]:3: error: attempted to implement `M`, which is final in interface `FinalMethod` [ImplFinalFunction] + // CHECK:STDERR: impl as FinalMethod { + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_impl_final.carbon:[[@LINE-6]]:1: in import [InImport] + // CHECK:STDERR: final_interfaces.carbon:10:3: note: associated function M declared here [AssociatedFunctionHere] + // CHECK:STDERR: final fn M(unused self) {} + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + impl as FinalMethod { + fn M(unused self) { } + } +} + +// --- fail_modified_associated_constants.carbon + +library "[[@TEST_NAME]]"; + +interface C { + // CHECK:STDERR: fail_modified_associated_constants.carbon:[[@LINE+4]]:3: error: semantics TODO: `interface modifier` [SemanticsTodo] + // CHECK:STDERR: default let T: type = C; + // CHECK:STDERR: ^~~~~~~ + // CHECK:STDERR: + default let T: type = C; + // CHECK:STDERR: fail_modified_associated_constants.carbon:[[@LINE+4]]:3: error: semantics TODO: `interface modifier` [SemanticsTodo] + // CHECK:STDERR: final let U: type = C; + // CHECK:STDERR: ^~~~~ + // CHECK:STDERR: + final let U: type = C; +} + +// CHECK:STDOUT: --- default_interfaces.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %DefaultFn.type: type = facet_type <@DefaultFn> [concrete] +// CHECK:STDOUT: %Self.4f0: %DefaultFn.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %DefaultFn.WithSelf.F.type.99d: type = fn_type @DefaultFn.WithSelf.F, @DefaultFn.WithSelf(%Self.4f0) [symbolic] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %DefaultFn.WithSelf.F.71b: %DefaultFn.WithSelf.F.type.99d = struct_value () [symbolic] +// CHECK:STDOUT: %DefaultFn.assoc_type: type = assoc_entity_type @DefaultFn [concrete] +// CHECK:STDOUT: %assoc0.251: %DefaultFn.assoc_type = assoc_entity element0, @DefaultFn.WithSelf.%DefaultFn.WithSelf.F.decl [concrete] +// CHECK:STDOUT: %DefaultMethod.type: type = facet_type <@DefaultMethod> [concrete] +// CHECK:STDOUT: %Self.be0: %DefaultMethod.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.be0 [symbolic] +// CHECK:STDOUT: %pattern_type.671: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %self.param_patt.b05: %pattern_type.671 = value_param_pattern [symbolic] +// CHECK:STDOUT: %self.patt.153: %pattern_type.671 = at_binding_pattern self, %self.param_patt.b05 [symbolic] +// CHECK:STDOUT: %DefaultMethod.WithSelf.M.type.5c3: type = fn_type @DefaultMethod.WithSelf.M, @DefaultMethod.WithSelf(%Self.be0) [symbolic] +// CHECK:STDOUT: %DefaultMethod.WithSelf.M.ff1: %DefaultMethod.WithSelf.M.type.5c3 = struct_value () [symbolic] +// CHECK:STDOUT: %DefaultMethod.assoc_type: type = assoc_entity_type @DefaultMethod [concrete] +// CHECK:STDOUT: %assoc0.a0f: %DefaultMethod.assoc_type = assoc_entity element0, @DefaultMethod.WithSelf.%DefaultMethod.WithSelf.M.decl [concrete] +// CHECK:STDOUT: %require_complete.09c: = require_complete_type %Self.as_type [symbolic] +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %pattern_type.8dc: type = pattern_type %DefaultFn.type [concrete] +// CHECK:STDOUT: %d.patt: %pattern_type.8dc = symbolic_binding_pattern d, 0 [symbolic] +// CHECK:STDOUT: %d: %DefaultFn.type = symbolic_binding d, 0 [symbolic] +// CHECK:STDOUT: %CallFn.type: type = fn_type @CallFn [concrete] +// CHECK:STDOUT: %CallFn: %CallFn.type = struct_value () [concrete] +// CHECK:STDOUT: %DefaultFn.WithSelf.F.type.0f7: type = fn_type @DefaultFn.WithSelf.F, @DefaultFn.WithSelf(%d) [symbolic] +// CHECK:STDOUT: %DefaultFn.WithSelf.F.6f2: %DefaultFn.WithSelf.F.type.0f7 = struct_value () [symbolic] +// CHECK:STDOUT: %d.as_type: type = facet_access_type %d [symbolic] +// CHECK:STDOUT: %DefaultFn.lookup_impl_witness: = lookup_impl_witness %d, @DefaultFn [symbolic] +// CHECK:STDOUT: %.2c3: type = fn_type_with_self_type %DefaultFn.WithSelf.F.type.0f7, %d [symbolic] +// CHECK:STDOUT: %impl.elem0.f87: %.2c3 = impl_witness_access %DefaultFn.lookup_impl_witness, element0 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.ba2: = specific_impl_function %impl.elem0.f87, @DefaultFn.WithSelf.F(%d) [symbolic] +// CHECK:STDOUT: %pattern_type.336: type = pattern_type %DefaultMethod.type [concrete] +// CHECK:STDOUT: %T.patt: %pattern_type.336 = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %T: %DefaultMethod.type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T [symbolic] +// CHECK:STDOUT: %pattern_type.70f: type = pattern_type %T.as_type [symbolic] +// CHECK:STDOUT: %t.param_patt: %pattern_type.70f = value_param_pattern [symbolic] +// CHECK:STDOUT: %t.patt: %pattern_type.70f = at_binding_pattern t, %t.param_patt [symbolic] +// CHECK:STDOUT: %CallMethod.type: type = fn_type @CallMethod [concrete] +// CHECK:STDOUT: %CallMethod: %CallMethod.type = struct_value () [concrete] +// CHECK:STDOUT: %require_complete.5bd: = require_complete_type %T.as_type [symbolic] +// CHECK:STDOUT: %DefaultMethod.WithSelf.M.type.0cf: type = fn_type @DefaultMethod.WithSelf.M, @DefaultMethod.WithSelf(%T) [symbolic] +// CHECK:STDOUT: %DefaultMethod.WithSelf.M.091: %DefaultMethod.WithSelf.M.type.0cf = struct_value () [symbolic] +// CHECK:STDOUT: %DefaultMethod.lookup_impl_witness: = lookup_impl_witness %T, @DefaultMethod [symbolic] +// CHECK:STDOUT: %.506: type = fn_type_with_self_type %DefaultMethod.WithSelf.M.type.0cf, %T [symbolic] +// CHECK:STDOUT: %impl.elem0.f26: %.506 = impl_witness_access %DefaultMethod.lookup_impl_witness, element0 [symbolic] +// CHECK:STDOUT: %self.param_patt.382: %pattern_type.70f = value_param_pattern [symbolic] +// CHECK:STDOUT: %self.patt.634: %pattern_type.70f = at_binding_pattern self, %self.param_patt.382 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.583: = specific_impl_function %impl.elem0.f26, @DefaultMethod.WithSelf.M(%T) [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: %DefaultFn.decl: type = interface_decl @DefaultFn [concrete = constants.%DefaultFn.type] {} {} +// CHECK:STDOUT: %DefaultMethod.decl: type = interface_decl @DefaultMethod [concrete = constants.%DefaultMethod.type] {} {} +// CHECK:STDOUT: %CallFn.decl: %CallFn.type = fn_decl @CallFn [concrete = constants.%CallFn] { +// CHECK:STDOUT: %d.patt.loc13_20.1: %pattern_type.8dc = symbolic_binding_pattern d, 0 [symbolic = %d.patt.loc13_20.2 (constants.%d.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc13: type = splice_block %DefaultFn.ref [concrete = constants.%DefaultFn.type] { +// CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen] +// CHECK:STDOUT: %DefaultFn.ref: type = name_ref DefaultFn, file.%DefaultFn.decl [concrete = constants.%DefaultFn.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %d.loc13_20.2: %DefaultFn.type = symbolic_binding d, 0 [symbolic = %d.loc13_20.1 (constants.%d)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %CallMethod.decl: %CallMethod.type = fn_decl @CallMethod [concrete = constants.%CallMethod] { +// CHECK:STDOUT: %T.patt.loc17_16.1: %pattern_type.336 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc17_16.2 (constants.%T.patt)] +// CHECK:STDOUT: %t.param_patt.loc17_34.1: @CallMethod.%pattern_type (%pattern_type.70f) = value_param_pattern [symbolic = %t.param_patt.loc17_34.2 (constants.%t.param_patt)] +// CHECK:STDOUT: %t.patt.loc17_34.1: @CallMethod.%pattern_type (%pattern_type.70f) = at_binding_pattern t, %t.param_patt.loc17_34.1 [symbolic = %t.patt.loc17_34.2 (constants.%t.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc17_18: type = splice_block %DefaultMethod.ref [concrete = constants.%DefaultMethod.type] { +// CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen] +// CHECK:STDOUT: %DefaultMethod.ref: type = name_ref DefaultMethod, file.%DefaultMethod.decl [concrete = constants.%DefaultMethod.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.loc17_16.2: %DefaultMethod.type = symbolic_binding T, 0 [symbolic = %T.loc17_16.1 (constants.%T)] +// CHECK:STDOUT: %t.param: @CallMethod.%T.as_type.loc17_36.1 (%T.as_type) = value_param call_param0 +// CHECK:STDOUT: %.loc17_36.1: type = splice_block %.loc17_36.2 [symbolic = %T.as_type.loc17_36.1 (constants.%T.as_type)] { +// CHECK:STDOUT: %T.ref: %DefaultMethod.type = name_ref T, %T.loc17_16.2 [symbolic = %T.loc17_16.1 (constants.%T)] +// CHECK:STDOUT: %T.as_type.loc17_36.2: type = facet_access_type %T.ref [symbolic = %T.as_type.loc17_36.1 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc17_36.2: type = converted %T.ref, %T.as_type.loc17_36.2 [symbolic = %T.as_type.loc17_36.1 (constants.%T.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %t: @CallMethod.%T.as_type.loc17_36.1 (%T.as_type) = wrapper_binding t, %t.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @DefaultFn { +// CHECK:STDOUT: %Self: %DefaultFn.type = symbolic_binding Self, 0 [symbolic = constants.%Self.4f0] +// CHECK:STDOUT: %DefaultFn.WithSelf.decl = interface_with_self_decl @DefaultFn [concrete] +// CHECK:STDOUT: +// CHECK:STDOUT: !with Self: +// CHECK:STDOUT: %DefaultFn.WithSelf.F.decl: @DefaultFn.WithSelf.%DefaultFn.WithSelf.F.type (%DefaultFn.WithSelf.F.type.99d) = fn_decl @DefaultFn.WithSelf.F [symbolic = @DefaultFn.WithSelf.%DefaultFn.WithSelf.F (constants.%DefaultFn.WithSelf.F.71b)] {} {} +// CHECK:STDOUT: %assoc0: %DefaultFn.assoc_type = assoc_entity element0, %DefaultFn.WithSelf.F.decl [concrete = constants.%assoc0.251] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .F = @DefaultFn.WithSelf.%assoc0 +// CHECK:STDOUT: witness = (@DefaultFn.WithSelf.%DefaultFn.WithSelf.F.decl) +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @DefaultMethod { +// CHECK:STDOUT: %Self: %DefaultMethod.type = symbolic_binding Self, 0 [symbolic = constants.%Self.be0] +// CHECK:STDOUT: %DefaultMethod.WithSelf.decl = interface_with_self_decl @DefaultMethod [concrete] +// CHECK:STDOUT: +// CHECK:STDOUT: !with Self: +// CHECK:STDOUT: %DefaultMethod.WithSelf.M.decl: @DefaultMethod.WithSelf.%DefaultMethod.WithSelf.M.type (%DefaultMethod.WithSelf.M.type.5c3) = fn_decl @DefaultMethod.WithSelf.M [symbolic = @DefaultMethod.WithSelf.%DefaultMethod.WithSelf.M (constants.%DefaultMethod.WithSelf.M.ff1)] { +// CHECK:STDOUT: %self.param_patt.loc10_23.1: @DefaultMethod.WithSelf.M.%pattern_type (%pattern_type.671) = value_param_pattern [symbolic = %self.param_patt.loc10_23.2 (constants.%self.param_patt.b05)] +// CHECK:STDOUT: %self.patt.loc10_23.1: @DefaultMethod.WithSelf.M.%pattern_type (%pattern_type.671) = at_binding_pattern self, %self.param_patt.loc10_23.1 [symbolic = %self.patt.loc10_23.2 (constants.%self.patt.153)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @DefaultMethod.WithSelf.M.%Self.as_type.loc10_23.1 (%Self.as_type) = value_param call_param0 +// CHECK:STDOUT: %.loc10_23.1: type = splice_block %.loc10_23.2 [symbolic = %Self.as_type.loc10_23.1 (constants.%Self.as_type)] { +// CHECK:STDOUT: %Self.ref: %DefaultMethod.type = name_ref Self, @DefaultMethod.%Self [symbolic = %Self (constants.%Self.be0)] +// CHECK:STDOUT: %Self.as_type.loc10_23.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc10_23.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %.loc10_23.2: type = converted %Self.ref, %Self.as_type.loc10_23.2 [symbolic = %Self.as_type.loc10_23.1 (constants.%Self.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @DefaultMethod.WithSelf.M.%Self.as_type.loc10_23.1 (%Self.as_type) = wrapper_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc0: %DefaultMethod.assoc_type = assoc_entity element0, %DefaultMethod.WithSelf.M.decl [concrete = constants.%assoc0.a0f] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .M = @DefaultMethod.WithSelf.%assoc0 +// CHECK:STDOUT: witness = (@DefaultMethod.WithSelf.%DefaultMethod.WithSelf.M.decl) +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @DefaultFn.WithSelf.F(@DefaultFn.%Self: %DefaultFn.type) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @DefaultMethod.WithSelf.M(@DefaultMethod.%Self: %DefaultMethod.type) { +// CHECK:STDOUT: %Self: %DefaultMethod.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self.be0)] +// CHECK:STDOUT: %Self.as_type.loc10_23.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc10_23.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %Self.as_type.loc10_23.1 [symbolic = %pattern_type (constants.%pattern_type.671)] +// CHECK:STDOUT: %self.param_patt.loc10_23.2: @DefaultMethod.WithSelf.M.%pattern_type (%pattern_type.671) = value_param_pattern [symbolic = %self.param_patt.loc10_23.2 (constants.%self.param_patt.b05)] +// CHECK:STDOUT: %self.patt.loc10_23.2: @DefaultMethod.WithSelf.M.%pattern_type (%pattern_type.671) = at_binding_pattern self, %self.param_patt.loc10_23.2 [symbolic = %self.patt.loc10_23.2 (constants.%self.patt.153)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type %Self.as_type.loc10_23.1 [symbolic = %require_complete (constants.%require_complete.09c)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @DefaultMethod.WithSelf.M.%Self.as_type.loc10_23.1 (%Self.as_type)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @CallFn(%d.loc13_20.2: %DefaultFn.type) { +// CHECK:STDOUT: %d.patt.loc13_20.2: %pattern_type.8dc = symbolic_binding_pattern d, 0 [symbolic = %d.patt.loc13_20.2 (constants.%d.patt)] +// CHECK:STDOUT: %d.loc13_20.1: %DefaultFn.type = symbolic_binding d, 0 [symbolic = %d.loc13_20.1 (constants.%d)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %d.as_type.loc14_4.2: type = facet_access_type %d.loc13_20.1 [symbolic = %d.as_type.loc14_4.2 (constants.%d.as_type)] +// CHECK:STDOUT: %DefaultFn.WithSelf.F.type: type = fn_type @DefaultFn.WithSelf.F, @DefaultFn.WithSelf(%d.loc13_20.1) [symbolic = %DefaultFn.WithSelf.F.type (constants.%DefaultFn.WithSelf.F.type.0f7)] +// CHECK:STDOUT: %.loc14_4.2: type = fn_type_with_self_type %DefaultFn.WithSelf.F.type, %d.loc13_20.1 [symbolic = %.loc14_4.2 (constants.%.2c3)] +// CHECK:STDOUT: %DefaultFn.lookup_impl_witness: = lookup_impl_witness %d.loc13_20.1, @DefaultFn [symbolic = %DefaultFn.lookup_impl_witness (constants.%DefaultFn.lookup_impl_witness)] +// CHECK:STDOUT: %impl.elem0.loc14_4.2: @CallFn.%.loc14_4.2 (%.2c3) = impl_witness_access %DefaultFn.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc14_4.2 (constants.%impl.elem0.f87)] +// CHECK:STDOUT: %specific_impl_fn.loc14_4.2: = specific_impl_function %impl.elem0.loc14_4.2, @DefaultFn.WithSelf.F(%d.loc13_20.1) [symbolic = %specific_impl_fn.loc14_4.2 (constants.%specific_impl_fn.ba2)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %d.ref: %DefaultFn.type = name_ref d, %d.loc13_20.2 [symbolic = %d.loc13_20.1 (constants.%d)] +// CHECK:STDOUT: %d.as_type.loc14_4.1: type = facet_access_type %d.ref [symbolic = %d.as_type.loc14_4.2 (constants.%d.as_type)] +// CHECK:STDOUT: %.loc14_4.1: type = converted %d.ref, %d.as_type.loc14_4.1 [symbolic = %d.as_type.loc14_4.2 (constants.%d.as_type)] +// CHECK:STDOUT: %F.ref: %DefaultFn.assoc_type = name_ref F, @DefaultFn.WithSelf.%assoc0 [concrete = constants.%assoc0.251] +// CHECK:STDOUT: %impl.elem0.loc14_4.1: @CallFn.%.loc14_4.2 (%.2c3) = impl_witness_access constants.%DefaultFn.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc14_4.2 (constants.%impl.elem0.f87)] +// CHECK:STDOUT: %specific_impl_fn.loc14_4.1: = specific_impl_function %impl.elem0.loc14_4.1, @DefaultFn.WithSelf.F(constants.%d) [symbolic = %specific_impl_fn.loc14_4.2 (constants.%specific_impl_fn.ba2)] +// CHECK:STDOUT: %DefaultFn.WithSelf.F.call: init %empty_tuple.type = call %specific_impl_fn.loc14_4.1() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @CallMethod(%T.loc17_16.2: %DefaultMethod.type) { +// CHECK:STDOUT: %T.patt.loc17_16.2: %pattern_type.336 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc17_16.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.loc17_16.1: %DefaultMethod.type = symbolic_binding T, 0 [symbolic = %T.loc17_16.1 (constants.%T)] +// CHECK:STDOUT: %T.as_type.loc17_36.1: type = facet_access_type %T.loc17_16.1 [symbolic = %T.as_type.loc17_36.1 (constants.%T.as_type)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %T.as_type.loc17_36.1 [symbolic = %pattern_type (constants.%pattern_type.70f)] +// CHECK:STDOUT: %t.param_patt.loc17_34.2: @CallMethod.%pattern_type (%pattern_type.70f) = value_param_pattern [symbolic = %t.param_patt.loc17_34.2 (constants.%t.param_patt)] +// CHECK:STDOUT: %t.patt.loc17_34.2: @CallMethod.%pattern_type (%pattern_type.70f) = at_binding_pattern t, %t.param_patt.loc17_34.2 [symbolic = %t.patt.loc17_34.2 (constants.%t.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type %T.as_type.loc17_36.1 [symbolic = %require_complete (constants.%require_complete.5bd)] +// CHECK:STDOUT: %DefaultMethod.WithSelf.M.type: type = fn_type @DefaultMethod.WithSelf.M, @DefaultMethod.WithSelf(%T.loc17_16.1) [symbolic = %DefaultMethod.WithSelf.M.type (constants.%DefaultMethod.WithSelf.M.type.0cf)] +// CHECK:STDOUT: %.loc18_4: type = fn_type_with_self_type %DefaultMethod.WithSelf.M.type, %T.loc17_16.1 [symbolic = %.loc18_4 (constants.%.506)] +// CHECK:STDOUT: %DefaultMethod.lookup_impl_witness: = lookup_impl_witness %T.loc17_16.1, @DefaultMethod [symbolic = %DefaultMethod.lookup_impl_witness (constants.%DefaultMethod.lookup_impl_witness)] +// CHECK:STDOUT: %impl.elem0.loc18_4.2: @CallMethod.%.loc18_4 (%.506) = impl_witness_access %DefaultMethod.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0.f26)] +// CHECK:STDOUT: %specific_impl_fn.loc18_4.2: = specific_impl_function %impl.elem0.loc18_4.2, @DefaultMethod.WithSelf.M(%T.loc17_16.1) [symbolic = %specific_impl_fn.loc18_4.2 (constants.%specific_impl_fn.583)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%t.param: @CallMethod.%T.as_type.loc17_36.1 (%T.as_type)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %t.ref: @CallMethod.%T.as_type.loc17_36.1 (%T.as_type) = name_ref t, %t +// CHECK:STDOUT: %M.ref: %DefaultMethod.assoc_type = name_ref M, @DefaultMethod.WithSelf.%assoc0 [concrete = constants.%assoc0.a0f] +// CHECK:STDOUT: %impl.elem0.loc18_4.1: @CallMethod.%.loc18_4 (%.506) = impl_witness_access constants.%DefaultMethod.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0.f26)] +// CHECK:STDOUT: %bound_method.loc18_4: = bound_method %t.ref, %impl.elem0.loc18_4.1 +// CHECK:STDOUT: %.loc18_7.1: %DefaultMethod.type = converted constants.%T.as_type, constants.%T [symbolic = %T.loc17_16.1 (constants.%T)] +// CHECK:STDOUT: %.loc18_7.2: %DefaultMethod.type = converted constants.%T.as_type, constants.%T [symbolic = %T.loc17_16.1 (constants.%T)] +// CHECK:STDOUT: %specific_impl_fn.loc18_4.1: = specific_impl_function %impl.elem0.loc18_4.1, @DefaultMethod.WithSelf.M(constants.%T) [symbolic = %specific_impl_fn.loc18_4.2 (constants.%specific_impl_fn.583)] +// CHECK:STDOUT: %bound_method.loc18_7: = bound_method %t.ref, %specific_impl_fn.loc18_4.1 +// CHECK:STDOUT: %DefaultMethod.WithSelf.M.call: init %empty_tuple.type = call %bound_method.loc18_7(%t.ref) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @DefaultFn.WithSelf(constants.%Self.4f0) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Self => constants.%Self.4f0 +// CHECK:STDOUT: %DefaultFn.WithSelf.F.type => constants.%DefaultFn.WithSelf.F.type.99d +// CHECK:STDOUT: %DefaultFn.WithSelf.F => constants.%DefaultFn.WithSelf.F.71b +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @DefaultFn.WithSelf.F(constants.%Self.4f0) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @DefaultMethod.WithSelf(constants.%Self.be0) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Self => constants.%Self.be0 +// CHECK:STDOUT: %DefaultMethod.WithSelf.M.type => constants.%DefaultMethod.WithSelf.M.type.5c3 +// CHECK:STDOUT: %DefaultMethod.WithSelf.M => constants.%DefaultMethod.WithSelf.M.ff1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @DefaultMethod.WithSelf.M(constants.%Self.be0) { +// CHECK:STDOUT: %Self => constants.%Self.be0 +// CHECK:STDOUT: %Self.as_type.loc10_23.1 => constants.%Self.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.671 +// CHECK:STDOUT: %self.param_patt.loc10_23.2 => constants.%self.param_patt.b05 +// CHECK:STDOUT: %self.patt.loc10_23.2 => constants.%self.patt.153 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CallFn(constants.%d) { +// CHECK:STDOUT: %d.patt.loc13_20.2 => constants.%d.patt +// CHECK:STDOUT: %d.loc13_20.1 => constants.%d +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @DefaultFn.WithSelf(constants.%d) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Self => constants.%d +// CHECK:STDOUT: %DefaultFn.WithSelf.F.type => constants.%DefaultFn.WithSelf.F.type.0f7 +// CHECK:STDOUT: %DefaultFn.WithSelf.F => constants.%DefaultFn.WithSelf.F.6f2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @DefaultFn.WithSelf.F(constants.%d) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CallMethod(constants.%T) { +// CHECK:STDOUT: %T.patt.loc17_16.2 => constants.%T.patt +// CHECK:STDOUT: %T.loc17_16.1 => constants.%T +// CHECK:STDOUT: %T.as_type.loc17_36.1 => constants.%T.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.70f +// CHECK:STDOUT: %t.param_patt.loc17_34.2 => constants.%t.param_patt +// CHECK:STDOUT: %t.patt.loc17_34.2 => constants.%t.patt +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @DefaultMethod.WithSelf(constants.%T) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Self => constants.%T +// CHECK:STDOUT: %DefaultMethod.WithSelf.M.type => constants.%DefaultMethod.WithSelf.M.type.0cf +// CHECK:STDOUT: %DefaultMethod.WithSelf.M => constants.%DefaultMethod.WithSelf.M.091 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @DefaultMethod.WithSelf.M(constants.%T) { +// CHECK:STDOUT: %Self => constants.%T +// CHECK:STDOUT: %Self.as_type.loc10_23.1 => constants.%T.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.70f +// CHECK:STDOUT: %self.param_patt.loc10_23.2 => constants.%self.param_patt.382 +// CHECK:STDOUT: %self.patt.loc10_23.2 => constants.%self.patt.634 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- final_interfaces.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %FinalFn.type: type = facet_type <@FinalFn> [concrete] +// CHECK:STDOUT: %Self.49e: %FinalFn.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %FinalFn.WithSelf.F.type.2c0: type = fn_type @FinalFn.WithSelf.F, @FinalFn.WithSelf(%Self.49e) [symbolic] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %FinalFn.WithSelf.F.744: %FinalFn.WithSelf.F.type.2c0 = struct_value () [symbolic] +// CHECK:STDOUT: %FinalFn.assoc_type: type = assoc_entity_type @FinalFn [concrete] +// CHECK:STDOUT: %assoc0.d6c: %FinalFn.assoc_type = assoc_entity element0, @FinalFn.WithSelf.%FinalFn.WithSelf.F.decl [concrete] +// CHECK:STDOUT: %FinalMethod.type: type = facet_type <@FinalMethod> [concrete] +// CHECK:STDOUT: %Self.e80: %FinalMethod.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.e80 [symbolic] +// CHECK:STDOUT: %pattern_type.32b: type = pattern_type %Self.as_type [symbolic] +// CHECK:STDOUT: %self.param_patt.724: %pattern_type.32b = value_param_pattern [symbolic] +// CHECK:STDOUT: %self.patt.478: %pattern_type.32b = at_binding_pattern self, %self.param_patt.724 [symbolic] +// CHECK:STDOUT: %FinalMethod.WithSelf.M.type.efa: type = fn_type @FinalMethod.WithSelf.M, @FinalMethod.WithSelf(%Self.e80) [symbolic] +// CHECK:STDOUT: %FinalMethod.WithSelf.M.68b: %FinalMethod.WithSelf.M.type.efa = struct_value () [symbolic] +// CHECK:STDOUT: %FinalMethod.assoc_type: type = assoc_entity_type @FinalMethod [concrete] +// CHECK:STDOUT: %assoc0.e67: %FinalMethod.assoc_type = assoc_entity element0, @FinalMethod.WithSelf.%FinalMethod.WithSelf.M.decl [concrete] +// CHECK:STDOUT: %require_complete.e87: = require_complete_type %Self.as_type [symbolic] +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %pattern_type.778: type = pattern_type %FinalFn.type [concrete] +// CHECK:STDOUT: %d.patt: %pattern_type.778 = symbolic_binding_pattern d, 0 [symbolic] +// CHECK:STDOUT: %d: %FinalFn.type = symbolic_binding d, 0 [symbolic] +// CHECK:STDOUT: %CallFn.type: type = fn_type @CallFn [concrete] +// CHECK:STDOUT: %CallFn: %CallFn.type = struct_value () [concrete] +// CHECK:STDOUT: %FinalFn.WithSelf.F.type.94e: type = fn_type @FinalFn.WithSelf.F, @FinalFn.WithSelf(%d) [symbolic] +// CHECK:STDOUT: %FinalFn.WithSelf.F.219: %FinalFn.WithSelf.F.type.94e = struct_value () [symbolic] +// CHECK:STDOUT: %d.as_type: type = facet_access_type %d [symbolic] +// CHECK:STDOUT: %FinalFn.lookup_impl_witness: = lookup_impl_witness %d, @FinalFn [symbolic] +// CHECK:STDOUT: %.ec4: type = fn_type_with_self_type %FinalFn.WithSelf.F.type.94e, %d [symbolic] +// CHECK:STDOUT: %impl.elem0.9ab: %.ec4 = impl_witness_access %FinalFn.lookup_impl_witness, element0 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.e4e: = specific_impl_function %impl.elem0.9ab, @FinalFn.WithSelf.F(%d) [symbolic] +// CHECK:STDOUT: %pattern_type.af4: type = pattern_type %FinalMethod.type [concrete] +// CHECK:STDOUT: %T.patt: %pattern_type.af4 = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %T: %FinalMethod.type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T [symbolic] +// CHECK:STDOUT: %pattern_type.ab8: type = pattern_type %T.as_type [symbolic] +// CHECK:STDOUT: %t.param_patt: %pattern_type.ab8 = value_param_pattern [symbolic] +// CHECK:STDOUT: %t.patt: %pattern_type.ab8 = at_binding_pattern t, %t.param_patt [symbolic] +// CHECK:STDOUT: %CallMethod.type: type = fn_type @CallMethod [concrete] +// CHECK:STDOUT: %CallMethod: %CallMethod.type = struct_value () [concrete] +// CHECK:STDOUT: %require_complete.3b2: = require_complete_type %T.as_type [symbolic] +// CHECK:STDOUT: %FinalMethod.WithSelf.M.type.913: type = fn_type @FinalMethod.WithSelf.M, @FinalMethod.WithSelf(%T) [symbolic] +// CHECK:STDOUT: %FinalMethod.WithSelf.M.4c6: %FinalMethod.WithSelf.M.type.913 = struct_value () [symbolic] +// CHECK:STDOUT: %FinalMethod.lookup_impl_witness: = lookup_impl_witness %T, @FinalMethod [symbolic] +// CHECK:STDOUT: %.e9f: type = fn_type_with_self_type %FinalMethod.WithSelf.M.type.913, %T [symbolic] +// CHECK:STDOUT: %impl.elem0.24d: %.e9f = impl_witness_access %FinalMethod.lookup_impl_witness, element0 [symbolic] +// CHECK:STDOUT: %self.param_patt.4d4: %pattern_type.ab8 = value_param_pattern [symbolic] +// CHECK:STDOUT: %self.patt.87d: %pattern_type.ab8 = at_binding_pattern self, %self.param_patt.4d4 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.2e2: = specific_impl_function %impl.elem0.24d, @FinalMethod.WithSelf.M(%T) [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: %FinalFn.decl: type = interface_decl @FinalFn [concrete = constants.%FinalFn.type] {} {} +// CHECK:STDOUT: %FinalMethod.decl: type = interface_decl @FinalMethod [concrete = constants.%FinalMethod.type] {} {} +// CHECK:STDOUT: %CallFn.decl: %CallFn.type = fn_decl @CallFn [concrete = constants.%CallFn] { +// CHECK:STDOUT: %d.patt.loc13_20.1: %pattern_type.778 = symbolic_binding_pattern d, 0 [symbolic = %d.patt.loc13_20.2 (constants.%d.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc13: type = splice_block %FinalFn.ref [concrete = constants.%FinalFn.type] { +// CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen] +// CHECK:STDOUT: %FinalFn.ref: type = name_ref FinalFn, file.%FinalFn.decl [concrete = constants.%FinalFn.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %d.loc13_20.2: %FinalFn.type = symbolic_binding d, 0 [symbolic = %d.loc13_20.1 (constants.%d)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %CallMethod.decl: %CallMethod.type = fn_decl @CallMethod [concrete = constants.%CallMethod] { +// CHECK:STDOUT: %T.patt.loc17_16.1: %pattern_type.af4 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc17_16.2 (constants.%T.patt)] +// CHECK:STDOUT: %t.param_patt.loc17_32.1: @CallMethod.%pattern_type (%pattern_type.ab8) = value_param_pattern [symbolic = %t.param_patt.loc17_32.2 (constants.%t.param_patt)] +// CHECK:STDOUT: %t.patt.loc17_32.1: @CallMethod.%pattern_type (%pattern_type.ab8) = at_binding_pattern t, %t.param_patt.loc17_32.1 [symbolic = %t.patt.loc17_32.2 (constants.%t.patt)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc17_18: type = splice_block %FinalMethod.ref [concrete = constants.%FinalMethod.type] { +// CHECK:STDOUT: %.Self.frozen: %type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen] +// CHECK:STDOUT: %FinalMethod.ref: type = name_ref FinalMethod, file.%FinalMethod.decl [concrete = constants.%FinalMethod.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.loc17_16.2: %FinalMethod.type = symbolic_binding T, 0 [symbolic = %T.loc17_16.1 (constants.%T)] +// CHECK:STDOUT: %t.param: @CallMethod.%T.as_type.loc17_34.1 (%T.as_type) = value_param call_param0 +// CHECK:STDOUT: %.loc17_34.1: type = splice_block %.loc17_34.2 [symbolic = %T.as_type.loc17_34.1 (constants.%T.as_type)] { +// CHECK:STDOUT: %T.ref: %FinalMethod.type = name_ref T, %T.loc17_16.2 [symbolic = %T.loc17_16.1 (constants.%T)] +// CHECK:STDOUT: %T.as_type.loc17_34.2: type = facet_access_type %T.ref [symbolic = %T.as_type.loc17_34.1 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc17_34.2: type = converted %T.ref, %T.as_type.loc17_34.2 [symbolic = %T.as_type.loc17_34.1 (constants.%T.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %t: @CallMethod.%T.as_type.loc17_34.1 (%T.as_type) = wrapper_binding t, %t.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @FinalFn { +// CHECK:STDOUT: %Self: %FinalFn.type = symbolic_binding Self, 0 [symbolic = constants.%Self.49e] +// CHECK:STDOUT: %FinalFn.WithSelf.decl = interface_with_self_decl @FinalFn [concrete] +// CHECK:STDOUT: +// CHECK:STDOUT: !with Self: +// CHECK:STDOUT: %FinalFn.WithSelf.F.decl: @FinalFn.WithSelf.%FinalFn.WithSelf.F.type (%FinalFn.WithSelf.F.type.2c0) = fn_decl @FinalFn.WithSelf.F [symbolic = @FinalFn.WithSelf.%FinalFn.WithSelf.F (constants.%FinalFn.WithSelf.F.744)] {} {} +// CHECK:STDOUT: %assoc0: %FinalFn.assoc_type = assoc_entity element0, %FinalFn.WithSelf.F.decl [concrete = constants.%assoc0.d6c] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .F = @FinalFn.WithSelf.%assoc0 +// CHECK:STDOUT: witness = (@FinalFn.WithSelf.%FinalFn.WithSelf.F.decl) +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @FinalMethod { +// CHECK:STDOUT: %Self: %FinalMethod.type = symbolic_binding Self, 0 [symbolic = constants.%Self.e80] +// CHECK:STDOUT: %FinalMethod.WithSelf.decl = interface_with_self_decl @FinalMethod [concrete] +// CHECK:STDOUT: +// CHECK:STDOUT: !with Self: +// CHECK:STDOUT: %FinalMethod.WithSelf.M.decl: @FinalMethod.WithSelf.%FinalMethod.WithSelf.M.type (%FinalMethod.WithSelf.M.type.efa) = fn_decl @FinalMethod.WithSelf.M [symbolic = @FinalMethod.WithSelf.%FinalMethod.WithSelf.M (constants.%FinalMethod.WithSelf.M.68b)] { +// CHECK:STDOUT: %self.param_patt.loc10_21.1: @FinalMethod.WithSelf.M.%pattern_type (%pattern_type.32b) = value_param_pattern [symbolic = %self.param_patt.loc10_21.2 (constants.%self.param_patt.724)] +// CHECK:STDOUT: %self.patt.loc10_21.1: @FinalMethod.WithSelf.M.%pattern_type (%pattern_type.32b) = at_binding_pattern self, %self.param_patt.loc10_21.1 [symbolic = %self.patt.loc10_21.2 (constants.%self.patt.478)] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @FinalMethod.WithSelf.M.%Self.as_type.loc10_21.1 (%Self.as_type) = value_param call_param0 +// CHECK:STDOUT: %.loc10_21.1: type = splice_block %.loc10_21.2 [symbolic = %Self.as_type.loc10_21.1 (constants.%Self.as_type)] { +// CHECK:STDOUT: %Self.ref: %FinalMethod.type = name_ref Self, @FinalMethod.%Self [symbolic = %Self (constants.%Self.e80)] +// CHECK:STDOUT: %Self.as_type.loc10_21.2: type = facet_access_type %Self.ref [symbolic = %Self.as_type.loc10_21.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %.loc10_21.2: type = converted %Self.ref, %Self.as_type.loc10_21.2 [symbolic = %Self.as_type.loc10_21.1 (constants.%Self.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @FinalMethod.WithSelf.M.%Self.as_type.loc10_21.1 (%Self.as_type) = wrapper_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc0: %FinalMethod.assoc_type = assoc_entity element0, %FinalMethod.WithSelf.M.decl [concrete = constants.%assoc0.e67] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .M = @FinalMethod.WithSelf.%assoc0 +// CHECK:STDOUT: witness = (@FinalMethod.WithSelf.%FinalMethod.WithSelf.M.decl) +// CHECK:STDOUT: +// CHECK:STDOUT: !requires: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @FinalFn.WithSelf.F(@FinalFn.%Self: %FinalFn.type) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @FinalMethod.WithSelf.M(@FinalMethod.%Self: %FinalMethod.type) { +// CHECK:STDOUT: %Self: %FinalMethod.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self.e80)] +// CHECK:STDOUT: %Self.as_type.loc10_21.1: type = facet_access_type %Self [symbolic = %Self.as_type.loc10_21.1 (constants.%Self.as_type)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %Self.as_type.loc10_21.1 [symbolic = %pattern_type (constants.%pattern_type.32b)] +// CHECK:STDOUT: %self.param_patt.loc10_21.2: @FinalMethod.WithSelf.M.%pattern_type (%pattern_type.32b) = value_param_pattern [symbolic = %self.param_patt.loc10_21.2 (constants.%self.param_patt.724)] +// CHECK:STDOUT: %self.patt.loc10_21.2: @FinalMethod.WithSelf.M.%pattern_type (%pattern_type.32b) = at_binding_pattern self, %self.param_patt.loc10_21.2 [symbolic = %self.patt.loc10_21.2 (constants.%self.patt.478)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type %Self.as_type.loc10_21.1 [symbolic = %require_complete (constants.%require_complete.e87)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @FinalMethod.WithSelf.M.%Self.as_type.loc10_21.1 (%Self.as_type)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @CallFn(%d.loc13_20.2: %FinalFn.type) { +// CHECK:STDOUT: %d.patt.loc13_20.2: %pattern_type.778 = symbolic_binding_pattern d, 0 [symbolic = %d.patt.loc13_20.2 (constants.%d.patt)] +// CHECK:STDOUT: %d.loc13_20.1: %FinalFn.type = symbolic_binding d, 0 [symbolic = %d.loc13_20.1 (constants.%d)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %d.as_type.loc14_4.2: type = facet_access_type %d.loc13_20.1 [symbolic = %d.as_type.loc14_4.2 (constants.%d.as_type)] +// CHECK:STDOUT: %FinalFn.WithSelf.F.type: type = fn_type @FinalFn.WithSelf.F, @FinalFn.WithSelf(%d.loc13_20.1) [symbolic = %FinalFn.WithSelf.F.type (constants.%FinalFn.WithSelf.F.type.94e)] +// CHECK:STDOUT: %.loc14_4.2: type = fn_type_with_self_type %FinalFn.WithSelf.F.type, %d.loc13_20.1 [symbolic = %.loc14_4.2 (constants.%.ec4)] +// CHECK:STDOUT: %FinalFn.lookup_impl_witness: = lookup_impl_witness %d.loc13_20.1, @FinalFn [symbolic = %FinalFn.lookup_impl_witness (constants.%FinalFn.lookup_impl_witness)] +// CHECK:STDOUT: %impl.elem0.loc14_4.2: @CallFn.%.loc14_4.2 (%.ec4) = impl_witness_access %FinalFn.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc14_4.2 (constants.%impl.elem0.9ab)] +// CHECK:STDOUT: %specific_impl_fn.loc14_4.2: = specific_impl_function %impl.elem0.loc14_4.2, @FinalFn.WithSelf.F(%d.loc13_20.1) [symbolic = %specific_impl_fn.loc14_4.2 (constants.%specific_impl_fn.e4e)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %d.ref: %FinalFn.type = name_ref d, %d.loc13_20.2 [symbolic = %d.loc13_20.1 (constants.%d)] +// CHECK:STDOUT: %d.as_type.loc14_4.1: type = facet_access_type %d.ref [symbolic = %d.as_type.loc14_4.2 (constants.%d.as_type)] +// CHECK:STDOUT: %.loc14_4.1: type = converted %d.ref, %d.as_type.loc14_4.1 [symbolic = %d.as_type.loc14_4.2 (constants.%d.as_type)] +// CHECK:STDOUT: %F.ref: %FinalFn.assoc_type = name_ref F, @FinalFn.WithSelf.%assoc0 [concrete = constants.%assoc0.d6c] +// CHECK:STDOUT: %impl.elem0.loc14_4.1: @CallFn.%.loc14_4.2 (%.ec4) = impl_witness_access constants.%FinalFn.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc14_4.2 (constants.%impl.elem0.9ab)] +// CHECK:STDOUT: %specific_impl_fn.loc14_4.1: = specific_impl_function %impl.elem0.loc14_4.1, @FinalFn.WithSelf.F(constants.%d) [symbolic = %specific_impl_fn.loc14_4.2 (constants.%specific_impl_fn.e4e)] +// CHECK:STDOUT: %FinalFn.WithSelf.F.call: init %empty_tuple.type = call %specific_impl_fn.loc14_4.1() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @CallMethod(%T.loc17_16.2: %FinalMethod.type) { +// CHECK:STDOUT: %T.patt.loc17_16.2: %pattern_type.af4 = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc17_16.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.loc17_16.1: %FinalMethod.type = symbolic_binding T, 0 [symbolic = %T.loc17_16.1 (constants.%T)] +// CHECK:STDOUT: %T.as_type.loc17_34.1: type = facet_access_type %T.loc17_16.1 [symbolic = %T.as_type.loc17_34.1 (constants.%T.as_type)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %T.as_type.loc17_34.1 [symbolic = %pattern_type (constants.%pattern_type.ab8)] +// CHECK:STDOUT: %t.param_patt.loc17_32.2: @CallMethod.%pattern_type (%pattern_type.ab8) = value_param_pattern [symbolic = %t.param_patt.loc17_32.2 (constants.%t.param_patt)] +// CHECK:STDOUT: %t.patt.loc17_32.2: @CallMethod.%pattern_type (%pattern_type.ab8) = at_binding_pattern t, %t.param_patt.loc17_32.2 [symbolic = %t.patt.loc17_32.2 (constants.%t.patt)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type %T.as_type.loc17_34.1 [symbolic = %require_complete (constants.%require_complete.3b2)] +// CHECK:STDOUT: %FinalMethod.WithSelf.M.type: type = fn_type @FinalMethod.WithSelf.M, @FinalMethod.WithSelf(%T.loc17_16.1) [symbolic = %FinalMethod.WithSelf.M.type (constants.%FinalMethod.WithSelf.M.type.913)] +// CHECK:STDOUT: %.loc18_4: type = fn_type_with_self_type %FinalMethod.WithSelf.M.type, %T.loc17_16.1 [symbolic = %.loc18_4 (constants.%.e9f)] +// CHECK:STDOUT: %FinalMethod.lookup_impl_witness: = lookup_impl_witness %T.loc17_16.1, @FinalMethod [symbolic = %FinalMethod.lookup_impl_witness (constants.%FinalMethod.lookup_impl_witness)] +// CHECK:STDOUT: %impl.elem0.loc18_4.2: @CallMethod.%.loc18_4 (%.e9f) = impl_witness_access %FinalMethod.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0.24d)] +// CHECK:STDOUT: %specific_impl_fn.loc18_4.2: = specific_impl_function %impl.elem0.loc18_4.2, @FinalMethod.WithSelf.M(%T.loc17_16.1) [symbolic = %specific_impl_fn.loc18_4.2 (constants.%specific_impl_fn.2e2)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%t.param: @CallMethod.%T.as_type.loc17_34.1 (%T.as_type)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %t.ref: @CallMethod.%T.as_type.loc17_34.1 (%T.as_type) = name_ref t, %t +// CHECK:STDOUT: %M.ref: %FinalMethod.assoc_type = name_ref M, @FinalMethod.WithSelf.%assoc0 [concrete = constants.%assoc0.e67] +// CHECK:STDOUT: %impl.elem0.loc18_4.1: @CallMethod.%.loc18_4 (%.e9f) = impl_witness_access constants.%FinalMethod.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0.24d)] +// CHECK:STDOUT: %bound_method.loc18_4: = bound_method %t.ref, %impl.elem0.loc18_4.1 +// CHECK:STDOUT: %.loc18_7.1: %FinalMethod.type = converted constants.%T.as_type, constants.%T [symbolic = %T.loc17_16.1 (constants.%T)] +// CHECK:STDOUT: %.loc18_7.2: %FinalMethod.type = converted constants.%T.as_type, constants.%T [symbolic = %T.loc17_16.1 (constants.%T)] +// CHECK:STDOUT: %specific_impl_fn.loc18_4.1: = specific_impl_function %impl.elem0.loc18_4.1, @FinalMethod.WithSelf.M(constants.%T) [symbolic = %specific_impl_fn.loc18_4.2 (constants.%specific_impl_fn.2e2)] +// CHECK:STDOUT: %bound_method.loc18_7: = bound_method %t.ref, %specific_impl_fn.loc18_4.1 +// CHECK:STDOUT: %FinalMethod.WithSelf.M.call: init %empty_tuple.type = call %bound_method.loc18_7(%t.ref) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @FinalFn.WithSelf(constants.%Self.49e) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Self => constants.%Self.49e +// CHECK:STDOUT: %FinalFn.WithSelf.F.type => constants.%FinalFn.WithSelf.F.type.2c0 +// CHECK:STDOUT: %FinalFn.WithSelf.F => constants.%FinalFn.WithSelf.F.744 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @FinalFn.WithSelf.F(constants.%Self.49e) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @FinalMethod.WithSelf(constants.%Self.e80) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Self => constants.%Self.e80 +// CHECK:STDOUT: %FinalMethod.WithSelf.M.type => constants.%FinalMethod.WithSelf.M.type.efa +// CHECK:STDOUT: %FinalMethod.WithSelf.M => constants.%FinalMethod.WithSelf.M.68b +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @FinalMethod.WithSelf.M(constants.%Self.e80) { +// CHECK:STDOUT: %Self => constants.%Self.e80 +// CHECK:STDOUT: %Self.as_type.loc10_21.1 => constants.%Self.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.32b +// CHECK:STDOUT: %self.param_patt.loc10_21.2 => constants.%self.param_patt.724 +// CHECK:STDOUT: %self.patt.loc10_21.2 => constants.%self.patt.478 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CallFn(constants.%d) { +// CHECK:STDOUT: %d.patt.loc13_20.2 => constants.%d.patt +// CHECK:STDOUT: %d.loc13_20.1 => constants.%d +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @FinalFn.WithSelf(constants.%d) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Self => constants.%d +// CHECK:STDOUT: %FinalFn.WithSelf.F.type => constants.%FinalFn.WithSelf.F.type.94e +// CHECK:STDOUT: %FinalFn.WithSelf.F => constants.%FinalFn.WithSelf.F.219 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @FinalFn.WithSelf.F(constants.%d) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @CallMethod(constants.%T) { +// CHECK:STDOUT: %T.patt.loc17_16.2 => constants.%T.patt +// CHECK:STDOUT: %T.loc17_16.1 => constants.%T +// CHECK:STDOUT: %T.as_type.loc17_34.1 => constants.%T.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.ab8 +// CHECK:STDOUT: %t.param_patt.loc17_32.2 => constants.%t.param_patt +// CHECK:STDOUT: %t.patt.loc17_32.2 => constants.%t.patt +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @FinalMethod.WithSelf(constants.%T) { +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Self => constants.%T +// CHECK:STDOUT: %FinalMethod.WithSelf.M.type => constants.%FinalMethod.WithSelf.M.type.913 +// CHECK:STDOUT: %FinalMethod.WithSelf.M => constants.%FinalMethod.WithSelf.M.4c6 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @FinalMethod.WithSelf.M(constants.%T) { +// CHECK:STDOUT: %Self => constants.%T +// CHECK:STDOUT: %Self.as_type.loc10_21.1 => constants.%T.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.ab8 +// CHECK:STDOUT: %self.param_patt.loc10_21.2 => constants.%self.param_patt.4d4 +// CHECK:STDOUT: %self.patt.loc10_21.2 => constants.%self.patt.87d +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- default_function.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %DefaultFn.type: type = facet_type <@DefaultFn> [concrete] +// CHECK:STDOUT: %.1d8: = impl_self_witness %C, @DefaultFn [concrete] +// CHECK:STDOUT: %DefaultFn.impl_witness: = impl_witness @C.as.DefaultFn.impl.%DefaultFn.impl_witness_table [concrete] +// CHECK:STDOUT: %DefaultFn.facet: %DefaultFn.type = facet_value %C, (%DefaultFn.impl_witness) [concrete] +// CHECK:STDOUT: %DefaultFn.WithSelf.F.type.08a: type = fn_type @DefaultFn.WithSelf.F, @DefaultFn.WithSelf(%DefaultFn.facet) [concrete] +// CHECK:STDOUT: %DefaultFn.WithSelf.F.7e6: %DefaultFn.WithSelf.F.type.08a = 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: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %CallFn.type: type = fn_type @CallFn [concrete] +// CHECK:STDOUT: %CallFn: %CallFn.type = struct_value () [concrete] +// CHECK:STDOUT: %CallFn.specific_fn: = specific_function %CallFn, @CallFn(%DefaultFn.facet) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.DefaultFn: type = import_ref Main//default_interfaces, DefaultFn, loaded [concrete = constants.%DefaultFn.type] +// CHECK:STDOUT: %Main.CallFn: %CallFn.type = import_ref Main//default_interfaces, CallFn, loaded [concrete = constants.%CallFn] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.DefaultFn.impl: %Self.ref as %DefaultFn.ref { +// CHECK:STDOUT: %DefaultFn.impl_witness_table = impl_witness_table (constants.%DefaultFn.WithSelf.F.7e6), @C.as.DefaultFn.impl [concrete] +// CHECK:STDOUT: %DefaultFn.impl_witness: = impl_witness %DefaultFn.impl_witness_table [concrete = constants.%DefaultFn.impl_witness] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .F = +// CHECK:STDOUT: extend %DefaultFn.ref +// CHECK:STDOUT: witness = %DefaultFn.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.DefaultFn.impl [concrete] {} { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %DefaultFn.ref: type = name_ref DefaultFn, imports.%Main.DefaultFn [concrete = constants.%DefaultFn.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc7: = impl_self_witness @C.as.DefaultFn.impl.%Self.ref, @DefaultFn [concrete = constants.%.1d8] +// 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: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: .DefaultFn = +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %CallFn.ref: %CallFn.type = name_ref CallFn, imports.%Main.CallFn [concrete = constants.%CallFn] +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %DefaultFn.facet: %DefaultFn.type = facet_value %C.ref, (constants.%DefaultFn.impl_witness) [concrete = constants.%DefaultFn.facet] +// CHECK:STDOUT: %.loc11: %DefaultFn.type = converted %C.ref, %DefaultFn.facet [concrete = constants.%DefaultFn.facet] +// CHECK:STDOUT: %CallFn.specific_fn: = specific_function %CallFn.ref, @CallFn(constants.%DefaultFn.facet) [concrete = constants.%CallFn.specific_fn] +// CHECK:STDOUT: %CallFn.call: init %empty_tuple.type = call %CallFn.specific_fn() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- default_method.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %DefaultMethod.type: type = facet_type <@DefaultMethod> [concrete] +// CHECK:STDOUT: %.3e0: = impl_self_witness %C, @DefaultMethod [concrete] +// CHECK:STDOUT: %DefaultMethod.impl_witness: = impl_witness @C.as.DefaultMethod.impl.%DefaultMethod.impl_witness_table [concrete] +// CHECK:STDOUT: %DefaultMethod.facet: %DefaultMethod.type = facet_value %C, (%DefaultMethod.impl_witness) [concrete] +// CHECK:STDOUT: %DefaultMethod.WithSelf.M.type.171: type = fn_type @DefaultMethod.WithSelf.M, @DefaultMethod.WithSelf(%DefaultMethod.facet) [concrete] +// CHECK:STDOUT: %DefaultMethod.WithSelf.M.076: %DefaultMethod.WithSelf.M.type.171 = 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: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %pattern_type.98b: type = pattern_type %C [concrete] +// CHECK:STDOUT: %c.patt: %pattern_type.98b = value_binding_pattern c [concrete] +// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] +// CHECK:STDOUT: %C.val: %C = struct_value () [concrete] +// CHECK:STDOUT: %.115: ref %C = temporary invalid, %C.val [concrete] +// CHECK:STDOUT: %CallMethod.type: type = fn_type @CallMethod [concrete] +// CHECK:STDOUT: %CallMethod: %CallMethod.type = struct_value () [concrete] +// CHECK:STDOUT: %CallMethod.specific_fn: = specific_function %CallMethod, @CallMethod(%DefaultMethod.facet) [concrete] +// CHECK:STDOUT: %Destroy.Op.type.1d8f74.2: type = fn_type @Destroy.Op.loc11_15.2 [concrete] +// CHECK:STDOUT: %Destroy.Op.1a2547.2: %Destroy.Op.type.1d8f74.2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.Op.bound: = bound_method %.115, %Destroy.Op.1a2547.2 [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.DefaultMethod: type = import_ref Main//default_interfaces, DefaultMethod, loaded [concrete = constants.%DefaultMethod.type] +// CHECK:STDOUT: %Main.CallMethod: %CallMethod.type = import_ref Main//default_interfaces, CallMethod, loaded [concrete = constants.%CallMethod] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.DefaultMethod.impl: %Self.ref as %DefaultMethod.ref { +// CHECK:STDOUT: %DefaultMethod.impl_witness_table = impl_witness_table (constants.%DefaultMethod.WithSelf.M.076), @C.as.DefaultMethod.impl [concrete] +// CHECK:STDOUT: %DefaultMethod.impl_witness: = impl_witness %DefaultMethod.impl_witness_table [concrete = constants.%DefaultMethod.impl_witness] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .M = +// CHECK:STDOUT: extend %DefaultMethod.ref +// CHECK:STDOUT: witness = %DefaultMethod.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.DefaultMethod.impl [concrete] {} { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %DefaultMethod.ref: type = name_ref DefaultMethod, imports.%Main.DefaultMethod [concrete = constants.%DefaultMethod.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc7: = impl_self_witness @C.as.DefaultMethod.impl.%Self.ref, @DefaultMethod [concrete = constants.%.3e0] +// 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: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: .DefaultMethod = +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc11_15.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc11_15.2: ref %C = temporary_storage +// CHECK:STDOUT: %.loc11_15.3: init %C to %.loc11_15.2 = class_init () [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc11_15.4: init %C = converted %.loc11_15.1, %.loc11_15.3 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc11_15.5: ref %C = temporary %.loc11_15.2, %.loc11_15.4 [concrete = constants.%.115] +// CHECK:STDOUT: %.loc11_15.6: %C = acquire_value %.loc11_15.5 [concrete = constants.%C.val] +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %c: %C = wrapper_binding c, %.loc11_15.6 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %c.patt: %pattern_type.98b = value_binding_pattern c [concrete = constants.%c.patt] +// CHECK:STDOUT: } +// CHECK:STDOUT: %CallMethod.ref: %CallMethod.type = name_ref CallMethod, imports.%Main.CallMethod [concrete = constants.%CallMethod] +// CHECK:STDOUT: %c.ref: %C = name_ref c, %c +// CHECK:STDOUT: %DefaultMethod.facet.loc12_15.1: %DefaultMethod.type = facet_value constants.%C, (constants.%DefaultMethod.impl_witness) [concrete = constants.%DefaultMethod.facet] +// CHECK:STDOUT: %.loc12_15.1: %DefaultMethod.type = converted constants.%C, %DefaultMethod.facet.loc12_15.1 [concrete = constants.%DefaultMethod.facet] +// CHECK:STDOUT: %DefaultMethod.facet.loc12_15.2: %DefaultMethod.type = facet_value constants.%C, (constants.%DefaultMethod.impl_witness) [concrete = constants.%DefaultMethod.facet] +// CHECK:STDOUT: %.loc12_15.2: %DefaultMethod.type = converted constants.%C, %DefaultMethod.facet.loc12_15.2 [concrete = constants.%DefaultMethod.facet] +// CHECK:STDOUT: %CallMethod.specific_fn: = specific_function %CallMethod.ref, @CallMethod(constants.%DefaultMethod.facet) [concrete = constants.%CallMethod.specific_fn] +// CHECK:STDOUT: %CallMethod.call: init %empty_tuple.type = call %CallMethod.specific_fn(%c.ref) +// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call constants.%Destroy.Op.bound(constants.%.115) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Destroy.Op.loc11_15.1(%self.param: ref %empty_struct_type) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Destroy.Op.loc11_15.2(%self.param: ref %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- default_function_overridden.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %C.G.type: type = fn_type @C.G [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.G: %C.G.type = struct_value () [concrete] +// CHECK:STDOUT: %DefaultFn.type: type = facet_type <@DefaultFn> [concrete] +// CHECK:STDOUT: %.1d8: = impl_self_witness %C, @DefaultFn [concrete] +// CHECK:STDOUT: %DefaultFn.impl_witness: = impl_witness @C.as.DefaultFn.impl.%DefaultFn.impl_witness_table [concrete] +// CHECK:STDOUT: %C.as.DefaultFn.impl.F.type: type = fn_type @C.as.DefaultFn.impl.F [concrete] +// CHECK:STDOUT: %C.as.DefaultFn.impl.F: %C.as.DefaultFn.impl.F.type = struct_value () [concrete] +// CHECK:STDOUT: %DefaultFn.facet: %DefaultFn.type = facet_value %C, (%DefaultFn.impl_witness) [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: %CallFn.type: type = fn_type @CallFn [concrete] +// CHECK:STDOUT: %CallFn: %CallFn.type = struct_value () [concrete] +// CHECK:STDOUT: %CallFn.specific_fn: = specific_function %CallFn, @CallFn(%DefaultFn.facet) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.DefaultFn: type = import_ref Main//default_interfaces, DefaultFn, loaded [concrete = constants.%DefaultFn.type] +// CHECK:STDOUT: %Main.CallFn: %CallFn.type = import_ref Main//default_interfaces, CallFn, loaded [concrete = constants.%CallFn] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.DefaultFn.impl: %Self.ref as %DefaultFn.ref { +// CHECK:STDOUT: %C.as.DefaultFn.impl.F.decl: %C.as.DefaultFn.impl.F.type = fn_decl @C.as.DefaultFn.impl.F [concrete = constants.%C.as.DefaultFn.impl.F] {} {} +// CHECK:STDOUT: %DefaultFn.impl_witness_table = impl_witness_table (%C.as.DefaultFn.impl.F.decl), @C.as.DefaultFn.impl [concrete] +// CHECK:STDOUT: %DefaultFn.impl_witness: = impl_witness %DefaultFn.impl_witness_table [concrete = constants.%DefaultFn.impl_witness] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .F = %C.as.DefaultFn.impl.F.decl +// CHECK:STDOUT: .C = +// CHECK:STDOUT: extend %DefaultFn.ref +// CHECK:STDOUT: witness = %DefaultFn.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %C.G.decl: %C.G.type = fn_decl @C.G [concrete = constants.%C.G] {} {} +// CHECK:STDOUT: impl_decl @C.as.DefaultFn.impl [concrete] {} { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %DefaultFn.ref: type = name_ref DefaultFn, imports.%Main.DefaultFn [concrete = constants.%DefaultFn.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc8: = impl_self_witness @C.as.DefaultFn.impl.%Self.ref, @DefaultFn [concrete = constants.%.1d8] +// 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: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: .G = %C.G.decl +// CHECK:STDOUT: .DefaultFn = +// CHECK:STDOUT: .C = +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.G() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.DefaultFn.impl.F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %G.ref: %C.G.type = name_ref G, @C.%C.G.decl [concrete = constants.%C.G] +// CHECK:STDOUT: %C.G.call: init %empty_tuple.type = call %G.ref() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %CallFn.ref: %CallFn.type = name_ref CallFn, imports.%Main.CallFn [concrete = constants.%CallFn] +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %DefaultFn.facet: %DefaultFn.type = facet_value %C.ref, (constants.%DefaultFn.impl_witness) [concrete = constants.%DefaultFn.facet] +// CHECK:STDOUT: %.loc14: %DefaultFn.type = converted %C.ref, %DefaultFn.facet [concrete = constants.%DefaultFn.facet] +// CHECK:STDOUT: %CallFn.specific_fn: = specific_function %CallFn.ref, @CallFn(constants.%DefaultFn.facet) [concrete = constants.%CallFn.specific_fn] +// CHECK:STDOUT: %CallFn.call: init %empty_tuple.type = call %CallFn.specific_fn() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- default_method_overridden.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %pattern_type.98b: type = pattern_type %C [concrete] +// CHECK:STDOUT: %self.param_patt.303: %pattern_type.98b = value_param_pattern [concrete] +// CHECK:STDOUT: %self.patt.49a718.1: %pattern_type.98b = at_binding_pattern self, %self.param_patt.303 [concrete] +// CHECK:STDOUT: %C.G.type: type = fn_type @C.G [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %C.G: %C.G.type = struct_value () [concrete] +// CHECK:STDOUT: %DefaultMethod.type: type = facet_type <@DefaultMethod> [concrete] +// CHECK:STDOUT: %.3e0: = impl_self_witness %C, @DefaultMethod [concrete] +// CHECK:STDOUT: %DefaultMethod.impl_witness: = impl_witness @C.as.DefaultMethod.impl.%DefaultMethod.impl_witness_table [concrete] +// CHECK:STDOUT: %self.patt.49a718.2: %pattern_type.98b = at_binding_pattern self, %self.param_patt.303 [concrete] +// CHECK:STDOUT: %C.as.DefaultMethod.impl.M.type: type = fn_type @C.as.DefaultMethod.impl.M [concrete] +// CHECK:STDOUT: %C.as.DefaultMethod.impl.M: %C.as.DefaultMethod.impl.M.type = struct_value () [concrete] +// CHECK:STDOUT: %DefaultMethod.facet: %DefaultMethod.type = facet_value %C, (%DefaultMethod.impl_witness) [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: %c.patt: %pattern_type.98b = value_binding_pattern c [concrete] +// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] +// CHECK:STDOUT: %C.val: %C = struct_value () [concrete] +// CHECK:STDOUT: %.115: ref %C = temporary invalid, %C.val [concrete] +// CHECK:STDOUT: %CallMethod.type: type = fn_type @CallMethod [concrete] +// CHECK:STDOUT: %CallMethod: %CallMethod.type = struct_value () [concrete] +// CHECK:STDOUT: %CallMethod.specific_fn: = specific_function %CallMethod, @CallMethod(%DefaultMethod.facet) [concrete] +// CHECK:STDOUT: %Destroy.Op.type.1d8f74.2: type = fn_type @Destroy.Op.loc14_15.2 [concrete] +// CHECK:STDOUT: %Destroy.Op.1a2547.2: %Destroy.Op.type.1d8f74.2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.Op.bound: = bound_method %.115, %Destroy.Op.1a2547.2 [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.DefaultMethod: type = import_ref Main//default_interfaces, DefaultMethod, loaded [concrete = constants.%DefaultMethod.type] +// CHECK:STDOUT: %Main.CallMethod: %CallMethod.type = import_ref Main//default_interfaces, CallMethod, loaded [concrete = constants.%CallMethod] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.DefaultMethod.impl: %Self.ref as %DefaultMethod.ref { +// CHECK:STDOUT: %C.as.DefaultMethod.impl.M.decl: %C.as.DefaultMethod.impl.M.type = fn_decl @C.as.DefaultMethod.impl.M [concrete = constants.%C.as.DefaultMethod.impl.M] { +// CHECK:STDOUT: %self.param_patt: %pattern_type.98b = value_param_pattern [concrete = constants.%self.param_patt.303] +// CHECK:STDOUT: %self.patt: %pattern_type.98b = at_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.49a718.2] +// 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 = wrapper_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %DefaultMethod.impl_witness_table = impl_witness_table (%C.as.DefaultMethod.impl.M.decl), @C.as.DefaultMethod.impl [concrete] +// CHECK:STDOUT: %DefaultMethod.impl_witness: = impl_witness %DefaultMethod.impl_witness_table [concrete = constants.%DefaultMethod.impl_witness] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .M = %C.as.DefaultMethod.impl.M.decl +// CHECK:STDOUT: extend %DefaultMethod.ref +// CHECK:STDOUT: witness = %DefaultMethod.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %C.G.decl: %C.G.type = fn_decl @C.G [concrete = constants.%C.G] { +// CHECK:STDOUT: %self.param_patt: %pattern_type.98b = value_param_pattern [concrete = constants.%self.param_patt.303] +// CHECK:STDOUT: %self.patt: %pattern_type.98b = at_binding_pattern self, %self.param_patt [concrete = constants.%self.patt.49a718.1] +// 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 = wrapper_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: impl_decl @C.as.DefaultMethod.impl [concrete] {} { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %DefaultMethod.ref: type = name_ref DefaultMethod, imports.%Main.DefaultMethod [concrete = constants.%DefaultMethod.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc8: = impl_self_witness @C.as.DefaultMethod.impl.%Self.ref, @DefaultMethod [concrete = constants.%.3e0] +// 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: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: .G = %C.G.decl +// CHECK:STDOUT: .DefaultMethod = +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.G(%self.param: %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.DefaultMethod.impl.M(%self.param: %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %self.ref: %C = name_ref self, %self +// CHECK:STDOUT: %G.ref: %C.G.type = name_ref G, @C.%C.G.decl [concrete = constants.%C.G] +// CHECK:STDOUT: %C.G.bound: = bound_method %self.ref, %G.ref +// CHECK:STDOUT: %C.G.call: init %empty_tuple.type = call %C.G.bound(%self.ref) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc14_15.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc14_15.2: ref %C = temporary_storage +// CHECK:STDOUT: %.loc14_15.3: init %C to %.loc14_15.2 = class_init () [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc14_15.4: init %C = converted %.loc14_15.1, %.loc14_15.3 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc14_15.5: ref %C = temporary %.loc14_15.2, %.loc14_15.4 [concrete = constants.%.115] +// CHECK:STDOUT: %.loc14_15.6: %C = acquire_value %.loc14_15.5 [concrete = constants.%C.val] +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %c: %C = wrapper_binding c, %.loc14_15.6 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %c.patt: %pattern_type.98b = value_binding_pattern c [concrete = constants.%c.patt] +// CHECK:STDOUT: } +// CHECK:STDOUT: %CallMethod.ref: %CallMethod.type = name_ref CallMethod, imports.%Main.CallMethod [concrete = constants.%CallMethod] +// CHECK:STDOUT: %c.ref: %C = name_ref c, %c +// CHECK:STDOUT: %DefaultMethod.facet.loc15_15.1: %DefaultMethod.type = facet_value constants.%C, (constants.%DefaultMethod.impl_witness) [concrete = constants.%DefaultMethod.facet] +// CHECK:STDOUT: %.loc15_15.1: %DefaultMethod.type = converted constants.%C, %DefaultMethod.facet.loc15_15.1 [concrete = constants.%DefaultMethod.facet] +// CHECK:STDOUT: %DefaultMethod.facet.loc15_15.2: %DefaultMethod.type = facet_value constants.%C, (constants.%DefaultMethod.impl_witness) [concrete = constants.%DefaultMethod.facet] +// CHECK:STDOUT: %.loc15_15.2: %DefaultMethod.type = converted constants.%C, %DefaultMethod.facet.loc15_15.2 [concrete = constants.%DefaultMethod.facet] +// CHECK:STDOUT: %CallMethod.specific_fn: = specific_function %CallMethod.ref, @CallMethod(constants.%DefaultMethod.facet) [concrete = constants.%CallMethod.specific_fn] +// CHECK:STDOUT: %CallMethod.call: init %empty_tuple.type = call %CallMethod.specific_fn(%c.ref) +// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call constants.%Destroy.Op.bound(constants.%.115) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Destroy.Op.loc14_15.1(%self.param: ref %empty_struct_type) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Destroy.Op.loc14_15.2(%self.param: ref %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- final_function.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %FinalFn.type: type = facet_type <@FinalFn> [concrete] +// CHECK:STDOUT: %.55e: = impl_self_witness %C, @FinalFn [concrete] +// CHECK:STDOUT: %FinalFn.impl_witness: = impl_witness @C.as.FinalFn.impl.%FinalFn.impl_witness_table [concrete] +// CHECK:STDOUT: %FinalFn.facet: %FinalFn.type = facet_value %C, (%FinalFn.impl_witness) [concrete] +// CHECK:STDOUT: %FinalFn.WithSelf.F.type.87d: type = fn_type @FinalFn.WithSelf.F, @FinalFn.WithSelf(%FinalFn.facet) [concrete] +// CHECK:STDOUT: %FinalFn.WithSelf.F.3f7: %FinalFn.WithSelf.F.type.87d = 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: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %CallFn.type: type = fn_type @CallFn [concrete] +// CHECK:STDOUT: %CallFn: %CallFn.type = struct_value () [concrete] +// CHECK:STDOUT: %CallFn.specific_fn: = specific_function %CallFn, @CallFn(%FinalFn.facet) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.FinalFn: type = import_ref Main//final_interfaces, FinalFn, loaded [concrete = constants.%FinalFn.type] +// CHECK:STDOUT: %Main.CallFn: %CallFn.type = import_ref Main//final_interfaces, CallFn, loaded [concrete = constants.%CallFn] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.FinalFn.impl: %Self.ref as %FinalFn.ref { +// CHECK:STDOUT: %FinalFn.impl_witness_table = impl_witness_table (constants.%FinalFn.WithSelf.F.3f7), @C.as.FinalFn.impl [concrete] +// CHECK:STDOUT: %FinalFn.impl_witness: = impl_witness %FinalFn.impl_witness_table [concrete = constants.%FinalFn.impl_witness] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .F = +// CHECK:STDOUT: extend %FinalFn.ref +// CHECK:STDOUT: witness = %FinalFn.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.FinalFn.impl [concrete] {} { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %FinalFn.ref: type = name_ref FinalFn, imports.%Main.FinalFn [concrete = constants.%FinalFn.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc7: = impl_self_witness @C.as.FinalFn.impl.%Self.ref, @FinalFn [concrete = constants.%.55e] +// 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: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: .FinalFn = +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %CallFn.ref: %CallFn.type = name_ref CallFn, imports.%Main.CallFn [concrete = constants.%CallFn] +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %FinalFn.facet: %FinalFn.type = facet_value %C.ref, (constants.%FinalFn.impl_witness) [concrete = constants.%FinalFn.facet] +// CHECK:STDOUT: %.loc11: %FinalFn.type = converted %C.ref, %FinalFn.facet [concrete = constants.%FinalFn.facet] +// CHECK:STDOUT: %CallFn.specific_fn: = specific_function %CallFn.ref, @CallFn(constants.%FinalFn.facet) [concrete = constants.%CallFn.specific_fn] +// CHECK:STDOUT: %CallFn.call: init %empty_tuple.type = call %CallFn.specific_fn() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- final_method.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %FinalMethod.type: type = facet_type <@FinalMethod> [concrete] +// CHECK:STDOUT: %.864: = impl_self_witness %C, @FinalMethod [concrete] +// CHECK:STDOUT: %FinalMethod.impl_witness: = impl_witness @C.as.FinalMethod.impl.%FinalMethod.impl_witness_table [concrete] +// CHECK:STDOUT: %FinalMethod.facet: %FinalMethod.type = facet_value %C, (%FinalMethod.impl_witness) [concrete] +// CHECK:STDOUT: %FinalMethod.WithSelf.M.type.7a1: type = fn_type @FinalMethod.WithSelf.M, @FinalMethod.WithSelf(%FinalMethod.facet) [concrete] +// CHECK:STDOUT: %FinalMethod.WithSelf.M.ed4: %FinalMethod.WithSelf.M.type.7a1 = 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: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %pattern_type.98b: type = pattern_type %C [concrete] +// CHECK:STDOUT: %c.patt: %pattern_type.98b = value_binding_pattern c [concrete] +// CHECK:STDOUT: %empty_struct: %empty_struct_type = struct_value () [concrete] +// CHECK:STDOUT: %C.val: %C = struct_value () [concrete] +// CHECK:STDOUT: %.115: ref %C = temporary invalid, %C.val [concrete] +// CHECK:STDOUT: %CallMethod.type: type = fn_type @CallMethod [concrete] +// CHECK:STDOUT: %CallMethod: %CallMethod.type = struct_value () [concrete] +// CHECK:STDOUT: %CallMethod.specific_fn: = specific_function %CallMethod, @CallMethod(%FinalMethod.facet) [concrete] +// CHECK:STDOUT: %Destroy.Op.type.1d8f74.2: type = fn_type @Destroy.Op.loc11_15.2 [concrete] +// CHECK:STDOUT: %Destroy.Op.1a2547.2: %Destroy.Op.type.1d8f74.2 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.Op.bound: = bound_method %.115, %Destroy.Op.1a2547.2 [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.FinalMethod: type = import_ref Main//final_interfaces, FinalMethod, loaded [concrete = constants.%FinalMethod.type] +// CHECK:STDOUT: %Main.CallMethod: %CallMethod.type = import_ref Main//final_interfaces, CallMethod, loaded [concrete = constants.%CallMethod] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.FinalMethod.impl: %Self.ref as %FinalMethod.ref { +// CHECK:STDOUT: %FinalMethod.impl_witness_table = impl_witness_table (constants.%FinalMethod.WithSelf.M.ed4), @C.as.FinalMethod.impl [concrete] +// CHECK:STDOUT: %FinalMethod.impl_witness: = impl_witness %FinalMethod.impl_witness_table [concrete = constants.%FinalMethod.impl_witness] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .M = +// CHECK:STDOUT: extend %FinalMethod.ref +// CHECK:STDOUT: witness = %FinalMethod.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: impl_decl @C.as.FinalMethod.impl [concrete] {} { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %FinalMethod.ref: type = name_ref FinalMethod, imports.%Main.FinalMethod [concrete = constants.%FinalMethod.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %.loc7: = impl_self_witness @C.as.FinalMethod.impl.%Self.ref, @FinalMethod [concrete = constants.%.864] +// 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: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: .FinalMethod = +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc11_15.1: %empty_struct_type = struct_literal () [concrete = constants.%empty_struct] +// CHECK:STDOUT: %.loc11_15.2: ref %C = temporary_storage +// CHECK:STDOUT: %.loc11_15.3: init %C to %.loc11_15.2 = class_init () [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc11_15.4: init %C = converted %.loc11_15.1, %.loc11_15.3 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc11_15.5: ref %C = temporary %.loc11_15.2, %.loc11_15.4 [concrete = constants.%.115] +// CHECK:STDOUT: %.loc11_15.6: %C = acquire_value %.loc11_15.5 [concrete = constants.%C.val] +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %c: %C = wrapper_binding c, %.loc11_15.6 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %c.patt: %pattern_type.98b = value_binding_pattern c [concrete = constants.%c.patt] +// CHECK:STDOUT: } +// CHECK:STDOUT: %CallMethod.ref: %CallMethod.type = name_ref CallMethod, imports.%Main.CallMethod [concrete = constants.%CallMethod] +// CHECK:STDOUT: %c.ref: %C = name_ref c, %c +// CHECK:STDOUT: %FinalMethod.facet.loc12_15.1: %FinalMethod.type = facet_value constants.%C, (constants.%FinalMethod.impl_witness) [concrete = constants.%FinalMethod.facet] +// CHECK:STDOUT: %.loc12_15.1: %FinalMethod.type = converted constants.%C, %FinalMethod.facet.loc12_15.1 [concrete = constants.%FinalMethod.facet] +// CHECK:STDOUT: %FinalMethod.facet.loc12_15.2: %FinalMethod.type = facet_value constants.%C, (constants.%FinalMethod.impl_witness) [concrete = constants.%FinalMethod.facet] +// CHECK:STDOUT: %.loc12_15.2: %FinalMethod.type = converted constants.%C, %FinalMethod.facet.loc12_15.2 [concrete = constants.%FinalMethod.facet] +// CHECK:STDOUT: %CallMethod.specific_fn: = specific_function %CallMethod.ref, @CallMethod(constants.%FinalMethod.facet) [concrete = constants.%CallMethod.specific_fn] +// CHECK:STDOUT: %CallMethod.call: init %empty_tuple.type = call %CallMethod.specific_fn(%c.ref) +// CHECK:STDOUT: %Destroy.Op.call: init %empty_tuple.type = call constants.%Destroy.Op.bound(constants.%.115) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Destroy.Op.loc11_15.1(%self.param: ref %empty_struct_type) = "no_op"; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Destroy.Op.loc11_15.2(%self.param: ref %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/diagnostics/kind.def b/toolchain/diagnostics/kind.def index c01c1c39db7b..a5151dbe1c82 100644 --- a/toolchain/diagnostics/kind.def +++ b/toolchain/diagnostics/kind.def @@ -376,6 +376,7 @@ CARBON_DIAGNOSTIC_KIND(ImplAsNonFacetType) CARBON_DIAGNOSTIC_KIND(ImplAsOutsideClass) CARBON_DIAGNOSTIC_KIND(ImplAssociatedConstantNeedsValue) CARBON_DIAGNOSTIC_KIND(ImplDeclInInvalidScope) +CARBON_DIAGNOSTIC_KIND(ImplFinalFunction) CARBON_DIAGNOSTIC_KIND(ImplFunctionWithNonFunction) CARBON_DIAGNOSTIC_KIND(ImplInTwoMatchFirst) CARBON_DIAGNOSTIC_KIND(ImplInTwoMatchFirstNote) @@ -575,6 +576,7 @@ CARBON_DIAGNOSTIC_KIND(ModifierAbstractNotAllowed) CARBON_DIAGNOSTIC_KIND(ModifierRequiresClass) CARBON_DIAGNOSTIC_KIND(ModifierRequiresInterface) CARBON_DIAGNOSTIC_KIND(ModifierExternNotAllowed) +CARBON_DIAGNOSTIC_KIND(ModifierFinalRequiresDefaultImpl) CARBON_DIAGNOSTIC_KIND(ModifierNotInContext) CARBON_DIAGNOSTIC_KIND(ModifierRepeated) CARBON_DIAGNOSTIC_KIND(ModifierNotAllowedWith) diff --git a/toolchain/lower/testdata/interface/modifiers.carbon b/toolchain/lower/testdata/interface/modifiers.carbon new file mode 100644 index 000000000000..f9b0e2c6fa6b --- /dev/null +++ b/toolchain/lower/testdata/interface/modifiers.carbon @@ -0,0 +1,594 @@ +// 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-FILE: toolchain/testing/testdata/min_prelude/convert.carbon +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/interface/modifiers.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/interface/modifiers.carbon + +// --- default_interfaces.carbon + +library "[[@TEST_NAME]]"; + +fn Hello() {} + +interface DefaultFn { + default fn F() { Hello(); } +} + +fn World[T: type](unused t: T) {} + +interface DefaultMethod { + default fn M(self) { World(self); } +} + +fn CallFn(generic d: DefaultFn) { + d.F(); +} + +fn CallMethod[T: DefaultMethod](t: T) { + t.M(); +} + +// --- final_interfaces.carbon + +library "[[@TEST_NAME]]"; + +interface FinalFn { + final fn F() {} +} + +interface FinalMethod { + final fn M(unused self) {} +} + +fn CallFn(generic f: FinalFn) { + f.F(); +} + +fn CallMethod[T: FinalMethod](t: T) { + t.M(); +} + +// --- default_function.carbon + +library "[[@TEST_NAME]]"; +import library "default_interfaces"; + +class C { + impl as DefaultFn {} +} + +fn F() { + CallFn(C); +} + +// --- default_method.carbon + +library "[[@TEST_NAME]]"; +import library "default_interfaces"; + +class C { + impl as DefaultMethod {} +} + +fn F() { + let c: C = {}; + CallMethod(c); +} + +// --- default_function_overridden.carbon + +library "[[@TEST_NAME]]"; +import library "default_interfaces"; + +class C { + fn Clone(unused other: C) { } + + impl as DefaultFn { + fn F() { C.Clone({}); } + } +} + +fn F() { + CallFn(C); +} + +// --- default_method_overridden.carbon + +library "[[@TEST_NAME]]"; +import library "default_interfaces"; + +class C { + fn Copy(unused self) { } + + impl as DefaultMethod { + fn M(self) { self.Copy(); } + } +} + +fn F() { + let c: C = {}; + CallMethod(c); +} + +// --- final_function.carbon + +library "[[@TEST_NAME]]"; +import library "final_interfaces"; + +class C { + impl as FinalFn {} +} + +fn F() { + CallFn(C); +} + +// --- final_method.carbon + +library "[[@TEST_NAME]]"; +import library "final_interfaces"; + +class C { + impl as FinalMethod {} +} + +fn F() { + let c: C = {}; + CallMethod(c); +} + +// CHECK:STDOUT: ; --- +// CHECK:STDOUT: ; ModuleID = 'default_interfaces.carbon' +// CHECK:STDOUT: source_filename = "default_interfaces.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_CHello.Main() #0 !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nounwind } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.dbg.cu = !{!0} +// CHECK:STDOUT: !llvm.module.flags = !{!2, !3} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !1 = !DIFile(filename: "default_interfaces.carbon", directory: "") +// CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !3 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Hello", linkageName: "_CHello.Main", scope: null, file: !1, line: 4, type: !5, spFlags: DISPFlagDefinition, unit: !0) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{null} +// CHECK:STDOUT: !7 = !DILocation(line: 4, column: 1, scope: !4) +// CHECK:STDOUT: +// CHECK:STDOUT: ; --- +// CHECK:STDOUT: ; ModuleID = 'final_interfaces.carbon' +// CHECK:STDOUT: source_filename = "final_interfaces.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.dbg.cu = !{!0} +// CHECK:STDOUT: !llvm.module.flags = !{!2, !3} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !1 = !DIFile(filename: "final_interfaces.carbon", directory: "") +// CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !3 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: +// CHECK:STDOUT: ; --- +// CHECK:STDOUT: ; ModuleID = 'default_function.carbon' +// CHECK:STDOUT: source_filename = "default_function.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_CF.Main() #0 !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: call void @_CCallFn.Main.794e85173e977a8b(), !dbg !7 +// CHECK:STDOUT: ret void, !dbg !8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define linkonce_odr void @_CCallFn.Main.794e85173e977a8b() #0 !dbg !9 { +// CHECK:STDOUT: call void @_CF.DefaultFn.Main.794e85173e977a8b(), !dbg !11 +// CHECK:STDOUT: ret void, !dbg !12 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: declare void @_CHello.Main() +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define linkonce_odr void @_CF.DefaultFn.Main.794e85173e977a8b() #0 !dbg !13 { +// CHECK:STDOUT: call void @_CHello.Main(), !dbg !14 +// CHECK:STDOUT: ret void, !dbg !15 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nounwind } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.dbg.cu = !{!0} +// CHECK:STDOUT: !llvm.module.flags = !{!2, !3} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !1 = !DIFile(filename: "default_function.carbon", directory: "") +// CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !3 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main", scope: null, file: !1, line: 9, type: !5, spFlags: DISPFlagDefinition, unit: !0) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{null} +// CHECK:STDOUT: !7 = !DILocation(line: 10, column: 3, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 9, column: 1, scope: !4) +// CHECK:STDOUT: !9 = distinct !DISubprogram(name: "CallFn", linkageName: "_CCallFn.Main.794e85173e977a8b", scope: null, file: !10, line: 16, type: !5, spFlags: DISPFlagDefinition, unit: !0) +// CHECK:STDOUT: !10 = !DIFile(filename: "default_interfaces.carbon", directory: "") +// CHECK:STDOUT: !11 = !DILocation(line: 17, column: 3, scope: !9) +// CHECK:STDOUT: !12 = !DILocation(line: 16, column: 1, scope: !9) +// CHECK:STDOUT: !13 = distinct !DISubprogram(name: "F", linkageName: "_CF.DefaultFn.Main.794e85173e977a8b", scope: null, file: !10, line: 7, type: !5, spFlags: DISPFlagDefinition, unit: !0) +// CHECK:STDOUT: !14 = !DILocation(line: 7, column: 20, scope: !13) +// CHECK:STDOUT: !15 = !DILocation(line: 7, column: 3, scope: !13) +// CHECK:STDOUT: +// CHECK:STDOUT: ; --- +// CHECK:STDOUT: ; ModuleID = 'default_method.carbon' +// CHECK:STDOUT: source_filename = "default_method.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: @C.val = internal constant {} zeroinitializer +// CHECK:STDOUT: @C.val.loc10_15.6 = internal constant {} zeroinitializer +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_CF.Main() #0 !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc10_15.2.temp = alloca {}, align 1, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc10_15.2.temp), !dbg !7 +// CHECK:STDOUT: call void @_CCallMethod.Main.805a971dc5455081(ptr @C.val.loc10_15.6), !dbg !8 +// CHECK:STDOUT: call void @"_COp.807eb4f2d3ed7e54:core.Destroy.Core"(ptr @C.val), !dbg !7 +// CHECK:STDOUT: ret void, !dbg !9 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define weak_odr void @"_COp.807eb4f2d3ed7e54:core.Destroy.Core"(ptr %self) #0 !dbg !10 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !16 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1 +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define linkonce_odr void @_CCallMethod.Main.805a971dc5455081(ptr %t) #0 !dbg !17 { +// CHECK:STDOUT: call void @_CM.DefaultMethod.Main.805a971dc5455081(ptr %t), !dbg !21 +// CHECK:STDOUT: ret void, !dbg !22 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: declare void @_CHello.Main() +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define linkonce_odr void @_CM.DefaultMethod.Main.805a971dc5455081(ptr %self) #0 !dbg !23 { +// CHECK:STDOUT: call void @_CWorld.Main.9522ff908e97e267(ptr %self), !dbg !26 +// CHECK:STDOUT: ret void, !dbg !27 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define linkonce_odr void @_CWorld.Main.9522ff908e97e267(ptr %t) #0 !dbg !28 { +// CHECK:STDOUT: ret void, !dbg !31 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nounwind } +// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.dbg.cu = !{!0} +// CHECK:STDOUT: !llvm.module.flags = !{!2, !3} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !1 = !DIFile(filename: "default_method.carbon", directory: "") +// CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !3 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main", scope: null, file: !1, line: 9, type: !5, spFlags: DISPFlagDefinition, unit: !0) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{null} +// CHECK:STDOUT: !7 = !DILocation(line: 10, column: 14, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 11, column: 3, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 9, column: 1, scope: !4) +// CHECK:STDOUT: !10 = distinct !DISubprogram(name: "Op", linkageName: "_COp.807eb4f2d3ed7e54:core.Destroy.Core", scope: null, file: !1, line: 10, type: !11, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !14) +// CHECK:STDOUT: !11 = !DISubroutineType(types: !12) +// CHECK:STDOUT: !12 = !{null, !13} +// CHECK:STDOUT: !13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +// CHECK:STDOUT: !14 = !{!15} +// CHECK:STDOUT: !15 = !DILocalVariable(arg: 1, scope: !10, type: !13) +// CHECK:STDOUT: !16 = !DILocation(line: 10, column: 14, scope: !10) +// CHECK:STDOUT: !17 = distinct !DISubprogram(name: "CallMethod", linkageName: "_CCallMethod.Main.805a971dc5455081", scope: null, file: !18, line: 20, type: !11, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !19) +// CHECK:STDOUT: !18 = !DIFile(filename: "default_interfaces.carbon", directory: "") +// CHECK:STDOUT: !19 = !{!20} +// CHECK:STDOUT: !20 = !DILocalVariable(arg: 1, scope: !17, type: !13) +// CHECK:STDOUT: !21 = !DILocation(line: 21, column: 3, scope: !17) +// CHECK:STDOUT: !22 = !DILocation(line: 20, column: 1, scope: !17) +// CHECK:STDOUT: !23 = distinct !DISubprogram(name: "M", linkageName: "_CM.DefaultMethod.Main.805a971dc5455081", scope: null, file: !18, line: 13, type: !11, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !24) +// CHECK:STDOUT: !24 = !{!25} +// CHECK:STDOUT: !25 = !DILocalVariable(arg: 1, scope: !23, type: !13) +// CHECK:STDOUT: !26 = !DILocation(line: 13, column: 24, scope: !23) +// CHECK:STDOUT: !27 = !DILocation(line: 13, column: 3, scope: !23) +// CHECK:STDOUT: !28 = distinct !DISubprogram(name: "World", linkageName: "_CWorld.Main.9522ff908e97e267", scope: null, file: !18, line: 10, type: !11, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !29) +// CHECK:STDOUT: !29 = !{!30} +// CHECK:STDOUT: !30 = !DILocalVariable(arg: 1, scope: !28, type: !13) +// CHECK:STDOUT: !31 = !DILocation(line: 10, column: 1, scope: !28) +// CHECK:STDOUT: +// CHECK:STDOUT: ; --- +// CHECK:STDOUT: ; ModuleID = 'default_function_overridden.carbon' +// CHECK:STDOUT: source_filename = "default_function_overridden.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: @C.val = internal constant {} zeroinitializer +// CHECK:STDOUT: @C.val.loc9_23.6 = internal constant {} zeroinitializer +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_CClone.C.Main(ptr %other) #0 !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !10 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @"_CF.C.Main:DefaultFn.Main"() #0 !dbg !11 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc9_23.2.temp = alloca {}, align 1, !dbg !14 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc9_23.2.temp), !dbg !14 +// CHECK:STDOUT: call void @_CClone.C.Main(ptr @C.val.loc9_23.6), !dbg !15 +// CHECK:STDOUT: call void @"_COp.807eb4f2d3ed7e54:core.Destroy.Core"(ptr @C.val), !dbg !14 +// CHECK:STDOUT: ret void, !dbg !16 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define weak_odr void @"_COp.807eb4f2d3ed7e54:core.Destroy.Core"(ptr %self) #0 !dbg !17 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !20 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_CF.Main() #0 !dbg !21 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: call void @_CCallFn.Main.794e85173e977a8b(), !dbg !22 +// CHECK:STDOUT: ret void, !dbg !23 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1 +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define linkonce_odr void @_CCallFn.Main.794e85173e977a8b() #0 !dbg !24 { +// CHECK:STDOUT: call void @"_CF.C.Main:DefaultFn.Main"(), !dbg !26 +// CHECK:STDOUT: ret void, !dbg !27 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: declare void @_CHello.Main() +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nounwind } +// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.dbg.cu = !{!0} +// CHECK:STDOUT: !llvm.module.flags = !{!2, !3} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !1 = !DIFile(filename: "default_function_overridden.carbon", directory: "") +// CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !3 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Clone", linkageName: "_CClone.C.Main", scope: null, file: !1, line: 6, type: !5, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !8) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{null, !7} +// CHECK:STDOUT: !7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +// CHECK:STDOUT: !8 = !{!9} +// CHECK:STDOUT: !9 = !DILocalVariable(arg: 1, scope: !4, type: !7) +// CHECK:STDOUT: !10 = !DILocation(line: 6, column: 3, scope: !4) +// CHECK:STDOUT: !11 = distinct !DISubprogram(name: "F", linkageName: "_CF.C.Main:DefaultFn.Main", scope: null, file: !1, line: 9, type: !12, spFlags: DISPFlagDefinition, unit: !0) +// CHECK:STDOUT: !12 = !DISubroutineType(types: !13) +// CHECK:STDOUT: !13 = !{null} +// CHECK:STDOUT: !14 = !DILocation(line: 9, column: 22, scope: !11) +// CHECK:STDOUT: !15 = !DILocation(line: 9, column: 14, scope: !11) +// CHECK:STDOUT: !16 = !DILocation(line: 9, column: 5, scope: !11) +// CHECK:STDOUT: !17 = distinct !DISubprogram(name: "Op", linkageName: "_COp.807eb4f2d3ed7e54:core.Destroy.Core", scope: null, file: !1, line: 9, type: !5, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !18) +// CHECK:STDOUT: !18 = !{!19} +// CHECK:STDOUT: !19 = !DILocalVariable(arg: 1, scope: !17, type: !7) +// CHECK:STDOUT: !20 = !DILocation(line: 9, column: 22, scope: !17) +// CHECK:STDOUT: !21 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main", scope: null, file: !1, line: 13, type: !12, spFlags: DISPFlagDefinition, unit: !0) +// CHECK:STDOUT: !22 = !DILocation(line: 14, column: 3, scope: !21) +// CHECK:STDOUT: !23 = !DILocation(line: 13, column: 1, scope: !21) +// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "CallFn", linkageName: "_CCallFn.Main.794e85173e977a8b", scope: null, file: !25, line: 16, type: !12, spFlags: DISPFlagDefinition, unit: !0) +// CHECK:STDOUT: !25 = !DIFile(filename: "default_interfaces.carbon", directory: "") +// CHECK:STDOUT: !26 = !DILocation(line: 17, column: 3, scope: !24) +// CHECK:STDOUT: !27 = !DILocation(line: 16, column: 1, scope: !24) +// CHECK:STDOUT: +// CHECK:STDOUT: ; --- +// CHECK:STDOUT: ; ModuleID = 'default_method_overridden.carbon' +// CHECK:STDOUT: source_filename = "default_method_overridden.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: @C.val = internal constant {} zeroinitializer +// CHECK:STDOUT: @C.val.loc14_15.6 = internal constant {} zeroinitializer +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_CCopy.C.Main(ptr %self) #0 !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !10 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @"_CM.C.Main:DefaultMethod.Main"(ptr %self) #0 !dbg !11 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: call void @_CCopy.C.Main(ptr %self), !dbg !14 +// CHECK:STDOUT: ret void, !dbg !15 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_CF.Main() #0 !dbg !16 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc14_15.2.temp = alloca {}, align 1, !dbg !19 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc14_15.2.temp), !dbg !19 +// CHECK:STDOUT: call void @_CCallMethod.Main.805a971dc5455081(ptr @C.val.loc14_15.6), !dbg !20 +// CHECK:STDOUT: call void @"_COp.807eb4f2d3ed7e54:core.Destroy.Core"(ptr @C.val), !dbg !19 +// CHECK:STDOUT: ret void, !dbg !21 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define weak_odr void @"_COp.807eb4f2d3ed7e54:core.Destroy.Core"(ptr %self) #0 !dbg !22 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !25 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1 +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define linkonce_odr void @_CCallMethod.Main.805a971dc5455081(ptr %t) #0 !dbg !26 { +// CHECK:STDOUT: call void @"_CM.C.Main:DefaultMethod.Main"(ptr %t), !dbg !30 +// CHECK:STDOUT: ret void, !dbg !31 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: declare void @_CHello.Main() +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nounwind } +// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.dbg.cu = !{!0} +// CHECK:STDOUT: !llvm.module.flags = !{!2, !3} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !1 = !DIFile(filename: "default_method_overridden.carbon", directory: "") +// CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !3 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Copy", linkageName: "_CCopy.C.Main", scope: null, file: !1, line: 6, type: !5, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !8) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{null, !7} +// CHECK:STDOUT: !7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +// CHECK:STDOUT: !8 = !{!9} +// CHECK:STDOUT: !9 = !DILocalVariable(arg: 1, scope: !4, type: !7) +// CHECK:STDOUT: !10 = !DILocation(line: 6, column: 3, scope: !4) +// CHECK:STDOUT: !11 = distinct !DISubprogram(name: "M", linkageName: "_CM.C.Main:DefaultMethod.Main", scope: null, file: !1, line: 9, type: !5, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !12) +// CHECK:STDOUT: !12 = !{!13} +// CHECK:STDOUT: !13 = !DILocalVariable(arg: 1, scope: !11, type: !7) +// CHECK:STDOUT: !14 = !DILocation(line: 9, column: 18, scope: !11) +// CHECK:STDOUT: !15 = !DILocation(line: 9, column: 5, scope: !11) +// CHECK:STDOUT: !16 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main", scope: null, file: !1, line: 13, type: !17, spFlags: DISPFlagDefinition, unit: !0) +// CHECK:STDOUT: !17 = !DISubroutineType(types: !18) +// CHECK:STDOUT: !18 = !{null} +// CHECK:STDOUT: !19 = !DILocation(line: 14, column: 14, scope: !16) +// CHECK:STDOUT: !20 = !DILocation(line: 15, column: 3, scope: !16) +// CHECK:STDOUT: !21 = !DILocation(line: 13, column: 1, scope: !16) +// CHECK:STDOUT: !22 = distinct !DISubprogram(name: "Op", linkageName: "_COp.807eb4f2d3ed7e54:core.Destroy.Core", scope: null, file: !1, line: 14, type: !5, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !23) +// CHECK:STDOUT: !23 = !{!24} +// CHECK:STDOUT: !24 = !DILocalVariable(arg: 1, scope: !22, type: !7) +// CHECK:STDOUT: !25 = !DILocation(line: 14, column: 14, scope: !22) +// CHECK:STDOUT: !26 = distinct !DISubprogram(name: "CallMethod", linkageName: "_CCallMethod.Main.805a971dc5455081", scope: null, file: !27, line: 20, type: !5, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !28) +// CHECK:STDOUT: !27 = !DIFile(filename: "default_interfaces.carbon", directory: "") +// CHECK:STDOUT: !28 = !{!29} +// CHECK:STDOUT: !29 = !DILocalVariable(arg: 1, scope: !26, type: !7) +// CHECK:STDOUT: !30 = !DILocation(line: 21, column: 3, scope: !26) +// CHECK:STDOUT: !31 = !DILocation(line: 20, column: 1, scope: !26) +// CHECK:STDOUT: +// CHECK:STDOUT: ; --- +// CHECK:STDOUT: ; ModuleID = 'final_function.carbon' +// CHECK:STDOUT: source_filename = "final_function.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_CF.Main() #0 !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: call void @_CCallFn.Main.e342d6e8ff5d87ae(), !dbg !7 +// CHECK:STDOUT: ret void, !dbg !8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define linkonce_odr void @_CCallFn.Main.e342d6e8ff5d87ae() #0 !dbg !9 { +// CHECK:STDOUT: call void @_CF.FinalFn.Main.e342d6e8ff5d87ae(), !dbg !11 +// CHECK:STDOUT: ret void, !dbg !12 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define linkonce_odr void @_CF.FinalFn.Main.e342d6e8ff5d87ae() #0 !dbg !13 { +// CHECK:STDOUT: ret void, !dbg !14 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nounwind } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.dbg.cu = !{!0} +// CHECK:STDOUT: !llvm.module.flags = !{!2, !3} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !1 = !DIFile(filename: "final_function.carbon", directory: "") +// CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !3 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main", scope: null, file: !1, line: 9, type: !5, spFlags: DISPFlagDefinition, unit: !0) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{null} +// CHECK:STDOUT: !7 = !DILocation(line: 10, column: 3, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 9, column: 1, scope: !4) +// CHECK:STDOUT: !9 = distinct !DISubprogram(name: "CallFn", linkageName: "_CCallFn.Main.e342d6e8ff5d87ae", scope: null, file: !10, line: 12, type: !5, spFlags: DISPFlagDefinition, unit: !0) +// CHECK:STDOUT: !10 = !DIFile(filename: "final_interfaces.carbon", directory: "") +// CHECK:STDOUT: !11 = !DILocation(line: 13, column: 3, scope: !9) +// CHECK:STDOUT: !12 = !DILocation(line: 12, column: 1, scope: !9) +// CHECK:STDOUT: !13 = distinct !DISubprogram(name: "F", linkageName: "_CF.FinalFn.Main.e342d6e8ff5d87ae", scope: null, file: !10, line: 5, type: !5, spFlags: DISPFlagDefinition, unit: !0) +// CHECK:STDOUT: !14 = !DILocation(line: 5, column: 3, scope: !13) +// CHECK:STDOUT: +// CHECK:STDOUT: ; --- +// CHECK:STDOUT: ; ModuleID = 'final_method.carbon' +// CHECK:STDOUT: source_filename = "final_method.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: @C.val = internal constant {} zeroinitializer +// CHECK:STDOUT: @C.val.loc10_15.6 = internal constant {} zeroinitializer +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define void @_CF.Main() #0 !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc10_15.2.temp = alloca {}, align 1, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc10_15.2.temp), !dbg !7 +// CHECK:STDOUT: call void @_CCallMethod.Main.96e0ef8a617a6362(ptr @C.val.loc10_15.6), !dbg !8 +// CHECK:STDOUT: call void @"_COp.807eb4f2d3ed7e54:core.Destroy.Core"(ptr @C.val), !dbg !7 +// CHECK:STDOUT: ret void, !dbg !9 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define weak_odr void @"_COp.807eb4f2d3ed7e54:core.Destroy.Core"(ptr %self) #0 !dbg !10 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !16 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1 +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define linkonce_odr void @_CCallMethod.Main.96e0ef8a617a6362(ptr %t) #0 !dbg !17 { +// CHECK:STDOUT: call void @_CM.FinalMethod.Main.96e0ef8a617a6362(ptr %t), !dbg !21 +// CHECK:STDOUT: ret void, !dbg !22 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nounwind +// CHECK:STDOUT: define linkonce_odr void @_CM.FinalMethod.Main.96e0ef8a617a6362(ptr %self) #0 !dbg !23 { +// CHECK:STDOUT: ret void, !dbg !26 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nounwind } +// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.dbg.cu = !{!0} +// CHECK:STDOUT: !llvm.module.flags = !{!2, !3} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !1 = !DIFile(filename: "final_method.carbon", directory: "") +// CHECK:STDOUT: !2 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !3 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main", scope: null, file: !1, line: 9, type: !5, spFlags: DISPFlagDefinition, unit: !0) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{null} +// CHECK:STDOUT: !7 = !DILocation(line: 10, column: 14, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 11, column: 3, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 9, column: 1, scope: !4) +// CHECK:STDOUT: !10 = distinct !DISubprogram(name: "Op", linkageName: "_COp.807eb4f2d3ed7e54:core.Destroy.Core", scope: null, file: !1, line: 10, type: !11, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !14) +// CHECK:STDOUT: !11 = !DISubroutineType(types: !12) +// CHECK:STDOUT: !12 = !{null, !13} +// CHECK:STDOUT: !13 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64) +// CHECK:STDOUT: !14 = !{!15} +// CHECK:STDOUT: !15 = !DILocalVariable(arg: 1, scope: !10, type: !13) +// CHECK:STDOUT: !16 = !DILocation(line: 10, column: 14, scope: !10) +// CHECK:STDOUT: !17 = distinct !DISubprogram(name: "CallMethod", linkageName: "_CCallMethod.Main.96e0ef8a617a6362", scope: null, file: !18, line: 16, type: !11, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !19) +// CHECK:STDOUT: !18 = !DIFile(filename: "final_interfaces.carbon", directory: "") +// CHECK:STDOUT: !19 = !{!20} +// CHECK:STDOUT: !20 = !DILocalVariable(arg: 1, scope: !17, type: !13) +// CHECK:STDOUT: !21 = !DILocation(line: 17, column: 3, scope: !17) +// CHECK:STDOUT: !22 = !DILocation(line: 16, column: 1, scope: !17) +// CHECK:STDOUT: !23 = distinct !DISubprogram(name: "M", linkageName: "_CM.FinalMethod.Main.96e0ef8a617a6362", scope: null, file: !18, line: 9, type: !11, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !24) +// CHECK:STDOUT: !24 = !{!25} +// CHECK:STDOUT: !25 = !DILocalVariable(arg: 1, scope: !23, type: !13) +// CHECK:STDOUT: !26 = !DILocation(line: 9, column: 3, scope: !23) +// CHECK:STDOUT: diff --git a/toolchain/sem_ir/function.h b/toolchain/sem_ir/function.h index 09c521201991..f5d3e886e975 100644 --- a/toolchain/sem_ir/function.h +++ b/toolchain/sem_ir/function.h @@ -59,6 +59,10 @@ struct FunctionFields { // Kinds of evaluation modifiers that can apply to functions. enum class EvaluationMode : uint8_t { None, Eval, MustEval }; + // Kinds of interface modifiers that can apply to functions. + // TODO: turn into a CARBON_ENUM for more convenient checks. + enum class InterfaceModifier : uint8_t { None, Default, Final }; + // The following members always have values, and do not change throughout the // lifetime of the function. @@ -170,6 +174,9 @@ struct FunctionFields { // function. EvaluationMode evaluation_mode = EvaluationMode::None; + // Which, if any, interface modifier is applied to this function. + InterfaceModifier interface_modifier = InterfaceModifier::None; + // The `self` parameter pattern, if any. This is the first pattern in // `param_patterns_id` (from EntityWithParamsBase). InstId self_param_id = InstId::None; @@ -185,6 +192,21 @@ struct FunctionFields { // function, in lexical order. The first block is the entry block. This will // be empty for declarations that don't have a visible definition. llvm::SmallVector body_block_ids = {}; + + friend auto operator<<(llvm::raw_ostream& out, InterfaceModifier modifier) + -> llvm::raw_ostream& { + using enum InterfaceModifier; + switch (modifier) { + case None: + return out << "none"; + case Default: + return out << "default"; + case Final: + return out << "final"; + } + + CARBON_FATAL("unhandled `ImplModifier` during printing"); + } }; inline constexpr FunctionFields::CallParamIndexRanges @@ -233,6 +255,9 @@ struct Function : public EntityWithParamsBase, cpp_thunk_callee_val.has_value()) { out << ", cpp_thunk_callee: " << cpp_thunk_callee_val; } + if (interface_modifier != InterfaceModifier::None) { + out << ", interface_modifier: " << interface_modifier; + } if (!body_block_ids.empty()) { out << llvm::formatv( ", body: [{0}]",