From 4821eec2f8fd745aa14e3df1e25093279beb34c7 Mon Sep 17 00:00:00 2001 From: Geoff Romer Date: Wed, 29 Oct 2025 09:28:56 -0700 Subject: [PATCH] Add support for `ref` patterns (#6283) Support for `bound`, and for the `ref` tag on arguments, is left as future work. --- toolchain/check/convert.cpp | 15 +- toolchain/check/handle_binding_pattern.cpp | 48 +- toolchain/check/node_stack.h | 1 + toolchain/check/pattern_match.cpp | 112 +- .../check/testdata/class/base_method.carbon | 64 +- .../testdata/class/base_method_addr.carbon | 195 +++ .../testdata/class/base_method_shadow.carbon | 88 +- .../class/base_method_shadow_addr.carbon | 259 +++ .../check/testdata/class/fail_ref_self.carbon | 153 ++ .../check/testdata/class/generic/basic.carbon | 72 +- .../testdata/class/generic/basic_addr.carbon | 287 ++++ toolchain/check/testdata/class/import.carbon | 28 +- .../check/testdata/class/import_addr.carbon | 463 +++++ toolchain/check/testdata/class/method.carbon | 52 +- .../check/testdata/class/method_addr.carbon | 492 ++++++ .../check/testdata/class/raw_self.carbon | 76 +- .../check/testdata/class/raw_self_addr.carbon | 235 +++ toolchain/check/testdata/class/self.carbon | 52 +- .../check/testdata/class/self_addr.carbon | 266 +++ .../testdata/class/self_conversion.carbon | 79 +- .../class/self_conversion_addr.carbon | 277 +++ .../testdata/class/syntactic_merge.carbon | 92 +- .../testdata/class/virtual_modifiers.carbon | 114 ++ .../check/testdata/impl/impl_thunk.carbon | 222 +++ .../testdata/impl/lookup/impl_forall.carbon | 106 +- .../impl/lookup/impl_forall_addr.carbon | 351 ++++ .../interface/compound_member_access.carbon | 584 ++++++- .../compound_member_access_addr.carbon | 1502 +++++++++++++++++ toolchain/check/testdata/let/ref.carbon | 302 ++++ toolchain/check/thunk.cpp | 5 +- toolchain/diagnostics/coverage_test.cpp | 7 - toolchain/diagnostics/diagnostic_kind.def | 3 + toolchain/lex/token_kind.def | 1 + toolchain/lower/file_context.cpp | 2 +- toolchain/lower/testdata/array/field.carbon | 20 +- .../lower/testdata/array/field_addr.carbon | 85 + toolchain/lower/testdata/class/method.carbon | 2 +- .../lower/testdata/class/method_addr.carbon | 51 + toolchain/lower/testdata/class/self.carbon | 10 +- .../lower/testdata/class/self_addr.carbon | 59 + .../testdata/function/call/ref_param.carbon | 56 + .../testdata/impl/instance_method.carbon | 6 +- .../testdata/impl/instance_method_addr.carbon | 58 + toolchain/parse/handle_binding_pattern.cpp | 16 + toolchain/parse/node_kind.def | 1 + toolchain/parse/state.def | 6 +- .../testdata/let/fail_generic_ref.carbon | 30 + toolchain/parse/testdata/let/let_ref.carbon | 60 + toolchain/parse/testdata/var/fail_ref.carbon | 30 + toolchain/parse/typed_nodes.h | 18 +- toolchain/sem_ir/function.cpp | 6 +- toolchain/sem_ir/function.h | 1 - 52 files changed, 6645 insertions(+), 475 deletions(-) create mode 100644 toolchain/check/testdata/class/base_method_addr.carbon create mode 100644 toolchain/check/testdata/class/base_method_shadow_addr.carbon create mode 100644 toolchain/check/testdata/class/fail_ref_self.carbon create mode 100644 toolchain/check/testdata/class/generic/basic_addr.carbon create mode 100644 toolchain/check/testdata/class/import_addr.carbon create mode 100644 toolchain/check/testdata/class/method_addr.carbon create mode 100644 toolchain/check/testdata/class/raw_self_addr.carbon create mode 100644 toolchain/check/testdata/class/self_addr.carbon create mode 100644 toolchain/check/testdata/class/self_conversion_addr.carbon create mode 100644 toolchain/check/testdata/impl/lookup/impl_forall_addr.carbon create mode 100644 toolchain/check/testdata/interface/compound_member_access_addr.carbon create mode 100644 toolchain/check/testdata/let/ref.carbon create mode 100644 toolchain/lower/testdata/array/field_addr.carbon create mode 100644 toolchain/lower/testdata/class/method_addr.carbon create mode 100644 toolchain/lower/testdata/class/self_addr.carbon create mode 100644 toolchain/lower/testdata/function/call/ref_param.carbon create mode 100644 toolchain/lower/testdata/impl/instance_method_addr.carbon create mode 100644 toolchain/parse/testdata/let/fail_generic_ref.carbon create mode 100644 toolchain/parse/testdata/let/let_ref.carbon create mode 100644 toolchain/parse/testdata/var/fail_ref.carbon diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index f8f42dde47eb..010039457175 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -1529,7 +1529,10 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id, } // Now perform any necessary value category conversions. - switch (SemIR::GetExprCategory(sem_ir, expr_id)) { + // This uses fallthrough to implement a very simple state machine over the + // category of expr_id, which is tracked by current_category. + switch (auto current_category = SemIR::GetExprCategory(sem_ir, expr_id); + current_category) { case SemIR::ExprCategory::NotExpr: case SemIR::ExprCategory::Mixed: CARBON_FATAL("Unexpected expression {0} after builtin conversions", @@ -1558,15 +1561,16 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id, expr_id = FinalizeTemporary(context, expr_id, target.kind == ConversionTarget::Discarded); // We now have an ephemeral reference. + current_category = SemIR::ExprCategory::EphemeralRef; [[fallthrough]]; case SemIR::ExprCategory::DurableRef: - if (target.kind == ConversionTarget::DurableRef) { + case SemIR::ExprCategory::EphemeralRef: + if (current_category == SemIR::ExprCategory::DurableRef && + target.kind == ConversionTarget::DurableRef) { break; } - [[fallthrough]]; - case SemIR::ExprCategory::EphemeralRef: // If a reference expression is an acceptable result, we're done. if (target.kind == ConversionTarget::ValueOrRef || target.kind == ConversionTarget::Discarded || @@ -1580,6 +1584,7 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id, context, SemIR::LocId(expr_id), {.type_id = target.type_id, .value_id = expr_id}); // We now have a value expression. + current_category = SemIR::ExprCategory::Value; [[fallthrough]]; case SemIR::ExprCategory::Value: @@ -1598,12 +1603,14 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id, // When initializing from a value, perform a copy. if (target.is_initializer()) { expr_id = PerformCopy(context, expr_id, target); + current_category = SemIR::ExprCategory::Initializing; } // When initializing a C++ thunk parameter, form a reference, creating a // temporary if needed. if (target.kind == ConversionTarget::CppThunkRef) { expr_id = ConvertValueForCppThunkRef(context, expr_id); + current_category = SemIR::ExprCategory::EphemeralRef; } break; diff --git a/toolchain/check/handle_binding_pattern.cpp b/toolchain/check/handle_binding_pattern.cpp index 629c3af84004..a83168fa09e4 100644 --- a/toolchain/check/handle_binding_pattern.cpp +++ b/toolchain/check/handle_binding_pattern.cpp @@ -39,21 +39,30 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id, SemIR::ExprRegionId type_expr_region_id = EndSubpatternAsExpr(context, cast_type_inst_id); - // The name in a template binding may be wrapped in `template`. + // The name in a generic binding may be wrapped in `template`. bool is_generic = node_kind == Parse::NodeKind::CompileTimeBindingPattern; - auto is_template = + bool is_template = context.node_stack() .PopAndDiscardSoloNodeIdIf(); // A non-generic template binding is diagnosed by the parser. is_template &= is_generic; + // The name in a runtime binding may be wrapped in `ref`. + bool is_ref = + context.node_stack() + .PopAndDiscardSoloNodeIdIf(); + SemIR::InstKind pattern_inst_kind; switch (node_kind) { case Parse::NodeKind::CompileTimeBindingPattern: pattern_inst_kind = SemIR::InstKind::SymbolicBindingPattern; break; case Parse::NodeKind::LetBindingPattern: - pattern_inst_kind = SemIR::InstKind::ValueBindingPattern; + if (is_ref) { + pattern_inst_kind = SemIR::InstKind::RefBindingPattern; + } else { + pattern_inst_kind = SemIR::InstKind::ValueBindingPattern; + } break; case Parse::NodeKind::VarBindingPattern: pattern_inst_kind = SemIR::InstKind::RefBindingPattern; @@ -166,16 +175,25 @@ static auto HandleAnyBindingPattern(Context& context, Parse::NodeId node_id, result_inst_id = SemIR::ErrorInst::InstId; } else { result_inst_id = make_binding_pattern(); + + // A binding pattern in a function signature is a `Call` parameter + // unless it's nested inside a `var` pattern (because then the + // enclosing `var` pattern is), or it's a compile-time binding pattern + // (because then it's not passed to the `Call` inst). if (node_kind == Parse::NodeKind::LetBindingPattern) { - // A value binding pattern in a function signature is a `Call` - // parameter, but a variable binding pattern is not (instead the - // enclosing `var` pattern is), and a symbolic binding pattern is not - // (because it's not passed to the `Call` inst). - result_inst_id = AddPatternInst( - context, node_id, - {.type_id = context.insts().Get(result_inst_id).type_id(), - .subpattern_id = result_inst_id, - .index = SemIR::CallParamIndex::None}); + if (is_ref) { + result_inst_id = AddPatternInst( + context, node_id, + {.type_id = context.insts().Get(result_inst_id).type_id(), + .subpattern_id = result_inst_id, + .index = SemIR::CallParamIndex::None}); + } else { + result_inst_id = AddPatternInst( + context, node_id, + {.type_id = context.insts().Get(result_inst_id).type_id(), + .subpattern_id = result_inst_id, + .index = SemIR::CallParamIndex::None}); + } } } context.node_stack().Push(node_id, result_inst_id); @@ -414,6 +432,12 @@ auto HandleParseNode(Context& context, Parse::AddrId node_id) -> bool { return true; } +auto HandleParseNode(Context& context, Parse::RefBindingNameId node_id) + -> bool { + context.node_stack().Push(node_id); + return true; +} + auto HandleParseNode(Context& context, Parse::TemplateBindingNameId node_id) -> bool { context.node_stack().Push(node_id); diff --git a/toolchain/check/node_stack.h b/toolchain/check/node_stack.h index 1428ae19d850..512aed0e489d 100644 --- a/toolchain/check/node_stack.h +++ b/toolchain/check/node_stack.h @@ -462,6 +462,7 @@ class NodeStack { case Parse::NodeKind::LetInitializer: case Parse::NodeKind::LetIntroducer: case Parse::NodeKind::NamedConstraintIntroducer: + case Parse::NodeKind::RefBindingName: case Parse::NodeKind::ReturnStatementStart: case Parse::NodeKind::StructLiteralStart: case Parse::NodeKind::StructTypeLiteralField: diff --git a/toolchain/check/pattern_match.cpp b/toolchain/check/pattern_match.cpp index 4515daaff8dd..47a892a281db 100644 --- a/toolchain/check/pattern_match.cpp +++ b/toolchain/check/pattern_match.cpp @@ -48,13 +48,11 @@ class MatchContext { SemIR::InstId pattern_id; // `None` when processing the callee side. SemIR::InstId scrutinee_id; - // Whether we are in a context where plain bindings are reference bindings. - // This happens in var patterns. - bool ref_binding_context; + bool is_self = false; auto Print(llvm::raw_ostream& out) const -> void { out << "{pattern_id: " << pattern_id << ", scrutinee_id: " << scrutinee_id - << ", ref_binding_context: " << ref_binding_context << "}"; + << ", is_self = " << is_self << "}"; } }; @@ -97,6 +95,8 @@ class MatchContext { // Implementations of `EmitPatternMatch` for particular pattern inst kinds. // The pattern argument is always equal to // `context.insts().Get(entry.pattern_id)`. + // TODO: drop pattern_inst_id parameter, which is redundant with + // entry.pattern_id auto DoEmitPatternMatch(Context& context, SemIR::AnyBindingPattern binding_pattern, SemIR::InstId pattern_inst_id, WorkItem entry) @@ -227,9 +227,18 @@ auto MatchContext::DoEmitPatternMatch(Context& context, InsertHere(context, type_expr_region_id); auto value_id = SemIR::InstId::None; if (kind_ == MatchKind::Local) { - auto conversion_kind = entry.ref_binding_context - ? ConversionTarget::DurableRef - : ConversionTarget::Value; + auto conversion_kind = [&binding_pattern]() -> ConversionTarget::Kind { + switch (binding_pattern.kind) { + case SemIR::SymbolicBindingPattern::Kind: + case SemIR::ValueBindingPattern::Kind: + return ConversionTarget::Value; + case SemIR::RefBindingPattern::Kind: + return ConversionTarget::DurableRef; + default: + CARBON_FATAL("Unexpected inst kind {0}", binding_pattern.kind); + } + }(); + if (!bind_name_id.has_value()) { // TODO: Is this appropriate, or should we perform a conversion based on // whether the `_` binding is a value or ref binding first, and then @@ -264,8 +273,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context, // the caller side of the pattern, so we traverse without emitting any // insts. AddWork({.pattern_id = addr_pattern.inner_id, - .scrutinee_id = SemIR::InstId::None, - .ref_binding_context = false}); + .scrutinee_id = SemIR::InstId::None}); return; } CARBON_CHECK(entry.scrutinee_id.has_value()); @@ -291,16 +299,13 @@ auto MatchContext::DoEmitPatternMatch(Context& context, context, SemIR::LocId(scrutinee_ref_id), {.type_id = GetPointerType(context, scrutinee_ref_type_inst_id), .lvalue_id = scrutinee_ref_id}); - AddWork({.pattern_id = addr_pattern.inner_id, - .scrutinee_id = new_scrutinee, - .ref_binding_context = false}); + AddWork({.pattern_id = addr_pattern.inner_id, .scrutinee_id = new_scrutinee}); } auto MatchContext::DoEmitPatternMatch(Context& context, SemIR::ValueParamPattern param_pattern, SemIR::InstId pattern_inst_id, WorkItem entry) -> void { - CARBON_CHECK(!entry.ref_binding_context); switch (kind_) { case MatchKind::Caller: { CARBON_CHECK( @@ -335,8 +340,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context, .pretty_name_id = SemIR::GetPrettyNameFromPatternId( context.sem_ir(), entry.pattern_id)}); AddWork({.pattern_id = param_pattern.subpattern_id, - .scrutinee_id = param_id, - .ref_binding_context = entry.ref_binding_context}); + .scrutinee_id = param_id}); results_.push_back(param_id); break; } @@ -350,7 +354,6 @@ auto MatchContext::DoEmitPatternMatch(Context& context, SemIR::RefParamPattern param_pattern, SemIR::InstId pattern_inst_id, WorkItem entry) -> void { - CARBON_CHECK(entry.ref_binding_context); switch (kind_) { case MatchKind::Caller: { CARBON_CHECK( @@ -358,11 +361,32 @@ auto MatchContext::DoEmitPatternMatch(Context& context, "Parameters out of order; expecting {0} but got {1}", results_.size(), param_pattern.index.index); CARBON_CHECK(entry.scrutinee_id.has_value()); - auto expr_category = - SemIR::GetExprCategory(context.sem_ir(), entry.scrutinee_id); - CARBON_CHECK(expr_category == SemIR::ExprCategory::EphemeralRef || - expr_category == SemIR::ExprCategory::DurableRef); - results_.push_back(entry.scrutinee_id); + + // TODO: If this is a `ref` pattern and !entry.is_self, require the + // scrutinee to have a `ref` tag. + + auto scrutinee_ref_id = ConvertToValueOrRefOfType( + context, SemIR::LocId(entry.scrutinee_id), entry.scrutinee_id, + ExtractScrutineeType( + context.sem_ir(), + SemIR::GetTypeOfInstInSpecific( + context.sem_ir(), callee_specific_id_, pattern_inst_id))); + + switch (SemIR::GetExprCategory(context.sem_ir(), scrutinee_ref_id)) { + case SemIR::ExprCategory::Error: + case SemIR::ExprCategory::DurableRef: + case SemIR::ExprCategory::EphemeralRef: + break; + default: + CARBON_DIAGNOSTIC(ValueForRefParam, Error, + "value expression passed to reference parameter"); + context.emitter().Emit(entry.scrutinee_id, ValueForRefParam); + // Add fake reference expression to preserve invariants. + auto scrutinee = context.insts().GetWithLocId(entry.scrutinee_id); + scrutinee_ref_id = AddInst( + context, scrutinee.loc_id, {.type_id = scrutinee.inst.type_id()}); + } + results_.push_back(scrutinee_ref_id); // Do not traverse farther, because the caller side of the pattern // ends here. break; @@ -379,8 +403,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context, .pretty_name_id = SemIR::GetPrettyNameFromPatternId( context.sem_ir(), entry.pattern_id)}); AddWork({.pattern_id = param_pattern.subpattern_id, - .scrutinee_id = param_id, - .ref_binding_context = entry.ref_binding_context}); + .scrutinee_id = param_id}); results_.push_back(param_id); break; } @@ -394,7 +417,6 @@ auto MatchContext::DoEmitPatternMatch(Context& context, SemIR::OutParamPattern param_pattern, SemIR::InstId pattern_inst_id, WorkItem entry) -> void { - CARBON_CHECK(!entry.ref_binding_context); switch (kind_) { case MatchKind::Caller: { CARBON_CHECK( @@ -427,8 +449,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context, .pretty_name_id = SemIR::GetPrettyNameFromPatternId( context.sem_ir(), entry.pattern_id)}); AddWork({.pattern_id = param_pattern.subpattern_id, - .scrutinee_id = param_id, - .ref_binding_context = entry.ref_binding_context}); + .scrutinee_id = param_id}); results_.push_back(param_id); break; } @@ -467,8 +488,7 @@ auto MatchContext::DoEmitPatternMatch(Context& context, // the caller side of the pattern, so we traverse without emitting any // insts. AddWork({.pattern_id = var_pattern.subpattern_id, - .scrutinee_id = SemIR::InstId::None, - .ref_binding_context = true}); + .scrutinee_id = SemIR::InstId::None}); return; } case MatchKind::Local: { @@ -515,9 +535,8 @@ auto MatchContext::DoEmitPatternMatch(Context& context, {.lhs_id = storage_id, .rhs_id = init_id}); } } - AddWork({.pattern_id = var_pattern.subpattern_id, - .scrutinee_id = storage_id, - .ref_binding_context = true}); + AddWork( + {.pattern_id = var_pattern.subpattern_id, .scrutinee_id = storage_id}); if (context.scope_stack().PeekIndex() == ScopeIndex::Package) { context.global_init().Suspend(); } @@ -535,9 +554,8 @@ auto MatchContext::DoEmitPatternMatch(Context& context, [&](llvm::ArrayRef subscrutinee_ids) { for (auto [subpattern_id, subscrutinee_id] : llvm::reverse(llvm::zip(subpattern_ids, subscrutinee_ids))) { - AddWork({.pattern_id = subpattern_id, - .scrutinee_id = subscrutinee_id, - .ref_binding_context = entry.ref_binding_context}); + AddWork( + {.pattern_id = subpattern_id, .scrutinee_id = subscrutinee_id}); } }; if (!entry.scrutinee_id.has_value()) { @@ -664,25 +682,22 @@ auto CalleePatternMatch(Context& context, // in the original order. if (return_slot_pattern_id.has_value()) { match.AddWork({.pattern_id = return_slot_pattern_id, - .scrutinee_id = SemIR::InstId::None, - .ref_binding_context = false}); + .scrutinee_id = SemIR::InstId::None}); } if (param_patterns_id.has_value()) { for (SemIR::InstId inst_id : llvm::reverse(context.inst_blocks().Get(param_patterns_id))) { - match.AddWork({.pattern_id = inst_id, - .scrutinee_id = SemIR::InstId::None, - .ref_binding_context = false}); + match.AddWork( + {.pattern_id = inst_id, .scrutinee_id = SemIR::InstId::None}); } } if (implicit_param_patterns_id.has_value()) { for (SemIR::InstId inst_id : llvm::reverse(context.inst_blocks().Get(implicit_param_patterns_id))) { - match.AddWork({.pattern_id = inst_id, - .scrutinee_id = SemIR::InstId::None, - .ref_binding_context = false}); + match.AddWork( + {.pattern_id = inst_id, .scrutinee_id = SemIR::InstId::None}); } } @@ -703,22 +718,19 @@ auto CallerPatternMatch(Context& context, SemIR::SpecificId specific_id, if (return_slot_arg_id.has_value()) { CARBON_CHECK(return_slot_pattern_id.has_value()); match.AddWork({.pattern_id = return_slot_pattern_id, - .scrutinee_id = return_slot_arg_id, - .ref_binding_context = false}); + .scrutinee_id = return_slot_arg_id}); } // Check type conversions per-element. for (auto [arg_id, param_pattern_id] : llvm::reverse(llvm::zip_equal( arg_refs, context.inst_blocks().GetOrEmpty(param_patterns_id)))) { - match.AddWork({.pattern_id = param_pattern_id, - .scrutinee_id = arg_id, - .ref_binding_context = false}); + match.AddWork({.pattern_id = param_pattern_id, .scrutinee_id = arg_id}); } if (self_pattern_id.has_value()) { match.AddWork({.pattern_id = self_pattern_id, .scrutinee_id = self_arg_id, - .ref_binding_context = false}); + .is_self = true}); } return match.DoWork(context); @@ -727,9 +739,7 @@ auto CallerPatternMatch(Context& context, SemIR::SpecificId specific_id, auto LocalPatternMatch(Context& context, SemIR::InstId pattern_id, SemIR::InstId scrutinee_id) -> void { MatchContext match(MatchKind::Local); - match.AddWork({.pattern_id = pattern_id, - .scrutinee_id = scrutinee_id, - .ref_binding_context = false}); + match.AddWork({.pattern_id = pattern_id, .scrutinee_id = scrutinee_id}); match.DoWork(context); } diff --git a/toolchain/check/testdata/class/base_method.carbon b/toolchain/check/testdata/class/base_method.carbon index 4c39b172672e..6de08a3b9284 100644 --- a/toolchain/check/testdata/class/base_method.carbon +++ b/toolchain/check/testdata/class/base_method.carbon @@ -15,11 +15,11 @@ base class Base { var a: i32; - fn F[addr self: Self*](); + fn F[ref self: Self](); } -fn Base.F[addr self: Self*]() { - (*self).a = 1; +fn Base.F[ref self: Self]() { + self.a = 1; } class Derived { @@ -40,9 +40,7 @@ fn Call(p: Derived*) { // CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] // CHECK:STDOUT: %Base.elem: type = unbound_element_type %Base, %i32 [concrete] -// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] -// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] -// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %pattern_type.bcc: type = pattern_type %Base [concrete] // CHECK:STDOUT: %Base.F.type: type = fn_type @Base.F [concrete] // CHECK:STDOUT: %Base.F: %Base.F.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %i32} [concrete] @@ -97,16 +95,12 @@ fn Call(p: Derived*) { // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %Base.decl: type = class_decl @Base [concrete = constants.%Base] {} {} // CHECK:STDOUT: %Base.F.decl: %Base.F.type = fn_decl @Base.F [concrete = constants.%Base.F] { -// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = value_binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] -// CHECK:STDOUT: %.loc21_11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %self.patt: %pattern_type.bcc = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.bcc = ref_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param.loc21: %ptr.11f = value_param call_param0 -// CHECK:STDOUT: %.loc21_26: type = splice_block %ptr.loc21 [concrete = constants.%ptr.11f] { -// CHECK:STDOUT: %Self.ref.loc21: type = name_ref Self, constants.%Base [concrete = constants.%Base] -// CHECK:STDOUT: %ptr.loc21: type = ptr_type %Self.ref.loc21 [concrete = constants.%ptr.11f] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self.loc21: %ptr.11f = value_binding self, %self.param.loc21 +// CHECK:STDOUT: %self.param.loc21: ref %Base = ref_param call_param0 +// CHECK:STDOUT: %Self.ref.loc21: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self.loc21: ref %Base = ref_binding self, %self.param.loc21 // CHECK:STDOUT: } // CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [concrete = constants.%Derived] {} {} // CHECK:STDOUT: %Call.decl: %Call.type = fn_decl @Call [concrete = constants.%Call] { @@ -127,16 +121,12 @@ fn Call(p: Derived*) { // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: %.loc16: %Base.elem = field_decl a, element0 [concrete] // CHECK:STDOUT: %Base.F.decl: %Base.F.type = fn_decl @Base.F [concrete = constants.%Base.F] { -// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = value_binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] -// CHECK:STDOUT: %.loc21_11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %self.patt: %pattern_type.bcc = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.bcc = ref_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param.loc18: %ptr.11f = value_param call_param0 -// CHECK:STDOUT: %.loc18: type = splice_block %ptr.loc18 [concrete = constants.%ptr.11f] { -// CHECK:STDOUT: %Self.ref.loc18: type = name_ref Self, constants.%Base [concrete = constants.%Base] -// CHECK:STDOUT: %ptr.loc18: type = ptr_type %Self.ref.loc18 [concrete = constants.%ptr.11f] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self.loc18: %ptr.11f = value_binding self, %self.param.loc18 +// CHECK:STDOUT: %self.param.loc18: ref %Base = ref_param call_param0 +// CHECK:STDOUT: %Self.ref.loc18: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self.loc18: ref %Base = ref_binding self, %self.param.loc18 // CHECK:STDOUT: } // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.a [concrete = constants.%complete_type.fd7] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -161,20 +151,19 @@ fn Call(p: Derived*) { // CHECK:STDOUT: extend %Base.ref // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @Base.F(%self.param.loc21: %ptr.11f) { +// CHECK:STDOUT: fn @Base.F(%self.param.loc21: %Base) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %self.ref: %ptr.11f = name_ref self, %self.loc21 -// CHECK:STDOUT: %.loc22_4: ref %Base = deref %self.ref +// CHECK:STDOUT: %self.ref: ref %Base = name_ref self, %self.loc21 // CHECK:STDOUT: %a.ref: %Base.elem = name_ref a, @Base.%.loc16 [concrete = @Base.%.loc16] -// CHECK:STDOUT: %.loc22_10: ref %i32 = class_element_access %.loc22_4, element0 +// CHECK:STDOUT: %.loc22_7: ref %i32 = class_element_access %self.ref, element0 // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] // CHECK:STDOUT: %impl.elem0: %.322 = impl_witness_access constants.%ImplicitAs.impl_witness.bc9, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b] -// CHECK:STDOUT: %bound_method.loc22_13.1: = bound_method %int_1, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound] +// CHECK:STDOUT: %bound_method.loc22_10.1: = bound_method %int_1, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound] // CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] -// CHECK:STDOUT: %bound_method.loc22_13.2: = bound_method %int_1, %specific_fn [concrete = constants.%bound_method] -// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc22_13.2(%int_1) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc22_13: init %i32 = converted %int_1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: assign %.loc22_10, %.loc22_13 +// CHECK:STDOUT: %bound_method.loc22_10.2: = bound_method %int_1, %specific_fn [concrete = constants.%bound_method] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc22_10.2(%int_1) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc22_10: init %i32 = converted %int_1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: assign %.loc22_7, %.loc22_10 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -184,12 +173,9 @@ fn Call(p: Derived*) { // CHECK:STDOUT: %.loc30_4.1: ref %Derived = deref %p.ref // CHECK:STDOUT: %F.ref: %Base.F.type = name_ref F, @Base.%Base.F.decl [concrete = constants.%Base.F] // CHECK:STDOUT: %Base.F.bound: = bound_method %.loc30_4.1, %F.ref -// CHECK:STDOUT: %addr.loc30_4.1: %ptr.404 = addr_of %.loc30_4.1 -// CHECK:STDOUT: %.loc30_4.2: ref %Derived = deref %addr.loc30_4.1 -// CHECK:STDOUT: %.loc30_4.3: ref %Base = class_element_access %.loc30_4.2, element0 -// CHECK:STDOUT: %addr.loc30_4.2: %ptr.11f = addr_of %.loc30_4.3 -// CHECK:STDOUT: %.loc30_4.4: %ptr.11f = converted %addr.loc30_4.1, %addr.loc30_4.2 -// CHECK:STDOUT: %Base.F.call: init %empty_tuple.type = call %Base.F.bound(%.loc30_4.4) +// CHECK:STDOUT: %.loc30_4.2: ref %Base = class_element_access %.loc30_4.1, element0 +// CHECK:STDOUT: %.loc30_4.3: ref %Base = converted %.loc30_4.1, %.loc30_4.2 +// CHECK:STDOUT: %Base.F.call: init %empty_tuple.type = call %Base.F.bound(%.loc30_4.3) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/base_method_addr.carbon b/toolchain/check/testdata/class/base_method_addr.carbon new file mode 100644 index 000000000000..5c37a373e2c8 --- /dev/null +++ b/toolchain/check/testdata/class/base_method_addr.carbon @@ -0,0 +1,195 @@ +// 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/class/base_method_addr.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/base_method_addr.carbon + +base class Base { + var a: i32; + + fn F[addr self: Self*](); +} + +fn Base.F[addr self: Self*]() { + (*self).a = 1; +} + +class Derived { + extend base: Base; +} + +fn Call(p: Derived*) { + (*p).F(); +} + +// CHECK:STDOUT: --- base_method_addr.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Base: type = class_type @Base [concrete] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] +// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %Base.elem: type = unbound_element_type %Base, %i32 [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Base.F.type: type = fn_type @Base.F [concrete] +// CHECK:STDOUT: %Base.F: %Base.F.type = struct_value () [concrete] +// CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %i32} [concrete] +// CHECK:STDOUT: %complete_type.fd7: = complete_type_witness %struct_type.a [concrete] +// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] +// CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] +// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.type.d14: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] +// CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.2a1: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51 = struct_value () [symbolic] +// CHECK:STDOUT: %ImplicitAs.impl_witness.bc9: = impl_witness imports.%ImplicitAs.impl_witness_table.132, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.51e: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.51e = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.d14 = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.bc9) [concrete] +// CHECK:STDOUT: %.322: type = fn_type_with_self_type %ImplicitAs.Convert.type.1b6, %ImplicitAs.facet [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] +// CHECK:STDOUT: %bound_method: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] +// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] +// CHECK:STDOUT: %Derived: type = class_type @Derived [concrete] +// CHECK:STDOUT: %Derived.elem: type = unbound_element_type %Derived, %Base [concrete] +// CHECK:STDOUT: %struct_type.base.b1e: type = struct_type {.base: %Base} [concrete] +// CHECK:STDOUT: %complete_type.15c: = complete_type_witness %struct_type.base.b1e [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Call.type: type = fn_type @Call [concrete] +// CHECK:STDOUT: %Call: %Call.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] +// CHECK:STDOUT: %Core.import_ref.e24: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.2a1)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table.132 = impl_witness_table (%Core.import_ref.e24), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Base = %Base.decl +// CHECK:STDOUT: .Derived = %Derived.decl +// CHECK:STDOUT: .Call = %Call.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Base.decl: type = class_decl @Base [concrete = constants.%Base] {} {} +// CHECK:STDOUT: %Base.F.decl: %Base.F.type = fn_decl @Base.F [concrete = constants.%Base.F] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc21_11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param.loc21: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %.loc21_26: type = splice_block %ptr.loc21 [concrete = constants.%ptr.11f] { +// CHECK:STDOUT: %Self.ref.loc21: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %ptr.loc21: type = ptr_type %Self.ref.loc21 [concrete = constants.%ptr.11f] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self.loc21: %ptr.11f = value_binding self, %self.param.loc21 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [concrete = constants.%Derived] {} {} +// CHECK:STDOUT: %Call.decl: %Call.type = fn_decl @Call [concrete = constants.%Call] { +// CHECK:STDOUT: %p.patt: %pattern_type.605 = value_binding_pattern p [concrete] +// CHECK:STDOUT: %p.param_patt: %pattern_type.605 = value_param_pattern %p.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %p.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %.loc29: type = splice_block %ptr [concrete = constants.%ptr.404] { +// CHECK:STDOUT: %Derived.ref: type = name_ref Derived, file.%Derived.decl [concrete = constants.%Derived] +// CHECK:STDOUT: %ptr: type = ptr_type %Derived.ref [concrete = constants.%ptr.404] +// CHECK:STDOUT: } +// CHECK:STDOUT: %p: %ptr.404 = value_binding p, %p.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Base { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc16: %Base.elem = field_decl a, element0 [concrete] +// CHECK:STDOUT: %Base.F.decl: %Base.F.type = fn_decl @Base.F [concrete = constants.%Base.F] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc21_11: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param.loc18: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %.loc18: type = splice_block %ptr.loc18 [concrete = constants.%ptr.11f] { +// CHECK:STDOUT: %Self.ref.loc18: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %ptr.loc18: type = ptr_type %Self.ref.loc18 [concrete = constants.%ptr.11f] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self.loc18: %ptr.11f = value_binding self, %self.param.loc18 +// CHECK:STDOUT: } +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.a [concrete = constants.%complete_type.fd7] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Base +// CHECK:STDOUT: .a = %.loc16 +// CHECK:STDOUT: .F = %Base.F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Derived { +// CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] +// CHECK:STDOUT: %.loc26: %Derived.elem = base_decl %Base.ref, element0 [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.base.b1e [concrete = constants.%complete_type.15c] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Derived +// CHECK:STDOUT: .Base = +// CHECK:STDOUT: .base = %.loc26 +// CHECK:STDOUT: .F = +// CHECK:STDOUT: extend %Base.ref +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.F(%self.param.loc21: %ptr.11f) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %self.ref: %ptr.11f = name_ref self, %self.loc21 +// CHECK:STDOUT: %.loc22_4: ref %Base = deref %self.ref +// CHECK:STDOUT: %a.ref: %Base.elem = name_ref a, @Base.%.loc16 [concrete = @Base.%.loc16] +// CHECK:STDOUT: %.loc22_10: ref %i32 = class_element_access %.loc22_4, element0 +// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %impl.elem0: %.322 = impl_witness_access constants.%ImplicitAs.impl_witness.bc9, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b] +// CHECK:STDOUT: %bound_method.loc22_13.1: = bound_method %int_1, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound] +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc22_13.2: = bound_method %int_1, %specific_fn [concrete = constants.%bound_method] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc22_13.2(%int_1) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc22_13: init %i32 = converted %int_1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: assign %.loc22_10, %.loc22_13 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Call(%p.param: %ptr.404) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %p.ref: %ptr.404 = name_ref p, %p +// CHECK:STDOUT: %.loc30_4.1: ref %Derived = deref %p.ref +// CHECK:STDOUT: %F.ref: %Base.F.type = name_ref F, @Base.%Base.F.decl [concrete = constants.%Base.F] +// CHECK:STDOUT: %Base.F.bound: = bound_method %.loc30_4.1, %F.ref +// CHECK:STDOUT: %addr.loc30_4.1: %ptr.404 = addr_of %.loc30_4.1 +// CHECK:STDOUT: %.loc30_4.2: ref %Derived = deref %addr.loc30_4.1 +// CHECK:STDOUT: %.loc30_4.3: ref %Base = class_element_access %.loc30_4.2, element0 +// CHECK:STDOUT: %addr.loc30_4.2: %ptr.11f = addr_of %.loc30_4.3 +// CHECK:STDOUT: %.loc30_4.4: %ptr.11f = converted %addr.loc30_4.1, %addr.loc30_4.2 +// CHECK:STDOUT: %Base.F.call: init %empty_tuple.type = call %Base.F.bound(%.loc30_4.4) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/base_method_shadow.carbon b/toolchain/check/testdata/class/base_method_shadow.carbon index f9a556aa3b0a..a4a3a0cf8fec 100644 --- a/toolchain/check/testdata/class/base_method_shadow.carbon +++ b/toolchain/check/testdata/class/base_method_shadow.carbon @@ -13,17 +13,17 @@ // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/base_method_shadow.carbon base class A { - fn F[addr self: Self*](); + fn F[ref self: Self](); } base class B { extend base: A; - fn F[addr self: Self*](); + fn F[ref self: Self](); } class C { extend base: B; - fn F[addr self: Self*](); + fn F[ref self: Self](); } class D { @@ -41,9 +41,7 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %A: type = class_type @A [concrete] -// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] -// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] -// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %pattern_type.c10: type = pattern_type %A [concrete] // CHECK:STDOUT: %A.F.type: type = fn_type @A.F [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %A.F: %A.F.type = struct_value () [concrete] @@ -51,22 +49,26 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %B.elem: type = unbound_element_type %B, %A [concrete] -// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] -// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %pattern_type.049: type = pattern_type %B [concrete] // CHECK:STDOUT: %B.F.type: type = fn_type @B.F [concrete] // CHECK:STDOUT: %B.F: %B.F.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.953: type = struct_type {.base: %A} [concrete] // CHECK:STDOUT: %complete_type.020: = complete_type_witness %struct_type.base.953 [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %B [concrete] -// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] -// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] // CHECK:STDOUT: %C.F.type: type = fn_type @C.F [concrete] // CHECK:STDOUT: %C.F: %C.F.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.0ff: type = struct_type {.base: %B} [concrete] // CHECK:STDOUT: %complete_type.98e: = complete_type_witness %struct_type.base.0ff [concrete] // CHECK:STDOUT: %D: type = class_type @D [concrete] // CHECK:STDOUT: %D.elem: type = unbound_element_type %D, %B [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] // CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] // CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] // CHECK:STDOUT: %Call.type: type = fn_type @Call [concrete] @@ -133,16 +135,12 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: // CHECK:STDOUT: class @A { // CHECK:STDOUT: %A.F.decl: %A.F.type = fn_decl @A.F [concrete = constants.%A.F] { -// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = value_binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] -// CHECK:STDOUT: %.loc16_8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %self.patt: %pattern_type.c10 = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.c10 = ref_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 -// CHECK:STDOUT: %.loc16_23: type = splice_block %ptr [concrete = constants.%ptr.6db] { -// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] -// CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr.6db] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self: %ptr.6db = value_binding self, %self.param +// CHECK:STDOUT: %self.param: ref %A = ref_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %self: ref %A = ref_binding self, %self.param // CHECK:STDOUT: } // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -156,16 +154,12 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A] // CHECK:STDOUT: %.loc20: %B.elem = base_decl %A.ref, element0 [concrete] // CHECK:STDOUT: %B.F.decl: %B.F.type = fn_decl @B.F [concrete = constants.%B.F] { -// CHECK:STDOUT: %self.patt: %pattern_type.960 = value_binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] -// CHECK:STDOUT: %.loc21_8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %self.patt: %pattern_type.049 = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.049 = ref_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 -// CHECK:STDOUT: %.loc21_23: type = splice_block %ptr [concrete = constants.%ptr.e79] { -// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] -// CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr.e79] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self: %ptr.e79 = value_binding self, %self.param +// CHECK:STDOUT: %self.param: ref %B = ref_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %self: ref %B = ref_binding self, %self.param // CHECK:STDOUT: } // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.base.953 [concrete = constants.%complete_type.020] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -182,16 +176,12 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [concrete = constants.%B] // CHECK:STDOUT: %.loc25: %C.elem = base_decl %B.ref, element0 [concrete] // CHECK:STDOUT: %C.F.decl: %C.F.type = fn_decl @C.F [concrete = constants.%C.F] { -// CHECK:STDOUT: %self.patt: %pattern_type.44a = value_binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] -// CHECK:STDOUT: %.loc26_8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %self.patt: %pattern_type.c48 = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.c48 = ref_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 -// CHECK:STDOUT: %.loc26_23: type = splice_block %ptr [concrete = constants.%ptr.019] { -// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] -// CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr.019] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self: %ptr.019 = value_binding self, %self.param +// CHECK:STDOUT: %self.param: ref %C = ref_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: ref %C = ref_binding self, %self.param // CHECK:STDOUT: } // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.base.0ff [concrete = constants.%complete_type.98e] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -218,11 +208,11 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: extend %B.ref // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @A.F(%self.param: %ptr.6db); +// CHECK:STDOUT: fn @A.F(%self.param: %A); // CHECK:STDOUT: -// CHECK:STDOUT: fn @B.F(%self.param: %ptr.e79); +// CHECK:STDOUT: fn @B.F(%self.param: %B); // CHECK:STDOUT: -// CHECK:STDOUT: fn @C.F(%self.param: %ptr.019); +// CHECK:STDOUT: fn @C.F(%self.param: %C); // CHECK:STDOUT: // CHECK:STDOUT: fn @Call(%a.param: %ptr.6db, %b.param: %ptr.e79, %c.param: %ptr.019, %d.param: %ptr.19c) { // CHECK:STDOUT: !entry: @@ -230,30 +220,24 @@ fn Call(a: A*, b: B*, c: C*, d: D*) { // CHECK:STDOUT: %.loc34: ref %A = deref %a.ref // CHECK:STDOUT: %F.ref.loc34: %A.F.type = name_ref F, @A.%A.F.decl [concrete = constants.%A.F] // CHECK:STDOUT: %A.F.bound: = bound_method %.loc34, %F.ref.loc34 -// CHECK:STDOUT: %addr.loc34: %ptr.6db = addr_of %.loc34 -// CHECK:STDOUT: %A.F.call: init %empty_tuple.type = call %A.F.bound(%addr.loc34) +// CHECK:STDOUT: %A.F.call: init %empty_tuple.type = call %A.F.bound(%.loc34) // CHECK:STDOUT: %b.ref: %ptr.e79 = name_ref b, %b // CHECK:STDOUT: %.loc35: ref %B = deref %b.ref // CHECK:STDOUT: %F.ref.loc35: %B.F.type = name_ref F, @B.%B.F.decl [concrete = constants.%B.F] // CHECK:STDOUT: %B.F.bound.loc35: = bound_method %.loc35, %F.ref.loc35 -// CHECK:STDOUT: %addr.loc35: %ptr.e79 = addr_of %.loc35 -// CHECK:STDOUT: %B.F.call.loc35: init %empty_tuple.type = call %B.F.bound.loc35(%addr.loc35) +// CHECK:STDOUT: %B.F.call.loc35: init %empty_tuple.type = call %B.F.bound.loc35(%.loc35) // CHECK:STDOUT: %c.ref: %ptr.019 = name_ref c, %c // CHECK:STDOUT: %.loc36: ref %C = deref %c.ref // CHECK:STDOUT: %F.ref.loc36: %C.F.type = name_ref F, @C.%C.F.decl [concrete = constants.%C.F] // CHECK:STDOUT: %C.F.bound: = bound_method %.loc36, %F.ref.loc36 -// CHECK:STDOUT: %addr.loc36: %ptr.019 = addr_of %.loc36 -// CHECK:STDOUT: %C.F.call: init %empty_tuple.type = call %C.F.bound(%addr.loc36) +// CHECK:STDOUT: %C.F.call: init %empty_tuple.type = call %C.F.bound(%.loc36) // CHECK:STDOUT: %d.ref: %ptr.19c = name_ref d, %d // CHECK:STDOUT: %.loc37_4.1: ref %D = deref %d.ref // CHECK:STDOUT: %F.ref.loc37: %B.F.type = name_ref F, @B.%B.F.decl [concrete = constants.%B.F] // CHECK:STDOUT: %B.F.bound.loc37: = bound_method %.loc37_4.1, %F.ref.loc37 -// CHECK:STDOUT: %addr.loc37_4.1: %ptr.19c = addr_of %.loc37_4.1 -// CHECK:STDOUT: %.loc37_4.2: ref %D = deref %addr.loc37_4.1 -// CHECK:STDOUT: %.loc37_4.3: ref %B = class_element_access %.loc37_4.2, element0 -// CHECK:STDOUT: %addr.loc37_4.2: %ptr.e79 = addr_of %.loc37_4.3 -// CHECK:STDOUT: %.loc37_4.4: %ptr.e79 = converted %addr.loc37_4.1, %addr.loc37_4.2 -// CHECK:STDOUT: %B.F.call.loc37: init %empty_tuple.type = call %B.F.bound.loc37(%.loc37_4.4) +// CHECK:STDOUT: %.loc37_4.2: ref %B = class_element_access %.loc37_4.1, element0 +// CHECK:STDOUT: %.loc37_4.3: ref %B = converted %.loc37_4.1, %.loc37_4.2 +// CHECK:STDOUT: %B.F.call.loc37: init %empty_tuple.type = call %B.F.bound.loc37(%.loc37_4.3) // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/base_method_shadow_addr.carbon b/toolchain/check/testdata/class/base_method_shadow_addr.carbon new file mode 100644 index 000000000000..9047a7b008ed --- /dev/null +++ b/toolchain/check/testdata/class/base_method_shadow_addr.carbon @@ -0,0 +1,259 @@ +// 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 +// 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/class/base_method_shadow_addr.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/base_method_shadow_addr.carbon + +base class A { + fn F[addr self: Self*](); +} + +base class B { + extend base: A; + fn F[addr self: Self*](); +} + +class C { + extend base: B; + fn F[addr self: Self*](); +} + +class D { + extend base: B; +} + +fn Call(a: A*, b: B*, c: C*, d: D*) { + (*a).F(); + (*b).F(); + (*c).F(); + (*d).F(); +} + +// CHECK:STDOUT: --- base_method_shadow_addr.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %A: type = class_type @A [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %A.F.type: type = fn_type @A.F [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %A.F: %A.F.type = struct_value () [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %B.elem: type = unbound_element_type %B, %A [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %pattern_type.960: type = pattern_type %ptr.e79 [concrete] +// CHECK:STDOUT: %B.F.type: type = fn_type @B.F [concrete] +// CHECK:STDOUT: %B.F: %B.F.type = struct_value () [concrete] +// CHECK:STDOUT: %struct_type.base.953: type = struct_type {.base: %A} [concrete] +// CHECK:STDOUT: %complete_type.020: = complete_type_witness %struct_type.base.953 [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %B [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %C.F.type: type = fn_type @C.F [concrete] +// CHECK:STDOUT: %C.F: %C.F.type = struct_value () [concrete] +// CHECK:STDOUT: %struct_type.base.0ff: type = struct_type {.base: %B} [concrete] +// CHECK:STDOUT: %complete_type.98e: = complete_type_witness %struct_type.base.0ff [concrete] +// CHECK:STDOUT: %D: type = class_type @D [concrete] +// CHECK:STDOUT: %D.elem: type = unbound_element_type %D, %B [concrete] +// CHECK:STDOUT: %ptr.19c: type = ptr_type %D [concrete] +// CHECK:STDOUT: %pattern_type.a94: type = pattern_type %ptr.19c [concrete] +// CHECK:STDOUT: %Call.type: type = fn_type @Call [concrete] +// CHECK:STDOUT: %Call: %Call.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .A = %A.decl +// CHECK:STDOUT: .B = %B.decl +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D.decl +// CHECK:STDOUT: .Call = %Call.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %A.decl: type = class_decl @A [concrete = constants.%A] {} {} +// CHECK:STDOUT: %B.decl: type = class_decl @B [concrete = constants.%B] {} {} +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: %D.decl: type = class_decl @D [concrete = constants.%D] {} {} +// CHECK:STDOUT: %Call.decl: %Call.type = fn_decl @Call [concrete = constants.%Call] { +// CHECK:STDOUT: %a.patt: %pattern_type.5f8 = value_binding_pattern a [concrete] +// CHECK:STDOUT: %a.param_patt: %pattern_type.5f8 = value_param_pattern %a.patt, call_param0 [concrete] +// CHECK:STDOUT: %b.patt: %pattern_type.960 = value_binding_pattern b [concrete] +// CHECK:STDOUT: %b.param_patt: %pattern_type.960 = value_param_pattern %b.patt, call_param1 [concrete] +// CHECK:STDOUT: %c.patt: %pattern_type.44a = value_binding_pattern c [concrete] +// CHECK:STDOUT: %c.param_patt: %pattern_type.44a = value_param_pattern %c.patt, call_param2 [concrete] +// CHECK:STDOUT: %d.patt: %pattern_type.a94 = value_binding_pattern d [concrete] +// CHECK:STDOUT: %d.param_patt: %pattern_type.a94 = value_param_pattern %d.patt, call_param3 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %a.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %.loc33_13: type = splice_block %ptr.loc33_13 [concrete = constants.%ptr.6db] { +// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A] +// CHECK:STDOUT: %ptr.loc33_13: type = ptr_type %A.ref [concrete = constants.%ptr.6db] +// CHECK:STDOUT: } +// CHECK:STDOUT: %a: %ptr.6db = value_binding a, %a.param +// CHECK:STDOUT: %b.param: %ptr.e79 = value_param call_param1 +// CHECK:STDOUT: %.loc33_20: type = splice_block %ptr.loc33_20 [concrete = constants.%ptr.e79] { +// CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [concrete = constants.%B] +// CHECK:STDOUT: %ptr.loc33_20: type = ptr_type %B.ref [concrete = constants.%ptr.e79] +// CHECK:STDOUT: } +// CHECK:STDOUT: %b: %ptr.e79 = value_binding b, %b.param +// CHECK:STDOUT: %c.param: %ptr.019 = value_param call_param2 +// CHECK:STDOUT: %.loc33_27: type = splice_block %ptr.loc33_27 [concrete = constants.%ptr.019] { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %ptr.loc33_27: type = ptr_type %C.ref [concrete = constants.%ptr.019] +// CHECK:STDOUT: } +// CHECK:STDOUT: %c: %ptr.019 = value_binding c, %c.param +// CHECK:STDOUT: %d.param: %ptr.19c = value_param call_param3 +// CHECK:STDOUT: %.loc33_34: type = splice_block %ptr.loc33_34 [concrete = constants.%ptr.19c] { +// CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D] +// CHECK:STDOUT: %ptr.loc33_34: type = ptr_type %D.ref [concrete = constants.%ptr.19c] +// CHECK:STDOUT: } +// CHECK:STDOUT: %d: %ptr.19c = value_binding d, %d.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @A { +// CHECK:STDOUT: %A.F.decl: %A.F.type = fn_decl @A.F [concrete = constants.%A.F] { +// CHECK:STDOUT: %self.patt: %pattern_type.5f8 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.5f8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc16_8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.6db = value_param call_param0 +// CHECK:STDOUT: %.loc16_23: type = splice_block %ptr [concrete = constants.%ptr.6db] { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%A [concrete = constants.%A] +// CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr.6db] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: %ptr.6db = value_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%A +// CHECK:STDOUT: .F = %A.F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @B { +// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A] +// CHECK:STDOUT: %.loc20: %B.elem = base_decl %A.ref, element0 [concrete] +// CHECK:STDOUT: %B.F.decl: %B.F.type = fn_decl @B.F [concrete = constants.%B.F] { +// CHECK:STDOUT: %self.patt: %pattern_type.960 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.960 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc21_8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.e79 = value_param call_param0 +// CHECK:STDOUT: %.loc21_23: type = splice_block %ptr [concrete = constants.%ptr.e79] { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [concrete = constants.%B] +// CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr.e79] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: %ptr.e79 = value_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.base.953 [concrete = constants.%complete_type.020] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%B +// CHECK:STDOUT: .A = +// CHECK:STDOUT: .base = %.loc20 +// CHECK:STDOUT: .F = %B.F.decl +// CHECK:STDOUT: extend %A.ref +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [concrete = constants.%B] +// CHECK:STDOUT: %.loc25: %C.elem = base_decl %B.ref, element0 [concrete] +// CHECK:STDOUT: %C.F.decl: %C.F.type = fn_decl @C.F [concrete = constants.%C.F] { +// CHECK:STDOUT: %self.patt: %pattern_type.44a = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.44a = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc26_8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr.019 = value_param call_param0 +// CHECK:STDOUT: %.loc26_23: type = splice_block %ptr [concrete = constants.%ptr.019] { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr.019] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: %ptr.019 = value_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.base.0ff [concrete = constants.%complete_type.98e] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: .B = +// CHECK:STDOUT: .base = %.loc25 +// CHECK:STDOUT: .F = %C.F.decl +// CHECK:STDOUT: extend %B.ref +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @D { +// CHECK:STDOUT: %B.ref: type = name_ref B, file.%B.decl [concrete = constants.%B] +// CHECK:STDOUT: %.loc30: %D.elem = base_decl %B.ref, element0 [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.base.0ff [concrete = constants.%complete_type.98e] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%D +// CHECK:STDOUT: .B = +// CHECK:STDOUT: .base = %.loc30 +// CHECK:STDOUT: .F = +// CHECK:STDOUT: extend %B.ref +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @A.F(%self.param: %ptr.6db); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B.F(%self.param: %ptr.e79); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.F(%self.param: %ptr.019); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Call(%a.param: %ptr.6db, %b.param: %ptr.e79, %c.param: %ptr.019, %d.param: %ptr.19c) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %a.ref: %ptr.6db = name_ref a, %a +// CHECK:STDOUT: %.loc34: ref %A = deref %a.ref +// CHECK:STDOUT: %F.ref.loc34: %A.F.type = name_ref F, @A.%A.F.decl [concrete = constants.%A.F] +// CHECK:STDOUT: %A.F.bound: = bound_method %.loc34, %F.ref.loc34 +// CHECK:STDOUT: %addr.loc34: %ptr.6db = addr_of %.loc34 +// CHECK:STDOUT: %A.F.call: init %empty_tuple.type = call %A.F.bound(%addr.loc34) +// CHECK:STDOUT: %b.ref: %ptr.e79 = name_ref b, %b +// CHECK:STDOUT: %.loc35: ref %B = deref %b.ref +// CHECK:STDOUT: %F.ref.loc35: %B.F.type = name_ref F, @B.%B.F.decl [concrete = constants.%B.F] +// CHECK:STDOUT: %B.F.bound.loc35: = bound_method %.loc35, %F.ref.loc35 +// CHECK:STDOUT: %addr.loc35: %ptr.e79 = addr_of %.loc35 +// CHECK:STDOUT: %B.F.call.loc35: init %empty_tuple.type = call %B.F.bound.loc35(%addr.loc35) +// CHECK:STDOUT: %c.ref: %ptr.019 = name_ref c, %c +// CHECK:STDOUT: %.loc36: ref %C = deref %c.ref +// CHECK:STDOUT: %F.ref.loc36: %C.F.type = name_ref F, @C.%C.F.decl [concrete = constants.%C.F] +// CHECK:STDOUT: %C.F.bound: = bound_method %.loc36, %F.ref.loc36 +// CHECK:STDOUT: %addr.loc36: %ptr.019 = addr_of %.loc36 +// CHECK:STDOUT: %C.F.call: init %empty_tuple.type = call %C.F.bound(%addr.loc36) +// CHECK:STDOUT: %d.ref: %ptr.19c = name_ref d, %d +// CHECK:STDOUT: %.loc37_4.1: ref %D = deref %d.ref +// CHECK:STDOUT: %F.ref.loc37: %B.F.type = name_ref F, @B.%B.F.decl [concrete = constants.%B.F] +// CHECK:STDOUT: %B.F.bound.loc37: = bound_method %.loc37_4.1, %F.ref.loc37 +// CHECK:STDOUT: %addr.loc37_4.1: %ptr.19c = addr_of %.loc37_4.1 +// CHECK:STDOUT: %.loc37_4.2: ref %D = deref %addr.loc37_4.1 +// CHECK:STDOUT: %.loc37_4.3: ref %B = class_element_access %.loc37_4.2, element0 +// CHECK:STDOUT: %addr.loc37_4.2: %ptr.e79 = addr_of %.loc37_4.3 +// CHECK:STDOUT: %.loc37_4.4: %ptr.e79 = converted %addr.loc37_4.1, %addr.loc37_4.2 +// CHECK:STDOUT: %B.F.call.loc37: init %empty_tuple.type = call %B.F.bound.loc37(%.loc37_4.4) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/fail_ref_self.carbon b/toolchain/check/testdata/class/fail_ref_self.carbon new file mode 100644 index 000000000000..790622b06019 --- /dev/null +++ b/toolchain/check/testdata/class/fail_ref_self.carbon @@ -0,0 +1,153 @@ +// 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 +// 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/class/fail_ref_self.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/fail_ref_self.carbon + +class Class { + fn F[ref self: Self](); +} + +fn Make() -> Class; + +fn F(c: Class, p: Class*) { + // CHECK:STDERR: fail_ref_self.carbon:[[@LINE+7]]:3: error: value expression passed to reference parameter [ValueForRefParam] + // CHECK:STDERR: c.F(); + // CHECK:STDERR: ^ + // CHECK:STDERR: fail_ref_self.carbon:[[@LINE-9]]:8: note: initializing function parameter [InCallToFunctionParam] + // CHECK:STDERR: fn F[ref self: Self](); + // CHECK:STDERR: ^~~~~~~~~~~~~~ + // CHECK:STDERR: + c.F(); + + // This call is OK. + (*p).F(); + + // So is this one. + Make().F(); +} + +// CHECK:STDOUT: --- fail_ref_self.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Class: type = class_type @Class [concrete] +// CHECK:STDOUT: %pattern_type.761: type = pattern_type %Class [concrete] +// CHECK:STDOUT: %Class.F.type: type = fn_type @Class.F [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %Make.type: type = fn_type @Make [concrete] +// CHECK:STDOUT: %Make: %Make.type = struct_value () [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %type_where: type = facet_type > [concrete] +// CHECK:STDOUT: %facet_value: %type_where = facet_value %Class, () [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.e99: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.378: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.e99 = struct_value () [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.378, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Class = %Class.decl +// CHECK:STDOUT: .Make = %Make.decl +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Class.decl: type = class_decl @Class [concrete = constants.%Class] {} {} +// CHECK:STDOUT: %Make.decl: %Make.type = fn_decl @Make [concrete = constants.%Make] { +// CHECK:STDOUT: %return.patt: %pattern_type.761 = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.761 = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Class.ref: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] +// CHECK:STDOUT: %return.param: ref %Class = out_param call_param0 +// CHECK:STDOUT: %return: ref %Class = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %c.patt: %pattern_type.761 = value_binding_pattern c [concrete] +// CHECK:STDOUT: %c.param_patt: %pattern_type.761 = value_param_pattern %c.patt, call_param0 [concrete] +// CHECK:STDOUT: %p.patt: %pattern_type.796 = value_binding_pattern p [concrete] +// CHECK:STDOUT: %p.param_patt: %pattern_type.796 = value_param_pattern %p.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %c.param: %Class = value_param call_param0 +// CHECK:STDOUT: %Class.ref.loc21_9: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] +// CHECK:STDOUT: %c: %Class = value_binding c, %c.param +// CHECK:STDOUT: %p.param: %ptr.e71 = value_param call_param1 +// CHECK:STDOUT: %.loc21: type = splice_block %ptr [concrete = constants.%ptr.e71] { +// CHECK:STDOUT: %Class.ref.loc21_19: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] +// CHECK:STDOUT: %ptr: type = ptr_type %Class.ref.loc21_19 [concrete = constants.%ptr.e71] +// CHECK:STDOUT: } +// CHECK:STDOUT: %p: %ptr.e71 = value_binding p, %p.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Class { +// CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { +// CHECK:STDOUT: %self.patt: %pattern_type.761 = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.761 = ref_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: ref %Class = ref_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: ref %Class = ref_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Class +// CHECK:STDOUT: .F = %Class.F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.F(%self.param: %Class); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Make() -> %return.param: %Class; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(%c.param: %Class, %p.param: %ptr.e71) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %c.ref: %Class = name_ref c, %c +// CHECK:STDOUT: %F.ref.loc29: %Class.F.type = name_ref F, @Class.%Class.F.decl [concrete = constants.%Class.F] +// CHECK:STDOUT: %Class.F.bound.loc29: = bound_method %c.ref, %F.ref.loc29 +// CHECK:STDOUT: %.loc29: ref %Class = temporary_storage +// CHECK:STDOUT: %Class.F.call.loc29: init %empty_tuple.type = call %Class.F.bound.loc29(%.loc29) +// CHECK:STDOUT: %p.ref: %ptr.e71 = name_ref p, %p +// CHECK:STDOUT: %.loc32: ref %Class = deref %p.ref +// CHECK:STDOUT: %F.ref.loc32: %Class.F.type = name_ref F, @Class.%Class.F.decl [concrete = constants.%Class.F] +// CHECK:STDOUT: %Class.F.bound.loc32: = bound_method %.loc32, %F.ref.loc32 +// CHECK:STDOUT: %Class.F.call.loc32: init %empty_tuple.type = call %Class.F.bound.loc32(%.loc32) +// CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make] +// CHECK:STDOUT: %.loc35_8.1: ref %Class = temporary_storage +// CHECK:STDOUT: %Make.call: init %Class = call %Make.ref() to %.loc35_8.1 +// CHECK:STDOUT: %.loc35_8.2: ref %Class = temporary %.loc35_8.1, %Make.call +// CHECK:STDOUT: %F.ref.loc35: %Class.F.type = name_ref F, @Class.%Class.F.decl [concrete = constants.%Class.F] +// CHECK:STDOUT: %Class.F.bound.loc35: = bound_method %.loc35_8.2, %F.ref.loc35 +// CHECK:STDOUT: %Class.F.call.loc35: init %empty_tuple.type = call %Class.F.bound.loc35(%.loc35_8.2) +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: = bound_method %.loc35_8.2, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.378 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.378, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method: = bound_method %.loc35_8.2, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %addr: %ptr.e71 = addr_of %.loc35_8.2 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/generic/basic.carbon b/toolchain/check/testdata/class/generic/basic.carbon index a136833d2c5e..20613d7ddf1c 100644 --- a/toolchain/check/testdata/class/generic/basic.carbon +++ b/toolchain/check/testdata/class/generic/basic.carbon @@ -16,8 +16,8 @@ library "[[@TEST_NAME]]"; //@dump-sem-ir-begin class Class(T:! Core.Copy) { - fn GetAddr[addr self: Self*]() -> T* { - return &self->k; + fn GetAddr[ref self: Self]() -> T* { + return &self.k; } fn GetValue[self: Self]() -> T { @@ -39,15 +39,12 @@ class Declaration(T:! type); // CHECK:STDOUT: %Class.type: type = generic_class_type @Class [concrete] // CHECK:STDOUT: %Class.generic: %Class.type = struct_value () [concrete] // CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T.417) [symbolic] -// CHECK:STDOUT: %ptr.5a6: type = ptr_type %Class [symbolic] -// CHECK:STDOUT: %pattern_type.ed4: type = pattern_type %ptr.5a6 [symbolic] -// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %pattern_type.fe4: type = pattern_type %Class [symbolic] // CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T.417 [symbolic] // CHECK:STDOUT: %ptr.d8c: type = ptr_type %T.binding.as_type [symbolic] // CHECK:STDOUT: %pattern_type.12f: type = pattern_type %ptr.d8c [symbolic] // CHECK:STDOUT: %Class.GetAddr.type: type = fn_type @Class.GetAddr, @Class(%T.417) [symbolic] // CHECK:STDOUT: %Class.GetAddr: %Class.GetAddr.type = struct_value () [symbolic] -// CHECK:STDOUT: %pattern_type.fe4: type = pattern_type %Class [symbolic] // CHECK:STDOUT: %pattern_type.f14b96.1: type = pattern_type %T.binding.as_type [symbolic] // CHECK:STDOUT: %Class.GetValue.type: type = fn_type @Class.GetValue, @Class(%T.417) [symbolic] // CHECK:STDOUT: %Class.GetValue: %Class.GetValue.type = struct_value () [symbolic] @@ -56,7 +53,6 @@ class Declaration(T:! type); // CHECK:STDOUT: %struct_type.k: type = struct_type {.k: %T.binding.as_type} [symbolic] // CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.k [symbolic] // CHECK:STDOUT: %require_complete.d1a: = require_complete_type %ptr.d8c [symbolic] -// CHECK:STDOUT: %require_complete.797: = require_complete_type %ptr.5a6 [symbolic] // CHECK:STDOUT: %require_complete.f79: = require_complete_type %Class [symbolic] // CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [concrete] // CHECK:STDOUT: %Copy.lookup_impl_witness.c42: = lookup_impl_witness %T.417, @Copy [symbolic] @@ -119,25 +115,23 @@ class Declaration(T:! type); // CHECK:STDOUT: // CHECK:STDOUT: class { // CHECK:STDOUT: %Class.GetAddr.decl: @Class.%Class.GetAddr.type (%Class.GetAddr.type) = fn_decl @Class.GetAddr [symbolic = @Class.%Class.GetAddr (constants.%Class.GetAddr)] { -// CHECK:STDOUT: %self.patt: @Class.GetAddr.%pattern_type.loc6_19 (%pattern_type.ed4) = value_binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: @Class.GetAddr.%pattern_type.loc6_19 (%pattern_type.ed4) = value_param_pattern %self.patt, call_param0 [concrete] -// CHECK:STDOUT: %.loc6_14: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] -// CHECK:STDOUT: %return.patt: @Class.GetAddr.%pattern_type.loc6_34 (%pattern_type.12f) = return_slot_pattern [concrete] -// CHECK:STDOUT: %return.param_patt: @Class.GetAddr.%pattern_type.loc6_34 (%pattern_type.12f) = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: %self.patt: @Class.GetAddr.%pattern_type.loc6_18 (%pattern_type.fe4) = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.GetAddr.%pattern_type.loc6_18 (%pattern_type.fe4) = ref_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: @Class.GetAddr.%pattern_type.loc6_32 (%pattern_type.12f) = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: @Class.GetAddr.%pattern_type.loc6_32 (%pattern_type.12f) = out_param_pattern %return.patt, call_param1 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %T.ref: %Copy.type = name_ref T, @Class.%T.loc5_13.2 [symbolic = %T (constants.%T.417)] // CHECK:STDOUT: %T.as_type: type = facet_access_type %T.ref [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] -// CHECK:STDOUT: %.loc6_38: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] -// CHECK:STDOUT: %ptr.loc6_38.2: type = ptr_type %.loc6_38 [symbolic = %ptr.loc6_38.1 (constants.%ptr.d8c)] -// CHECK:STDOUT: %self.param: @Class.GetAddr.%ptr.loc6_29.1 (%ptr.5a6) = value_param call_param0 -// CHECK:STDOUT: %.loc6_29: type = splice_block %ptr.loc6_29.2 [symbolic = %ptr.loc6_29.1 (constants.%ptr.5a6)] { -// CHECK:STDOUT: %.loc6_25: type = specific_constant constants.%Class, @Class(constants.%T.417) [symbolic = %Class (constants.%Class)] -// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc6_25 [symbolic = %Class (constants.%Class)] -// CHECK:STDOUT: %ptr.loc6_29.2: type = ptr_type %Self.ref [symbolic = %ptr.loc6_29.1 (constants.%ptr.5a6)] +// CHECK:STDOUT: %.loc6_36: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %ptr.loc6_36.2: type = ptr_type %.loc6_36 [symbolic = %ptr.loc6_36.1 (constants.%ptr.d8c)] +// CHECK:STDOUT: %self.param: ref @Class.GetAddr.%Class (%Class) = ref_param call_param0 +// CHECK:STDOUT: %.loc6_24.1: type = splice_block %Self.ref [symbolic = %Class (constants.%Class)] { +// CHECK:STDOUT: %.loc6_24.2: type = specific_constant constants.%Class, @Class(constants.%T.417) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc6_24.2 [symbolic = %Class (constants.%Class)] // CHECK:STDOUT: } -// CHECK:STDOUT: %self: @Class.GetAddr.%ptr.loc6_29.1 (%ptr.5a6) = value_binding self, %self.param -// CHECK:STDOUT: %return.param: ref @Class.GetAddr.%ptr.loc6_38.1 (%ptr.d8c) = out_param call_param1 -// CHECK:STDOUT: %return: ref @Class.GetAddr.%ptr.loc6_38.1 (%ptr.d8c) = return_slot %return.param +// CHECK:STDOUT: %self: ref @Class.GetAddr.%Class (%Class) = ref_binding self, %self.param +// CHECK:STDOUT: %return.param: ref @Class.GetAddr.%ptr.loc6_36.1 (%ptr.d8c) = out_param call_param1 +// CHECK:STDOUT: %return: ref @Class.GetAddr.%ptr.loc6_36.1 (%ptr.d8c) = return_slot %return.param // CHECK:STDOUT: } // CHECK:STDOUT: %Class.GetValue.decl: @Class.%Class.GetValue.type (%Class.GetValue.type) = fn_decl @Class.GetValue [symbolic = @Class.%Class.GetValue (constants.%Class.GetValue)] { // CHECK:STDOUT: %self.patt: @Class.GetValue.%pattern_type.loc10_15 (%pattern_type.fe4) = value_binding_pattern self [concrete] @@ -182,35 +176,32 @@ class Declaration(T:! type); // CHECK:STDOUT: generic fn @Class.GetAddr(@Class.%T.loc5_13.2: %Copy.type) { // CHECK:STDOUT: %T: %Copy.type = symbolic_binding T, 0 [symbolic = %T (constants.%T.417)] // CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class)] -// CHECK:STDOUT: %ptr.loc6_29.1: type = ptr_type %Class [symbolic = %ptr.loc6_29.1 (constants.%ptr.5a6)] -// CHECK:STDOUT: %pattern_type.loc6_19: type = pattern_type %ptr.loc6_29.1 [symbolic = %pattern_type.loc6_19 (constants.%pattern_type.ed4)] +// CHECK:STDOUT: %pattern_type.loc6_18: type = pattern_type %Class [symbolic = %pattern_type.loc6_18 (constants.%pattern_type.fe4)] // CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] -// CHECK:STDOUT: %ptr.loc6_38.1: type = ptr_type %T.binding.as_type [symbolic = %ptr.loc6_38.1 (constants.%ptr.d8c)] -// CHECK:STDOUT: %pattern_type.loc6_34: type = pattern_type %ptr.loc6_38.1 [symbolic = %pattern_type.loc6_34 (constants.%pattern_type.12f)] +// CHECK:STDOUT: %ptr.loc6_36.1: type = ptr_type %T.binding.as_type [symbolic = %ptr.loc6_36.1 (constants.%ptr.d8c)] +// CHECK:STDOUT: %pattern_type.loc6_32: type = pattern_type %ptr.loc6_36.1 [symbolic = %pattern_type.loc6_32 (constants.%pattern_type.12f)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete.loc6_34: = require_complete_type %ptr.loc6_38.1 [symbolic = %require_complete.loc6_34 (constants.%require_complete.d1a)] -// CHECK:STDOUT: %require_complete.loc6_23: = require_complete_type %ptr.loc6_29.1 [symbolic = %require_complete.loc6_23 (constants.%require_complete.797)] -// CHECK:STDOUT: %require_complete.loc7: = require_complete_type %Class [symbolic = %require_complete.loc7 (constants.%require_complete.f79)] +// CHECK:STDOUT: %require_complete.loc6_32: = require_complete_type %ptr.loc6_36.1 [symbolic = %require_complete.loc6_32 (constants.%require_complete.d1a)] +// CHECK:STDOUT: %require_complete.loc6_22: = require_complete_type %Class [symbolic = %require_complete.loc6_22 (constants.%require_complete.f79)] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %T.binding.as_type [symbolic = %Class.elem (constants.%Class.elem)] -// CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc6_38.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.34c)] -// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc6_38.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)] +// CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc6_36.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.34c)] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc6_36.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)] // CHECK:STDOUT: %.loc7_12.2: type = fn_type_with_self_type constants.%Copy.Op.type, %Copy.facet [symbolic = %.loc7_12.2 (constants.%.dba)] // CHECK:STDOUT: %impl.elem0.loc7_12.2: @Class.GetAddr.%.loc7_12.2 (%.dba) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc7_12.2 (constants.%impl.elem0.f88)] // CHECK:STDOUT: %specific_impl_fn.loc7_12.2: = specific_impl_function %impl.elem0.loc7_12.2, @Copy.Op(%Copy.facet) [symbolic = %specific_impl_fn.loc7_12.2 (constants.%specific_impl_fn.5e8)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%self.param: @Class.GetAddr.%ptr.loc6_29.1 (%ptr.5a6)) -> @Class.GetAddr.%ptr.loc6_38.1 (%ptr.d8c) { +// CHECK:STDOUT: fn(%self.param: @Class.GetAddr.%Class (%Class)) -> @Class.GetAddr.%ptr.loc6_36.1 (%ptr.d8c) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %self.ref: @Class.GetAddr.%ptr.loc6_29.1 (%ptr.5a6) = name_ref self, %self -// CHECK:STDOUT: %.loc7_17.1: ref @Class.GetAddr.%Class (%Class) = deref %self.ref +// CHECK:STDOUT: %self.ref: ref @Class.GetAddr.%Class (%Class) = name_ref self, %self // CHECK:STDOUT: %k.ref: @Class.GetAddr.%Class.elem (%Class.elem) = name_ref k, @Class.%.loc14_8 [concrete = @Class.%.loc14_8] -// CHECK:STDOUT: %.loc7_17.2: ref @Class.GetAddr.%T.binding.as_type (%T.binding.as_type) = class_element_access %.loc7_17.1, element0 -// CHECK:STDOUT: %addr: @Class.GetAddr.%ptr.loc6_38.1 (%ptr.d8c) = addr_of %.loc7_17.2 +// CHECK:STDOUT: %.loc7_17: ref @Class.GetAddr.%T.binding.as_type (%T.binding.as_type) = class_element_access %self.ref, element0 +// CHECK:STDOUT: %addr: @Class.GetAddr.%ptr.loc6_36.1 (%ptr.d8c) = addr_of %.loc7_17 // CHECK:STDOUT: %impl.elem0.loc7_12.1: @Class.GetAddr.%.loc7_12.2 (%.dba) = impl_witness_access constants.%Copy.lookup_impl_witness.34c, element0 [symbolic = %impl.elem0.loc7_12.2 (constants.%impl.elem0.f88)] // CHECK:STDOUT: %bound_method.loc7_12.1: = bound_method %addr, %impl.elem0.loc7_12.1 // CHECK:STDOUT: %specific_impl_fn.loc7_12.1: = specific_impl_function %impl.elem0.loc7_12.1, @Copy.Op(constants.%Copy.facet) [symbolic = %specific_impl_fn.loc7_12.2 (constants.%specific_impl_fn.5e8)] // CHECK:STDOUT: %bound_method.loc7_12.2: = bound_method %addr, %specific_impl_fn.loc7_12.1 -// CHECK:STDOUT: %.loc7_12.1: init @Class.GetAddr.%ptr.loc6_38.1 (%ptr.d8c) = call %bound_method.loc7_12.2(%addr) +// CHECK:STDOUT: %.loc7_12.1: init @Class.GetAddr.%ptr.loc6_36.1 (%ptr.d8c) = call %bound_method.loc7_12.2(%addr) // CHECK:STDOUT: return %.loc7_12.1 to %return // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -266,11 +257,10 @@ class Declaration(T:! type); // CHECK:STDOUT: specific @Class.GetAddr(constants.%T.417) { // CHECK:STDOUT: %T => constants.%T.417 // CHECK:STDOUT: %Class => constants.%Class -// CHECK:STDOUT: %ptr.loc6_29.1 => constants.%ptr.5a6 -// CHECK:STDOUT: %pattern_type.loc6_19 => constants.%pattern_type.ed4 +// CHECK:STDOUT: %pattern_type.loc6_18 => constants.%pattern_type.fe4 // CHECK:STDOUT: %T.binding.as_type => constants.%T.binding.as_type -// CHECK:STDOUT: %ptr.loc6_38.1 => constants.%ptr.d8c -// CHECK:STDOUT: %pattern_type.loc6_34 => constants.%pattern_type.12f +// CHECK:STDOUT: %ptr.loc6_36.1 => constants.%ptr.d8c +// CHECK:STDOUT: %pattern_type.loc6_32 => constants.%pattern_type.12f // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @Class.GetValue(constants.%T.417) { diff --git a/toolchain/check/testdata/class/generic/basic_addr.carbon b/toolchain/check/testdata/class/generic/basic_addr.carbon new file mode 100644 index 000000000000..90d4d75dc14c --- /dev/null +++ b/toolchain/check/testdata/class/generic/basic_addr.carbon @@ -0,0 +1,287 @@ +// 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/class/generic/basic_addr.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/generic/basic_addr.carbon + +// --- basic_addr.carbon + +library "[[@TEST_NAME]]"; + +//@dump-sem-ir-begin +class Class(T:! Core.Copy) { + fn GetAddr[addr self: Self*]() -> T* { + return &self->k; + } + + fn GetValue[self: Self]() -> T { + return self.k; + } + + var k: T; +} + +class Declaration(T:! type); +//@dump-sem-ir-end + +// CHECK:STDOUT: --- basic_addr.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] +// CHECK:STDOUT: %T.417: %Copy.type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %pattern_type.322: type = pattern_type %Copy.type [concrete] +// CHECK:STDOUT: %Class.type: type = generic_class_type @Class [concrete] +// CHECK:STDOUT: %Class.generic: %Class.type = struct_value () [concrete] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T.417) [symbolic] +// CHECK:STDOUT: %ptr.5a6: type = ptr_type %Class [symbolic] +// CHECK:STDOUT: %pattern_type.ed4: type = pattern_type %ptr.5a6 [symbolic] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T.417 [symbolic] +// CHECK:STDOUT: %ptr.d8c: type = ptr_type %T.binding.as_type [symbolic] +// CHECK:STDOUT: %pattern_type.12f: type = pattern_type %ptr.d8c [symbolic] +// CHECK:STDOUT: %Class.GetAddr.type: type = fn_type @Class.GetAddr, @Class(%T.417) [symbolic] +// CHECK:STDOUT: %Class.GetAddr: %Class.GetAddr.type = struct_value () [symbolic] +// CHECK:STDOUT: %pattern_type.fe4: type = pattern_type %Class [symbolic] +// CHECK:STDOUT: %pattern_type.f14b96.1: type = pattern_type %T.binding.as_type [symbolic] +// CHECK:STDOUT: %Class.GetValue.type: type = fn_type @Class.GetValue, @Class(%T.417) [symbolic] +// CHECK:STDOUT: %Class.GetValue: %Class.GetValue.type = struct_value () [symbolic] +// CHECK:STDOUT: %require_complete.d74: = require_complete_type %T.binding.as_type [symbolic] +// CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %T.binding.as_type [symbolic] +// CHECK:STDOUT: %struct_type.k: type = struct_type {.k: %T.binding.as_type} [symbolic] +// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.k [symbolic] +// CHECK:STDOUT: %require_complete.d1a: = require_complete_type %ptr.d8c [symbolic] +// CHECK:STDOUT: %require_complete.797: = require_complete_type %ptr.5a6 [symbolic] +// CHECK:STDOUT: %require_complete.f79: = require_complete_type %Class [symbolic] +// CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [concrete] +// CHECK:STDOUT: %Copy.lookup_impl_witness.c42: = lookup_impl_witness %T.417, @Copy [symbolic] +// CHECK:STDOUT: %.a79: type = fn_type_with_self_type %Copy.Op.type, %T.417 [symbolic] +// CHECK:STDOUT: %impl.elem0.fac: %.a79 = impl_witness_access %Copy.lookup_impl_witness.c42, element0 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.103: = specific_impl_function %impl.elem0.fac, @Copy.Op(%T.417) [symbolic] +// CHECK:STDOUT: %T.d9f: type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] +// CHECK:STDOUT: %Copy.lookup_impl_witness.34c: = lookup_impl_witness %ptr.d8c, @Copy [symbolic] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.d8c, (%Copy.lookup_impl_witness.34c) [symbolic] +// CHECK:STDOUT: %.dba: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet [symbolic] +// CHECK:STDOUT: %impl.elem0.f88: %.dba = impl_witness_access %Copy.lookup_impl_witness.34c, element0 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.5e8: = specific_impl_function %impl.elem0.f88, @Copy.Op(%Copy.facet) [symbolic] +// CHECK:STDOUT: %Declaration.type: type = generic_class_type @Declaration [concrete] +// CHECK:STDOUT: %Declaration.generic: %Declaration.type = struct_value () [concrete] +// 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: %Class.decl: %Class.type = class_decl @Class [concrete = constants.%Class.generic] { +// CHECK:STDOUT: %T.patt: %pattern_type.322 = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc5: type = splice_block %Copy.ref [concrete = constants.%Copy.type] { +// CHECK:STDOUT: +// CHECK:STDOUT: %Core.ref: = name_ref Core, imports.%Core [concrete = imports.%Core] +// CHECK:STDOUT: %Copy.ref: type = name_ref Copy, imports.%Core.Copy [concrete = constants.%Copy.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.loc5_13.2: %Copy.type = symbolic_binding T, 0 [symbolic = %T.loc5_13.1 (constants.%T.417)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %Declaration.decl: %Declaration.type = class_decl @Declaration [concrete = constants.%Declaration.generic] { +// CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: %T.loc17_19.2: type = symbolic_binding T, 0 [symbolic = %T.loc17_19.1 (constants.%T.d9f)] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @Class(%T.loc5_13.2: %Copy.type) { +// CHECK:STDOUT: %T.loc5_13.1: %Copy.type = symbolic_binding T, 0 [symbolic = %T.loc5_13.1 (constants.%T.417)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.GetAddr.type: type = fn_type @Class.GetAddr, @Class(%T.loc5_13.1) [symbolic = %Class.GetAddr.type (constants.%Class.GetAddr.type)] +// CHECK:STDOUT: %Class.GetAddr: @Class.%Class.GetAddr.type (%Class.GetAddr.type) = struct_value () [symbolic = %Class.GetAddr (constants.%Class.GetAddr)] +// CHECK:STDOUT: %Class.GetValue.type: type = fn_type @Class.GetValue, @Class(%T.loc5_13.1) [symbolic = %Class.GetValue.type (constants.%Class.GetValue.type)] +// CHECK:STDOUT: %Class.GetValue: @Class.%Class.GetValue.type (%Class.GetValue.type) = struct_value () [symbolic = %Class.GetValue (constants.%Class.GetValue)] +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T.loc5_13.1 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %require_complete: = require_complete_type %T.binding.as_type [symbolic = %require_complete (constants.%require_complete.d74)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T.loc5_13.1) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %T.binding.as_type [symbolic = %Class.elem (constants.%Class.elem)] +// CHECK:STDOUT: %struct_type.k: type = struct_type {.k: @Class.%T.binding.as_type (%T.binding.as_type)} [symbolic = %struct_type.k (constants.%struct_type.k)] +// CHECK:STDOUT: %complete_type.loc15_1.2: = complete_type_witness %struct_type.k [symbolic = %complete_type.loc15_1.2 (constants.%complete_type)] +// CHECK:STDOUT: +// CHECK:STDOUT: class { +// CHECK:STDOUT: %Class.GetAddr.decl: @Class.%Class.GetAddr.type (%Class.GetAddr.type) = fn_decl @Class.GetAddr [symbolic = @Class.%Class.GetAddr (constants.%Class.GetAddr)] { +// CHECK:STDOUT: %self.patt: @Class.GetAddr.%pattern_type.loc6_19 (%pattern_type.ed4) = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.GetAddr.%pattern_type.loc6_19 (%pattern_type.ed4) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc6_14: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %return.patt: @Class.GetAddr.%pattern_type.loc6_34 (%pattern_type.12f) = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: @Class.GetAddr.%pattern_type.loc6_34 (%pattern_type.12f) = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.ref: %Copy.type = name_ref T, @Class.%T.loc5_13.2 [symbolic = %T (constants.%T.417)] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T.ref [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %.loc6_38: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %ptr.loc6_38.2: type = ptr_type %.loc6_38 [symbolic = %ptr.loc6_38.1 (constants.%ptr.d8c)] +// CHECK:STDOUT: %self.param: @Class.GetAddr.%ptr.loc6_29.1 (%ptr.5a6) = value_param call_param0 +// CHECK:STDOUT: %.loc6_29: type = splice_block %ptr.loc6_29.2 [symbolic = %ptr.loc6_29.1 (constants.%ptr.5a6)] { +// CHECK:STDOUT: %.loc6_25: type = specific_constant constants.%Class, @Class(constants.%T.417) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc6_25 [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %ptr.loc6_29.2: type = ptr_type %Self.ref [symbolic = %ptr.loc6_29.1 (constants.%ptr.5a6)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.GetAddr.%ptr.loc6_29.1 (%ptr.5a6) = value_binding self, %self.param +// CHECK:STDOUT: %return.param: ref @Class.GetAddr.%ptr.loc6_38.1 (%ptr.d8c) = out_param call_param1 +// CHECK:STDOUT: %return: ref @Class.GetAddr.%ptr.loc6_38.1 (%ptr.d8c) = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %Class.GetValue.decl: @Class.%Class.GetValue.type (%Class.GetValue.type) = fn_decl @Class.GetValue [symbolic = @Class.%Class.GetValue (constants.%Class.GetValue)] { +// CHECK:STDOUT: %self.patt: @Class.GetValue.%pattern_type.loc10_15 (%pattern_type.fe4) = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @Class.GetValue.%pattern_type.loc10_15 (%pattern_type.fe4) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: @Class.GetValue.%pattern_type.loc10_29 (%pattern_type.f14b96.1) = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: @Class.GetValue.%pattern_type.loc10_29 (%pattern_type.f14b96.1) = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.ref: %Copy.type = name_ref T, @Class.%T.loc5_13.2 [symbolic = %T (constants.%T.417)] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T.ref [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %.loc10_32: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %self.param: @Class.GetValue.%Class (%Class) = value_param call_param0 +// CHECK:STDOUT: %.loc10_21.1: type = splice_block %Self.ref [symbolic = %Class (constants.%Class)] { +// CHECK:STDOUT: %.loc10_21.2: type = specific_constant constants.%Class, @Class(constants.%T.417) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc10_21.2 [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @Class.GetValue.%Class (%Class) = value_binding self, %self.param +// CHECK:STDOUT: %return.param: ref @Class.GetValue.%T.binding.as_type (%T.binding.as_type) = out_param call_param1 +// CHECK:STDOUT: %return: ref @Class.GetValue.%T.binding.as_type (%T.binding.as_type) = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.ref: %Copy.type = name_ref T, %T.loc5_13.2 [symbolic = %T.loc5_13.1 (constants.%T.417)] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T.ref [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %.loc14_10: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %.loc14_8: @Class.%Class.elem (%Class.elem) = field_decl k, element0 [concrete] +// CHECK:STDOUT: %complete_type.loc15_1.1: = complete_type_witness constants.%struct_type.k [symbolic = %complete_type.loc15_1.2 (constants.%complete_type)] +// CHECK:STDOUT: complete_type_witness = %complete_type.loc15_1.1 +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Class +// CHECK:STDOUT: .T = +// CHECK:STDOUT: .GetAddr = %Class.GetAddr.decl +// CHECK:STDOUT: .GetValue = %Class.GetValue.decl +// CHECK:STDOUT: .k = %.loc14_8 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic class @Declaration(%T.loc17_19.2: type) { +// CHECK:STDOUT: %T.loc17_19.1: type = symbolic_binding T, 0 [symbolic = %T.loc17_19.1 (constants.%T.d9f)] +// CHECK:STDOUT: +// CHECK:STDOUT: class; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.GetAddr(@Class.%T.loc5_13.2: %Copy.type) { +// CHECK:STDOUT: %T: %Copy.type = symbolic_binding T, 0 [symbolic = %T (constants.%T.417)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %ptr.loc6_29.1: type = ptr_type %Class [symbolic = %ptr.loc6_29.1 (constants.%ptr.5a6)] +// CHECK:STDOUT: %pattern_type.loc6_19: type = pattern_type %ptr.loc6_29.1 [symbolic = %pattern_type.loc6_19 (constants.%pattern_type.ed4)] +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %ptr.loc6_38.1: type = ptr_type %T.binding.as_type [symbolic = %ptr.loc6_38.1 (constants.%ptr.d8c)] +// CHECK:STDOUT: %pattern_type.loc6_34: type = pattern_type %ptr.loc6_38.1 [symbolic = %pattern_type.loc6_34 (constants.%pattern_type.12f)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete.loc6_34: = require_complete_type %ptr.loc6_38.1 [symbolic = %require_complete.loc6_34 (constants.%require_complete.d1a)] +// CHECK:STDOUT: %require_complete.loc6_23: = require_complete_type %ptr.loc6_29.1 [symbolic = %require_complete.loc6_23 (constants.%require_complete.797)] +// CHECK:STDOUT: %require_complete.loc7: = require_complete_type %Class [symbolic = %require_complete.loc7 (constants.%require_complete.f79)] +// CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %T.binding.as_type [symbolic = %Class.elem (constants.%Class.elem)] +// CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc6_38.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.34c)] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc6_38.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)] +// CHECK:STDOUT: %.loc7_12.2: type = fn_type_with_self_type constants.%Copy.Op.type, %Copy.facet [symbolic = %.loc7_12.2 (constants.%.dba)] +// CHECK:STDOUT: %impl.elem0.loc7_12.2: @Class.GetAddr.%.loc7_12.2 (%.dba) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc7_12.2 (constants.%impl.elem0.f88)] +// CHECK:STDOUT: %specific_impl_fn.loc7_12.2: = specific_impl_function %impl.elem0.loc7_12.2, @Copy.Op(%Copy.facet) [symbolic = %specific_impl_fn.loc7_12.2 (constants.%specific_impl_fn.5e8)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.GetAddr.%ptr.loc6_29.1 (%ptr.5a6)) -> @Class.GetAddr.%ptr.loc6_38.1 (%ptr.d8c) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %self.ref: @Class.GetAddr.%ptr.loc6_29.1 (%ptr.5a6) = name_ref self, %self +// CHECK:STDOUT: %.loc7_17.1: ref @Class.GetAddr.%Class (%Class) = deref %self.ref +// CHECK:STDOUT: %k.ref: @Class.GetAddr.%Class.elem (%Class.elem) = name_ref k, @Class.%.loc14_8 [concrete = @Class.%.loc14_8] +// CHECK:STDOUT: %.loc7_17.2: ref @Class.GetAddr.%T.binding.as_type (%T.binding.as_type) = class_element_access %.loc7_17.1, element0 +// CHECK:STDOUT: %addr: @Class.GetAddr.%ptr.loc6_38.1 (%ptr.d8c) = addr_of %.loc7_17.2 +// CHECK:STDOUT: %impl.elem0.loc7_12.1: @Class.GetAddr.%.loc7_12.2 (%.dba) = impl_witness_access constants.%Copy.lookup_impl_witness.34c, element0 [symbolic = %impl.elem0.loc7_12.2 (constants.%impl.elem0.f88)] +// CHECK:STDOUT: %bound_method.loc7_12.1: = bound_method %addr, %impl.elem0.loc7_12.1 +// CHECK:STDOUT: %specific_impl_fn.loc7_12.1: = specific_impl_function %impl.elem0.loc7_12.1, @Copy.Op(constants.%Copy.facet) [symbolic = %specific_impl_fn.loc7_12.2 (constants.%specific_impl_fn.5e8)] +// CHECK:STDOUT: %bound_method.loc7_12.2: = bound_method %addr, %specific_impl_fn.loc7_12.1 +// CHECK:STDOUT: %.loc7_12.1: init @Class.GetAddr.%ptr.loc6_38.1 (%ptr.d8c) = call %bound_method.loc7_12.2(%addr) +// CHECK:STDOUT: return %.loc7_12.1 to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Class.GetValue(@Class.%T.loc5_13.2: %Copy.type) { +// CHECK:STDOUT: %T: %Copy.type = symbolic_binding T, 0 [symbolic = %T (constants.%T.417)] +// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class)] +// CHECK:STDOUT: %pattern_type.loc10_15: type = pattern_type %Class [symbolic = %pattern_type.loc10_15 (constants.%pattern_type.fe4)] +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %pattern_type.loc10_29: type = pattern_type %T.binding.as_type [symbolic = %pattern_type.loc10_29 (constants.%pattern_type.f14b96.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete.loc10: = require_complete_type %Class [symbolic = %require_complete.loc10 (constants.%require_complete.f79)] +// CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %T.binding.as_type [symbolic = %Class.elem (constants.%Class.elem)] +// CHECK:STDOUT: %require_complete.loc11: = require_complete_type %T.binding.as_type [symbolic = %require_complete.loc11 (constants.%require_complete.d74)] +// CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %T, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.c42)] +// CHECK:STDOUT: %.loc11_16.4: type = fn_type_with_self_type constants.%Copy.Op.type, %T [symbolic = %.loc11_16.4 (constants.%.a79)] +// CHECK:STDOUT: %impl.elem0.loc11_16.2: @Class.GetValue.%.loc11_16.4 (%.a79) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc11_16.2 (constants.%impl.elem0.fac)] +// CHECK:STDOUT: %specific_impl_fn.loc11_16.2: = specific_impl_function %impl.elem0.loc11_16.2, @Copy.Op(%T) [symbolic = %specific_impl_fn.loc11_16.2 (constants.%specific_impl_fn.103)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @Class.GetValue.%Class (%Class)) -> %return.param: @Class.GetValue.%T.binding.as_type (%T.binding.as_type) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %self.ref: @Class.GetValue.%Class (%Class) = name_ref self, %self +// CHECK:STDOUT: %k.ref: @Class.GetValue.%Class.elem (%Class.elem) = name_ref k, @Class.%.loc14_8 [concrete = @Class.%.loc14_8] +// CHECK:STDOUT: %.loc11_16.1: ref @Class.GetValue.%T.binding.as_type (%T.binding.as_type) = class_element_access %self.ref, element0 +// CHECK:STDOUT: %.loc11_16.2: @Class.GetValue.%T.binding.as_type (%T.binding.as_type) = acquire_value %.loc11_16.1 +// CHECK:STDOUT: %impl.elem0.loc11_16.1: @Class.GetValue.%.loc11_16.4 (%.a79) = impl_witness_access constants.%Copy.lookup_impl_witness.c42, element0 [symbolic = %impl.elem0.loc11_16.2 (constants.%impl.elem0.fac)] +// CHECK:STDOUT: %bound_method.loc11_16.1: = bound_method %.loc11_16.2, %impl.elem0.loc11_16.1 +// CHECK:STDOUT: %specific_impl_fn.loc11_16.1: = specific_impl_function %impl.elem0.loc11_16.1, @Copy.Op(constants.%T.417) [symbolic = %specific_impl_fn.loc11_16.2 (constants.%specific_impl_fn.103)] +// CHECK:STDOUT: %bound_method.loc11_16.2: = bound_method %.loc11_16.2, %specific_impl_fn.loc11_16.1 +// CHECK:STDOUT: %.loc10_29: ref @Class.GetValue.%T.binding.as_type (%T.binding.as_type) = splice_block %return {} +// CHECK:STDOUT: %.loc11_16.3: init @Class.GetValue.%T.binding.as_type (%T.binding.as_type) = call %bound_method.loc11_16.2(%.loc11_16.2) to %.loc10_29 +// CHECK:STDOUT: return %.loc11_16.3 to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class(constants.%T.417) { +// CHECK:STDOUT: %T.loc5_13.1 => constants.%T.417 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %Class.GetAddr.type => constants.%Class.GetAddr.type +// CHECK:STDOUT: %Class.GetAddr => constants.%Class.GetAddr +// CHECK:STDOUT: %Class.GetValue.type => constants.%Class.GetValue.type +// CHECK:STDOUT: %Class.GetValue => constants.%Class.GetValue +// CHECK:STDOUT: %T.binding.as_type => constants.%T.binding.as_type +// CHECK:STDOUT: %require_complete => constants.%require_complete.d74 +// CHECK:STDOUT: %Class => constants.%Class +// CHECK:STDOUT: %Class.elem => constants.%Class.elem +// CHECK:STDOUT: %struct_type.k => constants.%struct_type.k +// CHECK:STDOUT: %complete_type.loc15_1.2 => constants.%complete_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.GetAddr(constants.%T.417) { +// CHECK:STDOUT: %T => constants.%T.417 +// CHECK:STDOUT: %Class => constants.%Class +// CHECK:STDOUT: %ptr.loc6_29.1 => constants.%ptr.5a6 +// CHECK:STDOUT: %pattern_type.loc6_19 => constants.%pattern_type.ed4 +// CHECK:STDOUT: %T.binding.as_type => constants.%T.binding.as_type +// CHECK:STDOUT: %ptr.loc6_38.1 => constants.%ptr.d8c +// CHECK:STDOUT: %pattern_type.loc6_34 => constants.%pattern_type.12f +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Class.GetValue(constants.%T.417) { +// CHECK:STDOUT: %T => constants.%T.417 +// CHECK:STDOUT: %Class => constants.%Class +// CHECK:STDOUT: %pattern_type.loc10_15 => constants.%pattern_type.fe4 +// CHECK:STDOUT: %T.binding.as_type => constants.%T.binding.as_type +// CHECK:STDOUT: %pattern_type.loc10_29 => constants.%pattern_type.f14b96.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Declaration(constants.%T.d9f) { +// CHECK:STDOUT: %T.loc17_19.1 => constants.%T.d9f +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/import.carbon b/toolchain/check/testdata/class/import.carbon index 17cf8852e056..f966eb89e06b 100644 --- a/toolchain/check/testdata/class/import.carbon +++ b/toolchain/check/testdata/class/import.carbon @@ -27,7 +27,7 @@ class ForwardDeclared; class ForwardDeclared { fn F[self: Self](); - fn G[addr self: Self*](); + fn G[ref self: Self](); } class Incomplete; @@ -71,9 +71,6 @@ fn Run() { // CHECK:STDOUT: %pattern_type.1b8: type = pattern_type %ForwardDeclared [concrete] // CHECK:STDOUT: %ForwardDeclared.F.type: type = fn_type @ForwardDeclared.F [concrete] // CHECK:STDOUT: %ForwardDeclared.F: %ForwardDeclared.F.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr: type = ptr_type %ForwardDeclared [concrete] -// CHECK:STDOUT: %pattern_type.ebb: type = pattern_type %ptr [concrete] -// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %ForwardDeclared.G.type: type = fn_type @ForwardDeclared.G [concrete] // CHECK:STDOUT: %ForwardDeclared.G: %ForwardDeclared.G.type = struct_value () [concrete] // CHECK:STDOUT: %Incomplete: type = class_type @Incomplete [concrete] @@ -134,16 +131,12 @@ fn Run() { // CHECK:STDOUT: %self: %ForwardDeclared = value_binding self, %self.param // CHECK:STDOUT: } // CHECK:STDOUT: %ForwardDeclared.G.decl: %ForwardDeclared.G.type = fn_decl @ForwardDeclared.G [concrete = constants.%ForwardDeclared.G] { -// CHECK:STDOUT: %self.patt: %pattern_type.ebb = value_binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: %pattern_type.ebb = value_param_pattern %self.patt, call_param0 [concrete] -// CHECK:STDOUT: %.loc15_8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %self.patt: %pattern_type.1b8 = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b8 = ref_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param: %ptr = value_param call_param0 -// CHECK:STDOUT: %.loc15_23: type = splice_block %ptr [concrete = constants.%ptr] { -// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%ForwardDeclared [concrete = constants.%ForwardDeclared] -// CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self: %ptr = value_binding self, %self.param +// CHECK:STDOUT: %self.param: ref %ForwardDeclared = ref_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%ForwardDeclared [concrete = constants.%ForwardDeclared] +// CHECK:STDOUT: %self: ref %ForwardDeclared = ref_binding self, %self.param // CHECK:STDOUT: } // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type.357] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -158,7 +151,7 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: fn @ForwardDeclared.F(%self.param: %ForwardDeclared); // CHECK:STDOUT: -// CHECK:STDOUT: fn @ForwardDeclared.G(%self.param: %ptr); +// CHECK:STDOUT: fn @ForwardDeclared.G(%self.param: %ForwardDeclared); // CHECK:STDOUT: // CHECK:STDOUT: --- b.carbon // CHECK:STDOUT: @@ -276,11 +269,11 @@ fn Run() { // CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//a, loc16_1, loaded [concrete = constants.%complete_type.357] // CHECK:STDOUT: %Main.import_ref.39e731.1 = import_ref Main//a, inst{{[0-9A-F]+}} [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.760: %ForwardDeclared.F.type = import_ref Main//a, loc14_21, loaded [concrete = constants.%ForwardDeclared.F] -// CHECK:STDOUT: %Main.import_ref.26e: %ForwardDeclared.G.type = import_ref Main//a, loc15_27, loaded [concrete = constants.%ForwardDeclared.G] +// CHECK:STDOUT: %Main.import_ref.26e: %ForwardDeclared.G.type = import_ref Main//a, loc15_25, loaded [concrete = constants.%ForwardDeclared.G] // CHECK:STDOUT: %Main.import_ref.8f24d3.3: = import_ref Main//a, loc16_1, loaded [concrete = constants.%complete_type.357] // CHECK:STDOUT: %Main.import_ref.39e731.2 = import_ref Main//a, inst{{[0-9A-F]+}} [no loc], unloaded // CHECK:STDOUT: %Main.import_ref.42a = import_ref Main//a, loc14_21, unloaded -// CHECK:STDOUT: %Main.import_ref.67a = import_ref Main//a, loc15_27, unloaded +// CHECK:STDOUT: %Main.import_ref.67a = import_ref Main//a, loc15_25, unloaded // CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/parts/copy, Copy, loaded [concrete = constants.%Copy.type] // CHECK:STDOUT: %Core.import_ref.659: @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op.type (%ptr.as.Copy.impl.Op.type.75b) = import_ref Core//prelude/parts/copy, loc{{\d+_\d+}}, loaded [symbolic = @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op (constants.%ptr.as.Copy.impl.Op.692)] // CHECK:STDOUT: %Copy.impl_witness_table.67d = impl_witness_table (%Core.import_ref.659), @ptr.as.Copy.impl [concrete] @@ -399,8 +392,7 @@ fn Run() { // CHECK:STDOUT: %c.ref.loc14: ref %ForwardDeclared.7b34f2.1 = name_ref c, %c // CHECK:STDOUT: %G.ref: %ForwardDeclared.G.type = name_ref G, imports.%Main.import_ref.26e [concrete = constants.%ForwardDeclared.G] // CHECK:STDOUT: %ForwardDeclared.G.bound: = bound_method %c.ref.loc14, %G.ref -// CHECK:STDOUT: %addr.loc14: %ptr.6cf = addr_of %c.ref.loc14 -// CHECK:STDOUT: %ForwardDeclared.G.call: init %empty_tuple.type = call %ForwardDeclared.G.bound(%addr.loc14) +// CHECK:STDOUT: %ForwardDeclared.G.call: init %empty_tuple.type = call %ForwardDeclared.G.bound(%c.ref.loc14) // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %d.patt: %pattern_type.ebb = ref_binding_pattern d [concrete] // CHECK:STDOUT: %d.var_patt: %pattern_type.ebb = var_pattern %d.patt [concrete] diff --git a/toolchain/check/testdata/class/import_addr.carbon b/toolchain/check/testdata/class/import_addr.carbon new file mode 100644 index 000000000000..446fee162f84 --- /dev/null +++ b/toolchain/check/testdata/class/import_addr.carbon @@ -0,0 +1,463 @@ +// 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/class/import_addr.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/import_addr.carbon + +// --- a.carbon + +library "[[@TEST_NAME]]"; + +class Empty { +} + +class Field { + var x: i32; +} + +class ForwardDeclared; + +class ForwardDeclared { + fn F[self: Self](); + fn G[addr self: Self*](); +} + +class Incomplete; + +// --- b.carbon + +library "[[@TEST_NAME]]"; + +import library "a"; + +fn Run() { + var a: Empty = {}; + + var b: Field = {.x = 1}; + b.x = 2; + + var c: ForwardDeclared = {}; + c.F(); + c.G(); + + var d: ForwardDeclared* = &c; + + var e: Incomplete*; +} + +// CHECK:STDOUT: --- a.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Empty: type = class_type @Empty [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %Field: type = class_type @Field [concrete] +// 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: %Field.elem: type = unbound_element_type %Field, %i32 [concrete] +// CHECK:STDOUT: %struct_type.x: type = struct_type {.x: %i32} [concrete] +// CHECK:STDOUT: %complete_type.1ec: = complete_type_witness %struct_type.x [concrete] +// CHECK:STDOUT: %ForwardDeclared: type = class_type @ForwardDeclared [concrete] +// CHECK:STDOUT: %pattern_type.1b8: type = pattern_type %ForwardDeclared [concrete] +// CHECK:STDOUT: %ForwardDeclared.F.type: type = fn_type @ForwardDeclared.F [concrete] +// CHECK:STDOUT: %ForwardDeclared.F: %ForwardDeclared.F.type = struct_value () [concrete] +// CHECK:STDOUT: %ptr: type = ptr_type %ForwardDeclared [concrete] +// CHECK:STDOUT: %pattern_type.ebb: type = pattern_type %ptr [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %ForwardDeclared.G.type: type = fn_type @ForwardDeclared.G [concrete] +// CHECK:STDOUT: %ForwardDeclared.G: %ForwardDeclared.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Incomplete: type = class_type @Incomplete [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .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: .Empty = %Empty.decl +// CHECK:STDOUT: .Field = %Field.decl +// CHECK:STDOUT: .ForwardDeclared = %ForwardDeclared.decl.loc11 +// CHECK:STDOUT: .Incomplete = %Incomplete.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Empty.decl: type = class_decl @Empty [concrete = constants.%Empty] {} {} +// CHECK:STDOUT: %Field.decl: type = class_decl @Field [concrete = constants.%Field] {} {} +// CHECK:STDOUT: %ForwardDeclared.decl.loc11: type = class_decl @ForwardDeclared [concrete = constants.%ForwardDeclared] {} {} +// CHECK:STDOUT: %ForwardDeclared.decl.loc13: type = class_decl @ForwardDeclared [concrete = constants.%ForwardDeclared] {} {} +// CHECK:STDOUT: %Incomplete.decl: type = class_decl @Incomplete [concrete = constants.%Incomplete] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Empty { +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Empty +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Field { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc8: %Field.elem = field_decl x, element0 [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.x [concrete = constants.%complete_type.1ec] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Field +// CHECK:STDOUT: .x = %.loc8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @ForwardDeclared { +// CHECK:STDOUT: %ForwardDeclared.F.decl: %ForwardDeclared.F.type = fn_decl @ForwardDeclared.F [concrete = constants.%ForwardDeclared.F] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b8 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b8 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ForwardDeclared = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%ForwardDeclared [concrete = constants.%ForwardDeclared] +// CHECK:STDOUT: %self: %ForwardDeclared = value_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %ForwardDeclared.G.decl: %ForwardDeclared.G.type = fn_decl @ForwardDeclared.G [concrete = constants.%ForwardDeclared.G] { +// CHECK:STDOUT: %self.patt: %pattern_type.ebb = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.ebb = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15_8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %ptr = value_param call_param0 +// CHECK:STDOUT: %.loc15_23: type = splice_block %ptr [concrete = constants.%ptr] { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%ForwardDeclared [concrete = constants.%ForwardDeclared] +// CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: %ptr = value_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%ForwardDeclared +// CHECK:STDOUT: .F = %ForwardDeclared.F.decl +// CHECK:STDOUT: .G = %ForwardDeclared.G.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Incomplete; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ForwardDeclared.F(%self.param: %ForwardDeclared); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ForwardDeclared.G(%self.param: %ptr); +// CHECK:STDOUT: +// CHECK:STDOUT: --- b.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Run.type: type = fn_type @Run [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Run: %Run.type = struct_value () [concrete] +// CHECK:STDOUT: %Empty: type = class_type @Empty [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %pattern_type.2f0: type = pattern_type %Empty [concrete] +// CHECK:STDOUT: %Empty.val: %Empty = struct_value () [concrete] +// CHECK:STDOUT: %Field: type = class_type @Field [concrete] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %struct_type.x.767: type = struct_type {.x: %i32} [concrete] +// CHECK:STDOUT: %complete_type.c07: = complete_type_witness %struct_type.x.767 [concrete] +// CHECK:STDOUT: %pattern_type.f46: type = pattern_type %Field [concrete] +// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] +// CHECK:STDOUT: %struct_type.x.c96: type = struct_type {.x: Core.IntLiteral} [concrete] +// CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] +// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.type.bd9: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] +// CHECK:STDOUT: %ImplicitAs.Convert.type.6da: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.365: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.8cf: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.365 = struct_value () [symbolic] +// CHECK:STDOUT: %ImplicitAs.impl_witness.09b: = impl_witness imports.%ImplicitAs.impl_witness_table.04e, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.069: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.13e: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.069 = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.bd9 = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.09b) [concrete] +// CHECK:STDOUT: %.1a5: type = fn_type_with_self_type %ImplicitAs.Convert.type.6da, %ImplicitAs.facet [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.b66: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.13e [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.13e, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] +// CHECK:STDOUT: %bound_method.c7c: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] +// CHECK:STDOUT: %int_1.47b: %i32 = int_value 1 [concrete] +// CHECK:STDOUT: %Field.val: %Field = struct_value (%int_1.47b) [concrete] +// CHECK:STDOUT: %Field.elem: type = unbound_element_type %Field, %i32 [concrete] +// CHECK:STDOUT: %int_2.ecc: Core.IntLiteral = int_value 2 [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.8e7: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.13e [concrete] +// CHECK:STDOUT: %bound_method.a94: = bound_method %int_2.ecc, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] +// CHECK:STDOUT: %int_2.d0d: %i32 = int_value 2 [concrete] +// CHECK:STDOUT: %ForwardDeclared.7b34f2.1: type = class_type @ForwardDeclared.1 [concrete] +// CHECK:STDOUT: %pattern_type.1b8: type = pattern_type %ForwardDeclared.7b34f2.1 [concrete] +// CHECK:STDOUT: %ForwardDeclared.val: %ForwardDeclared.7b34f2.1 = struct_value () [concrete] +// CHECK:STDOUT: %ForwardDeclared.F.type: type = fn_type @ForwardDeclared.F [concrete] +// CHECK:STDOUT: %ForwardDeclared.F: %ForwardDeclared.F.type = struct_value () [concrete] +// CHECK:STDOUT: %ForwardDeclared.G.type: type = fn_type @ForwardDeclared.G [concrete] +// CHECK:STDOUT: %ForwardDeclared.G: %ForwardDeclared.G.type = struct_value () [concrete] +// CHECK:STDOUT: %ptr.6cf: type = ptr_type %ForwardDeclared.7b34f2.1 [concrete] +// CHECK:STDOUT: %pattern_type.ebb: type = pattern_type %ptr.6cf [concrete] +// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] +// CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [concrete] +// CHECK:STDOUT: %T.d9f: type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.75b: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%T.d9f) [symbolic] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.692: %ptr.as.Copy.impl.Op.type.75b = struct_value () [symbolic] +// CHECK:STDOUT: %Copy.impl_witness.bf8: = impl_witness imports.%Copy.impl_witness_table.67d, @ptr.as.Copy.impl(%ForwardDeclared.7b34f2.1) [concrete] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.b63: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%ForwardDeclared.7b34f2.1) [concrete] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.8de: %ptr.as.Copy.impl.Op.type.b63 = struct_value () [concrete] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.6cf, (%Copy.impl_witness.bf8) [concrete] +// CHECK:STDOUT: %.05a: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet [concrete] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.specific_fn: = specific_function %ptr.as.Copy.impl.Op.8de, @ptr.as.Copy.impl.Op(%ForwardDeclared.7b34f2.1) [concrete] +// CHECK:STDOUT: %Incomplete: type = class_type @Incomplete [concrete] +// CHECK:STDOUT: %ptr.c62: type = ptr_type %Incomplete [concrete] +// CHECK:STDOUT: %pattern_type.275: type = pattern_type %ptr.c62 [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %type_where: type = facet_type > [concrete] +// CHECK:STDOUT: %facet_value.a09: %type_where = facet_value %ptr.c62, () [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.257: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.a09) [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.6fd: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.257 = struct_value () [concrete] +// CHECK:STDOUT: %ptr.c22: type = ptr_type %ptr.c62 [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.cdc: = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.6fd, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value.a09) [concrete] +// CHECK:STDOUT: %facet_value.481: %type_where = facet_value %ptr.6cf, () [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.6eb: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.481) [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.610: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.6eb = struct_value () [concrete] +// CHECK:STDOUT: %ptr.df0: type = ptr_type %ptr.6cf [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.250: = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.610, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value.481) [concrete] +// CHECK:STDOUT: %facet_value.c58: %type_where = facet_value %ForwardDeclared.7b34f2.1, () [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.d7f: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.c58) [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.e9e: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.d7f = struct_value () [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.cf0: = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.e9e, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value.c58) [concrete] +// CHECK:STDOUT: %facet_value.f6b: %type_where = facet_value %Field, () [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.b06: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.f6b) [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.088: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.b06 = struct_value () [concrete] +// CHECK:STDOUT: %ptr.d8b: type = ptr_type %Field [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.0a0: = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.088, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value.f6b) [concrete] +// CHECK:STDOUT: %facet_value.8d3: %type_where = facet_value %Empty, () [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.3f6: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value.8d3) [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.a12: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.3f6 = struct_value () [concrete] +// CHECK:STDOUT: %ptr.961: type = ptr_type %Empty [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.af0: = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.a12, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value.8d3) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Main.Empty: type = import_ref Main//a, Empty, loaded [concrete = constants.%Empty] +// CHECK:STDOUT: %Main.Field: type = import_ref Main//a, Field, loaded [concrete = constants.%Field] +// CHECK:STDOUT: %Main.ForwardDeclared: type = import_ref Main//a, ForwardDeclared, loaded [concrete = constants.%ForwardDeclared.7b34f2.1] +// CHECK:STDOUT: %Main.Incomplete: type = import_ref Main//a, Incomplete, loaded [concrete = constants.%Incomplete] +// CHECK:STDOUT: %Core.ece: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: .Copy = %Core.Copy +// CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Main.import_ref.8f24d3.1: = import_ref Main//a, loc5_1, loaded [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %Main.import_ref.fd7 = import_ref Main//a, inst{{[0-9A-F]+}} [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.709: = import_ref Main//a, loc9_1, loaded [concrete = constants.%complete_type.c07] +// CHECK:STDOUT: %Main.import_ref.845 = import_ref Main//a, inst{{[0-9A-F]+}} [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.4d2: %Field.elem = import_ref Main//a, loc8_8, loaded [concrete = %.d33] +// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] +// CHECK:STDOUT: %Core.import_ref.7d5: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.365) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.8cf)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table.04e = impl_witness_table (%Core.import_ref.7d5), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %.d33: %Field.elem = field_decl x, element0 [concrete] +// CHECK:STDOUT: %Main.import_ref.8f24d3.2: = import_ref Main//a, loc16_1, loaded [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %Main.import_ref.39e731.1 = import_ref Main//a, inst{{[0-9A-F]+}} [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.760: %ForwardDeclared.F.type = import_ref Main//a, loc14_21, loaded [concrete = constants.%ForwardDeclared.F] +// CHECK:STDOUT: %Main.import_ref.26e: %ForwardDeclared.G.type = import_ref Main//a, loc15_27, loaded [concrete = constants.%ForwardDeclared.G] +// CHECK:STDOUT: %Main.import_ref.8f24d3.3: = import_ref Main//a, loc16_1, loaded [concrete = constants.%complete_type.357] +// CHECK:STDOUT: %Main.import_ref.39e731.2 = import_ref Main//a, inst{{[0-9A-F]+}} [no loc], unloaded +// CHECK:STDOUT: %Main.import_ref.42a = import_ref Main//a, loc14_21, unloaded +// CHECK:STDOUT: %Main.import_ref.67a = import_ref Main//a, loc15_27, unloaded +// CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/parts/copy, Copy, loaded [concrete = constants.%Copy.type] +// CHECK:STDOUT: %Core.import_ref.659: @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op.type (%ptr.as.Copy.impl.Op.type.75b) = import_ref Core//prelude/parts/copy, loc{{\d+_\d+}}, loaded [symbolic = @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op (constants.%ptr.as.Copy.impl.Op.692)] +// CHECK:STDOUT: %Copy.impl_witness_table.67d = impl_witness_table (%Core.import_ref.659), @ptr.as.Copy.impl [concrete] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Empty = imports.%Main.Empty +// CHECK:STDOUT: .Field = imports.%Main.Field +// CHECK:STDOUT: .ForwardDeclared = imports.%Main.ForwardDeclared +// CHECK:STDOUT: .Incomplete = imports.%Main.Incomplete +// CHECK:STDOUT: .Core = imports.%Core.ece +// CHECK:STDOUT: .Run = %Run.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %default.import = import +// CHECK:STDOUT: %Run.decl: %Run.type = fn_decl @Run [concrete = constants.%Run] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Empty [from "a.carbon"] { +// CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.1 +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Main.import_ref.fd7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Field [from "a.carbon"] { +// CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.709 +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Main.import_ref.845 +// CHECK:STDOUT: .x = imports.%Main.import_ref.4d2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @ForwardDeclared.1 [from "a.carbon"] { +// CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.2 +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Main.import_ref.39e731.1 +// CHECK:STDOUT: .F = imports.%Main.import_ref.760 +// CHECK:STDOUT: .G = imports.%Main.import_ref.26e +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @ForwardDeclared.2 [from "a.carbon"] { +// CHECK:STDOUT: complete_type_witness = imports.%Main.import_ref.8f24d3.3 +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%Main.import_ref.39e731.2 +// CHECK:STDOUT: .F = imports.%Main.import_ref.42a +// CHECK:STDOUT: .G = imports.%Main.import_ref.67a +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Incomplete [from "a.carbon"]; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Run() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %a.patt: %pattern_type.2f0 = ref_binding_pattern a [concrete] +// CHECK:STDOUT: %a.var_patt: %pattern_type.2f0 = var_pattern %a.patt [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %a.var: ref %Empty = var %a.var_patt +// CHECK:STDOUT: %.loc7_19.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc7_19.2: init %Empty = class_init (), %a.var [concrete = constants.%Empty.val] +// CHECK:STDOUT: %.loc7_3: init %Empty = converted %.loc7_19.1, %.loc7_19.2 [concrete = constants.%Empty.val] +// CHECK:STDOUT: assign %a.var, %.loc7_3 +// CHECK:STDOUT: %Empty.ref: type = name_ref Empty, imports.%Main.Empty [concrete = constants.%Empty] +// CHECK:STDOUT: %a: ref %Empty = ref_binding a, %a.var +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %b.patt: %pattern_type.f46 = ref_binding_pattern b [concrete] +// CHECK:STDOUT: %b.var_patt: %pattern_type.f46 = var_pattern %b.patt [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %b.var: ref %Field = var %b.var_patt +// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc9_25.1: %struct_type.x.c96 = struct_literal (%int_1) +// CHECK:STDOUT: %impl.elem0.loc9: %.1a5 = impl_witness_access constants.%ImplicitAs.impl_witness.09b, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.13e] +// CHECK:STDOUT: %bound_method.loc9_25.1: = bound_method %int_1, %impl.elem0.loc9 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.b66] +// CHECK:STDOUT: %specific_fn.loc9: = specific_function %impl.elem0.loc9, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc9_25.2: = bound_method %int_1, %specific_fn.loc9 [concrete = constants.%bound_method.c7c] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc9: init %i32 = call %bound_method.loc9_25.2(%int_1) [concrete = constants.%int_1.47b] +// CHECK:STDOUT: %.loc9_25.2: init %i32 = converted %int_1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc9 [concrete = constants.%int_1.47b] +// CHECK:STDOUT: %.loc9_25.3: ref %i32 = class_element_access %b.var, element0 +// CHECK:STDOUT: %.loc9_25.4: init %i32 = initialize_from %.loc9_25.2 to %.loc9_25.3 [concrete = constants.%int_1.47b] +// CHECK:STDOUT: %.loc9_25.5: init %Field = class_init (%.loc9_25.4), %b.var [concrete = constants.%Field.val] +// CHECK:STDOUT: %.loc9_3: init %Field = converted %.loc9_25.1, %.loc9_25.5 [concrete = constants.%Field.val] +// CHECK:STDOUT: assign %b.var, %.loc9_3 +// CHECK:STDOUT: %Field.ref: type = name_ref Field, imports.%Main.Field [concrete = constants.%Field] +// CHECK:STDOUT: %b: ref %Field = ref_binding b, %b.var +// CHECK:STDOUT: %b.ref: ref %Field = name_ref b, %b +// CHECK:STDOUT: %x.ref: %Field.elem = name_ref x, imports.%Main.import_ref.4d2 [concrete = imports.%.d33] +// CHECK:STDOUT: %.loc10_4: ref %i32 = class_element_access %b.ref, element0 +// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc] +// CHECK:STDOUT: %impl.elem0.loc10: %.1a5 = impl_witness_access constants.%ImplicitAs.impl_witness.09b, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.13e] +// CHECK:STDOUT: %bound_method.loc10_7.1: = bound_method %int_2, %impl.elem0.loc10 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.8e7] +// CHECK:STDOUT: %specific_fn.loc10: = specific_function %impl.elem0.loc10, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc10_7.2: = bound_method %int_2, %specific_fn.loc10 [concrete = constants.%bound_method.a94] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc10: init %i32 = call %bound_method.loc10_7.2(%int_2) [concrete = constants.%int_2.d0d] +// CHECK:STDOUT: %.loc10_7: init %i32 = converted %int_2, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc10 [concrete = constants.%int_2.d0d] +// CHECK:STDOUT: assign %.loc10_4, %.loc10_7 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %c.patt: %pattern_type.1b8 = ref_binding_pattern c [concrete] +// CHECK:STDOUT: %c.var_patt: %pattern_type.1b8 = var_pattern %c.patt [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %c.var: ref %ForwardDeclared.7b34f2.1 = var %c.var_patt +// CHECK:STDOUT: %.loc12_29.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc12_29.2: init %ForwardDeclared.7b34f2.1 = class_init (), %c.var [concrete = constants.%ForwardDeclared.val] +// CHECK:STDOUT: %.loc12_3: init %ForwardDeclared.7b34f2.1 = converted %.loc12_29.1, %.loc12_29.2 [concrete = constants.%ForwardDeclared.val] +// CHECK:STDOUT: assign %c.var, %.loc12_3 +// CHECK:STDOUT: %ForwardDeclared.ref.loc12: type = name_ref ForwardDeclared, imports.%Main.ForwardDeclared [concrete = constants.%ForwardDeclared.7b34f2.1] +// CHECK:STDOUT: %c: ref %ForwardDeclared.7b34f2.1 = ref_binding c, %c.var +// CHECK:STDOUT: %c.ref.loc13: ref %ForwardDeclared.7b34f2.1 = name_ref c, %c +// CHECK:STDOUT: %F.ref: %ForwardDeclared.F.type = name_ref F, imports.%Main.import_ref.760 [concrete = constants.%ForwardDeclared.F] +// CHECK:STDOUT: %ForwardDeclared.F.bound: = bound_method %c.ref.loc13, %F.ref +// CHECK:STDOUT: %.loc13: %ForwardDeclared.7b34f2.1 = acquire_value %c.ref.loc13 +// CHECK:STDOUT: %ForwardDeclared.F.call: init %empty_tuple.type = call %ForwardDeclared.F.bound(%.loc13) +// CHECK:STDOUT: %c.ref.loc14: ref %ForwardDeclared.7b34f2.1 = name_ref c, %c +// CHECK:STDOUT: %G.ref: %ForwardDeclared.G.type = name_ref G, imports.%Main.import_ref.26e [concrete = constants.%ForwardDeclared.G] +// CHECK:STDOUT: %ForwardDeclared.G.bound: = bound_method %c.ref.loc14, %G.ref +// CHECK:STDOUT: %addr.loc14: %ptr.6cf = addr_of %c.ref.loc14 +// CHECK:STDOUT: %ForwardDeclared.G.call: init %empty_tuple.type = call %ForwardDeclared.G.bound(%addr.loc14) +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %d.patt: %pattern_type.ebb = ref_binding_pattern d [concrete] +// CHECK:STDOUT: %d.var_patt: %pattern_type.ebb = var_pattern %d.patt [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %d.var: ref %ptr.6cf = var %d.var_patt +// CHECK:STDOUT: %c.ref.loc16: ref %ForwardDeclared.7b34f2.1 = name_ref c, %c +// CHECK:STDOUT: %addr.loc16_29: %ptr.6cf = addr_of %c.ref.loc16 +// CHECK:STDOUT: %impl.elem0.loc16: %.05a = impl_witness_access constants.%Copy.impl_witness.bf8, element0 [concrete = constants.%ptr.as.Copy.impl.Op.8de] +// CHECK:STDOUT: %bound_method.loc16_29.1: = bound_method %addr.loc16_29, %impl.elem0.loc16 +// CHECK:STDOUT: %specific_fn.loc16: = specific_function %impl.elem0.loc16, @ptr.as.Copy.impl.Op(constants.%ForwardDeclared.7b34f2.1) [concrete = constants.%ptr.as.Copy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc16_29.2: = bound_method %addr.loc16_29, %specific_fn.loc16 +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.call: init %ptr.6cf = call %bound_method.loc16_29.2(%addr.loc16_29) +// CHECK:STDOUT: assign %d.var, %ptr.as.Copy.impl.Op.call +// CHECK:STDOUT: %.loc16: type = splice_block %ptr.loc16 [concrete = constants.%ptr.6cf] { +// CHECK:STDOUT: %ForwardDeclared.ref.loc16: type = name_ref ForwardDeclared, imports.%Main.ForwardDeclared [concrete = constants.%ForwardDeclared.7b34f2.1] +// CHECK:STDOUT: %ptr.loc16: type = ptr_type %ForwardDeclared.ref.loc16 [concrete = constants.%ptr.6cf] +// CHECK:STDOUT: } +// CHECK:STDOUT: %d: ref %ptr.6cf = ref_binding d, %d.var +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %e.patt: %pattern_type.275 = ref_binding_pattern e [concrete] +// CHECK:STDOUT: %e.var_patt: %pattern_type.275 = var_pattern %e.patt [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %e.var: ref %ptr.c62 = var %e.var_patt +// CHECK:STDOUT: %.loc18: type = splice_block %ptr.loc18 [concrete = constants.%ptr.c62] { +// CHECK:STDOUT: %Incomplete.ref: type = name_ref Incomplete, imports.%Main.Incomplete [concrete = constants.%Incomplete] +// CHECK:STDOUT: %ptr.loc18: type = ptr_type %Incomplete.ref [concrete = constants.%ptr.c62] +// CHECK:STDOUT: } +// CHECK:STDOUT: %e: ref %ptr.c62 = ref_binding e, %e.var +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc18: = bound_method %e.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.6fd +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.6fd, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.a09) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.cdc] +// CHECK:STDOUT: %bound_method.loc18: = bound_method %e.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %addr.loc18: %ptr.c22 = addr_of %e.var +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc18: init %empty_tuple.type = call %bound_method.loc18(%addr.loc18) +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc16: = bound_method %d.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.610 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.610, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.481) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.250] +// CHECK:STDOUT: %bound_method.loc16_3: = bound_method %d.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %addr.loc16_3: %ptr.df0 = addr_of %d.var +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc16: init %empty_tuple.type = call %bound_method.loc16_3(%addr.loc16_3) +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc12: = bound_method %c.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.e9e +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.e9e, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.c58) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.cf0] +// CHECK:STDOUT: %bound_method.loc12: = bound_method %c.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %addr.loc12: %ptr.6cf = addr_of %c.var +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc12: init %empty_tuple.type = call %bound_method.loc12(%addr.loc12) +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc9: = bound_method %b.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.088 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.4: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.088, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.f6b) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.0a0] +// CHECK:STDOUT: %bound_method.loc9_3: = bound_method %b.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.4 +// CHECK:STDOUT: %addr.loc9: %ptr.d8b = addr_of %b.var +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc9: init %empty_tuple.type = call %bound_method.loc9_3(%addr.loc9) +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc7: = bound_method %a.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.a12 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.5: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.a12, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.8d3) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.af0] +// CHECK:STDOUT: %bound_method.loc7: = bound_method %a.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.5 +// CHECK:STDOUT: %addr.loc7: %ptr.961 = addr_of %a.var +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7: init %empty_tuple.type = call %bound_method.loc7(%addr.loc7) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ForwardDeclared.F [from "a.carbon"]; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @ForwardDeclared.G [from "a.carbon"]; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/method.carbon b/toolchain/check/testdata/class/method.carbon index b825b459a6e2..171becc3644f 100644 --- a/toolchain/check/testdata/class/method.carbon +++ b/toolchain/check/testdata/class/method.carbon @@ -14,7 +14,7 @@ class Class { fn F[self: Self]() -> i32; - fn G[addr self: Self*]() -> i32; + fn G[ref self: Self]() -> i32; alias A = F; @@ -39,7 +39,7 @@ fn CallOnConstBoundMethod() -> i32 { return ({.k = 1} as Class).F(); } -fn CallWithAddr() -> i32 { +fn CallWithRef() -> i32 { var c: Class; return c.G(); } @@ -76,9 +76,6 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %Class.F.type: type = fn_type @Class.F [concrete] // CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] -// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] -// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %Class.G.type: type = fn_type @Class.G [concrete] // CHECK:STDOUT: %Class.G: %Class.G.type = struct_value () [concrete] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %i32 [concrete] @@ -124,9 +121,11 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: %facet_value: %type_where = facet_value %Class, () [concrete] // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.e99: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [concrete] // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.378: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.e99 = struct_value () [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.378, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value) [concrete] -// CHECK:STDOUT: %CallWithAddr.type: type = fn_type @CallWithAddr [concrete] -// CHECK:STDOUT: %CallWithAddr: %CallWithAddr.type = struct_value () [concrete] +// CHECK:STDOUT: %CallWithRef.type: type = fn_type @CallWithRef [concrete] +// CHECK:STDOUT: %CallWithRef: %CallWithRef.type = struct_value () [concrete] // CHECK:STDOUT: %CallFThroughPointer.type: type = fn_type @CallFThroughPointer [concrete] // CHECK:STDOUT: %CallFThroughPointer: %CallFThroughPointer.type = struct_value () [concrete] // CHECK:STDOUT: %CallGThroughPointer.type: type = fn_type @CallGThroughPointer [concrete] @@ -165,7 +164,7 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: .Call = %Call.decl // CHECK:STDOUT: .CallAlias = %CallAlias.decl // CHECK:STDOUT: .CallOnConstBoundMethod = %CallOnConstBoundMethod.decl -// CHECK:STDOUT: .CallWithAddr = %CallWithAddr.decl +// CHECK:STDOUT: .CallWithRef = %CallWithRef.decl // CHECK:STDOUT: .CallFThroughPointer = %CallFThroughPointer.decl // CHECK:STDOUT: .CallGThroughPointer = %CallGThroughPointer.decl // CHECK:STDOUT: .Make = %Make.decl @@ -225,7 +224,7 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } -// CHECK:STDOUT: %CallWithAddr.decl: %CallWithAddr.type = fn_decl @CallWithAddr [concrete = constants.%CallWithAddr] { +// CHECK:STDOUT: %CallWithRef.decl: %CallWithRef.type = fn_decl @CallWithRef [concrete = constants.%CallWithRef] { // CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] // CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param0 [concrete] // CHECK:STDOUT: } { @@ -312,20 +311,16 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: %return.loc16: ref %i32 = return_slot %return.param.loc16 // CHECK:STDOUT: } // CHECK:STDOUT: %Class.G.decl: %Class.G.type = fn_decl @Class.G [concrete = constants.%Class.G] { -// CHECK:STDOUT: %self.patt: %pattern_type.796 = value_binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] -// CHECK:STDOUT: %.loc17_8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %self.patt: %pattern_type.761 = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.761 = ref_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] // CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 -// CHECK:STDOUT: %.loc17_23: type = splice_block %ptr [concrete = constants.%ptr.e71] { -// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] -// CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr.e71] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self: %ptr.e71 = value_binding self, %self.param +// CHECK:STDOUT: %self.param: ref %Class = ref_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: ref %Class = ref_binding self, %self.param // CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1 // CHECK:STDOUT: %return: ref %i32 = return_slot %return.param // CHECK:STDOUT: } @@ -359,7 +354,7 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: return %Int.as.Copy.impl.Op.call to %return.loc24 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @Class.G(%self.param: %ptr.e71) -> %i32; +// CHECK:STDOUT: fn @Class.G(%self.param: %Class) -> %i32; // CHECK:STDOUT: // CHECK:STDOUT: fn @Call(%c.param: %Class) -> %i32 { // CHECK:STDOUT: !entry: @@ -408,7 +403,7 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: return %Class.F.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @CallWithAddr() -> %i32 { +// CHECK:STDOUT: fn @CallWithRef() -> %i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: name_binding_decl { // CHECK:STDOUT: %c.patt: %pattern_type.761 = ref_binding_pattern c [concrete] @@ -420,13 +415,12 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: %c.ref: ref %Class = name_ref c, %c // CHECK:STDOUT: %G.ref: %Class.G.type = name_ref G, @Class.%Class.G.decl [concrete = constants.%Class.G] // CHECK:STDOUT: %Class.G.bound: = bound_method %c.ref, %G.ref -// CHECK:STDOUT: %addr.loc44: %ptr.e71 = addr_of %c.ref -// CHECK:STDOUT: %Class.G.call: init %i32 = call %Class.G.bound(%addr.loc44) +// CHECK:STDOUT: %Class.G.call: init %i32 = call %Class.G.bound(%c.ref) // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.378 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.378, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method: = bound_method %c.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn -// CHECK:STDOUT: %addr.loc43: %ptr.e71 = addr_of %c.var -// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc43) +// CHECK:STDOUT: %addr: %ptr.e71 = addr_of %c.var +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) // CHECK:STDOUT: return %Class.G.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -447,8 +441,7 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: %.loc52: ref %Class = deref %p.ref // CHECK:STDOUT: %G.ref: %Class.G.type = name_ref G, @Class.%Class.G.decl [concrete = constants.%Class.G] // CHECK:STDOUT: %Class.G.bound: = bound_method %.loc52, %G.ref -// CHECK:STDOUT: %addr: %ptr.e71 = addr_of %.loc52 -// CHECK:STDOUT: %Class.G.call: init %i32 = call %Class.G.bound(%addr) +// CHECK:STDOUT: %Class.G.call: init %i32 = call %Class.G.bound(%.loc52) // CHECK:STDOUT: return %Class.G.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -480,13 +473,12 @@ fn CallGOnInitializingExpr() -> i32 { // CHECK:STDOUT: %.loc62_15.2: ref %Class = temporary %.loc62_15.1, %Make.call // CHECK:STDOUT: %G.ref: %Class.G.type = name_ref G, @Class.%Class.G.decl [concrete = constants.%Class.G] // CHECK:STDOUT: %Class.G.bound: = bound_method %.loc62_15.2, %G.ref -// CHECK:STDOUT: %addr.loc62_15.1: %ptr.e71 = addr_of %.loc62_15.2 -// CHECK:STDOUT: %Class.G.call: init %i32 = call %Class.G.bound(%addr.loc62_15.1) +// CHECK:STDOUT: %Class.G.call: init %i32 = call %Class.G.bound(%.loc62_15.2) // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: = bound_method %.loc62_15.2, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.378 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.378, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn] // CHECK:STDOUT: %bound_method: = bound_method %.loc62_15.2, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn -// CHECK:STDOUT: %addr.loc62_15.2: %ptr.e71 = addr_of %.loc62_15.2 -// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc62_15.2) +// CHECK:STDOUT: %addr: %ptr.e71 = addr_of %.loc62_15.2 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) // CHECK:STDOUT: return %Class.G.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/method_addr.carbon b/toolchain/check/testdata/class/method_addr.carbon new file mode 100644 index 000000000000..a1f671da8ce3 --- /dev/null +++ b/toolchain/check/testdata/class/method_addr.carbon @@ -0,0 +1,492 @@ +// 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/class/method_addr.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/method_addr.carbon + +class Class { + fn F[self: Self]() -> i32; + fn G[addr self: Self*]() -> i32; + + alias A = F; + + var k: i32; +} + +fn Class.F[self: Self]() -> i32 { + return self.k; +} + +fn Call(c: Class) -> i32 { + // TODO: The sem-ir for this call doesn't distinguish the `self` argument from + // the explicit arguments. + return c.F(); +} + +fn CallAlias(c: Class) -> i32 { + return c.A(); +} + +fn CallOnConstBoundMethod() -> i32 { + return ({.k = 1} as Class).F(); +} + +fn CallWithAddr() -> i32 { + var c: Class; + return c.G(); +} + +fn CallFThroughPointer(p: Class*) -> i32 { + return (*p).F(); +} + +fn CallGThroughPointer(p: Class*) -> i32 { + return (*p).G(); +} + +fn Make() -> Class; + +fn CallFOnInitializingExpr() -> i32 { + return Make().F(); +} + +fn CallGOnInitializingExpr() -> i32 { + return Make().G(); +} + +// CHECK:STDOUT: --- method_addr.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Class: type = class_type @Class [concrete] +// CHECK:STDOUT: %pattern_type.761: type = pattern_type %Class [concrete] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] +// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] +// CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] +// CHECK:STDOUT: %Class.F.type: type = fn_type @Class.F [concrete] +// CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Class.G.type: type = fn_type @Class.G [concrete] +// CHECK:STDOUT: %Class.G: %Class.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %i32 [concrete] +// CHECK:STDOUT: %struct_type.k.0bf: type = struct_type {.k: %i32} [concrete] +// CHECK:STDOUT: %complete_type.954: = complete_type_witness %struct_type.k.0bf [concrete] +// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] +// CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.24b: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.c95: %Int.as.Copy.impl.Op.type.24b = struct_value () [symbolic] +// CHECK:STDOUT: %Copy.impl_witness.fb7: = impl_witness imports.%Copy.impl_witness_table.b6a, @Int.as.Copy.impl(%int_32) [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.469: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%int_32) [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.dfd: %Int.as.Copy.impl.Op.type.469 = struct_value () [concrete] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %i32, (%Copy.impl_witness.fb7) [concrete] +// CHECK:STDOUT: %.65f: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: = specific_function %Int.as.Copy.impl.Op.dfd, @Int.as.Copy.impl.Op(%int_32) [concrete] +// CHECK:STDOUT: %Call.type: type = fn_type @Call [concrete] +// CHECK:STDOUT: %Call: %Call.type = struct_value () [concrete] +// CHECK:STDOUT: %CallAlias.type: type = fn_type @CallAlias [concrete] +// CHECK:STDOUT: %CallAlias: %CallAlias.type = struct_value () [concrete] +// CHECK:STDOUT: %CallOnConstBoundMethod.type: type = fn_type @CallOnConstBoundMethod [concrete] +// CHECK:STDOUT: %CallOnConstBoundMethod: %CallOnConstBoundMethod.type = struct_value () [concrete] +// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] +// CHECK:STDOUT: %struct_type.k.240: type = struct_type {.k: Core.IntLiteral} [concrete] +// CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] +// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.type.d14: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] +// CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.2a1: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51 = struct_value () [symbolic] +// CHECK:STDOUT: %ImplicitAs.impl_witness.bc9: = impl_witness imports.%ImplicitAs.impl_witness_table.132, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.51e: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.51e = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.d14 = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.bc9) [concrete] +// CHECK:STDOUT: %.322: type = fn_type_with_self_type %ImplicitAs.Convert.type.1b6, %ImplicitAs.facet [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] +// CHECK:STDOUT: %bound_method: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] +// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] +// CHECK:STDOUT: %Class.val: %Class = struct_value (%int_1.5d2) [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %type_where: type = facet_type > [concrete] +// CHECK:STDOUT: %facet_value: %type_where = facet_value %Class, () [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.e99: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.378: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.e99 = struct_value () [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.378, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value) [concrete] +// CHECK:STDOUT: %CallWithAddr.type: type = fn_type @CallWithAddr [concrete] +// CHECK:STDOUT: %CallWithAddr: %CallWithAddr.type = struct_value () [concrete] +// CHECK:STDOUT: %CallFThroughPointer.type: type = fn_type @CallFThroughPointer [concrete] +// CHECK:STDOUT: %CallFThroughPointer: %CallFThroughPointer.type = struct_value () [concrete] +// CHECK:STDOUT: %CallGThroughPointer.type: type = fn_type @CallGThroughPointer [concrete] +// CHECK:STDOUT: %CallGThroughPointer: %CallGThroughPointer.type = struct_value () [concrete] +// CHECK:STDOUT: %Make.type: type = fn_type @Make [concrete] +// CHECK:STDOUT: %Make: %Make.type = struct_value () [concrete] +// CHECK:STDOUT: %CallFOnInitializingExpr.type: type = fn_type @CallFOnInitializingExpr [concrete] +// CHECK:STDOUT: %CallFOnInitializingExpr: %CallFOnInitializingExpr.type = struct_value () [concrete] +// CHECK:STDOUT: %CallGOnInitializingExpr.type: type = fn_type @CallGOnInitializingExpr [concrete] +// CHECK:STDOUT: %CallGOnInitializingExpr: %CallGOnInitializingExpr.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Copy = %Core.Copy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/parts/copy, Copy, loaded [concrete = constants.%Copy.type] +// CHECK:STDOUT: %Core.import_ref.d12: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.24b) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Int.as.Copy.impl.%Int.as.Copy.impl.Op (constants.%Int.as.Copy.impl.Op.c95)] +// CHECK:STDOUT: %Copy.impl_witness_table.b6a = impl_witness_table (%Core.import_ref.d12), @Int.as.Copy.impl [concrete] +// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] +// CHECK:STDOUT: %Core.import_ref.e24: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.2a1)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table.132 = impl_witness_table (%Core.import_ref.e24), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Class = %Class.decl +// CHECK:STDOUT: .Call = %Call.decl +// CHECK:STDOUT: .CallAlias = %CallAlias.decl +// CHECK:STDOUT: .CallOnConstBoundMethod = %CallOnConstBoundMethod.decl +// CHECK:STDOUT: .CallWithAddr = %CallWithAddr.decl +// CHECK:STDOUT: .CallFThroughPointer = %CallFThroughPointer.decl +// CHECK:STDOUT: .CallGThroughPointer = %CallGThroughPointer.decl +// CHECK:STDOUT: .Make = %Make.decl +// CHECK:STDOUT: .CallFOnInitializingExpr = %CallFOnInitializingExpr.decl +// CHECK:STDOUT: .CallGOnInitializingExpr = %CallGOnInitializingExpr.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Class.decl: type = class_decl @Class [concrete = constants.%Class] {} {} +// CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { +// CHECK:STDOUT: %self.patt: %pattern_type.761 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.761 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32.loc24: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc24: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %self.param.loc24: %Class = value_param call_param0 +// CHECK:STDOUT: %Self.ref.loc24: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self.loc24: %Class = value_binding self, %self.param.loc24 +// CHECK:STDOUT: %return.param.loc24: ref %i32 = out_param call_param1 +// CHECK:STDOUT: %return.loc24: ref %i32 = return_slot %return.param.loc24 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Call.decl: %Call.type = fn_decl @Call [concrete = constants.%Call] { +// CHECK:STDOUT: %c.patt: %pattern_type.761 = value_binding_pattern c [concrete] +// CHECK:STDOUT: %c.param_patt: %pattern_type.761 = value_param_pattern %c.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %c.param: %Class = value_param call_param0 +// CHECK:STDOUT: %Class.ref: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] +// CHECK:STDOUT: %c: %Class = value_binding c, %c.param +// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %CallAlias.decl: %CallAlias.type = fn_decl @CallAlias [concrete = constants.%CallAlias] { +// CHECK:STDOUT: %c.patt: %pattern_type.761 = value_binding_pattern c [concrete] +// CHECK:STDOUT: %c.param_patt: %pattern_type.761 = value_param_pattern %c.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %c.param: %Class = value_param call_param0 +// CHECK:STDOUT: %Class.ref: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] +// CHECK:STDOUT: %c: %Class = value_binding c, %c.param +// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %CallOnConstBoundMethod.decl: %CallOnConstBoundMethod.type = fn_decl @CallOnConstBoundMethod [concrete = constants.%CallOnConstBoundMethod] { +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %CallWithAddr.decl: %CallWithAddr.type = fn_decl @CallWithAddr [concrete = constants.%CallWithAddr] { +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %CallFThroughPointer.decl: %CallFThroughPointer.type = fn_decl @CallFThroughPointer [concrete = constants.%CallFThroughPointer] { +// CHECK:STDOUT: %p.patt: %pattern_type.796 = value_binding_pattern p [concrete] +// CHECK:STDOUT: %p.param_patt: %pattern_type.796 = value_param_pattern %p.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %p.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %.loc47: type = splice_block %ptr [concrete = constants.%ptr.e71] { +// CHECK:STDOUT: %Class.ref: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] +// CHECK:STDOUT: %ptr: type = ptr_type %Class.ref [concrete = constants.%ptr.e71] +// CHECK:STDOUT: } +// CHECK:STDOUT: %p: %ptr.e71 = value_binding p, %p.param +// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %CallGThroughPointer.decl: %CallGThroughPointer.type = fn_decl @CallGThroughPointer [concrete = constants.%CallGThroughPointer] { +// CHECK:STDOUT: %p.patt: %pattern_type.796 = value_binding_pattern p [concrete] +// CHECK:STDOUT: %p.param_patt: %pattern_type.796 = value_param_pattern %p.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %p.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %.loc51: type = splice_block %ptr [concrete = constants.%ptr.e71] { +// CHECK:STDOUT: %Class.ref: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] +// CHECK:STDOUT: %ptr: type = ptr_type %Class.ref [concrete = constants.%ptr.e71] +// CHECK:STDOUT: } +// CHECK:STDOUT: %p: %ptr.e71 = value_binding p, %p.param +// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %Make.decl: %Make.type = fn_decl @Make [concrete = constants.%Make] { +// CHECK:STDOUT: %return.patt: %pattern_type.761 = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.761 = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %Class.ref: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] +// CHECK:STDOUT: %return.param: ref %Class = out_param call_param0 +// CHECK:STDOUT: %return: ref %Class = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %CallFOnInitializingExpr.decl: %CallFOnInitializingExpr.type = fn_decl @CallFOnInitializingExpr [concrete = constants.%CallFOnInitializingExpr] { +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %CallGOnInitializingExpr.decl: %CallGOnInitializingExpr.type = fn_decl @CallGOnInitializingExpr [concrete = constants.%CallGOnInitializingExpr] { +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param0 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Class { +// CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { +// CHECK:STDOUT: %self.patt: %pattern_type.761 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.761 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32.loc16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %self.param.loc16: %Class = value_param call_param0 +// CHECK:STDOUT: %Self.ref.loc16: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self.loc16: %Class = value_binding self, %self.param.loc16 +// CHECK:STDOUT: %return.param.loc16: ref %i32 = out_param call_param1 +// CHECK:STDOUT: %return.loc16: ref %i32 = return_slot %return.param.loc16 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Class.G.decl: %Class.G.type = fn_decl @Class.G [concrete = constants.%Class.G] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc17_8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %self.param: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %.loc17_23: type = splice_block %ptr [concrete = constants.%ptr.e71] { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %ptr: type = ptr_type %Self.ref [concrete = constants.%ptr.e71] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: %ptr.e71 = value_binding self, %self.param +// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %F.ref: %Class.F.type = name_ref F, %Class.F.decl [concrete = constants.%Class.F] +// CHECK:STDOUT: %A: %Class.F.type = alias_binding A, %Class.F.decl [concrete = constants.%Class.F] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc21: %Class.elem = field_decl k, element0 [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.k.0bf [concrete = constants.%complete_type.954] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Class +// CHECK:STDOUT: .F = %Class.F.decl +// CHECK:STDOUT: .G = %Class.G.decl +// CHECK:STDOUT: .A = %A +// CHECK:STDOUT: .k = %.loc21 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.F(%self.param.loc24: %Class) -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %self.ref: %Class = name_ref self, %self.loc24 +// CHECK:STDOUT: %k.ref: %Class.elem = name_ref k, @Class.%.loc21 [concrete = @Class.%.loc21] +// CHECK:STDOUT: %.loc25_14.1: ref %i32 = class_element_access %self.ref, element0 +// CHECK:STDOUT: %.loc25_14.2: %i32 = acquire_value %.loc25_14.1 +// CHECK:STDOUT: %impl.elem0: %.65f = impl_witness_access constants.%Copy.impl_witness.fb7, element0 [concrete = constants.%Int.as.Copy.impl.Op.dfd] +// CHECK:STDOUT: %bound_method.loc25_14.1: = bound_method %.loc25_14.2, %impl.elem0 +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc25_14.2: = bound_method %.loc25_14.2, %specific_fn +// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc25_14.2(%.loc25_14.2) +// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call to %return.loc24 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.G(%self.param: %ptr.e71) -> %i32; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Call(%c.param: %Class) -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %c.ref: %Class = name_ref c, %c +// CHECK:STDOUT: %F.ref: %Class.F.type = name_ref F, @Class.%Class.F.decl [concrete = constants.%Class.F] +// CHECK:STDOUT: %Class.F.bound: = bound_method %c.ref, %F.ref +// CHECK:STDOUT: %Class.F.call: init %i32 = call %Class.F.bound(%c.ref) +// CHECK:STDOUT: return %Class.F.call to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @CallAlias(%c.param: %Class) -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %c.ref: %Class = name_ref c, %c +// CHECK:STDOUT: %A.ref: %Class.F.type = name_ref A, @Class.%A [concrete = constants.%Class.F] +// CHECK:STDOUT: %Class.F.bound: = bound_method %c.ref, %A.ref +// CHECK:STDOUT: %Class.F.call: init %i32 = call %Class.F.bound(%c.ref) +// CHECK:STDOUT: return %Class.F.call to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @CallOnConstBoundMethod() -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %.loc39_18.1: %struct_type.k.240 = struct_literal (%int_1) +// CHECK:STDOUT: %Class.ref: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] +// CHECK:STDOUT: %impl.elem0: %.322 = impl_witness_access constants.%ImplicitAs.impl_witness.bc9, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b] +// CHECK:STDOUT: %bound_method.loc39_18.1: = bound_method %int_1, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound] +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc39_18.2: = bound_method %int_1, %specific_fn [concrete = constants.%bound_method] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc39_18.2(%int_1) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc39_18.2: init %i32 = converted %int_1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc39_18.3: ref %Class = temporary_storage +// CHECK:STDOUT: %.loc39_18.4: ref %i32 = class_element_access %.loc39_18.3, element0 +// CHECK:STDOUT: %.loc39_18.5: init %i32 = initialize_from %.loc39_18.2 to %.loc39_18.4 [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc39_18.6: init %Class = class_init (%.loc39_18.5), %.loc39_18.3 [concrete = constants.%Class.val] +// CHECK:STDOUT: %.loc39_18.7: ref %Class = temporary %.loc39_18.3, %.loc39_18.6 +// CHECK:STDOUT: %.loc39_20.1: ref %Class = converted %.loc39_18.1, %.loc39_18.7 +// CHECK:STDOUT: %F.ref: %Class.F.type = name_ref F, @Class.%Class.F.decl [concrete = constants.%Class.F] +// CHECK:STDOUT: %Class.F.bound: = bound_method %.loc39_20.1, %F.ref +// CHECK:STDOUT: %.loc39_20.2: %Class = acquire_value %.loc39_20.1 +// CHECK:STDOUT: %Class.F.call: init %i32 = call %Class.F.bound(%.loc39_20.2) +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: = bound_method %.loc39_18.7, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.378 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.378, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc39_18.3: = bound_method %.loc39_18.7, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %addr: %ptr.e71 = addr_of %.loc39_18.7 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc39_18.3(%addr) +// CHECK:STDOUT: return %Class.F.call to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @CallWithAddr() -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %c.patt: %pattern_type.761 = ref_binding_pattern c [concrete] +// CHECK:STDOUT: %c.var_patt: %pattern_type.761 = var_pattern %c.patt [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %c.var: ref %Class = var %c.var_patt +// CHECK:STDOUT: %Class.ref: type = name_ref Class, file.%Class.decl [concrete = constants.%Class] +// CHECK:STDOUT: %c: ref %Class = ref_binding c, %c.var +// CHECK:STDOUT: %c.ref: ref %Class = name_ref c, %c +// CHECK:STDOUT: %G.ref: %Class.G.type = name_ref G, @Class.%Class.G.decl [concrete = constants.%Class.G] +// CHECK:STDOUT: %Class.G.bound: = bound_method %c.ref, %G.ref +// CHECK:STDOUT: %addr.loc44: %ptr.e71 = addr_of %c.ref +// CHECK:STDOUT: %Class.G.call: init %i32 = call %Class.G.bound(%addr.loc44) +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: = bound_method %c.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.378 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.378, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method: = bound_method %c.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %addr.loc43: %ptr.e71 = addr_of %c.var +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc43) +// CHECK:STDOUT: return %Class.G.call to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @CallFThroughPointer(%p.param: %ptr.e71) -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %p.ref: %ptr.e71 = name_ref p, %p +// CHECK:STDOUT: %.loc48_11.1: ref %Class = deref %p.ref +// CHECK:STDOUT: %F.ref: %Class.F.type = name_ref F, @Class.%Class.F.decl [concrete = constants.%Class.F] +// CHECK:STDOUT: %Class.F.bound: = bound_method %.loc48_11.1, %F.ref +// CHECK:STDOUT: %.loc48_11.2: %Class = acquire_value %.loc48_11.1 +// CHECK:STDOUT: %Class.F.call: init %i32 = call %Class.F.bound(%.loc48_11.2) +// CHECK:STDOUT: return %Class.F.call to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @CallGThroughPointer(%p.param: %ptr.e71) -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %p.ref: %ptr.e71 = name_ref p, %p +// CHECK:STDOUT: %.loc52: ref %Class = deref %p.ref +// CHECK:STDOUT: %G.ref: %Class.G.type = name_ref G, @Class.%Class.G.decl [concrete = constants.%Class.G] +// CHECK:STDOUT: %Class.G.bound: = bound_method %.loc52, %G.ref +// CHECK:STDOUT: %addr: %ptr.e71 = addr_of %.loc52 +// CHECK:STDOUT: %Class.G.call: init %i32 = call %Class.G.bound(%addr) +// CHECK:STDOUT: return %Class.G.call to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Make() -> %return.param: %Class; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @CallFOnInitializingExpr() -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make] +// CHECK:STDOUT: %.loc58_15.1: ref %Class = temporary_storage +// CHECK:STDOUT: %Make.call: init %Class = call %Make.ref() to %.loc58_15.1 +// CHECK:STDOUT: %.loc58_15.2: ref %Class = temporary %.loc58_15.1, %Make.call +// CHECK:STDOUT: %F.ref: %Class.F.type = name_ref F, @Class.%Class.F.decl [concrete = constants.%Class.F] +// CHECK:STDOUT: %Class.F.bound: = bound_method %.loc58_15.2, %F.ref +// CHECK:STDOUT: %.loc58_15.3: %Class = acquire_value %.loc58_15.2 +// CHECK:STDOUT: %Class.F.call: init %i32 = call %Class.F.bound(%.loc58_15.3) +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: = bound_method %.loc58_15.2, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.378 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.378, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method: = bound_method %.loc58_15.2, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %addr: %ptr.e71 = addr_of %.loc58_15.2 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr) +// CHECK:STDOUT: return %Class.F.call to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @CallGOnInitializingExpr() -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, file.%Make.decl [concrete = constants.%Make] +// CHECK:STDOUT: %.loc62_15.1: ref %Class = temporary_storage +// CHECK:STDOUT: %Make.call: init %Class = call %Make.ref() to %.loc62_15.1 +// CHECK:STDOUT: %.loc62_15.2: ref %Class = temporary %.loc62_15.1, %Make.call +// CHECK:STDOUT: %G.ref: %Class.G.type = name_ref G, @Class.%Class.G.decl [concrete = constants.%Class.G] +// CHECK:STDOUT: %Class.G.bound: = bound_method %.loc62_15.2, %G.ref +// CHECK:STDOUT: %addr.loc62_15.1: %ptr.e71 = addr_of %.loc62_15.2 +// CHECK:STDOUT: %Class.G.call: init %i32 = call %Class.G.bound(%addr.loc62_15.1) +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: = bound_method %.loc62_15.2, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.378 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.378, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method: = bound_method %.loc62_15.2, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %addr.loc62_15.2: %ptr.e71 = addr_of %.loc62_15.2 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method(%addr.loc62_15.2) +// CHECK:STDOUT: return %Class.G.call to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/raw_self.carbon b/toolchain/check/testdata/class/raw_self.carbon index 4e23ddc8efbe..1fdaf8762ea3 100644 --- a/toolchain/check/testdata/class/raw_self.carbon +++ b/toolchain/check/testdata/class/raw_self.carbon @@ -13,13 +13,13 @@ // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/raw_self.carbon class Class { - fn F[addr self: Self*](r#self: i32); + fn F[ref self: Self](r#self: i32); fn G[self: Self](r#self: i32) -> (i32, i32); var n: i32; } -fn Class.F[addr self: Self*](r#self: i32) { - (*self).n = r#self; +fn Class.F[ref self: Self](r#self: i32) { + self.n = r#self; } fn Class.G[self: Self](r#self: i32) -> (i32, i32) { @@ -30,9 +30,7 @@ fn Class.G[self: Self](r#self: i32) -> (i32, i32) { // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %Class: type = class_type @Class [concrete] -// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] -// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] -// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %pattern_type.761: type = pattern_type %Class [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] @@ -41,7 +39,6 @@ fn Class.G[self: Self](r#self: i32) -> (i32, i32) { // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %Class.F.type: type = fn_type @Class.F [concrete] // CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [concrete] -// CHECK:STDOUT: %pattern_type.761: type = pattern_type %Class [concrete] // CHECK:STDOUT: %tuple.type.24b: type = tuple_type (type, type) [concrete] // CHECK:STDOUT: %tuple.type.d07: type = tuple_type (%i32, %i32) [concrete] // CHECK:STDOUT: %pattern_type.511: type = pattern_type %tuple.type.d07 [concrete] @@ -83,24 +80,20 @@ fn Class.G[self: Self](r#self: i32) -> (i32, i32) { // CHECK:STDOUT: %Core.import = import Core // CHECK:STDOUT: %Class.decl: type = class_decl @Class [concrete = constants.%Class] {} {} // CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { -// CHECK:STDOUT: %self.patt.loc21_17: %pattern_type.796 = value_binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt.loc21_21: %pattern_type.796 = value_param_pattern %self.patt.loc21_17, call_param0 [concrete] -// CHECK:STDOUT: %.loc21_12: %pattern_type.f6d = addr_pattern %self.param_patt.loc21_21 [concrete] -// CHECK:STDOUT: %self.patt.loc21_30: %pattern_type.7ce = value_binding_pattern r#self [concrete] -// CHECK:STDOUT: %self.param_patt.loc21_36: %pattern_type.7ce = value_param_pattern %self.patt.loc21_30, call_param1 [concrete] +// CHECK:STDOUT: %self.patt.loc21_16: %pattern_type.761 = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt.loc21_20: %pattern_type.761 = ref_param_pattern %self.patt.loc21_16, call_param0 [concrete] +// CHECK:STDOUT: %self.patt.loc21_28: %pattern_type.7ce = value_binding_pattern r#self [concrete] +// CHECK:STDOUT: %self.param_patt.loc21_34: %pattern_type.7ce = value_param_pattern %self.patt.loc21_28, call_param1 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param.loc21_21: %ptr.e71 = value_param call_param0 -// CHECK:STDOUT: %.loc21_27: type = splice_block %ptr.loc21 [concrete = constants.%ptr.e71] { -// CHECK:STDOUT: %Self.ref.loc21: type = name_ref Self, constants.%Class [concrete = constants.%Class] -// CHECK:STDOUT: %ptr.loc21: type = ptr_type %Self.ref.loc21 [concrete = constants.%ptr.e71] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self.loc21_17: %ptr.e71 = value_binding self, %self.param.loc21_21 -// CHECK:STDOUT: %self.param.loc21_36: %i32 = value_param call_param1 -// CHECK:STDOUT: %.loc21_38: type = splice_block %i32.loc21 [concrete = constants.%i32] { +// CHECK:STDOUT: %self.param.loc21_20: ref %Class = ref_param call_param0 +// CHECK:STDOUT: %Self.ref.loc21: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self.loc21_16: ref %Class = ref_binding self, %self.param.loc21_20 +// CHECK:STDOUT: %self.param.loc21_34: %i32 = value_param call_param1 +// CHECK:STDOUT: %.loc21: type = splice_block %i32.loc21 [concrete = constants.%i32] { // CHECK:STDOUT: %int_32.loc21: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc21: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } -// CHECK:STDOUT: %self.loc21_30: %i32 = value_binding r#self, %self.param.loc21_36 +// CHECK:STDOUT: %self.loc21_28: %i32 = value_binding r#self, %self.param.loc21_34 // CHECK:STDOUT: } // CHECK:STDOUT: %Class.G.decl: %Class.G.type = fn_decl @Class.G [concrete = constants.%Class.G] { // CHECK:STDOUT: %self.patt.loc25_12: %pattern_type.761 = value_binding_pattern self [concrete] @@ -132,24 +125,20 @@ fn Class.G[self: Self](r#self: i32) -> (i32, i32) { // CHECK:STDOUT: // CHECK:STDOUT: class @Class { // CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { -// CHECK:STDOUT: %self.patt.loc21_17: %pattern_type.796 = value_binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt.loc21_21: %pattern_type.796 = value_param_pattern %self.patt.loc21_17, call_param0 [concrete] -// CHECK:STDOUT: %.loc21_12: %pattern_type.f6d = addr_pattern %self.param_patt.loc21_21 [concrete] -// CHECK:STDOUT: %self.patt.loc21_30: %pattern_type.7ce = value_binding_pattern r#self [concrete] -// CHECK:STDOUT: %self.param_patt.loc21_36: %pattern_type.7ce = value_param_pattern %self.patt.loc21_30, call_param1 [concrete] +// CHECK:STDOUT: %self.patt.loc21_16: %pattern_type.761 = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt.loc21_20: %pattern_type.761 = ref_param_pattern %self.patt.loc21_16, call_param0 [concrete] +// CHECK:STDOUT: %self.patt.loc21_28: %pattern_type.7ce = value_binding_pattern r#self [concrete] +// CHECK:STDOUT: %self.param_patt.loc21_34: %pattern_type.7ce = value_param_pattern %self.patt.loc21_28, call_param1 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param.loc16_17: %ptr.e71 = value_param call_param0 -// CHECK:STDOUT: %.loc16_23: type = splice_block %ptr.loc16 [concrete = constants.%ptr.e71] { -// CHECK:STDOUT: %Self.ref.loc16: type = name_ref Self, constants.%Class [concrete = constants.%Class] -// CHECK:STDOUT: %ptr.loc16: type = ptr_type %Self.ref.loc16 [concrete = constants.%ptr.e71] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self.loc16_13: %ptr.e71 = value_binding self, %self.param.loc16_17 -// CHECK:STDOUT: %self.param.loc16_32: %i32 = value_param call_param1 -// CHECK:STDOUT: %.loc16_34: type = splice_block %i32.loc16 [concrete = constants.%i32] { +// CHECK:STDOUT: %self.param.loc16_16: ref %Class = ref_param call_param0 +// CHECK:STDOUT: %Self.ref.loc16: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self.loc16_12: ref %Class = ref_binding self, %self.param.loc16_16 +// CHECK:STDOUT: %self.param.loc16_30: %i32 = value_param call_param1 +// CHECK:STDOUT: %.loc16: type = splice_block %i32.loc16 [concrete = constants.%i32] { // CHECK:STDOUT: %int_32.loc16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] // CHECK:STDOUT: } -// CHECK:STDOUT: %self.loc16_26: %i32 = value_binding r#self, %self.param.loc16_32 +// CHECK:STDOUT: %self.loc16_24: %i32 = value_binding r#self, %self.param.loc16_30 // CHECK:STDOUT: } // CHECK:STDOUT: %Class.G.decl: %Class.G.type = fn_decl @Class.G [concrete = constants.%Class.G] { // CHECK:STDOUT: %self.patt.loc25_12: %pattern_type.761 = value_binding_pattern self [concrete] @@ -190,19 +179,18 @@ fn Class.G[self: Self](r#self: i32) -> (i32, i32) { // CHECK:STDOUT: .n = %.loc18 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @Class.F(%self.param.loc21_21: %ptr.e71, %self.param.loc21_36: %i32) { +// CHECK:STDOUT: fn @Class.F(%self.param.loc21_20: %Class, %self.param.loc21_34: %i32) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %self.ref.loc22_5: %ptr.e71 = name_ref self, %self.loc21_17 -// CHECK:STDOUT: %.loc22_4: ref %Class = deref %self.ref.loc22_5 +// CHECK:STDOUT: %self.ref.loc22_3: ref %Class = name_ref self, %self.loc21_16 // CHECK:STDOUT: %n.ref: %Class.elem = name_ref n, @Class.%.loc18 [concrete = @Class.%.loc18] -// CHECK:STDOUT: %.loc22_10: ref %i32 = class_element_access %.loc22_4, element0 -// CHECK:STDOUT: %self.ref.loc22_15: %i32 = name_ref r#self, %self.loc21_30 +// CHECK:STDOUT: %.loc22: ref %i32 = class_element_access %self.ref.loc22_3, element0 +// CHECK:STDOUT: %self.ref.loc22_12: %i32 = name_ref r#self, %self.loc21_28 // CHECK:STDOUT: %impl.elem0: %.65f = impl_witness_access constants.%Copy.impl_witness.fb7, element0 [concrete = constants.%Int.as.Copy.impl.Op.dfd] -// CHECK:STDOUT: %bound_method.loc22_15.1: = bound_method %self.ref.loc22_15, %impl.elem0 +// CHECK:STDOUT: %bound_method.loc22_12.1: = bound_method %self.ref.loc22_12, %impl.elem0 // CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc22_15.2: = bound_method %self.ref.loc22_15, %specific_fn -// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc22_15.2(%self.ref.loc22_15) -// CHECK:STDOUT: assign %.loc22_10, %Int.as.Copy.impl.Op.call +// CHECK:STDOUT: %bound_method.loc22_12.2: = bound_method %self.ref.loc22_12, %specific_fn +// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc22_12.2(%self.ref.loc22_12) +// CHECK:STDOUT: assign %.loc22, %Int.as.Copy.impl.Op.call // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/raw_self_addr.carbon b/toolchain/check/testdata/class/raw_self_addr.carbon new file mode 100644 index 000000000000..51aa3bc4da45 --- /dev/null +++ b/toolchain/check/testdata/class/raw_self_addr.carbon @@ -0,0 +1,235 @@ +// 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/class/raw_self_addr.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/raw_self_addr.carbon + +class Class { + fn F[addr self: Self*](r#self: i32); + fn G[self: Self](r#self: i32) -> (i32, i32); + var n: i32; +} + +fn Class.F[addr self: Self*](r#self: i32) { + (*self).n = r#self; +} + +fn Class.G[self: Self](r#self: i32) -> (i32, i32) { + return (self.n, r#self); +} + +// CHECK:STDOUT: --- raw_self_addr.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Class: type = class_type @Class [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [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: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] +// CHECK:STDOUT: %Class.F.type: type = fn_type @Class.F [concrete] +// CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [concrete] +// CHECK:STDOUT: %pattern_type.761: type = pattern_type %Class [concrete] +// CHECK:STDOUT: %tuple.type.24b: type = tuple_type (type, type) [concrete] +// CHECK:STDOUT: %tuple.type.d07: type = tuple_type (%i32, %i32) [concrete] +// CHECK:STDOUT: %pattern_type.511: type = pattern_type %tuple.type.d07 [concrete] +// CHECK:STDOUT: %Class.G.type: type = fn_type @Class.G [concrete] +// CHECK:STDOUT: %Class.G: %Class.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %i32 [concrete] +// CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete] +// CHECK:STDOUT: %complete_type.54b: = complete_type_witness %struct_type.n [concrete] +// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] +// CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.24b: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.c95: %Int.as.Copy.impl.Op.type.24b = struct_value () [symbolic] +// CHECK:STDOUT: %Copy.impl_witness.fb7: = impl_witness imports.%Copy.impl_witness_table.b6a, @Int.as.Copy.impl(%int_32) [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.469: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%int_32) [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.dfd: %Int.as.Copy.impl.Op.type.469 = struct_value () [concrete] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %i32, (%Copy.impl_witness.fb7) [concrete] +// CHECK:STDOUT: %.65f: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: = specific_function %Int.as.Copy.impl.Op.dfd, @Int.as.Copy.impl.Op(%int_32) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Copy = %Core.Copy +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/parts/copy, Copy, loaded [concrete = constants.%Copy.type] +// CHECK:STDOUT: %Core.import_ref.d12: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.24b) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Int.as.Copy.impl.%Int.as.Copy.impl.Op (constants.%Int.as.Copy.impl.Op.c95)] +// CHECK:STDOUT: %Copy.impl_witness_table.b6a = impl_witness_table (%Core.import_ref.d12), @Int.as.Copy.impl [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Class = %Class.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Class.decl: type = class_decl @Class [concrete = constants.%Class] {} {} +// CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { +// CHECK:STDOUT: %self.patt.loc21_17: %pattern_type.796 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt.loc21_21: %pattern_type.796 = value_param_pattern %self.patt.loc21_17, call_param0 [concrete] +// CHECK:STDOUT: %.loc21_12: %pattern_type.f6d = addr_pattern %self.param_patt.loc21_21 [concrete] +// CHECK:STDOUT: %self.patt.loc21_30: %pattern_type.7ce = value_binding_pattern r#self [concrete] +// CHECK:STDOUT: %self.param_patt.loc21_36: %pattern_type.7ce = value_param_pattern %self.patt.loc21_30, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param.loc21_21: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %.loc21_27: type = splice_block %ptr.loc21 [concrete = constants.%ptr.e71] { +// CHECK:STDOUT: %Self.ref.loc21: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %ptr.loc21: type = ptr_type %Self.ref.loc21 [concrete = constants.%ptr.e71] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self.loc21_17: %ptr.e71 = value_binding self, %self.param.loc21_21 +// CHECK:STDOUT: %self.param.loc21_36: %i32 = value_param call_param1 +// CHECK:STDOUT: %.loc21_38: type = splice_block %i32.loc21 [concrete = constants.%i32] { +// CHECK:STDOUT: %int_32.loc21: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc21: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self.loc21_30: %i32 = value_binding r#self, %self.param.loc21_36 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Class.G.decl: %Class.G.type = fn_decl @Class.G [concrete = constants.%Class.G] { +// CHECK:STDOUT: %self.patt.loc25_12: %pattern_type.761 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt.loc25_16: %pattern_type.761 = value_param_pattern %self.patt.loc25_12, call_param0 [concrete] +// CHECK:STDOUT: %self.patt.loc25_24: %pattern_type.7ce = value_binding_pattern r#self [concrete] +// CHECK:STDOUT: %self.param_patt.loc25_30: %pattern_type.7ce = value_param_pattern %self.patt.loc25_24, call_param1 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.511 = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.511 = out_param_pattern %return.patt, call_param2 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32.loc25_41: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc25_41: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %int_32.loc25_46: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc25_46: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc25_49.1: %tuple.type.24b = tuple_literal (%i32.loc25_41, %i32.loc25_46) +// CHECK:STDOUT: %.loc25_49.2: type = converted %.loc25_49.1, constants.%tuple.type.d07 [concrete = constants.%tuple.type.d07] +// CHECK:STDOUT: %self.param.loc25_16: %Class = value_param call_param0 +// CHECK:STDOUT: %Self.ref.loc25: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self.loc25_12: %Class = value_binding self, %self.param.loc25_16 +// CHECK:STDOUT: %self.param.loc25_30: %i32 = value_param call_param1 +// CHECK:STDOUT: %.loc25_32: type = splice_block %i32.loc25_32 [concrete = constants.%i32] { +// CHECK:STDOUT: %int_32.loc25_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc25_32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self.loc25_24: %i32 = value_binding r#self, %self.param.loc25_30 +// CHECK:STDOUT: %return.param.loc25: ref %tuple.type.d07 = out_param call_param2 +// CHECK:STDOUT: %return.loc25: ref %tuple.type.d07 = return_slot %return.param.loc25 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Class { +// CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { +// CHECK:STDOUT: %self.patt.loc21_17: %pattern_type.796 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt.loc21_21: %pattern_type.796 = value_param_pattern %self.patt.loc21_17, call_param0 [concrete] +// CHECK:STDOUT: %.loc21_12: %pattern_type.f6d = addr_pattern %self.param_patt.loc21_21 [concrete] +// CHECK:STDOUT: %self.patt.loc21_30: %pattern_type.7ce = value_binding_pattern r#self [concrete] +// CHECK:STDOUT: %self.param_patt.loc21_36: %pattern_type.7ce = value_param_pattern %self.patt.loc21_30, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param.loc16_17: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %.loc16_23: type = splice_block %ptr.loc16 [concrete = constants.%ptr.e71] { +// CHECK:STDOUT: %Self.ref.loc16: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %ptr.loc16: type = ptr_type %Self.ref.loc16 [concrete = constants.%ptr.e71] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self.loc16_13: %ptr.e71 = value_binding self, %self.param.loc16_17 +// CHECK:STDOUT: %self.param.loc16_32: %i32 = value_param call_param1 +// CHECK:STDOUT: %.loc16_34: type = splice_block %i32.loc16 [concrete = constants.%i32] { +// CHECK:STDOUT: %int_32.loc16: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc16: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self.loc16_26: %i32 = value_binding r#self, %self.param.loc16_32 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Class.G.decl: %Class.G.type = fn_decl @Class.G [concrete = constants.%Class.G] { +// CHECK:STDOUT: %self.patt.loc25_12: %pattern_type.761 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt.loc25_16: %pattern_type.761 = value_param_pattern %self.patt.loc25_12, call_param0 [concrete] +// CHECK:STDOUT: %self.patt.loc25_24: %pattern_type.7ce = value_binding_pattern r#self [concrete] +// CHECK:STDOUT: %self.param_patt.loc25_30: %pattern_type.7ce = value_param_pattern %self.patt.loc25_24, call_param1 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.511 = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.511 = out_param_pattern %return.patt, call_param2 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32.loc17_37: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc17_37: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %int_32.loc17_42: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc17_42: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc17_45.1: %tuple.type.24b = tuple_literal (%i32.loc17_37, %i32.loc17_42) +// CHECK:STDOUT: %.loc17_45.2: type = converted %.loc17_45.1, constants.%tuple.type.d07 [concrete = constants.%tuple.type.d07] +// CHECK:STDOUT: %self.param.loc17_12: %Class = value_param call_param0 +// CHECK:STDOUT: %Self.ref.loc17: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self.loc17_8: %Class = value_binding self, %self.param.loc17_12 +// CHECK:STDOUT: %self.param.loc17_26: %i32 = value_param call_param1 +// CHECK:STDOUT: %.loc17_28: type = splice_block %i32.loc17_28 [concrete = constants.%i32] { +// CHECK:STDOUT: %int_32.loc17_28: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc17_28: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self.loc17_20: %i32 = value_binding r#self, %self.param.loc17_26 +// CHECK:STDOUT: %return.param.loc17: ref %tuple.type.d07 = out_param call_param2 +// CHECK:STDOUT: %return.loc17: ref %tuple.type.d07 = return_slot %return.param.loc17 +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc18: %Class.elem = field_decl n, element0 [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.n [concrete = constants.%complete_type.54b] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Class +// CHECK:STDOUT: .F = %Class.F.decl +// CHECK:STDOUT: .G = %Class.G.decl +// CHECK:STDOUT: .n = %.loc18 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.F(%self.param.loc21_21: %ptr.e71, %self.param.loc21_36: %i32) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %self.ref.loc22_5: %ptr.e71 = name_ref self, %self.loc21_17 +// CHECK:STDOUT: %.loc22_4: ref %Class = deref %self.ref.loc22_5 +// CHECK:STDOUT: %n.ref: %Class.elem = name_ref n, @Class.%.loc18 [concrete = @Class.%.loc18] +// CHECK:STDOUT: %.loc22_10: ref %i32 = class_element_access %.loc22_4, element0 +// CHECK:STDOUT: %self.ref.loc22_15: %i32 = name_ref r#self, %self.loc21_30 +// CHECK:STDOUT: %impl.elem0: %.65f = impl_witness_access constants.%Copy.impl_witness.fb7, element0 [concrete = constants.%Int.as.Copy.impl.Op.dfd] +// CHECK:STDOUT: %bound_method.loc22_15.1: = bound_method %self.ref.loc22_15, %impl.elem0 +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc22_15.2: = bound_method %self.ref.loc22_15, %specific_fn +// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc22_15.2(%self.ref.loc22_15) +// CHECK:STDOUT: assign %.loc22_10, %Int.as.Copy.impl.Op.call +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.G(%self.param.loc25_16: %Class, %self.param.loc25_30: %i32) -> %return.param.loc25: %tuple.type.d07 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %self.ref.loc26_11: %Class = name_ref self, %self.loc25_12 +// CHECK:STDOUT: %n.ref: %Class.elem = name_ref n, @Class.%.loc18 [concrete = @Class.%.loc18] +// CHECK:STDOUT: %.loc26_15.1: ref %i32 = class_element_access %self.ref.loc26_11, element0 +// CHECK:STDOUT: %.loc26_15.2: %i32 = acquire_value %.loc26_15.1 +// CHECK:STDOUT: %self.ref.loc26_19: %i32 = name_ref r#self, %self.loc25_24 +// CHECK:STDOUT: %.loc26_25.1: %tuple.type.d07 = tuple_literal (%.loc26_15.2, %self.ref.loc26_19) +// CHECK:STDOUT: %impl.elem0.loc26_15: %.65f = impl_witness_access constants.%Copy.impl_witness.fb7, element0 [concrete = constants.%Int.as.Copy.impl.Op.dfd] +// CHECK:STDOUT: %bound_method.loc26_15.1: = bound_method %.loc26_15.2, %impl.elem0.loc26_15 +// CHECK:STDOUT: %specific_fn.loc26_15: = specific_function %impl.elem0.loc26_15, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc26_15.2: = bound_method %.loc26_15.2, %specific_fn.loc26_15 +// CHECK:STDOUT: %Int.as.Copy.impl.Op.call.loc26_15: init %i32 = call %bound_method.loc26_15.2(%.loc26_15.2) +// CHECK:STDOUT: %tuple.elem0: ref %i32 = tuple_access %return.loc25, element0 +// CHECK:STDOUT: %.loc26_25.2: init %i32 = initialize_from %Int.as.Copy.impl.Op.call.loc26_15 to %tuple.elem0 +// CHECK:STDOUT: %impl.elem0.loc26_19: %.65f = impl_witness_access constants.%Copy.impl_witness.fb7, element0 [concrete = constants.%Int.as.Copy.impl.Op.dfd] +// CHECK:STDOUT: %bound_method.loc26_19.1: = bound_method %self.ref.loc26_19, %impl.elem0.loc26_19 +// CHECK:STDOUT: %specific_fn.loc26_19: = specific_function %impl.elem0.loc26_19, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc26_19.2: = bound_method %self.ref.loc26_19, %specific_fn.loc26_19 +// CHECK:STDOUT: %Int.as.Copy.impl.Op.call.loc26_19: init %i32 = call %bound_method.loc26_19.2(%self.ref.loc26_19) +// CHECK:STDOUT: %tuple.elem1: ref %i32 = tuple_access %return.loc25, element1 +// CHECK:STDOUT: %.loc26_25.3: init %i32 = initialize_from %Int.as.Copy.impl.Op.call.loc26_19 to %tuple.elem1 +// CHECK:STDOUT: %.loc26_25.4: init %tuple.type.d07 = tuple_init (%.loc26_25.2, %.loc26_25.3) to %return.loc25 +// CHECK:STDOUT: %.loc26_26: init %tuple.type.d07 = converted %.loc26_25.1, %.loc26_25.4 +// CHECK:STDOUT: return %.loc26_26 to %return.loc25 +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/self.carbon b/toolchain/check/testdata/class/self.carbon index 5ea37b476b57..63668a06eeb6 100644 --- a/toolchain/check/testdata/class/self.carbon +++ b/toolchain/check/testdata/class/self.carbon @@ -18,7 +18,7 @@ library "[[@TEST_NAME]]"; class Class { fn F[self: Self]() -> i32; - fn G[addr self: Self*]() -> i32; + fn G[ref self: Self]() -> i32; var n: i32; } @@ -27,8 +27,8 @@ fn Class.F[self: Self]() -> i32 { return self.n; } -fn Class.G[addr self: Self*]() -> i32 { - return (*self).n; +fn Class.G[ref self: Self]() -> i32 { + return self.n; } // --- fail_return_self_value.carbon @@ -59,9 +59,6 @@ class Class { // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %Class.F.type: type = fn_type @Class.F [concrete] // CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] -// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] -// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %Class.G.type: type = fn_type @Class.G [concrete] // CHECK:STDOUT: %Class.G: %Class.G.type = struct_value () [concrete] // CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %i32 [concrete] @@ -114,20 +111,16 @@ class Class { // CHECK:STDOUT: %return.loc11: ref %i32 = return_slot %return.param.loc11 // CHECK:STDOUT: } // CHECK:STDOUT: %Class.G.decl: %Class.G.type = fn_decl @Class.G [concrete = constants.%Class.G] { -// CHECK:STDOUT: %self.patt: %pattern_type.796 = value_binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] -// CHECK:STDOUT: %.loc15_12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %self.patt: %pattern_type.761 = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.761 = ref_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] // CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %int_32.loc15: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc15: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %self.param.loc15: %ptr.e71 = value_param call_param0 -// CHECK:STDOUT: %.loc15_27: type = splice_block %ptr.loc15 [concrete = constants.%ptr.e71] { -// CHECK:STDOUT: %Self.ref.loc15: type = name_ref Self, constants.%Class [concrete = constants.%Class] -// CHECK:STDOUT: %ptr.loc15: type = ptr_type %Self.ref.loc15 [concrete = constants.%ptr.e71] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self.loc15: %ptr.e71 = value_binding self, %self.param.loc15 +// CHECK:STDOUT: %self.param.loc15: ref %Class = ref_param call_param0 +// CHECK:STDOUT: %Self.ref.loc15: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self.loc15: ref %Class = ref_binding self, %self.param.loc15 // CHECK:STDOUT: %return.param.loc15: ref %i32 = out_param call_param1 // CHECK:STDOUT: %return.loc15: ref %i32 = return_slot %return.param.loc15 // CHECK:STDOUT: } @@ -149,20 +142,16 @@ class Class { // CHECK:STDOUT: %return.loc5: ref %i32 = return_slot %return.param.loc5 // CHECK:STDOUT: } // CHECK:STDOUT: %Class.G.decl: %Class.G.type = fn_decl @Class.G [concrete = constants.%Class.G] { -// CHECK:STDOUT: %self.patt: %pattern_type.796 = value_binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] -// CHECK:STDOUT: %.loc15_12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %self.patt: %pattern_type.761 = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.761 = ref_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] // CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %int_32.loc6: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] // CHECK:STDOUT: %i32.loc6: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] -// CHECK:STDOUT: %self.param.loc6: %ptr.e71 = value_param call_param0 -// CHECK:STDOUT: %.loc6: type = splice_block %ptr.loc6 [concrete = constants.%ptr.e71] { -// CHECK:STDOUT: %Self.ref.loc6: type = name_ref Self, constants.%Class [concrete = constants.%Class] -// CHECK:STDOUT: %ptr.loc6: type = ptr_type %Self.ref.loc6 [concrete = constants.%ptr.e71] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self.loc6: %ptr.e71 = value_binding self, %self.param.loc6 +// CHECK:STDOUT: %self.param.loc6: ref %Class = ref_param call_param0 +// CHECK:STDOUT: %Self.ref.loc6: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self.loc6: ref %Class = ref_binding self, %self.param.loc6 // CHECK:STDOUT: %return.param.loc6: ref %i32 = out_param call_param1 // CHECK:STDOUT: %return.loc6: ref %i32 = return_slot %return.param.loc6 // CHECK:STDOUT: } @@ -193,18 +182,17 @@ class Class { // CHECK:STDOUT: return %Int.as.Copy.impl.Op.call to %return.loc11 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @Class.G(%self.param.loc15: %ptr.e71) -> %i32 { +// CHECK:STDOUT: fn @Class.G(%self.param.loc15: %Class) -> %i32 { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %self.ref: %ptr.e71 = name_ref self, %self.loc15 -// CHECK:STDOUT: %.loc16_11: ref %Class = deref %self.ref +// CHECK:STDOUT: %self.ref: ref %Class = name_ref self, %self.loc15 // CHECK:STDOUT: %n.ref: %Class.elem = name_ref n, @Class.%.loc8 [concrete = @Class.%.loc8] -// CHECK:STDOUT: %.loc16_17.1: ref %i32 = class_element_access %.loc16_11, element0 -// CHECK:STDOUT: %.loc16_17.2: %i32 = acquire_value %.loc16_17.1 +// CHECK:STDOUT: %.loc16_14.1: ref %i32 = class_element_access %self.ref, element0 +// CHECK:STDOUT: %.loc16_14.2: %i32 = acquire_value %.loc16_14.1 // CHECK:STDOUT: %impl.elem0: %.65f = impl_witness_access constants.%Copy.impl_witness.fb7, element0 [concrete = constants.%Int.as.Copy.impl.Op.dfd] -// CHECK:STDOUT: %bound_method.loc16_17.1: = bound_method %.loc16_17.2, %impl.elem0 +// CHECK:STDOUT: %bound_method.loc16_14.1: = bound_method %.loc16_14.2, %impl.elem0 // CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn] -// CHECK:STDOUT: %bound_method.loc16_17.2: = bound_method %.loc16_17.2, %specific_fn -// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc16_17.2(%.loc16_17.2) +// CHECK:STDOUT: %bound_method.loc16_14.2: = bound_method %.loc16_14.2, %specific_fn +// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc16_14.2(%.loc16_14.2) // CHECK:STDOUT: return %Int.as.Copy.impl.Op.call to %return.loc15 // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/self_addr.carbon b/toolchain/check/testdata/class/self_addr.carbon new file mode 100644 index 000000000000..2865f9477f66 --- /dev/null +++ b/toolchain/check/testdata/class/self_addr.carbon @@ -0,0 +1,266 @@ +// 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/class/self_addr.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/self_addr.carbon + +// --- self.carbon + +library "[[@TEST_NAME]]"; + +class Class { + fn F[self: Self]() -> i32; + fn G[addr self: Self*]() -> i32; + + var n: i32; +} + +fn Class.F[self: Self]() -> i32 { + return self.n; +} + +fn Class.G[addr self: Self*]() -> i32 { + return (*self).n; +} + +// --- fail_return_self_value.carbon + +library "[[@TEST_NAME]]"; + +class Class { + // CHECK:STDERR: fail_return_self_value.carbon:[[@LINE+7]]:25: error: cannot implicitly convert non-type value of type `Class` to `type` [ConversionFailureNonTypeToFacet] + // CHECK:STDERR: fn F[self: Self]() -> self; + // CHECK:STDERR: ^~~~ + // CHECK:STDERR: fail_return_self_value.carbon:[[@LINE+4]]:25: note: type `Class` does not implement interface `Core.ImplicitAs(type)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: fn F[self: Self]() -> self; + // CHECK:STDERR: ^~~~ + // CHECK:STDERR: + fn F[self: Self]() -> self; +} + +// CHECK:STDOUT: --- self.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Class: type = class_type @Class [concrete] +// CHECK:STDOUT: %pattern_type.761: type = pattern_type %Class [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: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] +// CHECK:STDOUT: %Class.F.type: type = fn_type @Class.F [concrete] +// CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [concrete] +// CHECK:STDOUT: %ptr.e71: type = ptr_type %Class [concrete] +// CHECK:STDOUT: %pattern_type.796: type = pattern_type %ptr.e71 [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Class.G.type: type = fn_type @Class.G [concrete] +// CHECK:STDOUT: %Class.G: %Class.G.type = struct_value () [concrete] +// CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %i32 [concrete] +// CHECK:STDOUT: %struct_type.n: type = struct_type {.n: %i32} [concrete] +// CHECK:STDOUT: %complete_type.54b: = complete_type_witness %struct_type.n [concrete] +// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] +// CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.24b: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.c95: %Int.as.Copy.impl.Op.type.24b = struct_value () [symbolic] +// CHECK:STDOUT: %Copy.impl_witness.fb7: = impl_witness imports.%Copy.impl_witness_table.b6a, @Int.as.Copy.impl(%int_32) [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.469: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%int_32) [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.dfd: %Int.as.Copy.impl.Op.type.469 = struct_value () [concrete] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %i32, (%Copy.impl_witness.fb7) [concrete] +// CHECK:STDOUT: %.65f: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: = specific_function %Int.as.Copy.impl.Op.dfd, @Int.as.Copy.impl.Op(%int_32) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Copy = %Core.Copy +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/parts/copy, Copy, loaded [concrete = constants.%Copy.type] +// CHECK:STDOUT: %Core.import_ref.d12: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.24b) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Int.as.Copy.impl.%Int.as.Copy.impl.Op (constants.%Int.as.Copy.impl.Op.c95)] +// CHECK:STDOUT: %Copy.impl_witness_table.b6a = impl_witness_table (%Core.import_ref.d12), @Int.as.Copy.impl [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Class = %Class.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Class.decl: type = class_decl @Class [concrete = constants.%Class] {} {} +// CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { +// CHECK:STDOUT: %self.patt: %pattern_type.761 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.761 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32.loc11: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc11: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %self.param.loc11: %Class = value_param call_param0 +// CHECK:STDOUT: %Self.ref.loc11: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self.loc11: %Class = value_binding self, %self.param.loc11 +// CHECK:STDOUT: %return.param.loc11: ref %i32 = out_param call_param1 +// CHECK:STDOUT: %return.loc11: ref %i32 = return_slot %return.param.loc11 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Class.G.decl: %Class.G.type = fn_decl @Class.G [concrete = constants.%Class.G] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15_12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32.loc15: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc15: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %self.param.loc15: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %.loc15_27: type = splice_block %ptr.loc15 [concrete = constants.%ptr.e71] { +// CHECK:STDOUT: %Self.ref.loc15: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %ptr.loc15: type = ptr_type %Self.ref.loc15 [concrete = constants.%ptr.e71] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self.loc15: %ptr.e71 = value_binding self, %self.param.loc15 +// CHECK:STDOUT: %return.param.loc15: ref %i32 = out_param call_param1 +// CHECK:STDOUT: %return.loc15: ref %i32 = return_slot %return.param.loc15 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Class { +// CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { +// CHECK:STDOUT: %self.patt: %pattern_type.761 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.761 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32.loc5: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc5: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %self.param.loc5: %Class = value_param call_param0 +// CHECK:STDOUT: %Self.ref.loc5: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self.loc5: %Class = value_binding self, %self.param.loc5 +// CHECK:STDOUT: %return.param.loc5: ref %i32 = out_param call_param1 +// CHECK:STDOUT: %return.loc5: ref %i32 = return_slot %return.param.loc5 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Class.G.decl: %Class.G.type = fn_decl @Class.G [concrete = constants.%Class.G] { +// CHECK:STDOUT: %self.patt: %pattern_type.796 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.796 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc15_12: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32.loc6: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc6: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %self.param.loc6: %ptr.e71 = value_param call_param0 +// CHECK:STDOUT: %.loc6: type = splice_block %ptr.loc6 [concrete = constants.%ptr.e71] { +// CHECK:STDOUT: %Self.ref.loc6: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %ptr.loc6: type = ptr_type %Self.ref.loc6 [concrete = constants.%ptr.e71] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self.loc6: %ptr.e71 = value_binding self, %self.param.loc6 +// CHECK:STDOUT: %return.param.loc6: ref %i32 = out_param call_param1 +// CHECK:STDOUT: %return.loc6: ref %i32 = return_slot %return.param.loc6 +// CHECK:STDOUT: } +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc8: %Class.elem = field_decl n, element0 [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.n [concrete = constants.%complete_type.54b] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Class +// CHECK:STDOUT: .F = %Class.F.decl +// CHECK:STDOUT: .G = %Class.G.decl +// CHECK:STDOUT: .n = %.loc8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.F(%self.param.loc11: %Class) -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %self.ref: %Class = name_ref self, %self.loc11 +// CHECK:STDOUT: %n.ref: %Class.elem = name_ref n, @Class.%.loc8 [concrete = @Class.%.loc8] +// CHECK:STDOUT: %.loc12_14.1: ref %i32 = class_element_access %self.ref, element0 +// CHECK:STDOUT: %.loc12_14.2: %i32 = acquire_value %.loc12_14.1 +// CHECK:STDOUT: %impl.elem0: %.65f = impl_witness_access constants.%Copy.impl_witness.fb7, element0 [concrete = constants.%Int.as.Copy.impl.Op.dfd] +// CHECK:STDOUT: %bound_method.loc12_14.1: = bound_method %.loc12_14.2, %impl.elem0 +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc12_14.2: = bound_method %.loc12_14.2, %specific_fn +// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc12_14.2(%.loc12_14.2) +// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call to %return.loc11 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.G(%self.param.loc15: %ptr.e71) -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %self.ref: %ptr.e71 = name_ref self, %self.loc15 +// CHECK:STDOUT: %.loc16_11: ref %Class = deref %self.ref +// CHECK:STDOUT: %n.ref: %Class.elem = name_ref n, @Class.%.loc8 [concrete = @Class.%.loc8] +// CHECK:STDOUT: %.loc16_17.1: ref %i32 = class_element_access %.loc16_11, element0 +// CHECK:STDOUT: %.loc16_17.2: %i32 = acquire_value %.loc16_17.1 +// CHECK:STDOUT: %impl.elem0: %.65f = impl_witness_access constants.%Copy.impl_witness.fb7, element0 [concrete = constants.%Int.as.Copy.impl.Op.dfd] +// CHECK:STDOUT: %bound_method.loc16_17.1: = bound_method %.loc16_17.2, %impl.elem0 +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc16_17.2: = bound_method %.loc16_17.2, %specific_fn +// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc16_17.2(%.loc16_17.2) +// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call to %return.loc15 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_return_self_value.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Class: type = class_type @Class [concrete] +// CHECK:STDOUT: %pattern_type.761: type = pattern_type %Class [concrete] +// CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] +// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] +// CHECK:STDOUT: %Class.F.type: type = fn_type @Class.F [concrete] +// CHECK:STDOUT: %Class.F: %Class.F.type = struct_value () [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Class = %Class.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Class.decl: type = class_decl @Class [concrete = constants.%Class] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Class { +// CHECK:STDOUT: %Class.F.decl: %Class.F.type = fn_decl @Class.F [concrete = constants.%Class.F] { +// CHECK:STDOUT: %self.patt: %pattern_type.761 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.761 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.ref: %Class = name_ref self, %self +// CHECK:STDOUT: %.loc12: type = converted %self.ref, [concrete = ] +// CHECK:STDOUT: %self.param: %Class = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Class [concrete = constants.%Class] +// CHECK:STDOUT: %self: %Class = value_binding self, %self.param +// CHECK:STDOUT: %return.param: ref = out_param call_param1 +// CHECK:STDOUT: %return: ref = return_slot %return.param +// 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.%Class +// CHECK:STDOUT: .F = %Class.F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Class.F(%self.param: %Class) -> ; +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/self_conversion.carbon b/toolchain/check/testdata/class/self_conversion.carbon index 7c6211e235ba..4f5d3c46a530 100644 --- a/toolchain/check/testdata/class/self_conversion.carbon +++ b/toolchain/check/testdata/class/self_conversion.carbon @@ -20,19 +20,19 @@ class Derived { extend base: Base; fn SelfBase[self: Base]() -> i32; - fn AddrSelfBase[addr self: Base*](); + fn RefSelfBase[ref self: Base](); } fn Derived.SelfBase[self: Base]() -> i32 { return self.a; } -fn Derived.AddrSelfBase[addr self: Base*]() { - (*self).a = 1; +fn Derived.RefSelfBase[ref self: Base]() { + self.a = 1; } fn Call(p: Derived*) -> i32 { - (*p).AddrSelfBase(); + (*p).RefSelfBase(); return (*p).SelfBase(); } @@ -55,11 +55,8 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] // CHECK:STDOUT: %Derived.SelfBase.type: type = fn_type @Derived.SelfBase [concrete] // CHECK:STDOUT: %Derived.SelfBase: %Derived.SelfBase.type = struct_value () [concrete] -// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] -// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] -// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] -// CHECK:STDOUT: %Derived.AddrSelfBase.type: type = fn_type @Derived.AddrSelfBase [concrete] -// CHECK:STDOUT: %Derived.AddrSelfBase: %Derived.AddrSelfBase.type = struct_value () [concrete] +// CHECK:STDOUT: %Derived.RefSelfBase.type: type = fn_type @Derived.RefSelfBase [concrete] +// CHECK:STDOUT: %Derived.RefSelfBase: %Derived.RefSelfBase.type = struct_value () [concrete] // CHECK:STDOUT: %struct_type.base.b1e: type = struct_type {.base: %Base} [concrete] // CHECK:STDOUT: %complete_type.15c: = complete_type_witness %struct_type.base.b1e [concrete] // CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] @@ -136,17 +133,13 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: %return.param.loc26: ref %i32 = out_param call_param1 // CHECK:STDOUT: %return.loc26: ref %i32 = return_slot %return.param.loc26 // CHECK:STDOUT: } -// CHECK:STDOUT: %Derived.AddrSelfBase.decl: %Derived.AddrSelfBase.type = fn_decl @Derived.AddrSelfBase [concrete = constants.%Derived.AddrSelfBase] { -// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = value_binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] -// CHECK:STDOUT: %.loc30_25: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %Derived.RefSelfBase.decl: %Derived.RefSelfBase.type = fn_decl @Derived.RefSelfBase [concrete = constants.%Derived.RefSelfBase] { +// CHECK:STDOUT: %self.patt: %pattern_type.bcc = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.bcc = ref_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param.loc30: %ptr.11f = value_param call_param0 -// CHECK:STDOUT: %.loc30_40: type = splice_block %ptr.loc30 [concrete = constants.%ptr.11f] { -// CHECK:STDOUT: %Base.ref.loc30: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] -// CHECK:STDOUT: %ptr.loc30: type = ptr_type %Base.ref.loc30 [concrete = constants.%ptr.11f] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self.loc30: %ptr.11f = value_binding self, %self.param.loc30 +// CHECK:STDOUT: %self.param.loc30: ref %Base = ref_param call_param0 +// CHECK:STDOUT: %Base.ref.loc30: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] +// CHECK:STDOUT: %self.loc30: ref %Base = ref_binding self, %self.param.loc30 // CHECK:STDOUT: } // CHECK:STDOUT: %Call.decl: %Call.type = fn_decl @Call [concrete = constants.%Call] { // CHECK:STDOUT: %p.patt: %pattern_type.605 = value_binding_pattern p [concrete] @@ -197,17 +190,13 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: %return.param.loc22: ref %i32 = out_param call_param1 // CHECK:STDOUT: %return.loc22: ref %i32 = return_slot %return.param.loc22 // CHECK:STDOUT: } -// CHECK:STDOUT: %Derived.AddrSelfBase.decl: %Derived.AddrSelfBase.type = fn_decl @Derived.AddrSelfBase [concrete = constants.%Derived.AddrSelfBase] { -// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = value_binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] -// CHECK:STDOUT: %.loc30_25: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %Derived.RefSelfBase.decl: %Derived.RefSelfBase.type = fn_decl @Derived.RefSelfBase [concrete = constants.%Derived.RefSelfBase] { +// CHECK:STDOUT: %self.patt: %pattern_type.bcc = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.bcc = ref_param_pattern %self.patt, call_param0 [concrete] // CHECK:STDOUT: } { -// CHECK:STDOUT: %self.param.loc23: %ptr.11f = value_param call_param0 -// CHECK:STDOUT: %.loc23: type = splice_block %ptr.loc23 [concrete = constants.%ptr.11f] { -// CHECK:STDOUT: %Base.ref.loc23: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] -// CHECK:STDOUT: %ptr.loc23: type = ptr_type %Base.ref.loc23 [concrete = constants.%ptr.11f] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self.loc23: %ptr.11f = value_binding self, %self.param.loc23 +// CHECK:STDOUT: %self.param.loc23: ref %Base = ref_param call_param0 +// CHECK:STDOUT: %Base.ref.loc23: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] +// CHECK:STDOUT: %self.loc23: ref %Base = ref_binding self, %self.param.loc23 // CHECK:STDOUT: } // CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.base.b1e [concrete = constants.%complete_type.15c] // CHECK:STDOUT: complete_type_witness = %complete_type @@ -217,7 +206,7 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: .Base = // CHECK:STDOUT: .base = %.loc20 // CHECK:STDOUT: .SelfBase = %Derived.SelfBase.decl -// CHECK:STDOUT: .AddrSelfBase = %Derived.AddrSelfBase.decl +// CHECK:STDOUT: .RefSelfBase = %Derived.RefSelfBase.decl // CHECK:STDOUT: extend %Base.ref // CHECK:STDOUT: } // CHECK:STDOUT: @@ -235,20 +224,19 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: return %Int.as.Copy.impl.Op.call to %return.loc26 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @Derived.AddrSelfBase(%self.param.loc30: %ptr.11f) { +// CHECK:STDOUT: fn @Derived.RefSelfBase(%self.param.loc30: %Base) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %self.ref: %ptr.11f = name_ref self, %self.loc30 -// CHECK:STDOUT: %.loc31_4: ref %Base = deref %self.ref +// CHECK:STDOUT: %self.ref: ref %Base = name_ref self, %self.loc30 // CHECK:STDOUT: %a.ref: %Base.elem = name_ref a, @Base.%.loc16 [concrete = @Base.%.loc16] -// CHECK:STDOUT: %.loc31_10: ref %i32 = class_element_access %.loc31_4, element0 +// CHECK:STDOUT: %.loc31_7: ref %i32 = class_element_access %self.ref, element0 // CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] // CHECK:STDOUT: %impl.elem0: %.322 = impl_witness_access constants.%ImplicitAs.impl_witness.bc9, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b] -// CHECK:STDOUT: %bound_method.loc31_13.1: = bound_method %int_1, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound] +// CHECK:STDOUT: %bound_method.loc31_10.1: = bound_method %int_1, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound] // CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] -// CHECK:STDOUT: %bound_method.loc31_13.2: = bound_method %int_1, %specific_fn [concrete = constants.%bound_method] -// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc31_13.2(%int_1) [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: %.loc31_13: init %i32 = converted %int_1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_1.5d2] -// CHECK:STDOUT: assign %.loc31_10, %.loc31_13 +// CHECK:STDOUT: %bound_method.loc31_10.2: = bound_method %int_1, %specific_fn [concrete = constants.%bound_method] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc31_10.2(%int_1) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc31_10: init %i32 = converted %int_1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: assign %.loc31_7, %.loc31_10 // CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -256,14 +244,11 @@ fn Call(p: Derived*) -> i32 { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %p.ref.loc35: %ptr.404 = name_ref p, %p // CHECK:STDOUT: %.loc35_4.1: ref %Derived = deref %p.ref.loc35 -// CHECK:STDOUT: %AddrSelfBase.ref: %Derived.AddrSelfBase.type = name_ref AddrSelfBase, @Derived.%Derived.AddrSelfBase.decl [concrete = constants.%Derived.AddrSelfBase] -// CHECK:STDOUT: %Derived.AddrSelfBase.bound: = bound_method %.loc35_4.1, %AddrSelfBase.ref -// CHECK:STDOUT: %addr.loc35_4.1: %ptr.404 = addr_of %.loc35_4.1 -// CHECK:STDOUT: %.loc35_4.2: ref %Derived = deref %addr.loc35_4.1 -// CHECK:STDOUT: %.loc35_4.3: ref %Base = class_element_access %.loc35_4.2, element0 -// CHECK:STDOUT: %addr.loc35_4.2: %ptr.11f = addr_of %.loc35_4.3 -// CHECK:STDOUT: %.loc35_4.4: %ptr.11f = converted %addr.loc35_4.1, %addr.loc35_4.2 -// CHECK:STDOUT: %Derived.AddrSelfBase.call: init %empty_tuple.type = call %Derived.AddrSelfBase.bound(%.loc35_4.4) +// CHECK:STDOUT: %RefSelfBase.ref: %Derived.RefSelfBase.type = name_ref RefSelfBase, @Derived.%Derived.RefSelfBase.decl [concrete = constants.%Derived.RefSelfBase] +// CHECK:STDOUT: %Derived.RefSelfBase.bound: = bound_method %.loc35_4.1, %RefSelfBase.ref +// CHECK:STDOUT: %.loc35_4.2: ref %Base = class_element_access %.loc35_4.1, element0 +// CHECK:STDOUT: %.loc35_4.3: ref %Base = converted %.loc35_4.1, %.loc35_4.2 +// CHECK:STDOUT: %Derived.RefSelfBase.call: init %empty_tuple.type = call %Derived.RefSelfBase.bound(%.loc35_4.3) // CHECK:STDOUT: %p.ref.loc36: %ptr.404 = name_ref p, %p // CHECK:STDOUT: %.loc36_11.1: ref %Derived = deref %p.ref.loc36 // CHECK:STDOUT: %SelfBase.ref: %Derived.SelfBase.type = name_ref SelfBase, @Derived.%Derived.SelfBase.decl [concrete = constants.%Derived.SelfBase] diff --git a/toolchain/check/testdata/class/self_conversion_addr.carbon b/toolchain/check/testdata/class/self_conversion_addr.carbon new file mode 100644 index 000000000000..2140a0a108ba --- /dev/null +++ b/toolchain/check/testdata/class/self_conversion_addr.carbon @@ -0,0 +1,277 @@ +// 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/class/self_conversion_addr.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/self_conversion_addr.carbon + +base class Base { + var a: i32; +} + +class Derived { + extend base: Base; + + fn SelfBase[self: Base]() -> i32; + fn AddrSelfBase[addr self: Base*](); +} + +fn Derived.SelfBase[self: Base]() -> i32 { + return self.a; +} + +fn Derived.AddrSelfBase[addr self: Base*]() { + (*self).a = 1; +} + +fn Call(p: Derived*) -> i32 { + (*p).AddrSelfBase(); + return (*p).SelfBase(); +} + +// CHECK:STDOUT: --- self_conversion_addr.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Base: type = class_type @Base [concrete] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] +// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [concrete] +// CHECK:STDOUT: %N: Core.IntLiteral = symbolic_binding N, 0 [symbolic] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %Base.elem: type = unbound_element_type %Base, %i32 [concrete] +// CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %i32} [concrete] +// CHECK:STDOUT: %complete_type.fd7: = complete_type_witness %struct_type.a [concrete] +// CHECK:STDOUT: %Derived: type = class_type @Derived [concrete] +// CHECK:STDOUT: %Derived.elem: type = unbound_element_type %Derived, %Base [concrete] +// CHECK:STDOUT: %pattern_type.bcc: type = pattern_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] +// CHECK:STDOUT: %Derived.SelfBase.type: type = fn_type @Derived.SelfBase [concrete] +// CHECK:STDOUT: %Derived.SelfBase: %Derived.SelfBase.type = struct_value () [concrete] +// CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] +// CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %Derived.AddrSelfBase.type: type = fn_type @Derived.AddrSelfBase [concrete] +// CHECK:STDOUT: %Derived.AddrSelfBase: %Derived.AddrSelfBase.type = struct_value () [concrete] +// CHECK:STDOUT: %struct_type.base.b1e: type = struct_type {.base: %Base} [concrete] +// CHECK:STDOUT: %complete_type.15c: = complete_type_witness %struct_type.base.b1e [concrete] +// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] +// CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.24b: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%N) [symbolic] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.c95: %Int.as.Copy.impl.Op.type.24b = struct_value () [symbolic] +// CHECK:STDOUT: %Copy.impl_witness.fb7: = impl_witness imports.%Copy.impl_witness_table.b6a, @Int.as.Copy.impl(%int_32) [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.type.469: type = fn_type @Int.as.Copy.impl.Op, @Int.as.Copy.impl(%int_32) [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.dfd: %Int.as.Copy.impl.Op.type.469 = struct_value () [concrete] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %i32, (%Copy.impl_witness.fb7) [concrete] +// CHECK:STDOUT: %.65f: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet [concrete] +// CHECK:STDOUT: %Int.as.Copy.impl.Op.specific_fn: = specific_function %Int.as.Copy.impl.Op.dfd, @Int.as.Copy.impl.Op(%int_32) [concrete] +// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] +// CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] +// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.type.d14: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] +// CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.2a1: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51 = struct_value () [symbolic] +// CHECK:STDOUT: %ImplicitAs.impl_witness.bc9: = impl_witness imports.%ImplicitAs.impl_witness_table.132, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.51e: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.51e = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.d14 = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.bc9) [concrete] +// CHECK:STDOUT: %.322: type = fn_type_with_self_type %ImplicitAs.Convert.type.1b6, %ImplicitAs.facet [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] +// CHECK:STDOUT: %bound_method: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] +// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] +// CHECK:STDOUT: %ptr.404: type = ptr_type %Derived [concrete] +// CHECK:STDOUT: %pattern_type.605: type = pattern_type %ptr.404 [concrete] +// CHECK:STDOUT: %Call.type: type = fn_type @Call [concrete] +// CHECK:STDOUT: %Call: %Call.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .Int = %Core.Int +// CHECK:STDOUT: .Copy = %Core.Copy +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.Int: %Int.type = import_ref Core//prelude/parts/int, Int, loaded [concrete = constants.%Int.generic] +// CHECK:STDOUT: %Core.Copy: type = import_ref Core//prelude/parts/copy, Copy, loaded [concrete = constants.%Copy.type] +// CHECK:STDOUT: %Core.import_ref.d12: @Int.as.Copy.impl.%Int.as.Copy.impl.Op.type (%Int.as.Copy.impl.Op.type.24b) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Int.as.Copy.impl.%Int.as.Copy.impl.Op (constants.%Int.as.Copy.impl.Op.c95)] +// CHECK:STDOUT: %Copy.impl_witness_table.b6a = impl_witness_table (%Core.import_ref.d12), @Int.as.Copy.impl [concrete] +// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] +// CHECK:STDOUT: %Core.import_ref.e24: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.2a1)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table.132 = impl_witness_table (%Core.import_ref.e24), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .Base = %Base.decl +// CHECK:STDOUT: .Derived = %Derived.decl +// CHECK:STDOUT: .Call = %Call.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Base.decl: type = class_decl @Base [concrete = constants.%Base] {} {} +// CHECK:STDOUT: %Derived.decl: type = class_decl @Derived [concrete = constants.%Derived] {} {} +// CHECK:STDOUT: %Derived.SelfBase.decl: %Derived.SelfBase.type = fn_decl @Derived.SelfBase [concrete = constants.%Derived.SelfBase] { +// CHECK:STDOUT: %self.patt: %pattern_type.bcc = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.bcc = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32.loc26: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc26: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %self.param.loc26: %Base = value_param call_param0 +// CHECK:STDOUT: %Base.ref.loc26: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] +// CHECK:STDOUT: %self.loc26: %Base = value_binding self, %self.param.loc26 +// CHECK:STDOUT: %return.param.loc26: ref %i32 = out_param call_param1 +// CHECK:STDOUT: %return.loc26: ref %i32 = return_slot %return.param.loc26 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Derived.AddrSelfBase.decl: %Derived.AddrSelfBase.type = fn_decl @Derived.AddrSelfBase [concrete = constants.%Derived.AddrSelfBase] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc30_25: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param.loc30: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %.loc30_40: type = splice_block %ptr.loc30 [concrete = constants.%ptr.11f] { +// CHECK:STDOUT: %Base.ref.loc30: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] +// CHECK:STDOUT: %ptr.loc30: type = ptr_type %Base.ref.loc30 [concrete = constants.%ptr.11f] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self.loc30: %ptr.11f = value_binding self, %self.param.loc30 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Call.decl: %Call.type = fn_decl @Call [concrete = constants.%Call] { +// CHECK:STDOUT: %p.patt: %pattern_type.605 = value_binding_pattern p [concrete] +// CHECK:STDOUT: %p.param_patt: %pattern_type.605 = value_param_pattern %p.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %p.param: %ptr.404 = value_param call_param0 +// CHECK:STDOUT: %.loc34: type = splice_block %ptr [concrete = constants.%ptr.404] { +// CHECK:STDOUT: %Derived.ref: type = name_ref Derived, file.%Derived.decl [concrete = constants.%Derived] +// CHECK:STDOUT: %ptr: type = ptr_type %Derived.ref [concrete = constants.%ptr.404] +// CHECK:STDOUT: } +// CHECK:STDOUT: %p: %ptr.404 = value_binding p, %p.param +// CHECK:STDOUT: %return.param: ref %i32 = out_param call_param1 +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Base { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc16: %Base.elem = field_decl a, element0 [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.a [concrete = constants.%complete_type.fd7] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Base +// CHECK:STDOUT: .a = %.loc16 +// CHECK:STDOUT: .Base = +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Derived { +// CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] +// CHECK:STDOUT: %.loc20: %Derived.elem = base_decl %Base.ref, element0 [concrete] +// CHECK:STDOUT: %Derived.SelfBase.decl: %Derived.SelfBase.type = fn_decl @Derived.SelfBase [concrete = constants.%Derived.SelfBase] { +// CHECK:STDOUT: %self.patt: %pattern_type.bcc = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.bcc = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.7ce = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.7ce = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %int_32.loc22: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc22: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %self.param.loc22: %Base = value_param call_param0 +// CHECK:STDOUT: %Base.ref.loc22: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] +// CHECK:STDOUT: %self.loc22: %Base = value_binding self, %self.param.loc22 +// CHECK:STDOUT: %return.param.loc22: ref %i32 = out_param call_param1 +// CHECK:STDOUT: %return.loc22: ref %i32 = return_slot %return.param.loc22 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Derived.AddrSelfBase.decl: %Derived.AddrSelfBase.type = fn_decl @Derived.AddrSelfBase [concrete = constants.%Derived.AddrSelfBase] { +// CHECK:STDOUT: %self.patt: %pattern_type.1b9 = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.1b9 = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc30_25: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param.loc23: %ptr.11f = value_param call_param0 +// CHECK:STDOUT: %.loc23: type = splice_block %ptr.loc23 [concrete = constants.%ptr.11f] { +// CHECK:STDOUT: %Base.ref.loc23: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] +// CHECK:STDOUT: %ptr.loc23: type = ptr_type %Base.ref.loc23 [concrete = constants.%ptr.11f] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self.loc23: %ptr.11f = value_binding self, %self.param.loc23 +// CHECK:STDOUT: } +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.base.b1e [concrete = constants.%complete_type.15c] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Derived +// CHECK:STDOUT: .Base = +// CHECK:STDOUT: .base = %.loc20 +// CHECK:STDOUT: .SelfBase = %Derived.SelfBase.decl +// CHECK:STDOUT: .AddrSelfBase = %Derived.AddrSelfBase.decl +// CHECK:STDOUT: extend %Base.ref +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.SelfBase(%self.param.loc26: %Base) -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %self.ref: %Base = name_ref self, %self.loc26 +// CHECK:STDOUT: %a.ref: %Base.elem = name_ref a, @Base.%.loc16 [concrete = @Base.%.loc16] +// CHECK:STDOUT: %.loc27_14.1: ref %i32 = class_element_access %self.ref, element0 +// CHECK:STDOUT: %.loc27_14.2: %i32 = acquire_value %.loc27_14.1 +// CHECK:STDOUT: %impl.elem0: %.65f = impl_witness_access constants.%Copy.impl_witness.fb7, element0 [concrete = constants.%Int.as.Copy.impl.Op.dfd] +// CHECK:STDOUT: %bound_method.loc27_14.1: = bound_method %.loc27_14.2, %impl.elem0 +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Int.as.Copy.impl.Op(constants.%int_32) [concrete = constants.%Int.as.Copy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc27_14.2: = bound_method %.loc27_14.2, %specific_fn +// CHECK:STDOUT: %Int.as.Copy.impl.Op.call: init %i32 = call %bound_method.loc27_14.2(%.loc27_14.2) +// CHECK:STDOUT: return %Int.as.Copy.impl.Op.call to %return.loc26 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Derived.AddrSelfBase(%self.param.loc30: %ptr.11f) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %self.ref: %ptr.11f = name_ref self, %self.loc30 +// CHECK:STDOUT: %.loc31_4: ref %Base = deref %self.ref +// CHECK:STDOUT: %a.ref: %Base.elem = name_ref a, @Base.%.loc16 [concrete = @Base.%.loc16] +// CHECK:STDOUT: %.loc31_10: ref %i32 = class_element_access %.loc31_4, element0 +// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %impl.elem0: %.322 = impl_witness_access constants.%ImplicitAs.impl_witness.bc9, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b] +// CHECK:STDOUT: %bound_method.loc31_13.1: = bound_method %int_1, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound] +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc31_13.2: = bound_method %int_1, %specific_fn [concrete = constants.%bound_method] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc31_13.2(%int_1) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc31_13: init %i32 = converted %int_1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: assign %.loc31_10, %.loc31_13 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Call(%p.param: %ptr.404) -> %i32 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %p.ref.loc35: %ptr.404 = name_ref p, %p +// CHECK:STDOUT: %.loc35_4.1: ref %Derived = deref %p.ref.loc35 +// CHECK:STDOUT: %AddrSelfBase.ref: %Derived.AddrSelfBase.type = name_ref AddrSelfBase, @Derived.%Derived.AddrSelfBase.decl [concrete = constants.%Derived.AddrSelfBase] +// CHECK:STDOUT: %Derived.AddrSelfBase.bound: = bound_method %.loc35_4.1, %AddrSelfBase.ref +// CHECK:STDOUT: %addr.loc35_4.1: %ptr.404 = addr_of %.loc35_4.1 +// CHECK:STDOUT: %.loc35_4.2: ref %Derived = deref %addr.loc35_4.1 +// CHECK:STDOUT: %.loc35_4.3: ref %Base = class_element_access %.loc35_4.2, element0 +// CHECK:STDOUT: %addr.loc35_4.2: %ptr.11f = addr_of %.loc35_4.3 +// CHECK:STDOUT: %.loc35_4.4: %ptr.11f = converted %addr.loc35_4.1, %addr.loc35_4.2 +// CHECK:STDOUT: %Derived.AddrSelfBase.call: init %empty_tuple.type = call %Derived.AddrSelfBase.bound(%.loc35_4.4) +// CHECK:STDOUT: %p.ref.loc36: %ptr.404 = name_ref p, %p +// CHECK:STDOUT: %.loc36_11.1: ref %Derived = deref %p.ref.loc36 +// CHECK:STDOUT: %SelfBase.ref: %Derived.SelfBase.type = name_ref SelfBase, @Derived.%Derived.SelfBase.decl [concrete = constants.%Derived.SelfBase] +// CHECK:STDOUT: %Derived.SelfBase.bound: = bound_method %.loc36_11.1, %SelfBase.ref +// CHECK:STDOUT: %.loc36_11.2: ref %Base = class_element_access %.loc36_11.1, element0 +// CHECK:STDOUT: %.loc36_11.3: ref %Base = converted %.loc36_11.1, %.loc36_11.2 +// CHECK:STDOUT: %.loc36_11.4: %Base = acquire_value %.loc36_11.3 +// CHECK:STDOUT: %Derived.SelfBase.call: init %i32 = call %Derived.SelfBase.bound(%.loc36_11.4) +// CHECK:STDOUT: return %Derived.SelfBase.call to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/syntactic_merge.carbon b/toolchain/check/testdata/class/syntactic_merge.carbon index 5c3c0c6521cf..956b736903f2 100644 --- a/toolchain/check/testdata/class/syntactic_merge.carbon +++ b/toolchain/check/testdata/class/syntactic_merge.carbon @@ -167,16 +167,37 @@ class Foo(a:! const (const C)) {} library "[[@TEST_NAME]]"; +base class Base { + var a: (); + + fn F[ref self: Self](); +} + +// CHECK:STDERR: fail_self_type.carbon:[[@LINE+7]]:21: error: redeclaration syntax differs here [RedeclParamSyntaxDiffers] +// CHECK:STDERR: fn Base.F[ref self: Base]() { +// CHECK:STDERR: ^~~~ +// CHECK:STDERR: fail_self_type.carbon:[[@LINE-6]]:18: note: comparing with previous declaration here [RedeclParamSyntaxPrevious] +// CHECK:STDERR: fn F[ref self: Self](); +// CHECK:STDERR: ^~~~ +// CHECK:STDERR: +fn Base.F[ref self: Base]() { + self.a = (); +} + +// --- fail_self_type_addr.carbon + +library "[[@TEST_NAME]]"; + base class Base { var a: (); fn F[addr self: Self*](); } -// CHECK:STDERR: fail_self_type.carbon:[[@LINE+7]]:22: error: redeclaration syntax differs here [RedeclParamSyntaxDiffers] +// CHECK:STDERR: fail_self_type_addr.carbon:[[@LINE+7]]:22: error: redeclaration syntax differs here [RedeclParamSyntaxDiffers] // CHECK:STDERR: fn Base.F[addr self: Base*]() { // CHECK:STDERR: ^~~~ -// CHECK:STDERR: fail_self_type.carbon:[[@LINE-6]]:19: note: comparing with previous declaration here [RedeclParamSyntaxPrevious] +// CHECK:STDERR: fail_self_type_addr.carbon:[[@LINE-6]]:19: note: comparing with previous declaration here [RedeclParamSyntaxPrevious] // CHECK:STDERR: fn F[addr self: Self*](); // CHECK:STDERR: ^~~~ // CHECK:STDERR: @@ -1132,6 +1153,73 @@ fn Base.F[addr self: Base*]() { // CHECK:STDOUT: %Base: type = class_type @Base [concrete] // CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] // CHECK:STDOUT: %Base.elem: type = unbound_element_type %Base, %empty_tuple.type [concrete] +// CHECK:STDOUT: %pattern_type: type = pattern_type %Base [concrete] +// CHECK:STDOUT: %Base.F.type.7c6384.1: type = fn_type @Base.F.loc7 [concrete] +// CHECK:STDOUT: %Base.F.d17bbc.1: %Base.F.type.7c6384.1 = struct_value () [concrete] +// CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %empty_tuple.type} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %struct_type.a [concrete] +// CHECK:STDOUT: %Base.F.type.7c6384.2: type = fn_type @Base.F.loc17 [concrete] +// CHECK:STDOUT: %Base.F.d17bbc.2: %Base.F.type.7c6384.2 = struct_value () [concrete] +// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Base = %Base.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Base.decl: type = class_decl @Base [concrete = constants.%Base] {} {} +// CHECK:STDOUT: %Base.F.decl: %Base.F.type.7c6384.2 = fn_decl @Base.F.loc17 [concrete = constants.%Base.F.d17bbc.2] { +// CHECK:STDOUT: %self.patt: %pattern_type = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type = ref_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: ref %Base = ref_param call_param0 +// CHECK:STDOUT: %Base.ref: type = name_ref Base, file.%Base.decl [concrete = constants.%Base] +// CHECK:STDOUT: %self: ref %Base = ref_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Base { +// CHECK:STDOUT: %.loc5_11.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc5_11.2: type = converted %.loc5_11.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type] +// CHECK:STDOUT: %.loc5_8: %Base.elem = field_decl a, element0 [concrete] +// CHECK:STDOUT: %Base.F.decl: %Base.F.type.7c6384.1 = fn_decl @Base.F.loc7 [concrete = constants.%Base.F.d17bbc.1] { +// CHECK:STDOUT: %self.patt: %pattern_type = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type = ref_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: ref %Base = ref_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [concrete = constants.%Base] +// CHECK:STDOUT: %self: ref %Base = ref_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.a [concrete = constants.%complete_type] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Base +// CHECK:STDOUT: .a = %.loc5_8 +// CHECK:STDOUT: .F = %Base.F.decl +// CHECK:STDOUT: .Base = +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.F.loc7(%self.param: %Base); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Base.F.loc17(%self.param: %Base) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %self.ref: ref %Base = name_ref self, %self +// CHECK:STDOUT: %a.ref: %Base.elem = name_ref a, @Base.%.loc5_8 [concrete = @Base.%.loc5_8] +// CHECK:STDOUT: %.loc18_7: ref %empty_tuple.type = class_element_access %self.ref, element0 +// CHECK:STDOUT: %.loc18_13.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %.loc18_13.2: init %empty_tuple.type = tuple_init () to %.loc18_7 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc18_10: init %empty_tuple.type = converted %.loc18_13.1, %.loc18_13.2 [concrete = constants.%empty_tuple] +// CHECK:STDOUT: assign %.loc18_7, %.loc18_10 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_self_type_addr.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Base: type = class_type @Base [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Base.elem: type = unbound_element_type %Base, %empty_tuple.type [concrete] // CHECK:STDOUT: %ptr.11f: type = ptr_type %Base [concrete] // CHECK:STDOUT: %pattern_type.1b9: type = pattern_type %ptr.11f [concrete] // CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] diff --git a/toolchain/check/testdata/class/virtual_modifiers.carbon b/toolchain/check/testdata/class/virtual_modifiers.carbon index 00294ecb9d9b..e25af1da3f24 100644 --- a/toolchain/check/testdata/class/virtual_modifiers.carbon +++ b/toolchain/check/testdata/class/virtual_modifiers.carbon @@ -290,6 +290,26 @@ class T2 { override fn F(); } +// --- fail_ref_self_mismatch.carbon + +library "[[@TEST_NAME]]"; + +base class T1 { + virtual fn F1[self: Self](); +} + +class T2 { + extend base: T1; + // CHECK:STDERR: fail_ref_self_mismatch.carbon:[[@LINE+7]]:18: error: redeclaration differs at implicit parameter 1 [RedeclParamDiffers] + // CHECK:STDERR: override fn F1[ref self: Self](); + // CHECK:STDERR: ^~~~~~~~~~~~~~ + // CHECK:STDERR: fail_ref_self_mismatch.carbon:[[@LINE-8]]:17: note: previous declaration's corresponding implicit parameter here [RedeclParamPrevious] + // CHECK:STDERR: virtual fn F1[self: Self](); + // CHECK:STDERR: ^~~~~~~~~~ + // CHECK:STDERR: + override fn F1[ref self: Self](); +} + // --- fail_addr_self_mismatch.carbon library "[[@TEST_NAME]]"; @@ -2558,6 +2578,100 @@ class T2(G2:! type) { // CHECK:STDOUT: // CHECK:STDOUT: fn @T2.F(); // CHECK:STDOUT: +// CHECK:STDOUT: --- fail_ref_self_mismatch.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %T1: type = class_type @T1 [concrete] +// CHECK:STDOUT: %pattern_type.28b: type = pattern_type %T1 [concrete] +// CHECK:STDOUT: %T1.F1.type: type = fn_type @T1.F1 [concrete] +// CHECK:STDOUT: %T1.F1: %T1.F1.type = struct_value () [concrete] +// CHECK:STDOUT: %ptr.454: type = ptr_type [concrete] +// CHECK:STDOUT: %T1.vtable_decl: ref %ptr.454 = vtable_decl @T1.vtable [concrete] +// CHECK:STDOUT: %struct_type.vptr: type = struct_type {.: %ptr.454} [concrete] +// CHECK:STDOUT: %complete_type.513: = complete_type_witness %struct_type.vptr [concrete] +// CHECK:STDOUT: %T2: type = class_type @T2 [concrete] +// CHECK:STDOUT: %T2.elem: type = unbound_element_type %T2, %T1 [concrete] +// CHECK:STDOUT: %pattern_type.682: type = pattern_type %T2 [concrete] +// CHECK:STDOUT: %T2.F1.type: type = fn_type @T2.F1 [concrete] +// CHECK:STDOUT: %T2.F1: %T2.F1.type = struct_value () [concrete] +// CHECK:STDOUT: %T2.vtable_decl: ref %ptr.454 = vtable_decl @T2.vtable [concrete] +// CHECK:STDOUT: %struct_type.base: type = struct_type {.base: %T1} [concrete] +// CHECK:STDOUT: %complete_type.e14: = complete_type_witness %struct_type.base [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .T1 = %T1.decl +// CHECK:STDOUT: .T2 = %T2.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %T1.decl: type = class_decl @T1 [concrete = constants.%T1] {} {} +// CHECK:STDOUT: %T2.decl: type = class_decl @T2 [concrete = constants.%T2] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @T1 { +// CHECK:STDOUT: %T1.F1.decl: %T1.F1.type = fn_decl @T1.F1 [concrete = constants.%T1.F1] { +// CHECK:STDOUT: %self.patt: %pattern_type.28b = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.28b = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: %T1 = value_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%T1 [concrete = constants.%T1] +// CHECK:STDOUT: %self: %T1 = value_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %vtable_decl: ref %ptr.454 = vtable_decl @T1.vtable [concrete = constants.%T1.vtable_decl] +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.vptr [concrete = constants.%complete_type.513] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: vtable_decl = %vtable_decl +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%T1 +// CHECK:STDOUT: .F1 = %T1.F1.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @T2 { +// CHECK:STDOUT: %T1.ref: type = name_ref T1, file.%T1.decl [concrete = constants.%T1] +// CHECK:STDOUT: %.loc9: %T2.elem = base_decl %T1.ref, element0 [concrete] +// CHECK:STDOUT: %T2.F1.decl: %T2.F1.type = fn_decl @T2.F1 [concrete = constants.%T2.F1] { +// CHECK:STDOUT: %self.patt: %pattern_type.682 = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.682 = ref_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: ref %T2 = ref_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%T2 [concrete = constants.%T2] +// CHECK:STDOUT: %self: ref %T2 = ref_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %vtable_decl: ref %ptr.454 = vtable_decl @T2.vtable [concrete = constants.%T2.vtable_decl] +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.base [concrete = constants.%complete_type.e14] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: vtable_decl = %vtable_decl +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%T2 +// CHECK:STDOUT: .T1 = +// CHECK:STDOUT: .base = %.loc9 +// CHECK:STDOUT: .F1 = %T2.F1.decl +// CHECK:STDOUT: extend %T1.ref +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: vtable @T1.vtable { +// CHECK:STDOUT: @T1.%T1.F1.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: vtable @T2.vtable { +// CHECK:STDOUT: @T2.%T2.F1.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: virtual fn @T1.F1(%self.param: %T1); +// CHECK:STDOUT: +// CHECK:STDOUT: override fn @T2.F1(%self.param: %T2); +// CHECK:STDOUT: // CHECK:STDOUT: --- fail_addr_self_mismatch.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { diff --git a/toolchain/check/testdata/impl/impl_thunk.carbon b/toolchain/check/testdata/impl/impl_thunk.carbon index dba4e3dfecf7..64c5c6f56e6e 100644 --- a/toolchain/check/testdata/impl/impl_thunk.carbon +++ b/toolchain/check/testdata/impl/impl_thunk.carbon @@ -45,6 +45,24 @@ base class A {} base class B { extend base: A; } class C { extend base: B; } +interface X { + fn F[ref self: Self](other: Self*) -> Self*; +} + +impl B as X { + //@dump-sem-ir-begin + fn F[ref self: A](other: A*) -> C*; + //@dump-sem-ir-end +} + +// --- inheritance_conversion_addr.carbon + +library "[[@TEST_NAME]]"; + +base class A {} +base class B { extend base: A; } +class C { extend base: B; } + interface X { fn F[addr self: Self*](other: Self*) -> Self*; } @@ -80,6 +98,24 @@ base class A {} base class B { extend base: A; } class C { extend base: B; } +interface X { + fn F[ref self: Self](other: Self*) -> Self*; +} + +impl B as X { + //@dump-sem-ir-begin + fn F[ref self: A](other: A*) -> C*; + //@dump-sem-ir-end +} + +// --- inheritance_value_conversion_pointer_addr.carbon + +library "[[@TEST_NAME]]"; + +base class A {} +base class B { extend base: A; } +class C { extend base: B; } + interface X { fn F[addr self: Self*](other: Self*) -> Self*; } @@ -402,6 +438,99 @@ impl () as I({}) { // CHECK:STDOUT: %A: type = class_type @A [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %pattern_type.c10: type = pattern_type %A [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %B.as.X.impl.F.type.84a1c2.1: type = fn_type @B.as.X.impl.F.loc14_37.1 [concrete] +// CHECK:STDOUT: %B.as.X.impl.F.b849c8.1: %B.as.X.impl.F.type.84a1c2.1 = struct_value () [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %B.as.X.impl.F.type.84a1c2.2: type = fn_type @B.as.X.impl.F.loc14_37.2 [concrete] +// CHECK:STDOUT: %B.as.X.impl.F.b849c8.2: %B.as.X.impl.F.type.84a1c2.2 = struct_value () [concrete] +// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] +// CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [concrete] +// CHECK:STDOUT: %T.d9f: type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.75b: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%T.d9f) [symbolic] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.692: %ptr.as.Copy.impl.Op.type.75b = struct_value () [symbolic] +// CHECK:STDOUT: %Copy.impl_witness.5dd: = impl_witness imports.%Copy.impl_witness_table.67d, @ptr.as.Copy.impl(%B) [concrete] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.0a3: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%B) [concrete] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.8c4: %ptr.as.Copy.impl.Op.type.0a3 = struct_value () [concrete] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.e79, (%Copy.impl_witness.5dd) [concrete] +// CHECK:STDOUT: %.ee7: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet [concrete] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.specific_fn: = specific_function %ptr.as.Copy.impl.Op.8c4, @ptr.as.Copy.impl.Op(%B) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core.import_ref.659: @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op.type (%ptr.as.Copy.impl.Op.type.75b) = import_ref Core//prelude/parts/copy, loc{{\d+_\d+}}, loaded [symbolic = @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op (constants.%ptr.as.Copy.impl.Op.692)] +// CHECK:STDOUT: %Copy.impl_witness_table.67d = impl_witness_table (%Core.import_ref.659), @ptr.as.Copy.impl [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.X.impl: %B.ref as %X.ref { +// CHECK:STDOUT: %B.as.X.impl.F.decl.loc14_37.1: %B.as.X.impl.F.type.84a1c2.1 = fn_decl @B.as.X.impl.F.loc14_37.1 [concrete = constants.%B.as.X.impl.F.b849c8.1] { +// CHECK:STDOUT: %self.patt: %pattern_type.c10 = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.c10 = ref_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %other.patt: %pattern_type.5f8 = value_binding_pattern other [concrete] +// CHECK:STDOUT: %other.param_patt: %pattern_type.5f8 = value_param_pattern %other.patt, call_param1 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.44a = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.44a = out_param_pattern %return.patt, call_param2 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %ptr.loc14_36: type = ptr_type %C.ref [concrete = constants.%ptr.019] +// CHECK:STDOUT: %self.param: ref %A = ref_param call_param0 +// CHECK:STDOUT: %A.ref.loc14_18: type = name_ref A, file.%A.decl [concrete = constants.%A] +// CHECK:STDOUT: %self: ref %A = ref_binding self, %self.param +// CHECK:STDOUT: %other.param: %ptr.6db = value_param call_param1 +// CHECK:STDOUT: %.loc14: type = splice_block %ptr.loc14_29 [concrete = constants.%ptr.6db] { +// CHECK:STDOUT: %A.ref.loc14_28: type = name_ref A, file.%A.decl [concrete = constants.%A] +// CHECK:STDOUT: %ptr.loc14_29: type = ptr_type %A.ref.loc14_28 [concrete = constants.%ptr.6db] +// CHECK:STDOUT: } +// CHECK:STDOUT: %other: %ptr.6db = value_binding other, %other.param +// CHECK:STDOUT: %return.param: ref %ptr.019 = out_param call_param2 +// CHECK:STDOUT: %return: ref %ptr.019 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %B.as.X.impl.F.decl.loc14_37.2: %B.as.X.impl.F.type.84a1c2.2 = fn_decl @B.as.X.impl.F.loc14_37.2 [concrete = constants.%B.as.X.impl.F.b849c8.2] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .A = +// CHECK:STDOUT: .C = +// CHECK:STDOUT: .F = %B.as.X.impl.F.decl.loc14_37.1 +// CHECK:STDOUT: witness = file.%X.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.X.impl.F.loc14_37.1(%self.param: %A, %other.param: %ptr.6db) -> %ptr.019; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.X.impl.F.loc14_37.2(%self.param: %B, %other.param: %ptr.e79) -> %ptr.e79 [thunk @B.as.X.impl.%B.as.X.impl.F.decl.loc14_37.1] { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %F.ref: %B.as.X.impl.F.type.84a1c2.1 = name_ref F, @B.as.X.impl.%B.as.X.impl.F.decl.loc14_37.1 [concrete = constants.%B.as.X.impl.F.b849c8.1] +// CHECK:STDOUT: +// CHECK:STDOUT: %B.as.X.impl.F.bound: = bound_method %self.ref, %F.ref +// CHECK:STDOUT: +// CHECK:STDOUT: %B.as.X.impl.F.call: init %ptr.019 = call %B.as.X.impl.F.bound(%.loc9_16.2, %.loc9_29.3) +// CHECK:STDOUT: %.loc14_37.1: %ptr.019 = value_of_initializer %B.as.X.impl.F.call +// CHECK:STDOUT: %.loc14_37.2: %ptr.019 = converted %B.as.X.impl.F.call, %.loc14_37.1 +// CHECK:STDOUT: %.loc14_37.3: ref %C = deref %.loc14_37.2 +// CHECK:STDOUT: %.loc14_37.4: ref %B = class_element_access %.loc14_37.3, element0 +// CHECK:STDOUT: %addr.loc14: %ptr.e79 = addr_of %.loc14_37.4 +// CHECK:STDOUT: %.loc14_37.5: %ptr.e79 = converted %B.as.X.impl.F.call, %addr.loc14 +// CHECK:STDOUT: %impl.elem0: %.ee7 = impl_witness_access constants.%Copy.impl_witness.5dd, element0 [concrete = constants.%ptr.as.Copy.impl.Op.8c4] +// CHECK:STDOUT: %bound_method.loc14_37.1: = bound_method %.loc14_37.5, %impl.elem0 +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @ptr.as.Copy.impl.Op(constants.%B) [concrete = constants.%ptr.as.Copy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc14_37.2: = bound_method %.loc14_37.5, %specific_fn +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.call: init %ptr.e79 = call %bound_method.loc14_37.2(%.loc14_37.5) +// CHECK:STDOUT: return %ptr.as.Copy.impl.Op.call to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- inheritance_conversion_addr.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %A: type = class_type @A [concrete] +// CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] // CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] @@ -553,6 +682,99 @@ impl () as I({}) { // CHECK:STDOUT: %A: type = class_type @A [concrete] // CHECK:STDOUT: %B: type = class_type @B [concrete] // CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %pattern_type.c10: type = pattern_type %A [concrete] +// CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] +// CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %pattern_type.44a: type = pattern_type %ptr.019 [concrete] +// CHECK:STDOUT: %B.as.X.impl.F.type.84a1c2.1: type = fn_type @B.as.X.impl.F.loc14_37.1 [concrete] +// CHECK:STDOUT: %B.as.X.impl.F.b849c8.1: %B.as.X.impl.F.type.84a1c2.1 = struct_value () [concrete] +// CHECK:STDOUT: %ptr.e79: type = ptr_type %B [concrete] +// CHECK:STDOUT: %B.as.X.impl.F.type.84a1c2.2: type = fn_type @B.as.X.impl.F.loc14_37.2 [concrete] +// CHECK:STDOUT: %B.as.X.impl.F.b849c8.2: %B.as.X.impl.F.type.84a1c2.2 = struct_value () [concrete] +// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] +// CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [concrete] +// CHECK:STDOUT: %T.d9f: type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.75b: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%T.d9f) [symbolic] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.692: %ptr.as.Copy.impl.Op.type.75b = struct_value () [symbolic] +// CHECK:STDOUT: %Copy.impl_witness.5dd: = impl_witness imports.%Copy.impl_witness_table.67d, @ptr.as.Copy.impl(%B) [concrete] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.0a3: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%B) [concrete] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.8c4: %ptr.as.Copy.impl.Op.type.0a3 = struct_value () [concrete] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.e79, (%Copy.impl_witness.5dd) [concrete] +// CHECK:STDOUT: %.ee7: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet [concrete] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.specific_fn: = specific_function %ptr.as.Copy.impl.Op.8c4, @ptr.as.Copy.impl.Op(%B) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core.import_ref.659: @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op.type (%ptr.as.Copy.impl.Op.type.75b) = import_ref Core//prelude/parts/copy, loc{{\d+_\d+}}, loaded [symbolic = @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op (constants.%ptr.as.Copy.impl.Op.692)] +// CHECK:STDOUT: %Copy.impl_witness_table.67d = impl_witness_table (%Core.import_ref.659), @ptr.as.Copy.impl [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @B.as.X.impl: %B.ref as %X.ref { +// CHECK:STDOUT: %B.as.X.impl.F.decl.loc14_37.1: %B.as.X.impl.F.type.84a1c2.1 = fn_decl @B.as.X.impl.F.loc14_37.1 [concrete = constants.%B.as.X.impl.F.b849c8.1] { +// CHECK:STDOUT: %self.patt: %pattern_type.c10 = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.c10 = ref_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %other.patt: %pattern_type.5f8 = value_binding_pattern other [concrete] +// CHECK:STDOUT: %other.param_patt: %pattern_type.5f8 = value_param_pattern %other.patt, call_param1 [concrete] +// CHECK:STDOUT: %return.patt: %pattern_type.44a = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: %pattern_type.44a = out_param_pattern %return.patt, call_param2 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %ptr.loc14_36: type = ptr_type %C.ref [concrete = constants.%ptr.019] +// CHECK:STDOUT: %self.param: ref %A = ref_param call_param0 +// CHECK:STDOUT: %A.ref.loc14_18: type = name_ref A, file.%A.decl [concrete = constants.%A] +// CHECK:STDOUT: %self: ref %A = ref_binding self, %self.param +// CHECK:STDOUT: %other.param: %ptr.6db = value_param call_param1 +// CHECK:STDOUT: %.loc14: type = splice_block %ptr.loc14_29 [concrete = constants.%ptr.6db] { +// CHECK:STDOUT: %A.ref.loc14_28: type = name_ref A, file.%A.decl [concrete = constants.%A] +// CHECK:STDOUT: %ptr.loc14_29: type = ptr_type %A.ref.loc14_28 [concrete = constants.%ptr.6db] +// CHECK:STDOUT: } +// CHECK:STDOUT: %other: %ptr.6db = value_binding other, %other.param +// CHECK:STDOUT: %return.param: ref %ptr.019 = out_param call_param2 +// CHECK:STDOUT: %return: ref %ptr.019 = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %B.as.X.impl.F.decl.loc14_37.2: %B.as.X.impl.F.type.84a1c2.2 = fn_decl @B.as.X.impl.F.loc14_37.2 [concrete = constants.%B.as.X.impl.F.b849c8.2] { +// CHECK:STDOUT: +// CHECK:STDOUT: } { +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .A = +// CHECK:STDOUT: .C = +// CHECK:STDOUT: .F = %B.as.X.impl.F.decl.loc14_37.1 +// CHECK:STDOUT: witness = file.%X.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.X.impl.F.loc14_37.1(%self.param: %A, %other.param: %ptr.6db) -> %ptr.019; +// CHECK:STDOUT: +// CHECK:STDOUT: fn @B.as.X.impl.F.loc14_37.2(%self.param: %B, %other.param: %ptr.e79) -> %ptr.e79 [thunk @B.as.X.impl.%B.as.X.impl.F.decl.loc14_37.1] { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %F.ref: %B.as.X.impl.F.type.84a1c2.1 = name_ref F, @B.as.X.impl.%B.as.X.impl.F.decl.loc14_37.1 [concrete = constants.%B.as.X.impl.F.b849c8.1] +// CHECK:STDOUT: +// CHECK:STDOUT: %B.as.X.impl.F.bound: = bound_method %self.ref, %F.ref +// CHECK:STDOUT: +// CHECK:STDOUT: %B.as.X.impl.F.call: init %ptr.019 = call %B.as.X.impl.F.bound(%.loc9_16.2, %.loc9_29.3) +// CHECK:STDOUT: %.loc14_37.1: %ptr.019 = value_of_initializer %B.as.X.impl.F.call +// CHECK:STDOUT: %.loc14_37.2: %ptr.019 = converted %B.as.X.impl.F.call, %.loc14_37.1 +// CHECK:STDOUT: %.loc14_37.3: ref %C = deref %.loc14_37.2 +// CHECK:STDOUT: %.loc14_37.4: ref %B = class_element_access %.loc14_37.3, element0 +// CHECK:STDOUT: %addr.loc14: %ptr.e79 = addr_of %.loc14_37.4 +// CHECK:STDOUT: %.loc14_37.5: %ptr.e79 = converted %B.as.X.impl.F.call, %addr.loc14 +// CHECK:STDOUT: %impl.elem0: %.ee7 = impl_witness_access constants.%Copy.impl_witness.5dd, element0 [concrete = constants.%ptr.as.Copy.impl.Op.8c4] +// CHECK:STDOUT: %bound_method.loc14_37.1: = bound_method %.loc14_37.5, %impl.elem0 +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @ptr.as.Copy.impl.Op(constants.%B) [concrete = constants.%ptr.as.Copy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc14_37.2: = bound_method %.loc14_37.5, %specific_fn +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.call: init %ptr.e79 = call %bound_method.loc14_37.2(%.loc14_37.5) +// CHECK:STDOUT: return %ptr.as.Copy.impl.Op.call to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- inheritance_value_conversion_pointer_addr.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %A: type = class_type @A [concrete] +// CHECK:STDOUT: %B: type = class_type @B [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] // CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %ptr.6db: type = ptr_type %A [concrete] // CHECK:STDOUT: %pattern_type.5f8: type = pattern_type %ptr.6db [concrete] diff --git a/toolchain/check/testdata/impl/lookup/impl_forall.carbon b/toolchain/check/testdata/impl/lookup/impl_forall.carbon index ce1cad587d73..cfcbb0426a37 100644 --- a/toolchain/check/testdata/impl/lookup/impl_forall.carbon +++ b/toolchain/check/testdata/impl/lookup/impl_forall.carbon @@ -18,13 +18,13 @@ class A(T:! type) { } interface I(U:! type) { - fn F[addr self: Self*]() -> U*; + fn F[ref self: Self]() -> U*; } //@dump-sem-ir-begin impl forall [V:! type] A(V) as I(V) { - fn F[addr self: Self*]() -> V* { - return &self->n; + fn F[ref self: Self]() -> V* { + return &self.n; } } //@dump-sem-ir-end @@ -50,20 +50,17 @@ fn TestSpecific(a: A({})*) -> {}* { // CHECK:STDOUT: %A.generic: %A.type = struct_value () [concrete] // CHECK:STDOUT: %I.type.dac: type = generic_interface_type @I [concrete] // CHECK:STDOUT: %I.generic: %I.type.dac = struct_value () [concrete] -// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] // CHECK:STDOUT: %V.d9f: type = symbolic_binding V, 0 [symbolic] // CHECK:STDOUT: %A.2ddf89.2: type = class_type @A, @A(%V.d9f) [symbolic] // CHECK:STDOUT: %I.type.07036d.2: type = facet_type <@I, @I(%V.d9f)> [symbolic] // CHECK:STDOUT: %require_complete.c94ab4.1: = require_complete_type %I.type.07036d.2 [symbolic] // CHECK:STDOUT: %I.impl_witness.0c179e.1: = impl_witness file.%I.impl_witness_table, @A.as.I.impl(%V.d9f) [symbolic] -// CHECK:STDOUT: %ptr.6f46b6.1: type = ptr_type %A.2ddf89.2 [symbolic] -// CHECK:STDOUT: %pattern_type.2180b5.1: type = pattern_type %ptr.6f46b6.1 [symbolic] +// CHECK:STDOUT: %pattern_type.99475c.1: type = pattern_type %A.2ddf89.2 [symbolic] // CHECK:STDOUT: %ptr.4f0b5c.2: type = ptr_type %V.d9f [symbolic] // CHECK:STDOUT: %pattern_type.a603a0.2: type = pattern_type %ptr.4f0b5c.2 [symbolic] // CHECK:STDOUT: %A.as.I.impl.F.type.2974bf.1: type = fn_type @A.as.I.impl.F, @A.as.I.impl(%V.d9f) [symbolic] // CHECK:STDOUT: %A.as.I.impl.F.786476.1: %A.as.I.impl.F.type.2974bf.1 = struct_value () [symbolic] // CHECK:STDOUT: %require_complete.482d3f.1: = require_complete_type %ptr.4f0b5c.2 [symbolic] -// CHECK:STDOUT: %require_complete.743ecf.1: = require_complete_type %ptr.6f46b6.1 [symbolic] // CHECK:STDOUT: %A.elem.ee5a68.2: type = unbound_element_type %A.2ddf89.2, %V.d9f [symbolic] // CHECK:STDOUT: %require_complete.f6b5ff.1: = require_complete_type %A.2ddf89.2 [symbolic] // CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] @@ -77,8 +74,8 @@ fn TestSpecific(a: A({})*) -> {}* { // CHECK:STDOUT: %specific_impl_fn.6a1: = specific_impl_function %impl.elem0.928, @Copy.Op(%Copy.facet.747) [symbolic] // CHECK:STDOUT: %W: type = symbolic_binding W, 0 [symbolic] // CHECK:STDOUT: %A.2ddf89.3: type = class_type @A, @A(%W) [symbolic] -// CHECK:STDOUT: %ptr.6f46b6.2: type = ptr_type %A.2ddf89.3 [symbolic] -// CHECK:STDOUT: %pattern_type.2180b5.2: type = pattern_type %ptr.6f46b6.2 [symbolic] +// CHECK:STDOUT: %ptr.6f4: type = ptr_type %A.2ddf89.3 [symbolic] +// CHECK:STDOUT: %pattern_type.218: type = pattern_type %ptr.6f4 [symbolic] // CHECK:STDOUT: %ptr.4f0b5c.4: type = ptr_type %W [symbolic] // CHECK:STDOUT: %pattern_type.a603a0.4: type = pattern_type %ptr.4f0b5c.4 [symbolic] // CHECK:STDOUT: %I.type.07036d.3: type = facet_type <@I, @I(%W)> [symbolic] @@ -98,7 +95,6 @@ fn TestSpecific(a: A({})*) -> {}* { // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] // CHECK:STDOUT: %A.235: type = class_type @A, @A(%empty_struct_type) [concrete] // CHECK:STDOUT: %ptr.197: type = ptr_type %A.235 [concrete] -// CHECK:STDOUT: %pattern_type.e47: type = pattern_type %ptr.197 [concrete] // CHECK:STDOUT: %ptr.c28: type = ptr_type %empty_struct_type [concrete] // CHECK:STDOUT: %pattern_type.1cc: type = pattern_type %ptr.c28 [concrete] // CHECK:STDOUT: %I.type.399: type = facet_type <@I, @I(%empty_struct_type)> [concrete] @@ -111,12 +107,12 @@ fn TestSpecific(a: A({})*) -> {}* { // CHECK:STDOUT: %A.as.I.impl.F.041: %A.as.I.impl.F.type.184 = struct_value () [concrete] // CHECK:STDOUT: %I.facet.6ea: %I.type.399 = facet_value %A.235, (%I.impl_witness.915) [concrete] // CHECK:STDOUT: %.824: type = fn_type_with_self_type %I.F.type.684, %I.facet.6ea [concrete] +// CHECK:STDOUT: %pattern_type.496: type = pattern_type %A.235 [concrete] // CHECK:STDOUT: %A.as.I.impl.F.specific_fn: = specific_function %A.as.I.impl.F.041, @A.as.I.impl.F(%empty_struct_type) [concrete] // CHECK:STDOUT: %A.elem.2af: type = unbound_element_type %A.235, %empty_struct_type [concrete] // CHECK:STDOUT: %struct_type.n.91c: type = struct_type {.n: %empty_struct_type} [concrete] // CHECK:STDOUT: %complete_type.0a6: = complete_type_witness %struct_type.n.91c [concrete] // CHECK:STDOUT: %complete_type.38e: = complete_type_witness %ptr.c28 [concrete] -// CHECK:STDOUT: %complete_type.d27: = complete_type_witness %ptr.197 [concrete] // CHECK:STDOUT: %Copy.impl_witness.433: = impl_witness imports.%Copy.impl_witness_table.67d, @ptr.as.Copy.impl(%empty_struct_type) [concrete] // CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.424: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%empty_struct_type) [concrete] // CHECK:STDOUT: %ptr.as.Copy.impl.Op.15e: %ptr.as.Copy.impl.Op.type.424 = struct_value () [concrete] @@ -160,22 +156,18 @@ fn TestSpecific(a: A({})*) -> {}* { // CHECK:STDOUT: // CHECK:STDOUT: impl: %A.loc12_27.2 as %I.type.loc12_35.2 { // CHECK:STDOUT: %A.as.I.impl.F.decl: @A.as.I.impl.%A.as.I.impl.F.type (%A.as.I.impl.F.type.2974bf.1) = fn_decl @A.as.I.impl.F [symbolic = @A.as.I.impl.%A.as.I.impl.F (constants.%A.as.I.impl.F.786476.1)] { -// CHECK:STDOUT: %self.patt: @A.as.I.impl.F.%pattern_type.loc13_13 (%pattern_type.2180b5.1) = value_binding_pattern self [concrete] -// CHECK:STDOUT: %self.param_patt: @A.as.I.impl.F.%pattern_type.loc13_13 (%pattern_type.2180b5.1) = value_param_pattern %self.patt, call_param0 [concrete] -// CHECK:STDOUT: %.loc13_8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] -// CHECK:STDOUT: %return.patt: @A.as.I.impl.F.%pattern_type.loc13_28 (%pattern_type.a603a0.2) = return_slot_pattern [concrete] -// CHECK:STDOUT: %return.param_patt: @A.as.I.impl.F.%pattern_type.loc13_28 (%pattern_type.a603a0.2) = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: %self.patt: @A.as.I.impl.F.%pattern_type.loc13_12 (%pattern_type.99475c.1) = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @A.as.I.impl.F.%pattern_type.loc13_12 (%pattern_type.99475c.1) = ref_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %return.patt: @A.as.I.impl.F.%pattern_type.loc13_26 (%pattern_type.a603a0.2) = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: @A.as.I.impl.F.%pattern_type.loc13_26 (%pattern_type.a603a0.2) = out_param_pattern %return.patt, call_param1 [concrete] // CHECK:STDOUT: } { // CHECK:STDOUT: %V.ref: type = name_ref V, @A.as.I.impl.%V.loc12_14.2 [symbolic = %V (constants.%V.d9f)] -// CHECK:STDOUT: %ptr.loc13_32.2: type = ptr_type %V.ref [symbolic = %ptr.loc13_32.1 (constants.%ptr.4f0b5c.2)] -// CHECK:STDOUT: %self.param: @A.as.I.impl.F.%ptr.loc13_23.1 (%ptr.6f46b6.1) = value_param call_param0 -// CHECK:STDOUT: %.loc13_23: type = splice_block %ptr.loc13_23.2 [symbolic = %ptr.loc13_23.1 (constants.%ptr.6f46b6.1)] { -// CHECK:STDOUT: %Self.ref: type = name_ref Self, @A.as.I.impl.%A.loc12_27.2 [symbolic = %A (constants.%A.2ddf89.2)] -// CHECK:STDOUT: %ptr.loc13_23.2: type = ptr_type %Self.ref [symbolic = %ptr.loc13_23.1 (constants.%ptr.6f46b6.1)] -// CHECK:STDOUT: } -// CHECK:STDOUT: %self: @A.as.I.impl.F.%ptr.loc13_23.1 (%ptr.6f46b6.1) = value_binding self, %self.param -// CHECK:STDOUT: %return.param: ref @A.as.I.impl.F.%ptr.loc13_32.1 (%ptr.4f0b5c.2) = out_param call_param1 -// CHECK:STDOUT: %return: ref @A.as.I.impl.F.%ptr.loc13_32.1 (%ptr.4f0b5c.2) = return_slot %return.param +// CHECK:STDOUT: %ptr.loc13_30.2: type = ptr_type %V.ref [symbolic = %ptr.loc13_30.1 (constants.%ptr.4f0b5c.2)] +// CHECK:STDOUT: %self.param: ref @A.as.I.impl.F.%A (%A.2ddf89.2) = ref_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @A.as.I.impl.%A.loc12_27.2 [symbolic = %A (constants.%A.2ddf89.2)] +// CHECK:STDOUT: %self: ref @A.as.I.impl.F.%A (%A.2ddf89.2) = ref_binding self, %self.param +// CHECK:STDOUT: %return.param: ref @A.as.I.impl.F.%ptr.loc13_30.1 (%ptr.4f0b5c.2) = out_param call_param1 +// CHECK:STDOUT: %return: ref @A.as.I.impl.F.%ptr.loc13_30.1 (%ptr.4f0b5c.2) = return_slot %return.param // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: !members: @@ -188,34 +180,31 @@ fn TestSpecific(a: A({})*) -> {}* { // CHECK:STDOUT: generic fn @A.as.I.impl.F(@A.as.I.impl.%V.loc12_14.2: type) { // CHECK:STDOUT: %V: type = symbolic_binding V, 0 [symbolic = %V (constants.%V.d9f)] // CHECK:STDOUT: %A: type = class_type @A, @A(%V) [symbolic = %A (constants.%A.2ddf89.2)] -// CHECK:STDOUT: %ptr.loc13_23.1: type = ptr_type %A [symbolic = %ptr.loc13_23.1 (constants.%ptr.6f46b6.1)] -// CHECK:STDOUT: %pattern_type.loc13_13: type = pattern_type %ptr.loc13_23.1 [symbolic = %pattern_type.loc13_13 (constants.%pattern_type.2180b5.1)] -// CHECK:STDOUT: %ptr.loc13_32.1: type = ptr_type %V [symbolic = %ptr.loc13_32.1 (constants.%ptr.4f0b5c.2)] -// CHECK:STDOUT: %pattern_type.loc13_28: type = pattern_type %ptr.loc13_32.1 [symbolic = %pattern_type.loc13_28 (constants.%pattern_type.a603a0.2)] +// CHECK:STDOUT: %pattern_type.loc13_12: type = pattern_type %A [symbolic = %pattern_type.loc13_12 (constants.%pattern_type.99475c.1)] +// CHECK:STDOUT: %ptr.loc13_30.1: type = ptr_type %V [symbolic = %ptr.loc13_30.1 (constants.%ptr.4f0b5c.2)] +// CHECK:STDOUT: %pattern_type.loc13_26: type = pattern_type %ptr.loc13_30.1 [symbolic = %pattern_type.loc13_26 (constants.%pattern_type.a603a0.2)] // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete.loc13_28: = require_complete_type %ptr.loc13_32.1 [symbolic = %require_complete.loc13_28 (constants.%require_complete.482d3f.1)] -// CHECK:STDOUT: %require_complete.loc13_17: = require_complete_type %ptr.loc13_23.1 [symbolic = %require_complete.loc13_17 (constants.%require_complete.743ecf.1)] -// CHECK:STDOUT: %require_complete.loc14: = require_complete_type %A [symbolic = %require_complete.loc14 (constants.%require_complete.f6b5ff.1)] +// CHECK:STDOUT: %require_complete.loc13_26: = require_complete_type %ptr.loc13_30.1 [symbolic = %require_complete.loc13_26 (constants.%require_complete.482d3f.1)] +// CHECK:STDOUT: %require_complete.loc13_16: = require_complete_type %A [symbolic = %require_complete.loc13_16 (constants.%require_complete.f6b5ff.1)] // CHECK:STDOUT: %A.elem: type = unbound_element_type %A, %V [symbolic = %A.elem (constants.%A.elem.ee5a68.2)] -// CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc13_32.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.c66)] -// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc13_32.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet.747)] +// CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc13_30.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.c66)] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc13_30.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet.747)] // CHECK:STDOUT: %.loc14_12.2: type = fn_type_with_self_type constants.%Copy.Op.type, %Copy.facet [symbolic = %.loc14_12.2 (constants.%.89d)] // CHECK:STDOUT: %impl.elem0.loc14_12.2: @A.as.I.impl.F.%.loc14_12.2 (%.89d) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc14_12.2 (constants.%impl.elem0.928)] // CHECK:STDOUT: %specific_impl_fn.loc14_12.2: = specific_impl_function %impl.elem0.loc14_12.2, @Copy.Op(%Copy.facet) [symbolic = %specific_impl_fn.loc14_12.2 (constants.%specific_impl_fn.6a1)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%self.param: @A.as.I.impl.F.%ptr.loc13_23.1 (%ptr.6f46b6.1)) -> @A.as.I.impl.F.%ptr.loc13_32.1 (%ptr.4f0b5c.2) { +// CHECK:STDOUT: fn(%self.param: @A.as.I.impl.F.%A (%A.2ddf89.2)) -> @A.as.I.impl.F.%ptr.loc13_30.1 (%ptr.4f0b5c.2) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %self.ref: @A.as.I.impl.F.%ptr.loc13_23.1 (%ptr.6f46b6.1) = name_ref self, %self -// CHECK:STDOUT: %.loc14_17.1: ref @A.as.I.impl.F.%A (%A.2ddf89.2) = deref %self.ref +// CHECK:STDOUT: %self.ref: ref @A.as.I.impl.F.%A (%A.2ddf89.2) = name_ref self, %self // CHECK:STDOUT: %n.ref: @A.as.I.impl.F.%A.elem (%A.elem.ee5a68.2) = name_ref n, @A.%.loc4 [concrete = @A.%.loc4] -// CHECK:STDOUT: %.loc14_17.2: ref @A.as.I.impl.F.%V (%V.d9f) = class_element_access %.loc14_17.1, element0 -// CHECK:STDOUT: %addr: @A.as.I.impl.F.%ptr.loc13_32.1 (%ptr.4f0b5c.2) = addr_of %.loc14_17.2 +// CHECK:STDOUT: %.loc14_17: ref @A.as.I.impl.F.%V (%V.d9f) = class_element_access %self.ref, element0 +// CHECK:STDOUT: %addr: @A.as.I.impl.F.%ptr.loc13_30.1 (%ptr.4f0b5c.2) = addr_of %.loc14_17 // CHECK:STDOUT: %impl.elem0.loc14_12.1: @A.as.I.impl.F.%.loc14_12.2 (%.89d) = impl_witness_access constants.%Copy.lookup_impl_witness.c66, element0 [symbolic = %impl.elem0.loc14_12.2 (constants.%impl.elem0.928)] // CHECK:STDOUT: %bound_method.loc14_12.1: = bound_method %addr, %impl.elem0.loc14_12.1 // CHECK:STDOUT: %specific_impl_fn.loc14_12.1: = specific_impl_function %impl.elem0.loc14_12.1, @Copy.Op(constants.%Copy.facet.747) [symbolic = %specific_impl_fn.loc14_12.2 (constants.%specific_impl_fn.6a1)] // CHECK:STDOUT: %bound_method.loc14_12.2: = bound_method %addr, %specific_impl_fn.loc14_12.1 -// CHECK:STDOUT: %.loc14_12.1: init @A.as.I.impl.F.%ptr.loc13_32.1 (%ptr.4f0b5c.2) = call %bound_method.loc14_12.2(%addr) +// CHECK:STDOUT: %.loc14_12.1: init @A.as.I.impl.F.%ptr.loc13_30.1 (%ptr.4f0b5c.2) = call %bound_method.loc14_12.2(%addr) // CHECK:STDOUT: return %.loc14_12.1 to %return // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -237,21 +226,20 @@ fn TestSpecific(a: A({})*) -> {}* { // CHECK:STDOUT: %specific_impl_fn.loc21_11.2: = specific_impl_function %impl.elem0.loc21_11.2, @I.F(%W.loc19_16.1, %I.facet) [symbolic = %specific_impl_fn.loc21_11.2 (constants.%specific_impl_fn.2e3)] // CHECK:STDOUT: %require_complete.loc21_11: = require_complete_type %A.loc19_32.1 [symbolic = %require_complete.loc21_11 (constants.%require_complete.f6b5ff.2)] // CHECK:STDOUT: -// CHECK:STDOUT: fn(%a.param: @TestGeneric.%ptr.loc19_33.1 (%ptr.6f46b6.2)) -> @TestGeneric.%ptr.loc19_40.1 (%ptr.4f0b5c.4) { +// CHECK:STDOUT: fn(%a.param: @TestGeneric.%ptr.loc19_33.1 (%ptr.6f4)) -> @TestGeneric.%ptr.loc19_40.1 (%ptr.4f0b5c.4) { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %a.ref: @TestGeneric.%ptr.loc19_33.1 (%ptr.6f46b6.2) = name_ref a, %a +// CHECK:STDOUT: %a.ref: @TestGeneric.%ptr.loc19_33.1 (%ptr.6f4) = name_ref a, %a // CHECK:STDOUT: %I.ref: %I.type.dac = name_ref I, file.%I.decl [concrete = constants.%I.generic] // CHECK:STDOUT: %W.ref.loc21: type = name_ref W, %W.loc19_16.2 [symbolic = %W.loc19_16.1 (constants.%W)] // CHECK:STDOUT: %I.type.loc21_17.1: type = facet_type <@I, @I(constants.%W)> [symbolic = %I.type.loc21_17.2 (constants.%I.type.07036d.3)] -// CHECK:STDOUT: %.loc21_18: @TestGeneric.%I.assoc_type (%I.assoc_type.b650b2.3) = specific_constant @I.%assoc0.loc8_33.1, @I(constants.%W) [symbolic = %assoc0 (constants.%assoc0.b4fda0.3)] +// CHECK:STDOUT: %.loc21_18: @TestGeneric.%I.assoc_type (%I.assoc_type.b650b2.3) = specific_constant @I.%assoc0.loc8_31.1, @I(constants.%W) [symbolic = %assoc0 (constants.%assoc0.b4fda0.3)] // CHECK:STDOUT: %F.ref: @TestGeneric.%I.assoc_type (%I.assoc_type.b650b2.3) = name_ref F, %.loc21_18 [symbolic = %assoc0 (constants.%assoc0.b4fda0.3)] // CHECK:STDOUT: %.loc21_11.1: ref @TestGeneric.%A.loc19_32.1 (%A.2ddf89.3) = deref %a.ref // CHECK:STDOUT: %impl.elem0.loc21_11.1: @TestGeneric.%.loc21_11.2 (%.e50) = impl_witness_access constants.%I.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc21_11.2 (constants.%impl.elem0.a9e)] // CHECK:STDOUT: %bound_method.loc21_11: = bound_method %.loc21_11.1, %impl.elem0.loc21_11.1 // CHECK:STDOUT: %specific_impl_fn.loc21_11.1: = specific_impl_function %impl.elem0.loc21_11.1, @I.F(constants.%W, constants.%I.facet.84d) [symbolic = %specific_impl_fn.loc21_11.2 (constants.%specific_impl_fn.2e3)] // CHECK:STDOUT: %bound_method.loc21_22: = bound_method %.loc21_11.1, %specific_impl_fn.loc21_11.1 -// CHECK:STDOUT: %addr: @TestGeneric.%ptr.loc19_33.1 (%ptr.6f46b6.2) = addr_of %.loc21_11.1 -// CHECK:STDOUT: %.loc21_22: init @TestGeneric.%ptr.loc19_40.1 (%ptr.4f0b5c.4) = call %bound_method.loc21_22(%addr) +// CHECK:STDOUT: %.loc21_22: init @TestGeneric.%ptr.loc19_40.1 (%ptr.4f0b5c.4) = call %bound_method.loc21_22(%.loc21_11.1) // CHECK:STDOUT: return %.loc21_22 to %return // CHECK:STDOUT: } // CHECK:STDOUT: } @@ -263,15 +251,14 @@ fn TestSpecific(a: A({})*) -> {}* { // CHECK:STDOUT: %.loc27_17: %empty_struct_type = struct_literal () // CHECK:STDOUT: %.loc27_18: type = converted %.loc27_17, constants.%empty_struct_type [concrete = constants.%empty_struct_type] // CHECK:STDOUT: %I.type: type = facet_type <@I, @I(constants.%empty_struct_type)> [concrete = constants.%I.type.399] -// CHECK:STDOUT: %.loc27_19: %I.assoc_type.22c = specific_constant @I.%assoc0.loc8_33.1, @I(constants.%empty_struct_type) [concrete = constants.%assoc0.a7f] +// CHECK:STDOUT: %.loc27_19: %I.assoc_type.22c = specific_constant @I.%assoc0.loc8_31.1, @I(constants.%empty_struct_type) [concrete = constants.%assoc0.a7f] // CHECK:STDOUT: %F.ref: %I.assoc_type.22c = name_ref F, %.loc27_19 [concrete = constants.%assoc0.a7f] // CHECK:STDOUT: %.loc27_11: ref %A.235 = deref %a.ref // CHECK:STDOUT: %impl.elem0: %.824 = impl_witness_access constants.%I.impl_witness.915, element0 [concrete = constants.%A.as.I.impl.F.041] // CHECK:STDOUT: %bound_method.loc27_11: = bound_method %.loc27_11, %impl.elem0 // CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @A.as.I.impl.F(constants.%empty_struct_type) [concrete = constants.%A.as.I.impl.F.specific_fn] // CHECK:STDOUT: %bound_method.loc27_23: = bound_method %.loc27_11, %specific_fn -// CHECK:STDOUT: %addr: %ptr.197 = addr_of %.loc27_11 -// CHECK:STDOUT: %A.as.I.impl.F.call: init %ptr.c28 = call %bound_method.loc27_23(%addr) +// CHECK:STDOUT: %A.as.I.impl.F.call: init %ptr.c28 = call %bound_method.loc27_23(%.loc27_11) // CHECK:STDOUT: return %A.as.I.impl.F.call to %return // CHECK:STDOUT: } // CHECK:STDOUT: @@ -290,17 +277,16 @@ fn TestSpecific(a: A({})*) -> {}* { // CHECK:STDOUT: specific @A.as.I.impl.F(constants.%V.d9f) { // CHECK:STDOUT: %V => constants.%V.d9f // CHECK:STDOUT: %A => constants.%A.2ddf89.2 -// CHECK:STDOUT: %ptr.loc13_23.1 => constants.%ptr.6f46b6.1 -// CHECK:STDOUT: %pattern_type.loc13_13 => constants.%pattern_type.2180b5.1 -// CHECK:STDOUT: %ptr.loc13_32.1 => constants.%ptr.4f0b5c.2 -// CHECK:STDOUT: %pattern_type.loc13_28 => constants.%pattern_type.a603a0.2 +// CHECK:STDOUT: %pattern_type.loc13_12 => constants.%pattern_type.99475c.1 +// CHECK:STDOUT: %ptr.loc13_30.1 => constants.%ptr.4f0b5c.2 +// CHECK:STDOUT: %pattern_type.loc13_26 => constants.%pattern_type.a603a0.2 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: specific @TestGeneric(constants.%W) { // CHECK:STDOUT: %W.loc19_16.1 => constants.%W // CHECK:STDOUT: %A.loc19_32.1 => constants.%A.2ddf89.3 -// CHECK:STDOUT: %ptr.loc19_33.1 => constants.%ptr.6f46b6.2 -// CHECK:STDOUT: %pattern_type.loc19_26 => constants.%pattern_type.2180b5.2 +// CHECK:STDOUT: %ptr.loc19_33.1 => constants.%ptr.6f4 +// CHECK:STDOUT: %pattern_type.loc19_26 => constants.%pattern_type.218 // CHECK:STDOUT: %ptr.loc19_40.1 => constants.%ptr.4f0b5c.4 // CHECK:STDOUT: %pattern_type.loc19_36 => constants.%pattern_type.a603a0.4 // CHECK:STDOUT: } @@ -332,15 +318,13 @@ fn TestSpecific(a: A({})*) -> {}* { // CHECK:STDOUT: specific @A.as.I.impl.F(constants.%empty_struct_type) { // CHECK:STDOUT: %V => constants.%empty_struct_type // CHECK:STDOUT: %A => constants.%A.235 -// CHECK:STDOUT: %ptr.loc13_23.1 => constants.%ptr.197 -// CHECK:STDOUT: %pattern_type.loc13_13 => constants.%pattern_type.e47 -// CHECK:STDOUT: %ptr.loc13_32.1 => constants.%ptr.c28 -// CHECK:STDOUT: %pattern_type.loc13_28 => constants.%pattern_type.1cc +// CHECK:STDOUT: %pattern_type.loc13_12 => constants.%pattern_type.496 +// CHECK:STDOUT: %ptr.loc13_30.1 => constants.%ptr.c28 +// CHECK:STDOUT: %pattern_type.loc13_26 => constants.%pattern_type.1cc // CHECK:STDOUT: // CHECK:STDOUT: !definition: -// CHECK:STDOUT: %require_complete.loc13_28 => constants.%complete_type.38e -// CHECK:STDOUT: %require_complete.loc13_17 => constants.%complete_type.d27 -// CHECK:STDOUT: %require_complete.loc14 => constants.%complete_type.0a6 +// CHECK:STDOUT: %require_complete.loc13_26 => constants.%complete_type.38e +// CHECK:STDOUT: %require_complete.loc13_16 => constants.%complete_type.0a6 // CHECK:STDOUT: %A.elem => constants.%A.elem.2af // CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.impl_witness.433 // CHECK:STDOUT: %Copy.facet => constants.%Copy.facet.48c diff --git a/toolchain/check/testdata/impl/lookup/impl_forall_addr.carbon b/toolchain/check/testdata/impl/lookup/impl_forall_addr.carbon new file mode 100644 index 000000000000..0973cc4724a7 --- /dev/null +++ b/toolchain/check/testdata/impl/lookup/impl_forall_addr.carbon @@ -0,0 +1,351 @@ +// 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/impl/lookup/impl_forall_addr.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/lookup/impl_forall_addr.carbon + +// --- impl_forall.carbon +library "[[@TEST_NAME]]"; + +class A(T:! type) { + var n: T; +} + +interface I(U:! type) { + fn F[addr self: Self*]() -> U*; +} + +//@dump-sem-ir-begin +impl forall [V:! type] A(V) as I(V) { + fn F[addr self: Self*]() -> V* { + return &self->n; + } +} +//@dump-sem-ir-end + +fn TestGeneric[W:! type](a: A(W)*) -> W* { + //@dump-sem-ir-begin + return a->(I(W).F)(); + //@dump-sem-ir-end +} + +fn TestSpecific(a: A({})*) -> {}* { + //@dump-sem-ir-begin + return a->(I({}).F)(); + //@dump-sem-ir-end +} + +// CHECK:STDOUT: --- impl_forall.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %T.d9f: type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete] +// CHECK:STDOUT: %A.type: type = generic_class_type @A [concrete] +// CHECK:STDOUT: %A.generic: %A.type = struct_value () [concrete] +// CHECK:STDOUT: %I.type.dac: type = generic_interface_type @I [concrete] +// CHECK:STDOUT: %I.generic: %I.type.dac = struct_value () [concrete] +// CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] +// CHECK:STDOUT: %V.d9f: type = symbolic_binding V, 0 [symbolic] +// CHECK:STDOUT: %A.2ddf89.2: type = class_type @A, @A(%V.d9f) [symbolic] +// CHECK:STDOUT: %I.type.07036d.2: type = facet_type <@I, @I(%V.d9f)> [symbolic] +// CHECK:STDOUT: %require_complete.c94ab4.1: = require_complete_type %I.type.07036d.2 [symbolic] +// CHECK:STDOUT: %I.impl_witness.0c179e.1: = impl_witness file.%I.impl_witness_table, @A.as.I.impl(%V.d9f) [symbolic] +// CHECK:STDOUT: %ptr.6f46b6.1: type = ptr_type %A.2ddf89.2 [symbolic] +// CHECK:STDOUT: %pattern_type.2180b5.1: type = pattern_type %ptr.6f46b6.1 [symbolic] +// CHECK:STDOUT: %ptr.4f0b5c.2: type = ptr_type %V.d9f [symbolic] +// CHECK:STDOUT: %pattern_type.a603a0.2: type = pattern_type %ptr.4f0b5c.2 [symbolic] +// CHECK:STDOUT: %A.as.I.impl.F.type.2974bf.1: type = fn_type @A.as.I.impl.F, @A.as.I.impl(%V.d9f) [symbolic] +// CHECK:STDOUT: %A.as.I.impl.F.786476.1: %A.as.I.impl.F.type.2974bf.1 = struct_value () [symbolic] +// CHECK:STDOUT: %require_complete.482d3f.1: = require_complete_type %ptr.4f0b5c.2 [symbolic] +// CHECK:STDOUT: %require_complete.743ecf.1: = require_complete_type %ptr.6f46b6.1 [symbolic] +// CHECK:STDOUT: %A.elem.ee5a68.2: type = unbound_element_type %A.2ddf89.2, %V.d9f [symbolic] +// CHECK:STDOUT: %require_complete.f6b5ff.1: = require_complete_type %A.2ddf89.2 [symbolic] +// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete] +// CHECK:STDOUT: %Copy.Op.type: type = fn_type @Copy.Op [concrete] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.75bcbe.1: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%T.d9f) [symbolic] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.692ac2.1: %ptr.as.Copy.impl.Op.type.75bcbe.1 = struct_value () [symbolic] +// CHECK:STDOUT: %Copy.lookup_impl_witness.c66: = lookup_impl_witness %ptr.4f0b5c.2, @Copy [symbolic] +// CHECK:STDOUT: %Copy.facet.747: %Copy.type = facet_value %ptr.4f0b5c.2, (%Copy.lookup_impl_witness.c66) [symbolic] +// CHECK:STDOUT: %.89d: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet.747 [symbolic] +// CHECK:STDOUT: %impl.elem0.928: %.89d = impl_witness_access %Copy.lookup_impl_witness.c66, element0 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.6a1: = specific_impl_function %impl.elem0.928, @Copy.Op(%Copy.facet.747) [symbolic] +// CHECK:STDOUT: %W: type = symbolic_binding W, 0 [symbolic] +// CHECK:STDOUT: %A.2ddf89.3: type = class_type @A, @A(%W) [symbolic] +// CHECK:STDOUT: %ptr.6f46b6.2: type = ptr_type %A.2ddf89.3 [symbolic] +// CHECK:STDOUT: %pattern_type.2180b5.2: type = pattern_type %ptr.6f46b6.2 [symbolic] +// CHECK:STDOUT: %ptr.4f0b5c.4: type = ptr_type %W [symbolic] +// CHECK:STDOUT: %pattern_type.a603a0.4: type = pattern_type %ptr.4f0b5c.4 [symbolic] +// CHECK:STDOUT: %I.type.07036d.3: type = facet_type <@I, @I(%W)> [symbolic] +// CHECK:STDOUT: %I.F.type.76d346.3: type = fn_type @I.F, @I(%W) [symbolic] +// CHECK:STDOUT: %I.assoc_type.b650b2.3: type = assoc_entity_type @I, @I(%W) [symbolic] +// CHECK:STDOUT: %assoc0.b4fda0.3: %I.assoc_type.b650b2.3 = assoc_entity element0, @I.%I.F.decl [symbolic] +// CHECK:STDOUT: %require_complete.c94ab4.2: = require_complete_type %I.type.07036d.3 [symbolic] +// CHECK:STDOUT: %I.impl_witness.0c179e.2: = impl_witness file.%I.impl_witness_table, @A.as.I.impl(%W) [symbolic] +// CHECK:STDOUT: %A.as.I.impl.F.type.2974bf.2: type = fn_type @A.as.I.impl.F, @A.as.I.impl(%W) [symbolic] +// CHECK:STDOUT: %A.as.I.impl.F.786476.2: %A.as.I.impl.F.type.2974bf.2 = struct_value () [symbolic] +// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %A.2ddf89.3, @I, @I(%W) [symbolic] +// CHECK:STDOUT: %I.facet.84d: %I.type.07036d.3 = facet_value %A.2ddf89.3, (%I.lookup_impl_witness) [symbolic] +// CHECK:STDOUT: %.e50: type = fn_type_with_self_type %I.F.type.76d346.3, %I.facet.84d [symbolic] +// CHECK:STDOUT: %impl.elem0.a9e: %.e50 = impl_witness_access %I.lookup_impl_witness, element0 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.2e3: = specific_impl_function %impl.elem0.a9e, @I.F(%W, %I.facet.84d) [symbolic] +// CHECK:STDOUT: %require_complete.f6b5ff.2: = require_complete_type %A.2ddf89.3 [symbolic] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %A.235: type = class_type @A, @A(%empty_struct_type) [concrete] +// CHECK:STDOUT: %ptr.197: type = ptr_type %A.235 [concrete] +// CHECK:STDOUT: %pattern_type.e47: type = pattern_type %ptr.197 [concrete] +// CHECK:STDOUT: %ptr.c28: type = ptr_type %empty_struct_type [concrete] +// CHECK:STDOUT: %pattern_type.1cc: type = pattern_type %ptr.c28 [concrete] +// CHECK:STDOUT: %I.type.399: type = facet_type <@I, @I(%empty_struct_type)> [concrete] +// CHECK:STDOUT: %I.F.type.684: type = fn_type @I.F, @I(%empty_struct_type) [concrete] +// CHECK:STDOUT: %I.assoc_type.22c: type = assoc_entity_type @I, @I(%empty_struct_type) [concrete] +// CHECK:STDOUT: %assoc0.a7f: %I.assoc_type.22c = assoc_entity element0, @I.%I.F.decl [concrete] +// CHECK:STDOUT: %complete_type.e4b: = complete_type_witness %I.type.399 [concrete] +// CHECK:STDOUT: %I.impl_witness.915: = impl_witness file.%I.impl_witness_table, @A.as.I.impl(%empty_struct_type) [concrete] +// CHECK:STDOUT: %A.as.I.impl.F.type.184: type = fn_type @A.as.I.impl.F, @A.as.I.impl(%empty_struct_type) [concrete] +// CHECK:STDOUT: %A.as.I.impl.F.041: %A.as.I.impl.F.type.184 = struct_value () [concrete] +// CHECK:STDOUT: %I.facet.6ea: %I.type.399 = facet_value %A.235, (%I.impl_witness.915) [concrete] +// CHECK:STDOUT: %.824: type = fn_type_with_self_type %I.F.type.684, %I.facet.6ea [concrete] +// CHECK:STDOUT: %A.as.I.impl.F.specific_fn: = specific_function %A.as.I.impl.F.041, @A.as.I.impl.F(%empty_struct_type) [concrete] +// CHECK:STDOUT: %A.elem.2af: type = unbound_element_type %A.235, %empty_struct_type [concrete] +// CHECK:STDOUT: %struct_type.n.91c: type = struct_type {.n: %empty_struct_type} [concrete] +// CHECK:STDOUT: %complete_type.0a6: = complete_type_witness %struct_type.n.91c [concrete] +// CHECK:STDOUT: %complete_type.38e: = complete_type_witness %ptr.c28 [concrete] +// CHECK:STDOUT: %complete_type.d27: = complete_type_witness %ptr.197 [concrete] +// CHECK:STDOUT: %Copy.impl_witness.433: = impl_witness imports.%Copy.impl_witness_table.67d, @ptr.as.Copy.impl(%empty_struct_type) [concrete] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.type.424: type = fn_type @ptr.as.Copy.impl.Op, @ptr.as.Copy.impl(%empty_struct_type) [concrete] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.15e: %ptr.as.Copy.impl.Op.type.424 = struct_value () [concrete] +// CHECK:STDOUT: %Copy.facet.48c: %Copy.type = facet_value %ptr.c28, (%Copy.impl_witness.433) [concrete] +// CHECK:STDOUT: %.fb0: type = fn_type_with_self_type %Copy.Op.type, %Copy.facet.48c [concrete] +// CHECK:STDOUT: %ptr.as.Copy.impl.Op.specific_fn: = specific_function %ptr.as.Copy.impl.Op.15e, @ptr.as.Copy.impl.Op(%empty_struct_type) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core.import_ref.659: @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op.type (%ptr.as.Copy.impl.Op.type.75bcbe.1) = import_ref Core//prelude/parts/copy, loc{{\d+_\d+}}, loaded [symbolic = @ptr.as.Copy.impl.%ptr.as.Copy.impl.Op (constants.%ptr.as.Copy.impl.Op.692ac2.1)] +// CHECK:STDOUT: %Copy.impl_witness_table.67d = impl_witness_table (%Core.import_ref.659), @ptr.as.Copy.impl [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: impl_decl @A.as.I.impl [concrete] { +// CHECK:STDOUT: %V.patt: %pattern_type.98f = symbolic_binding_pattern V, 0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %A.ref: %A.type = name_ref A, file.%A.decl [concrete = constants.%A.generic] +// CHECK:STDOUT: %V.ref.loc12_26: type = name_ref V, %V.loc12_14.2 [symbolic = %V.loc12_14.1 (constants.%V.d9f)] +// CHECK:STDOUT: %A.loc12_27.2: type = class_type @A, @A(constants.%V.d9f) [symbolic = %A.loc12_27.1 (constants.%A.2ddf89.2)] +// CHECK:STDOUT: %I.ref: %I.type.dac = name_ref I, file.%I.decl [concrete = constants.%I.generic] +// CHECK:STDOUT: %V.ref.loc12_34: type = name_ref V, %V.loc12_14.2 [symbolic = %V.loc12_14.1 (constants.%V.d9f)] +// CHECK:STDOUT: %I.type.loc12_35.2: type = facet_type <@I, @I(constants.%V.d9f)> [symbolic = %I.type.loc12_35.1 (constants.%I.type.07036d.2)] +// CHECK:STDOUT: +// CHECK:STDOUT: %V.loc12_14.2: type = symbolic_binding V, 0 [symbolic = %V.loc12_14.1 (constants.%V.d9f)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (@A.as.I.impl.%A.as.I.impl.F.decl), @A.as.I.impl [concrete] +// CHECK:STDOUT: %I.impl_witness: = impl_witness %I.impl_witness_table, @A.as.I.impl(constants.%V.d9f) [symbolic = @A.as.I.impl.%I.impl_witness (constants.%I.impl_witness.0c179e.1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic impl @A.as.I.impl(%V.loc12_14.2: type) { +// CHECK:STDOUT: %V.loc12_14.1: type = symbolic_binding V, 0 [symbolic = %V.loc12_14.1 (constants.%V.d9f)] +// CHECK:STDOUT: %A.loc12_27.1: type = class_type @A, @A(%V.loc12_14.1) [symbolic = %A.loc12_27.1 (constants.%A.2ddf89.2)] +// CHECK:STDOUT: %I.type.loc12_35.1: type = facet_type <@I, @I(%V.loc12_14.1)> [symbolic = %I.type.loc12_35.1 (constants.%I.type.07036d.2)] +// CHECK:STDOUT: %require_complete: = require_complete_type %I.type.loc12_35.1 [symbolic = %require_complete (constants.%require_complete.c94ab4.1)] +// CHECK:STDOUT: %I.impl_witness: = impl_witness file.%I.impl_witness_table, @A.as.I.impl(%V.loc12_14.1) [symbolic = %I.impl_witness (constants.%I.impl_witness.0c179e.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %A.as.I.impl.F.type: type = fn_type @A.as.I.impl.F, @A.as.I.impl(%V.loc12_14.1) [symbolic = %A.as.I.impl.F.type (constants.%A.as.I.impl.F.type.2974bf.1)] +// CHECK:STDOUT: %A.as.I.impl.F: @A.as.I.impl.%A.as.I.impl.F.type (%A.as.I.impl.F.type.2974bf.1) = struct_value () [symbolic = %A.as.I.impl.F (constants.%A.as.I.impl.F.786476.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: impl: %A.loc12_27.2 as %I.type.loc12_35.2 { +// CHECK:STDOUT: %A.as.I.impl.F.decl: @A.as.I.impl.%A.as.I.impl.F.type (%A.as.I.impl.F.type.2974bf.1) = fn_decl @A.as.I.impl.F [symbolic = @A.as.I.impl.%A.as.I.impl.F (constants.%A.as.I.impl.F.786476.1)] { +// CHECK:STDOUT: %self.patt: @A.as.I.impl.F.%pattern_type.loc13_13 (%pattern_type.2180b5.1) = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @A.as.I.impl.F.%pattern_type.loc13_13 (%pattern_type.2180b5.1) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: %.loc13_8: %pattern_type.f6d = addr_pattern %self.param_patt [concrete] +// CHECK:STDOUT: %return.patt: @A.as.I.impl.F.%pattern_type.loc13_28 (%pattern_type.a603a0.2) = return_slot_pattern [concrete] +// CHECK:STDOUT: %return.param_patt: @A.as.I.impl.F.%pattern_type.loc13_28 (%pattern_type.a603a0.2) = out_param_pattern %return.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %V.ref: type = name_ref V, @A.as.I.impl.%V.loc12_14.2 [symbolic = %V (constants.%V.d9f)] +// CHECK:STDOUT: %ptr.loc13_32.2: type = ptr_type %V.ref [symbolic = %ptr.loc13_32.1 (constants.%ptr.4f0b5c.2)] +// CHECK:STDOUT: %self.param: @A.as.I.impl.F.%ptr.loc13_23.1 (%ptr.6f46b6.1) = value_param call_param0 +// CHECK:STDOUT: %.loc13_23: type = splice_block %ptr.loc13_23.2 [symbolic = %ptr.loc13_23.1 (constants.%ptr.6f46b6.1)] { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, @A.as.I.impl.%A.loc12_27.2 [symbolic = %A (constants.%A.2ddf89.2)] +// CHECK:STDOUT: %ptr.loc13_23.2: type = ptr_type %Self.ref [symbolic = %ptr.loc13_23.1 (constants.%ptr.6f46b6.1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @A.as.I.impl.F.%ptr.loc13_23.1 (%ptr.6f46b6.1) = value_binding self, %self.param +// CHECK:STDOUT: %return.param: ref @A.as.I.impl.F.%ptr.loc13_32.1 (%ptr.4f0b5c.2) = out_param call_param1 +// CHECK:STDOUT: %return: ref @A.as.I.impl.F.%ptr.loc13_32.1 (%ptr.4f0b5c.2) = return_slot %return.param +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .V = +// CHECK:STDOUT: .F = %A.as.I.impl.F.decl +// CHECK:STDOUT: witness = file.%I.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @A.as.I.impl.F(@A.as.I.impl.%V.loc12_14.2: type) { +// CHECK:STDOUT: %V: type = symbolic_binding V, 0 [symbolic = %V (constants.%V.d9f)] +// CHECK:STDOUT: %A: type = class_type @A, @A(%V) [symbolic = %A (constants.%A.2ddf89.2)] +// CHECK:STDOUT: %ptr.loc13_23.1: type = ptr_type %A [symbolic = %ptr.loc13_23.1 (constants.%ptr.6f46b6.1)] +// CHECK:STDOUT: %pattern_type.loc13_13: type = pattern_type %ptr.loc13_23.1 [symbolic = %pattern_type.loc13_13 (constants.%pattern_type.2180b5.1)] +// CHECK:STDOUT: %ptr.loc13_32.1: type = ptr_type %V [symbolic = %ptr.loc13_32.1 (constants.%ptr.4f0b5c.2)] +// CHECK:STDOUT: %pattern_type.loc13_28: type = pattern_type %ptr.loc13_32.1 [symbolic = %pattern_type.loc13_28 (constants.%pattern_type.a603a0.2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete.loc13_28: = require_complete_type %ptr.loc13_32.1 [symbolic = %require_complete.loc13_28 (constants.%require_complete.482d3f.1)] +// CHECK:STDOUT: %require_complete.loc13_17: = require_complete_type %ptr.loc13_23.1 [symbolic = %require_complete.loc13_17 (constants.%require_complete.743ecf.1)] +// CHECK:STDOUT: %require_complete.loc14: = require_complete_type %A [symbolic = %require_complete.loc14 (constants.%require_complete.f6b5ff.1)] +// CHECK:STDOUT: %A.elem: type = unbound_element_type %A, %V [symbolic = %A.elem (constants.%A.elem.ee5a68.2)] +// CHECK:STDOUT: %Copy.lookup_impl_witness: = lookup_impl_witness %ptr.loc13_32.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.c66)] +// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc13_32.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet.747)] +// CHECK:STDOUT: %.loc14_12.2: type = fn_type_with_self_type constants.%Copy.Op.type, %Copy.facet [symbolic = %.loc14_12.2 (constants.%.89d)] +// CHECK:STDOUT: %impl.elem0.loc14_12.2: @A.as.I.impl.F.%.loc14_12.2 (%.89d) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc14_12.2 (constants.%impl.elem0.928)] +// CHECK:STDOUT: %specific_impl_fn.loc14_12.2: = specific_impl_function %impl.elem0.loc14_12.2, @Copy.Op(%Copy.facet) [symbolic = %specific_impl_fn.loc14_12.2 (constants.%specific_impl_fn.6a1)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @A.as.I.impl.F.%ptr.loc13_23.1 (%ptr.6f46b6.1)) -> @A.as.I.impl.F.%ptr.loc13_32.1 (%ptr.4f0b5c.2) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %self.ref: @A.as.I.impl.F.%ptr.loc13_23.1 (%ptr.6f46b6.1) = name_ref self, %self +// CHECK:STDOUT: %.loc14_17.1: ref @A.as.I.impl.F.%A (%A.2ddf89.2) = deref %self.ref +// CHECK:STDOUT: %n.ref: @A.as.I.impl.F.%A.elem (%A.elem.ee5a68.2) = name_ref n, @A.%.loc4 [concrete = @A.%.loc4] +// CHECK:STDOUT: %.loc14_17.2: ref @A.as.I.impl.F.%V (%V.d9f) = class_element_access %.loc14_17.1, element0 +// CHECK:STDOUT: %addr: @A.as.I.impl.F.%ptr.loc13_32.1 (%ptr.4f0b5c.2) = addr_of %.loc14_17.2 +// CHECK:STDOUT: %impl.elem0.loc14_12.1: @A.as.I.impl.F.%.loc14_12.2 (%.89d) = impl_witness_access constants.%Copy.lookup_impl_witness.c66, element0 [symbolic = %impl.elem0.loc14_12.2 (constants.%impl.elem0.928)] +// CHECK:STDOUT: %bound_method.loc14_12.1: = bound_method %addr, %impl.elem0.loc14_12.1 +// CHECK:STDOUT: %specific_impl_fn.loc14_12.1: = specific_impl_function %impl.elem0.loc14_12.1, @Copy.Op(constants.%Copy.facet.747) [symbolic = %specific_impl_fn.loc14_12.2 (constants.%specific_impl_fn.6a1)] +// CHECK:STDOUT: %bound_method.loc14_12.2: = bound_method %addr, %specific_impl_fn.loc14_12.1 +// CHECK:STDOUT: %.loc14_12.1: init @A.as.I.impl.F.%ptr.loc13_32.1 (%ptr.4f0b5c.2) = call %bound_method.loc14_12.2(%addr) +// CHECK:STDOUT: return %.loc14_12.1 to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @TestGeneric(%W.loc19_16.2: type) { +// CHECK:STDOUT: +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: %I.type.loc21_17.2: type = facet_type <@I, @I(%W.loc19_16.1)> [symbolic = %I.type.loc21_17.2 (constants.%I.type.07036d.3)] +// CHECK:STDOUT: %require_complete.loc21_18: = require_complete_type %I.type.loc21_17.2 [symbolic = %require_complete.loc21_18 (constants.%require_complete.c94ab4.2)] +// CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type @I, @I(%W.loc19_16.1) [symbolic = %I.assoc_type (constants.%I.assoc_type.b650b2.3)] +// CHECK:STDOUT: %assoc0: @TestGeneric.%I.assoc_type (%I.assoc_type.b650b2.3) = assoc_entity element0, @I.%I.F.decl [symbolic = %assoc0 (constants.%assoc0.b4fda0.3)] +// CHECK:STDOUT: %I.lookup_impl_witness: = lookup_impl_witness %A.loc19_32.1, @I, @I(%W.loc19_16.1) [symbolic = %I.lookup_impl_witness (constants.%I.lookup_impl_witness)] +// CHECK:STDOUT: %I.F.type: type = fn_type @I.F, @I(%W.loc19_16.1) [symbolic = %I.F.type (constants.%I.F.type.76d346.3)] +// CHECK:STDOUT: %I.facet: @TestGeneric.%I.type.loc21_17.2 (%I.type.07036d.3) = facet_value %A.loc19_32.1, (%I.lookup_impl_witness) [symbolic = %I.facet (constants.%I.facet.84d)] +// CHECK:STDOUT: %.loc21_11.2: type = fn_type_with_self_type %I.F.type, %I.facet [symbolic = %.loc21_11.2 (constants.%.e50)] +// CHECK:STDOUT: %impl.elem0.loc21_11.2: @TestGeneric.%.loc21_11.2 (%.e50) = impl_witness_access %I.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc21_11.2 (constants.%impl.elem0.a9e)] +// CHECK:STDOUT: %specific_impl_fn.loc21_11.2: = specific_impl_function %impl.elem0.loc21_11.2, @I.F(%W.loc19_16.1, %I.facet) [symbolic = %specific_impl_fn.loc21_11.2 (constants.%specific_impl_fn.2e3)] +// CHECK:STDOUT: %require_complete.loc21_11: = require_complete_type %A.loc19_32.1 [symbolic = %require_complete.loc21_11 (constants.%require_complete.f6b5ff.2)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%a.param: @TestGeneric.%ptr.loc19_33.1 (%ptr.6f46b6.2)) -> @TestGeneric.%ptr.loc19_40.1 (%ptr.4f0b5c.4) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %a.ref: @TestGeneric.%ptr.loc19_33.1 (%ptr.6f46b6.2) = name_ref a, %a +// CHECK:STDOUT: %I.ref: %I.type.dac = name_ref I, file.%I.decl [concrete = constants.%I.generic] +// CHECK:STDOUT: %W.ref.loc21: type = name_ref W, %W.loc19_16.2 [symbolic = %W.loc19_16.1 (constants.%W)] +// CHECK:STDOUT: %I.type.loc21_17.1: type = facet_type <@I, @I(constants.%W)> [symbolic = %I.type.loc21_17.2 (constants.%I.type.07036d.3)] +// CHECK:STDOUT: %.loc21_18: @TestGeneric.%I.assoc_type (%I.assoc_type.b650b2.3) = specific_constant @I.%assoc0.loc8_33.1, @I(constants.%W) [symbolic = %assoc0 (constants.%assoc0.b4fda0.3)] +// CHECK:STDOUT: %F.ref: @TestGeneric.%I.assoc_type (%I.assoc_type.b650b2.3) = name_ref F, %.loc21_18 [symbolic = %assoc0 (constants.%assoc0.b4fda0.3)] +// CHECK:STDOUT: %.loc21_11.1: ref @TestGeneric.%A.loc19_32.1 (%A.2ddf89.3) = deref %a.ref +// CHECK:STDOUT: %impl.elem0.loc21_11.1: @TestGeneric.%.loc21_11.2 (%.e50) = impl_witness_access constants.%I.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc21_11.2 (constants.%impl.elem0.a9e)] +// CHECK:STDOUT: %bound_method.loc21_11: = bound_method %.loc21_11.1, %impl.elem0.loc21_11.1 +// CHECK:STDOUT: %specific_impl_fn.loc21_11.1: = specific_impl_function %impl.elem0.loc21_11.1, @I.F(constants.%W, constants.%I.facet.84d) [symbolic = %specific_impl_fn.loc21_11.2 (constants.%specific_impl_fn.2e3)] +// CHECK:STDOUT: %bound_method.loc21_22: = bound_method %.loc21_11.1, %specific_impl_fn.loc21_11.1 +// CHECK:STDOUT: %addr: @TestGeneric.%ptr.loc19_33.1 (%ptr.6f46b6.2) = addr_of %.loc21_11.1 +// CHECK:STDOUT: %.loc21_22: init @TestGeneric.%ptr.loc19_40.1 (%ptr.4f0b5c.4) = call %bound_method.loc21_22(%addr) +// CHECK:STDOUT: return %.loc21_22 to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @TestSpecific(%a.param: %ptr.197) -> %ptr.c28 { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %a.ref: %ptr.197 = name_ref a, %a +// CHECK:STDOUT: %I.ref: %I.type.dac = name_ref I, file.%I.decl [concrete = constants.%I.generic] +// CHECK:STDOUT: %.loc27_17: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %.loc27_18: type = converted %.loc27_17, constants.%empty_struct_type [concrete = constants.%empty_struct_type] +// CHECK:STDOUT: %I.type: type = facet_type <@I, @I(constants.%empty_struct_type)> [concrete = constants.%I.type.399] +// CHECK:STDOUT: %.loc27_19: %I.assoc_type.22c = specific_constant @I.%assoc0.loc8_33.1, @I(constants.%empty_struct_type) [concrete = constants.%assoc0.a7f] +// CHECK:STDOUT: %F.ref: %I.assoc_type.22c = name_ref F, %.loc27_19 [concrete = constants.%assoc0.a7f] +// CHECK:STDOUT: %.loc27_11: ref %A.235 = deref %a.ref +// CHECK:STDOUT: %impl.elem0: %.824 = impl_witness_access constants.%I.impl_witness.915, element0 [concrete = constants.%A.as.I.impl.F.041] +// CHECK:STDOUT: %bound_method.loc27_11: = bound_method %.loc27_11, %impl.elem0 +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @A.as.I.impl.F(constants.%empty_struct_type) [concrete = constants.%A.as.I.impl.F.specific_fn] +// CHECK:STDOUT: %bound_method.loc27_23: = bound_method %.loc27_11, %specific_fn +// CHECK:STDOUT: %addr: %ptr.197 = addr_of %.loc27_11 +// CHECK:STDOUT: %A.as.I.impl.F.call: init %ptr.c28 = call %bound_method.loc27_23(%addr) +// CHECK:STDOUT: return %A.as.I.impl.F.call to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.as.I.impl(constants.%V.d9f) { +// CHECK:STDOUT: %V.loc12_14.1 => constants.%V.d9f +// CHECK:STDOUT: %A.loc12_27.1 => constants.%A.2ddf89.2 +// CHECK:STDOUT: %I.type.loc12_35.1 => constants.%I.type.07036d.2 +// CHECK:STDOUT: %require_complete => constants.%require_complete.c94ab4.1 +// CHECK:STDOUT: %I.impl_witness => constants.%I.impl_witness.0c179e.1 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %A.as.I.impl.F.type => constants.%A.as.I.impl.F.type.2974bf.1 +// CHECK:STDOUT: %A.as.I.impl.F => constants.%A.as.I.impl.F.786476.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.as.I.impl.F(constants.%V.d9f) { +// CHECK:STDOUT: %V => constants.%V.d9f +// CHECK:STDOUT: %A => constants.%A.2ddf89.2 +// CHECK:STDOUT: %ptr.loc13_23.1 => constants.%ptr.6f46b6.1 +// CHECK:STDOUT: %pattern_type.loc13_13 => constants.%pattern_type.2180b5.1 +// CHECK:STDOUT: %ptr.loc13_32.1 => constants.%ptr.4f0b5c.2 +// CHECK:STDOUT: %pattern_type.loc13_28 => constants.%pattern_type.a603a0.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @TestGeneric(constants.%W) { +// CHECK:STDOUT: %W.loc19_16.1 => constants.%W +// CHECK:STDOUT: %A.loc19_32.1 => constants.%A.2ddf89.3 +// CHECK:STDOUT: %ptr.loc19_33.1 => constants.%ptr.6f46b6.2 +// CHECK:STDOUT: %pattern_type.loc19_26 => constants.%pattern_type.2180b5.2 +// CHECK:STDOUT: %ptr.loc19_40.1 => constants.%ptr.4f0b5c.4 +// CHECK:STDOUT: %pattern_type.loc19_36 => constants.%pattern_type.a603a0.4 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.as.I.impl(constants.%W) { +// CHECK:STDOUT: %V.loc12_14.1 => constants.%W +// CHECK:STDOUT: %A.loc12_27.1 => constants.%A.2ddf89.3 +// CHECK:STDOUT: %I.type.loc12_35.1 => constants.%I.type.07036d.3 +// CHECK:STDOUT: %require_complete => constants.%require_complete.c94ab4.2 +// CHECK:STDOUT: %I.impl_witness => constants.%I.impl_witness.0c179e.2 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %A.as.I.impl.F.type => constants.%A.as.I.impl.F.type.2974bf.2 +// CHECK:STDOUT: %A.as.I.impl.F => constants.%A.as.I.impl.F.786476.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.as.I.impl(constants.%empty_struct_type) { +// CHECK:STDOUT: %V.loc12_14.1 => constants.%empty_struct_type +// CHECK:STDOUT: %A.loc12_27.1 => constants.%A.235 +// CHECK:STDOUT: %I.type.loc12_35.1 => constants.%I.type.399 +// CHECK:STDOUT: %require_complete => constants.%complete_type.e4b +// CHECK:STDOUT: %I.impl_witness => constants.%I.impl_witness.915 +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %A.as.I.impl.F.type => constants.%A.as.I.impl.F.type.184 +// CHECK:STDOUT: %A.as.I.impl.F => constants.%A.as.I.impl.F.041 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.as.I.impl.F(constants.%empty_struct_type) { +// CHECK:STDOUT: %V => constants.%empty_struct_type +// CHECK:STDOUT: %A => constants.%A.235 +// CHECK:STDOUT: %ptr.loc13_23.1 => constants.%ptr.197 +// CHECK:STDOUT: %pattern_type.loc13_13 => constants.%pattern_type.e47 +// CHECK:STDOUT: %ptr.loc13_32.1 => constants.%ptr.c28 +// CHECK:STDOUT: %pattern_type.loc13_28 => constants.%pattern_type.1cc +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete.loc13_28 => constants.%complete_type.38e +// CHECK:STDOUT: %require_complete.loc13_17 => constants.%complete_type.d27 +// CHECK:STDOUT: %require_complete.loc14 => constants.%complete_type.0a6 +// CHECK:STDOUT: %A.elem => constants.%A.elem.2af +// CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.impl_witness.433 +// CHECK:STDOUT: %Copy.facet => constants.%Copy.facet.48c +// CHECK:STDOUT: %.loc14_12.2 => constants.%.fb0 +// CHECK:STDOUT: %impl.elem0.loc14_12.2 => constants.%ptr.as.Copy.impl.Op.15e +// CHECK:STDOUT: %specific_impl_fn.loc14_12.2 => constants.%ptr.as.Copy.impl.Op.specific_fn +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/interface/compound_member_access.carbon b/toolchain/check/testdata/interface/compound_member_access.carbon index f1b872f7ca5d..3c3aab0ca1fa 100644 --- a/toolchain/check/testdata/interface/compound_member_access.carbon +++ b/toolchain/check/testdata/interface/compound_member_access.carbon @@ -70,6 +70,26 @@ fn Compound3(V:! K2, y: V) { // --- instance.carbon library "[[@TEST_NAME]]"; +interface L1 { + fn R1[self: Self](); + fn S1[ref self: Self](); +} + +// Simple member access. +fn Simple4(T:! L1, x: T, p: T*) { + x.R1(); + p->S1(); +} + +// This should be equivalent to `Simple4` above, but using compound member access. +fn Compound4(V:! L1, y: V, p: V*) { + y.(L1.R1)(); + p->(L1.S1)(); +} + +// --- instance_addr.carbon +library "[[@TEST_NAME]]"; + interface L1 { fn R1[self: Self](); fn S1[addr self: Self*](); @@ -93,7 +113,7 @@ library "[[@TEST_NAME]]"; interface L2 { fn R2[self: Self](); - fn S2[addr self: Self*](); + fn S2[ref self: Self](); } // Simple member access. Fails since calling an instance method without an object. @@ -110,8 +130,8 @@ fn Simple5(T:! L2) { // CHECK:STDERR: T.S2(); // CHECK:STDERR: ^~~~~~ // CHECK:STDERR: fail_interface_instance_caller_not.carbon:[[@LINE-16]]:3: note: calling function declared here [InCallToFunction] - // CHECK:STDERR: fn S2[addr self: Self*](); - // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fn S2[ref self: Self](); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: T.S2(); } @@ -130,6 +150,49 @@ fn Compound5(V:! L2) { V.(L2.S2)(); } +// --- fail_interface_instance_caller_not_addr.carbon + +library "[[@TEST_NAME]]"; + +interface L2 { + fn R2[self: Self](); + fn S2[addr self: Self*](); +} + +// Simple member access. Fails since calling an instance method without an object. +fn Simple5(T:! L2) { + // CHECK:STDERR: fail_interface_instance_caller_not_addr.carbon:[[@LINE+7]]:3: error: missing object argument in method call [MissingObjectInMethodCall] + // CHECK:STDERR: T.R2(); + // CHECK:STDERR: ^~~~~~ + // CHECK:STDERR: fail_interface_instance_caller_not_addr.carbon:[[@LINE-9]]:3: note: calling function declared here [InCallToFunction] + // CHECK:STDERR: fn R2[self: Self](); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + T.R2(); + // CHECK:STDERR: fail_interface_instance_caller_not_addr.carbon:[[@LINE+7]]:3: error: missing object argument in method call [MissingObjectInMethodCall] + // CHECK:STDERR: T.S2(); + // CHECK:STDERR: ^~~~~~ + // CHECK:STDERR: fail_interface_instance_caller_not_addr.carbon:[[@LINE-16]]:3: note: calling function declared here [InCallToFunction] + // CHECK:STDERR: fn S2[addr self: Self*](); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + T.S2(); +} + +// TODO: Expected to fail in the same way as `Simple5`. +fn Compound5(V:! L2) { + // CHECK:STDERR: fail_interface_instance_caller_not_addr.carbon:[[@LINE+4]]:3: error: cannot access member of interface `L2` in type `L2` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: V.(L2.R2)(); + // CHECK:STDERR: ^~~~~~~~~ + // CHECK:STDERR: + V.(L2.R2)(); + // CHECK:STDERR: fail_interface_instance_caller_not_addr.carbon:[[@LINE+4]]:3: error: cannot access member of interface `L2` in type `L2` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: V.(L2.S2)(); + // CHECK:STDERR: ^~~~~~~~~ + // CHECK:STDERR: + V.(L2.S2)(); +} + // --- fail_combine_non_instance.carbon library "[[@TEST_NAME]]"; @@ -653,6 +716,316 @@ fn Works() { // CHECK:STDOUT: %L1.R1: %L1.R1.type = struct_value () [concrete] // CHECK:STDOUT: %L1.assoc_type: type = assoc_entity_type @L1 [concrete] // CHECK:STDOUT: %assoc0: %L1.assoc_type = assoc_entity element0, @L1.%L1.R1.decl [concrete] +// CHECK:STDOUT: %L1.S1.type: type = fn_type @L1.S1 [concrete] +// CHECK:STDOUT: %L1.S1: %L1.S1.type = struct_value () [concrete] +// CHECK:STDOUT: %assoc1: %L1.assoc_type = assoc_entity element1, @L1.%L1.S1.decl [concrete] +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %T: %L1.type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %pattern_type.e3e: type = pattern_type %L1.type [concrete] +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T [symbolic] +// CHECK:STDOUT: %pattern_type.510a66.2: type = pattern_type %T.binding.as_type [symbolic] +// CHECK:STDOUT: %ptr.5db4e7.1: type = ptr_type %T.binding.as_type [symbolic] +// CHECK:STDOUT: %pattern_type.f1f60b.1: type = pattern_type %ptr.5db4e7.1 [symbolic] +// CHECK:STDOUT: %Simple4.type: type = fn_type @Simple4 [concrete] +// CHECK:STDOUT: %Simple4: %Simple4.type = struct_value () [concrete] +// CHECK:STDOUT: %require_complete.b98a62.1: = require_complete_type %T.binding.as_type [symbolic] +// CHECK:STDOUT: %require_complete.80837b.1: = require_complete_type %ptr.5db4e7.1 [symbolic] +// CHECK:STDOUT: %L1.lookup_impl_witness.497b38.1: = lookup_impl_witness %T, @L1 [symbolic] +// CHECK:STDOUT: %.2c3978.1: type = fn_type_with_self_type %L1.R1.type, %T [symbolic] +// CHECK:STDOUT: %impl.elem0.d3a613.1: %.2c3978.1 = impl_witness_access %L1.lookup_impl_witness.497b38.1, element0 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.f8ac37.1: = specific_impl_function %impl.elem0.d3a613.1, @L1.R1(%T) [symbolic] +// CHECK:STDOUT: %.45c8db.1: type = fn_type_with_self_type %L1.S1.type, %T [symbolic] +// CHECK:STDOUT: %impl.elem1.c3a14a.1: %.45c8db.1 = impl_witness_access %L1.lookup_impl_witness.497b38.1, element1 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.c2ec1e.1: = specific_impl_function %impl.elem1.c3a14a.1, @L1.S1(%T) [symbolic] +// CHECK:STDOUT: %V: %L1.type = symbolic_binding V, 0 [symbolic] +// CHECK:STDOUT: %V.binding.as_type: type = symbolic_binding_type V, 0, %V [symbolic] +// CHECK:STDOUT: %pattern_type.510a66.3: type = pattern_type %V.binding.as_type [symbolic] +// CHECK:STDOUT: %ptr.5db4e7.2: type = ptr_type %V.binding.as_type [symbolic] +// CHECK:STDOUT: %pattern_type.f1f60b.2: type = pattern_type %ptr.5db4e7.2 [symbolic] +// CHECK:STDOUT: %Compound4.type: type = fn_type @Compound4 [concrete] +// CHECK:STDOUT: %Compound4: %Compound4.type = struct_value () [concrete] +// CHECK:STDOUT: %require_complete.b98a62.2: = require_complete_type %V.binding.as_type [symbolic] +// CHECK:STDOUT: %require_complete.80837b.2: = require_complete_type %ptr.5db4e7.2 [symbolic] +// CHECK:STDOUT: %L1.lookup_impl_witness.497b38.2: = lookup_impl_witness %V, @L1 [symbolic] +// CHECK:STDOUT: %.2c3978.2: type = fn_type_with_self_type %L1.R1.type, %V [symbolic] +// CHECK:STDOUT: %impl.elem0.d3a613.2: %.2c3978.2 = impl_witness_access %L1.lookup_impl_witness.497b38.2, element0 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.f8ac37.2: = specific_impl_function %impl.elem0.d3a613.2, @L1.R1(%V) [symbolic] +// CHECK:STDOUT: %.45c8db.2: type = fn_type_with_self_type %L1.S1.type, %V [symbolic] +// CHECK:STDOUT: %impl.elem1.c3a14a.2: %.45c8db.2 = impl_witness_access %L1.lookup_impl_witness.497b38.2, element1 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.c2ec1e.2: = specific_impl_function %impl.elem1.c3a14a.2, @L1.S1(%V) [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .L1 = %L1.decl +// CHECK:STDOUT: .Simple4 = %Simple4.decl +// CHECK:STDOUT: .Compound4 = %Compound4.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %L1.decl: type = interface_decl @L1 [concrete = constants.%L1.type] {} {} +// CHECK:STDOUT: %Simple4.decl: %Simple4.type = fn_decl @Simple4 [concrete = constants.%Simple4] { +// CHECK:STDOUT: %T.patt: %pattern_type.e3e = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %x.patt: @Simple4.%pattern_type.loc9_20 (%pattern_type.510a66.2) = value_binding_pattern x [concrete] +// CHECK:STDOUT: %x.param_patt: @Simple4.%pattern_type.loc9_20 (%pattern_type.510a66.2) = value_param_pattern %x.patt, call_param0 [concrete] +// CHECK:STDOUT: %p.patt: @Simple4.%pattern_type.loc9_26 (%pattern_type.f1f60b.1) = value_binding_pattern p [concrete] +// CHECK:STDOUT: %p.param_patt: @Simple4.%pattern_type.loc9_26 (%pattern_type.f1f60b.1) = value_param_pattern %p.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc9_16: type = splice_block %L1.ref [concrete = constants.%L1.type] { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %L1.ref: type = name_ref L1, file.%L1.decl [concrete = constants.%L1.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.loc9_12.2: %L1.type = symbolic_binding T, 0 [symbolic = %T.loc9_12.1 (constants.%T)] +// CHECK:STDOUT: %x.param: @Simple4.%T.binding.as_type (%T.binding.as_type) = value_param call_param0 +// CHECK:STDOUT: %.loc9_23.1: type = splice_block %.loc9_23.2 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] { +// CHECK:STDOUT: %T.ref.loc9_23: %L1.type = name_ref T, %T.loc9_12.2 [symbolic = %T.loc9_12.1 (constants.%T)] +// CHECK:STDOUT: %T.as_type.loc9_23: type = facet_access_type %T.ref.loc9_23 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %.loc9_23.2: type = converted %T.ref.loc9_23, %T.as_type.loc9_23 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: @Simple4.%T.binding.as_type (%T.binding.as_type) = value_binding x, %x.param +// CHECK:STDOUT: %p.param: @Simple4.%ptr.loc9_30.1 (%ptr.5db4e7.1) = value_param call_param1 +// CHECK:STDOUT: %.loc9_30.1: type = splice_block %ptr.loc9_30.2 [symbolic = %ptr.loc9_30.1 (constants.%ptr.5db4e7.1)] { +// CHECK:STDOUT: %T.ref.loc9_29: %L1.type = name_ref T, %T.loc9_12.2 [symbolic = %T.loc9_12.1 (constants.%T)] +// CHECK:STDOUT: %T.as_type.loc9_30: type = facet_access_type %T.ref.loc9_29 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %.loc9_30.2: type = converted %T.ref.loc9_29, %T.as_type.loc9_30 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %ptr.loc9_30.2: type = ptr_type %.loc9_30.2 [symbolic = %ptr.loc9_30.1 (constants.%ptr.5db4e7.1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %p: @Simple4.%ptr.loc9_30.1 (%ptr.5db4e7.1) = value_binding p, %p.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %Compound4.decl: %Compound4.type = fn_decl @Compound4 [concrete = constants.%Compound4] { +// CHECK:STDOUT: %V.patt: %pattern_type.e3e = symbolic_binding_pattern V, 0 [concrete] +// CHECK:STDOUT: %y.patt: @Compound4.%pattern_type.loc15_22 (%pattern_type.510a66.3) = value_binding_pattern y [concrete] +// CHECK:STDOUT: %y.param_patt: @Compound4.%pattern_type.loc15_22 (%pattern_type.510a66.3) = value_param_pattern %y.patt, call_param0 [concrete] +// CHECK:STDOUT: %p.patt: @Compound4.%pattern_type.loc15_28 (%pattern_type.f1f60b.2) = value_binding_pattern p [concrete] +// CHECK:STDOUT: %p.param_patt: @Compound4.%pattern_type.loc15_28 (%pattern_type.f1f60b.2) = value_param_pattern %p.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc15_18: type = splice_block %L1.ref.loc15 [concrete = constants.%L1.type] { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %L1.ref.loc15: type = name_ref L1, file.%L1.decl [concrete = constants.%L1.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %V.loc15_14.2: %L1.type = symbolic_binding V, 0 [symbolic = %V.loc15_14.1 (constants.%V)] +// CHECK:STDOUT: %y.param: @Compound4.%V.binding.as_type (%V.binding.as_type) = value_param call_param0 +// CHECK:STDOUT: %.loc15_25.1: type = splice_block %.loc15_25.2 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] { +// CHECK:STDOUT: %V.ref.loc15_25: %L1.type = name_ref V, %V.loc15_14.2 [symbolic = %V.loc15_14.1 (constants.%V)] +// CHECK:STDOUT: %V.as_type.loc15_25: type = facet_access_type %V.ref.loc15_25 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] +// CHECK:STDOUT: %.loc15_25.2: type = converted %V.ref.loc15_25, %V.as_type.loc15_25 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %y: @Compound4.%V.binding.as_type (%V.binding.as_type) = value_binding y, %y.param +// CHECK:STDOUT: %p.param: @Compound4.%ptr.loc15_32.1 (%ptr.5db4e7.2) = value_param call_param1 +// CHECK:STDOUT: %.loc15_32.1: type = splice_block %ptr.loc15_32.2 [symbolic = %ptr.loc15_32.1 (constants.%ptr.5db4e7.2)] { +// CHECK:STDOUT: %V.ref.loc15_31: %L1.type = name_ref V, %V.loc15_14.2 [symbolic = %V.loc15_14.1 (constants.%V)] +// CHECK:STDOUT: %V.as_type.loc15_32: type = facet_access_type %V.ref.loc15_31 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] +// CHECK:STDOUT: %.loc15_32.2: type = converted %V.ref.loc15_31, %V.as_type.loc15_32 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] +// CHECK:STDOUT: %ptr.loc15_32.2: type = ptr_type %.loc15_32.2 [symbolic = %ptr.loc15_32.1 (constants.%ptr.5db4e7.2)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %p: @Compound4.%ptr.loc15_32.1 (%ptr.5db4e7.2) = value_binding p, %p.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @L1 { +// CHECK:STDOUT: %Self: %L1.type = symbolic_binding Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %L1.R1.decl: %L1.R1.type = fn_decl @L1.R1 [concrete = constants.%L1.R1] { +// CHECK:STDOUT: %self.patt: @L1.R1.%pattern_type (%pattern_type.510a66.1) = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @L1.R1.%pattern_type (%pattern_type.510a66.1) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @L1.R1.%Self.binding.as_type (%Self.binding.as_type) = value_param call_param0 +// CHECK:STDOUT: %.loc4_15.1: type = splice_block %.loc4_15.2 [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] { +// CHECK:STDOUT: %Self.ref: %L1.type = name_ref Self, @L1.%Self [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.ref [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %.loc4_15.2: type = converted %Self.ref, %Self.as_type [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @L1.R1.%Self.binding.as_type (%Self.binding.as_type) = value_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc0: %L1.assoc_type = assoc_entity element0, %L1.R1.decl [concrete = constants.%assoc0] +// CHECK:STDOUT: %L1.S1.decl: %L1.S1.type = fn_decl @L1.S1 [concrete = constants.%L1.S1] { +// CHECK:STDOUT: %self.patt: @L1.S1.%pattern_type (%pattern_type.510a66.1) = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @L1.S1.%pattern_type (%pattern_type.510a66.1) = ref_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: ref @L1.S1.%Self.binding.as_type (%Self.binding.as_type) = ref_param call_param0 +// CHECK:STDOUT: %.loc5_19.1: type = splice_block %.loc5_19.2 [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] { +// CHECK:STDOUT: %Self.ref: %L1.type = name_ref Self, @L1.%Self [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.ref [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %.loc5_19.2: type = converted %Self.ref, %Self.as_type [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: ref @L1.S1.%Self.binding.as_type (%Self.binding.as_type) = ref_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc1: %L1.assoc_type = assoc_entity element1, %L1.S1.decl [concrete = constants.%assoc1] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .R1 = %assoc0 +// CHECK:STDOUT: .S1 = %assoc1 +// CHECK:STDOUT: witness = (%L1.R1.decl, %L1.S1.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @L1.R1(@L1.%Self: %L1.type) { +// CHECK:STDOUT: %Self: %L1.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %Self.binding.as_type [symbolic = %pattern_type (constants.%pattern_type.510a66.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @L1.R1.%Self.binding.as_type (%Self.binding.as_type)); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @L1.S1(@L1.%Self: %L1.type) { +// CHECK:STDOUT: %Self: %L1.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %Self.binding.as_type [symbolic = %pattern_type (constants.%pattern_type.510a66.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @L1.S1.%Self.binding.as_type (%Self.binding.as_type)); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Simple4(%T.loc9_12.2: %L1.type) { +// CHECK:STDOUT: %T.loc9_12.1: %L1.type = symbolic_binding T, 0 [symbolic = %T.loc9_12.1 (constants.%T)] +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T.loc9_12.1 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %pattern_type.loc9_20: type = pattern_type %T.binding.as_type [symbolic = %pattern_type.loc9_20 (constants.%pattern_type.510a66.2)] +// CHECK:STDOUT: %ptr.loc9_30.1: type = ptr_type %T.binding.as_type [symbolic = %ptr.loc9_30.1 (constants.%ptr.5db4e7.1)] +// CHECK:STDOUT: %pattern_type.loc9_26: type = pattern_type %ptr.loc9_30.1 [symbolic = %pattern_type.loc9_26 (constants.%pattern_type.f1f60b.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete.loc9_21: = require_complete_type %T.binding.as_type [symbolic = %require_complete.loc9_21 (constants.%require_complete.b98a62.1)] +// CHECK:STDOUT: %require_complete.loc9_27: = require_complete_type %ptr.loc9_30.1 [symbolic = %require_complete.loc9_27 (constants.%require_complete.80837b.1)] +// CHECK:STDOUT: %L1.lookup_impl_witness: = lookup_impl_witness %T.loc9_12.1, @L1 [symbolic = %L1.lookup_impl_witness (constants.%L1.lookup_impl_witness.497b38.1)] +// CHECK:STDOUT: %.loc10_4: type = fn_type_with_self_type constants.%L1.R1.type, %T.loc9_12.1 [symbolic = %.loc10_4 (constants.%.2c3978.1)] +// CHECK:STDOUT: %impl.elem0.loc10_4.2: @Simple4.%.loc10_4 (%.2c3978.1) = impl_witness_access %L1.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc10_4.2 (constants.%impl.elem0.d3a613.1)] +// CHECK:STDOUT: %specific_impl_fn.loc10_4.2: = specific_impl_function %impl.elem0.loc10_4.2, @L1.R1(%T.loc9_12.1) [symbolic = %specific_impl_fn.loc10_4.2 (constants.%specific_impl_fn.f8ac37.1)] +// CHECK:STDOUT: %.loc11_4.2: type = fn_type_with_self_type constants.%L1.S1.type, %T.loc9_12.1 [symbolic = %.loc11_4.2 (constants.%.45c8db.1)] +// CHECK:STDOUT: %impl.elem1.loc11_4.2: @Simple4.%.loc11_4.2 (%.45c8db.1) = impl_witness_access %L1.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc11_4.2 (constants.%impl.elem1.c3a14a.1)] +// CHECK:STDOUT: %specific_impl_fn.loc11_4.2: = specific_impl_function %impl.elem1.loc11_4.2, @L1.S1(%T.loc9_12.1) [symbolic = %specific_impl_fn.loc11_4.2 (constants.%specific_impl_fn.c2ec1e.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param: @Simple4.%T.binding.as_type (%T.binding.as_type), %p.param: @Simple4.%ptr.loc9_30.1 (%ptr.5db4e7.1)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %x.ref: @Simple4.%T.binding.as_type (%T.binding.as_type) = name_ref x, %x +// CHECK:STDOUT: %R1.ref: %L1.assoc_type = name_ref R1, @L1.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %impl.elem0.loc10_4.1: @Simple4.%.loc10_4 (%.2c3978.1) = impl_witness_access constants.%L1.lookup_impl_witness.497b38.1, element0 [symbolic = %impl.elem0.loc10_4.2 (constants.%impl.elem0.d3a613.1)] +// CHECK:STDOUT: %bound_method.loc10_4: = bound_method %x.ref, %impl.elem0.loc10_4.1 +// CHECK:STDOUT: %specific_impl_fn.loc10_4.1: = specific_impl_function %impl.elem0.loc10_4.1, @L1.R1(constants.%T) [symbolic = %specific_impl_fn.loc10_4.2 (constants.%specific_impl_fn.f8ac37.1)] +// CHECK:STDOUT: %bound_method.loc10_8: = bound_method %x.ref, %specific_impl_fn.loc10_4.1 +// CHECK:STDOUT: %.loc10_8: init %empty_tuple.type = call %bound_method.loc10_8(%x.ref) +// CHECK:STDOUT: %p.ref: @Simple4.%ptr.loc9_30.1 (%ptr.5db4e7.1) = name_ref p, %p +// CHECK:STDOUT: %.loc11_4.1: ref @Simple4.%T.binding.as_type (%T.binding.as_type) = deref %p.ref +// CHECK:STDOUT: %S1.ref: %L1.assoc_type = name_ref S1, @L1.%assoc1 [concrete = constants.%assoc1] +// CHECK:STDOUT: %impl.elem1.loc11_4.1: @Simple4.%.loc11_4.2 (%.45c8db.1) = impl_witness_access constants.%L1.lookup_impl_witness.497b38.1, element1 [symbolic = %impl.elem1.loc11_4.2 (constants.%impl.elem1.c3a14a.1)] +// CHECK:STDOUT: %bound_method.loc11_4: = bound_method %.loc11_4.1, %impl.elem1.loc11_4.1 +// CHECK:STDOUT: %specific_impl_fn.loc11_4.1: = specific_impl_function %impl.elem1.loc11_4.1, @L1.S1(constants.%T) [symbolic = %specific_impl_fn.loc11_4.2 (constants.%specific_impl_fn.c2ec1e.1)] +// CHECK:STDOUT: %bound_method.loc11_9: = bound_method %.loc11_4.1, %specific_impl_fn.loc11_4.1 +// CHECK:STDOUT: %.loc11_9: init %empty_tuple.type = call %bound_method.loc11_9(%.loc11_4.1) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Compound4(%V.loc15_14.2: %L1.type) { +// CHECK:STDOUT: %V.loc15_14.1: %L1.type = symbolic_binding V, 0 [symbolic = %V.loc15_14.1 (constants.%V)] +// CHECK:STDOUT: %V.binding.as_type: type = symbolic_binding_type V, 0, %V.loc15_14.1 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] +// CHECK:STDOUT: %pattern_type.loc15_22: type = pattern_type %V.binding.as_type [symbolic = %pattern_type.loc15_22 (constants.%pattern_type.510a66.3)] +// CHECK:STDOUT: %ptr.loc15_32.1: type = ptr_type %V.binding.as_type [symbolic = %ptr.loc15_32.1 (constants.%ptr.5db4e7.2)] +// CHECK:STDOUT: %pattern_type.loc15_28: type = pattern_type %ptr.loc15_32.1 [symbolic = %pattern_type.loc15_28 (constants.%pattern_type.f1f60b.2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete.loc15_23: = require_complete_type %V.binding.as_type [symbolic = %require_complete.loc15_23 (constants.%require_complete.b98a62.2)] +// CHECK:STDOUT: %require_complete.loc15_29: = require_complete_type %ptr.loc15_32.1 [symbolic = %require_complete.loc15_29 (constants.%require_complete.80837b.2)] +// CHECK:STDOUT: %L1.lookup_impl_witness: = lookup_impl_witness %V.loc15_14.1, @L1 [symbolic = %L1.lookup_impl_witness (constants.%L1.lookup_impl_witness.497b38.2)] +// CHECK:STDOUT: %.loc16_4: type = fn_type_with_self_type constants.%L1.R1.type, %V.loc15_14.1 [symbolic = %.loc16_4 (constants.%.2c3978.2)] +// CHECK:STDOUT: %impl.elem0.loc16_4.2: @Compound4.%.loc16_4 (%.2c3978.2) = impl_witness_access %L1.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc16_4.2 (constants.%impl.elem0.d3a613.2)] +// CHECK:STDOUT: %specific_impl_fn.loc16_4.2: = specific_impl_function %impl.elem0.loc16_4.2, @L1.R1(%V.loc15_14.1) [symbolic = %specific_impl_fn.loc16_4.2 (constants.%specific_impl_fn.f8ac37.2)] +// CHECK:STDOUT: %.loc17_4.2: type = fn_type_with_self_type constants.%L1.S1.type, %V.loc15_14.1 [symbolic = %.loc17_4.2 (constants.%.45c8db.2)] +// CHECK:STDOUT: %impl.elem1.loc17_4.2: @Compound4.%.loc17_4.2 (%.45c8db.2) = impl_witness_access %L1.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc17_4.2 (constants.%impl.elem1.c3a14a.2)] +// CHECK:STDOUT: %specific_impl_fn.loc17_4.2: = specific_impl_function %impl.elem1.loc17_4.2, @L1.S1(%V.loc15_14.1) [symbolic = %specific_impl_fn.loc17_4.2 (constants.%specific_impl_fn.c2ec1e.2)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%y.param: @Compound4.%V.binding.as_type (%V.binding.as_type), %p.param: @Compound4.%ptr.loc15_32.1 (%ptr.5db4e7.2)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %y.ref: @Compound4.%V.binding.as_type (%V.binding.as_type) = name_ref y, %y +// CHECK:STDOUT: %L1.ref.loc16: type = name_ref L1, file.%L1.decl [concrete = constants.%L1.type] +// CHECK:STDOUT: %R1.ref: %L1.assoc_type = name_ref R1, @L1.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %impl.elem0.loc16_4.1: @Compound4.%.loc16_4 (%.2c3978.2) = impl_witness_access constants.%L1.lookup_impl_witness.497b38.2, element0 [symbolic = %impl.elem0.loc16_4.2 (constants.%impl.elem0.d3a613.2)] +// CHECK:STDOUT: %bound_method.loc16_4: = bound_method %y.ref, %impl.elem0.loc16_4.1 +// CHECK:STDOUT: %specific_impl_fn.loc16_4.1: = specific_impl_function %impl.elem0.loc16_4.1, @L1.R1(constants.%V) [symbolic = %specific_impl_fn.loc16_4.2 (constants.%specific_impl_fn.f8ac37.2)] +// CHECK:STDOUT: %bound_method.loc16_13: = bound_method %y.ref, %specific_impl_fn.loc16_4.1 +// CHECK:STDOUT: %.loc16_13: init %empty_tuple.type = call %bound_method.loc16_13(%y.ref) +// CHECK:STDOUT: %p.ref: @Compound4.%ptr.loc15_32.1 (%ptr.5db4e7.2) = name_ref p, %p +// CHECK:STDOUT: %L1.ref.loc17: type = name_ref L1, file.%L1.decl [concrete = constants.%L1.type] +// CHECK:STDOUT: %S1.ref: %L1.assoc_type = name_ref S1, @L1.%assoc1 [concrete = constants.%assoc1] +// CHECK:STDOUT: %.loc17_4.1: ref @Compound4.%V.binding.as_type (%V.binding.as_type) = deref %p.ref +// CHECK:STDOUT: %impl.elem1.loc17_4.1: @Compound4.%.loc17_4.2 (%.45c8db.2) = impl_witness_access constants.%L1.lookup_impl_witness.497b38.2, element1 [symbolic = %impl.elem1.loc17_4.2 (constants.%impl.elem1.c3a14a.2)] +// CHECK:STDOUT: %bound_method.loc17_4: = bound_method %.loc17_4.1, %impl.elem1.loc17_4.1 +// CHECK:STDOUT: %specific_impl_fn.loc17_4.1: = specific_impl_function %impl.elem1.loc17_4.1, @L1.S1(constants.%V) [symbolic = %specific_impl_fn.loc17_4.2 (constants.%specific_impl_fn.c2ec1e.2)] +// CHECK:STDOUT: %bound_method.loc17_14: = bound_method %.loc17_4.1, %specific_impl_fn.loc17_4.1 +// CHECK:STDOUT: %.loc17_14: init %empty_tuple.type = call %bound_method.loc17_14(%.loc17_4.1) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L1.R1(constants.%Self) { +// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.510a66.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L1.S1(constants.%Self) { +// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.510a66.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Simple4(constants.%T) { +// CHECK:STDOUT: %T.loc9_12.1 => constants.%T +// CHECK:STDOUT: %T.binding.as_type => constants.%T.binding.as_type +// CHECK:STDOUT: %pattern_type.loc9_20 => constants.%pattern_type.510a66.2 +// CHECK:STDOUT: %ptr.loc9_30.1 => constants.%ptr.5db4e7.1 +// CHECK:STDOUT: %pattern_type.loc9_26 => constants.%pattern_type.f1f60b.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L1.R1(constants.%T) { +// CHECK:STDOUT: %Self => constants.%T +// CHECK:STDOUT: %Self.binding.as_type => constants.%T.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.510a66.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L1.S1(constants.%T) { +// CHECK:STDOUT: %Self => constants.%T +// CHECK:STDOUT: %Self.binding.as_type => constants.%T.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.510a66.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Compound4(constants.%V) { +// CHECK:STDOUT: %V.loc15_14.1 => constants.%V +// CHECK:STDOUT: %V.binding.as_type => constants.%V.binding.as_type +// CHECK:STDOUT: %pattern_type.loc15_22 => constants.%pattern_type.510a66.3 +// CHECK:STDOUT: %ptr.loc15_32.1 => constants.%ptr.5db4e7.2 +// CHECK:STDOUT: %pattern_type.loc15_28 => constants.%pattern_type.f1f60b.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L1.R1(constants.%V) { +// CHECK:STDOUT: %Self => constants.%V +// CHECK:STDOUT: %Self.binding.as_type => constants.%V.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.510a66.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L1.S1(constants.%V) { +// CHECK:STDOUT: %Self => constants.%V +// CHECK:STDOUT: %Self.binding.as_type => constants.%V.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.510a66.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- instance_addr.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %L1.type: type = facet_type <@L1> [concrete] +// CHECK:STDOUT: %Self: %L1.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic] +// CHECK:STDOUT: %pattern_type.510a66.1: type = pattern_type %Self.binding.as_type [symbolic] +// CHECK:STDOUT: %L1.R1.type: type = fn_type @L1.R1 [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %L1.R1: %L1.R1.type = struct_value () [concrete] +// CHECK:STDOUT: %L1.assoc_type: type = assoc_entity_type @L1 [concrete] +// CHECK:STDOUT: %assoc0: %L1.assoc_type = assoc_entity element0, @L1.%L1.R1.decl [concrete] // CHECK:STDOUT: %ptr.5db4e7.1: type = ptr_type %Self.binding.as_type [symbolic] // CHECK:STDOUT: %pattern_type.f1f60b.1: type = pattern_type %ptr.5db4e7.1 [symbolic] // CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] @@ -974,6 +1347,211 @@ fn Works() { // CHECK:STDOUT: %L2.R2: %L2.R2.type = struct_value () [concrete] // CHECK:STDOUT: %L2.assoc_type: type = assoc_entity_type @L2 [concrete] // CHECK:STDOUT: %assoc0: %L2.assoc_type = assoc_entity element0, @L2.%L2.R2.decl [concrete] +// CHECK:STDOUT: %L2.S2.type: type = fn_type @L2.S2 [concrete] +// CHECK:STDOUT: %L2.S2: %L2.S2.type = struct_value () [concrete] +// CHECK:STDOUT: %assoc1: %L2.assoc_type = assoc_entity element1, @L2.%L2.S2.decl [concrete] +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %T: %L2.type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %pattern_type.38f: type = pattern_type %L2.type [concrete] +// CHECK:STDOUT: %Simple5.type: type = fn_type @Simple5 [concrete] +// CHECK:STDOUT: %Simple5: %Simple5.type = struct_value () [concrete] +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T [symbolic] +// CHECK:STDOUT: %L2.lookup_impl_witness: = lookup_impl_witness %T, @L2 [symbolic] +// CHECK:STDOUT: %.6fc: type = fn_type_with_self_type %L2.R2.type, %T [symbolic] +// CHECK:STDOUT: %impl.elem0: %.6fc = impl_witness_access %L2.lookup_impl_witness, element0 [symbolic] +// CHECK:STDOUT: %pattern_type.c87c75.2: type = pattern_type %T.binding.as_type [symbolic] +// CHECK:STDOUT: %specific_impl_fn.a65: = specific_impl_function %impl.elem0, @L2.R2(%T) [symbolic] +// CHECK:STDOUT: %.0b4: type = fn_type_with_self_type %L2.S2.type, %T [symbolic] +// CHECK:STDOUT: %impl.elem1: %.0b4 = impl_witness_access %L2.lookup_impl_witness, element1 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.b7b: = specific_impl_function %impl.elem1, @L2.S2(%T) [symbolic] +// CHECK:STDOUT: %V: %L2.type = symbolic_binding V, 0 [symbolic] +// CHECK:STDOUT: %Compound5.type: type = fn_type @Compound5 [concrete] +// CHECK:STDOUT: %Compound5: %Compound5.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .L2 = %L2.decl +// CHECK:STDOUT: .Simple5 = %Simple5.decl +// CHECK:STDOUT: .Compound5 = %Compound5.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %L2.decl: type = interface_decl @L2 [concrete = constants.%L2.type] {} {} +// CHECK:STDOUT: %Simple5.decl: %Simple5.type = fn_decl @Simple5 [concrete = constants.%Simple5] { +// CHECK:STDOUT: %T.patt: %pattern_type.38f = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc10: type = splice_block %L2.ref [concrete = constants.%L2.type] { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %L2.ref: type = name_ref L2, file.%L2.decl [concrete = constants.%L2.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.loc10_12.2: %L2.type = symbolic_binding T, 0 [symbolic = %T.loc10_12.1 (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %Compound5.decl: %Compound5.type = fn_decl @Compound5 [concrete = constants.%Compound5] { +// CHECK:STDOUT: %V.patt: %pattern_type.38f = symbolic_binding_pattern V, 0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc30: type = splice_block %L2.ref.loc30 [concrete = constants.%L2.type] { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %L2.ref.loc30: type = name_ref L2, file.%L2.decl [concrete = constants.%L2.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %V.loc30_14.2: %L2.type = symbolic_binding V, 0 [symbolic = %V.loc30_14.1 (constants.%V)] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @L2 { +// CHECK:STDOUT: %Self: %L2.type = symbolic_binding Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %L2.R2.decl: %L2.R2.type = fn_decl @L2.R2 [concrete = constants.%L2.R2] { +// CHECK:STDOUT: %self.patt: @L2.R2.%pattern_type (%pattern_type.c87c75.1) = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @L2.R2.%pattern_type (%pattern_type.c87c75.1) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @L2.R2.%Self.binding.as_type (%Self.binding.as_type) = value_param call_param0 +// CHECK:STDOUT: %.loc5_15.1: type = splice_block %.loc5_15.2 [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] { +// CHECK:STDOUT: %Self.ref: %L2.type = name_ref Self, @L2.%Self [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.ref [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %.loc5_15.2: type = converted %Self.ref, %Self.as_type [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @L2.R2.%Self.binding.as_type (%Self.binding.as_type) = value_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc0: %L2.assoc_type = assoc_entity element0, %L2.R2.decl [concrete = constants.%assoc0] +// CHECK:STDOUT: %L2.S2.decl: %L2.S2.type = fn_decl @L2.S2 [concrete = constants.%L2.S2] { +// CHECK:STDOUT: %self.patt: @L2.S2.%pattern_type (%pattern_type.c87c75.1) = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @L2.S2.%pattern_type (%pattern_type.c87c75.1) = ref_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: ref @L2.S2.%Self.binding.as_type (%Self.binding.as_type) = ref_param call_param0 +// CHECK:STDOUT: %.loc6_19.1: type = splice_block %.loc6_19.2 [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] { +// CHECK:STDOUT: %Self.ref: %L2.type = name_ref Self, @L2.%Self [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.ref [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %.loc6_19.2: type = converted %Self.ref, %Self.as_type [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: ref @L2.S2.%Self.binding.as_type (%Self.binding.as_type) = ref_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc1: %L2.assoc_type = assoc_entity element1, %L2.S2.decl [concrete = constants.%assoc1] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .R2 = %assoc0 +// CHECK:STDOUT: .S2 = %assoc1 +// CHECK:STDOUT: witness = (%L2.R2.decl, %L2.S2.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @L2.R2(@L2.%Self: %L2.type) { +// CHECK:STDOUT: %Self: %L2.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %Self.binding.as_type [symbolic = %pattern_type (constants.%pattern_type.c87c75.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @L2.R2.%Self.binding.as_type (%Self.binding.as_type)); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @L2.S2(@L2.%Self: %L2.type) { +// CHECK:STDOUT: %Self: %L2.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %Self.binding.as_type [symbolic = %pattern_type (constants.%pattern_type.c87c75.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @L2.S2.%Self.binding.as_type (%Self.binding.as_type)); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Simple5(%T.loc10_12.2: %L2.type) { +// CHECK:STDOUT: %T.loc10_12.1: %L2.type = symbolic_binding T, 0 [symbolic = %T.loc10_12.1 (constants.%T)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T.loc10_12.1 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %L2.lookup_impl_witness: = lookup_impl_witness %T.loc10_12.1, @L2 [symbolic = %L2.lookup_impl_witness (constants.%L2.lookup_impl_witness)] +// CHECK:STDOUT: %.loc18_4.2: type = fn_type_with_self_type constants.%L2.R2.type, %T.loc10_12.1 [symbolic = %.loc18_4.2 (constants.%.6fc)] +// CHECK:STDOUT: %impl.elem0.loc18_4.2: @Simple5.%.loc18_4.2 (%.6fc) = impl_witness_access %L2.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %specific_impl_fn.loc18_4.2: = specific_impl_function %impl.elem0.loc18_4.2, @L2.R2(%T.loc10_12.1) [symbolic = %specific_impl_fn.loc18_4.2 (constants.%specific_impl_fn.a65)] +// CHECK:STDOUT: %.loc26_4.2: type = fn_type_with_self_type constants.%L2.S2.type, %T.loc10_12.1 [symbolic = %.loc26_4.2 (constants.%.0b4)] +// CHECK:STDOUT: %impl.elem1.loc26_4.2: @Simple5.%.loc26_4.2 (%.0b4) = impl_witness_access %L2.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc26_4.2 (constants.%impl.elem1)] +// CHECK:STDOUT: %specific_impl_fn.loc26_4.2: = specific_impl_function %impl.elem1.loc26_4.2, @L2.S2(%T.loc10_12.1) [symbolic = %specific_impl_fn.loc26_4.2 (constants.%specific_impl_fn.b7b)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %T.ref.loc18: %L2.type = name_ref T, %T.loc10_12.2 [symbolic = %T.loc10_12.1 (constants.%T)] +// CHECK:STDOUT: %R2.ref: %L2.assoc_type = name_ref R2, @L2.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %T.as_type.loc18: type = facet_access_type %T.ref.loc18 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %.loc18_4.1: type = converted %T.ref.loc18, %T.as_type.loc18 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %impl.elem0.loc18_4.1: @Simple5.%.loc18_4.2 (%.6fc) = impl_witness_access constants.%L2.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %specific_impl_fn.loc18_4.1: = specific_impl_function %impl.elem0.loc18_4.1, @L2.R2(constants.%T) [symbolic = %specific_impl_fn.loc18_4.2 (constants.%specific_impl_fn.a65)] +// CHECK:STDOUT: %.loc18_8: init %empty_tuple.type = call %specific_impl_fn.loc18_4.1() [concrete = ] +// CHECK:STDOUT: %T.ref.loc26: %L2.type = name_ref T, %T.loc10_12.2 [symbolic = %T.loc10_12.1 (constants.%T)] +// CHECK:STDOUT: %S2.ref: %L2.assoc_type = name_ref S2, @L2.%assoc1 [concrete = constants.%assoc1] +// CHECK:STDOUT: %T.as_type.loc26: type = facet_access_type %T.ref.loc26 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %.loc26_4.1: type = converted %T.ref.loc26, %T.as_type.loc26 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %impl.elem1.loc26_4.1: @Simple5.%.loc26_4.2 (%.0b4) = impl_witness_access constants.%L2.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc26_4.2 (constants.%impl.elem1)] +// CHECK:STDOUT: %specific_impl_fn.loc26_4.1: = specific_impl_function %impl.elem1.loc26_4.1, @L2.S2(constants.%T) [symbolic = %specific_impl_fn.loc26_4.2 (constants.%specific_impl_fn.b7b)] +// CHECK:STDOUT: %.loc26_8: init %empty_tuple.type = call %specific_impl_fn.loc26_4.1() [concrete = ] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Compound5(%V.loc30_14.2: %L2.type) { +// CHECK:STDOUT: %V.loc30_14.1: %L2.type = symbolic_binding V, 0 [symbolic = %V.loc30_14.1 (constants.%V)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %V.ref.loc35: %L2.type = name_ref V, %V.loc30_14.2 [symbolic = %V.loc30_14.1 (constants.%V)] +// CHECK:STDOUT: %L2.ref.loc35: type = name_ref L2, file.%L2.decl [concrete = constants.%L2.type] +// CHECK:STDOUT: %R2.ref: %L2.assoc_type = name_ref R2, @L2.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %V.ref.loc40: %L2.type = name_ref V, %V.loc30_14.2 [symbolic = %V.loc30_14.1 (constants.%V)] +// CHECK:STDOUT: %L2.ref.loc40: type = name_ref L2, file.%L2.decl [concrete = constants.%L2.type] +// CHECK:STDOUT: %S2.ref: %L2.assoc_type = name_ref S2, @L2.%assoc1 [concrete = constants.%assoc1] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L2.R2(constants.%Self) { +// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.c87c75.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L2.S2(constants.%Self) { +// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.c87c75.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Simple5(constants.%T) { +// CHECK:STDOUT: %T.loc10_12.1 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L2.R2(constants.%T) { +// CHECK:STDOUT: %Self => constants.%T +// CHECK:STDOUT: %Self.binding.as_type => constants.%T.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.c87c75.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L2.S2(constants.%T) { +// CHECK:STDOUT: %Self => constants.%T +// CHECK:STDOUT: %Self.binding.as_type => constants.%T.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.c87c75.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Compound5(constants.%V) { +// CHECK:STDOUT: %V.loc30_14.1 => constants.%V +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_interface_instance_caller_not_addr.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %L2.type: type = facet_type <@L2> [concrete] +// CHECK:STDOUT: %Self: %L2.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic] +// CHECK:STDOUT: %pattern_type.c87c75.1: type = pattern_type %Self.binding.as_type [symbolic] +// CHECK:STDOUT: %L2.R2.type: type = fn_type @L2.R2 [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %L2.R2: %L2.R2.type = struct_value () [concrete] +// CHECK:STDOUT: %L2.assoc_type: type = assoc_entity_type @L2 [concrete] +// CHECK:STDOUT: %assoc0: %L2.assoc_type = assoc_entity element0, @L2.%L2.R2.decl [concrete] // CHECK:STDOUT: %ptr.707d07.1: type = ptr_type %Self.binding.as_type [symbolic] // CHECK:STDOUT: %pattern_type.2fa31b.1: type = pattern_type %ptr.707d07.1 [symbolic] // CHECK:STDOUT: %pattern_type.f6d: type = pattern_type auto [concrete] diff --git a/toolchain/check/testdata/interface/compound_member_access_addr.carbon b/toolchain/check/testdata/interface/compound_member_access_addr.carbon new file mode 100644 index 000000000000..336b19470e4a --- /dev/null +++ b/toolchain/check/testdata/interface/compound_member_access_addr.carbon @@ -0,0 +1,1502 @@ +// 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 +// 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/compound_member_access_addr.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interface/compound_member_access_addr.carbon + +// --- associated_constant.carbon +library "[[@TEST_NAME]]"; + +interface J { + let U:! type; +} + +// Simple member access. +fn Simple1(T:! J, S:! T.U) {} + +// This should be equivalent to `Simple1` above, but using compound member access. +fn Compound1(V:! J, W:! V.(J.U)) {} + +// --- non_instance.carbon +library "[[@TEST_NAME]]"; + +interface K1 { + fn Q1(); +} + +// Simple member access. +fn Simple2(T:! K1) { + T.Q1(); +} + +// This should be equivalent to `Simple2` above, but using compound member access. +fn Compound2(V:! K1) { + V.(K1.Q1)(); +} + +// --- fail_caller_instance_interface_not.carbon +library "[[@TEST_NAME]]"; + +interface K2 { + fn Q2(); +} + +// Simple member access allows this. +fn Simple3(T:! K2, x: T) { + x.Q2(); +} + +// Compound member access does not. It tries to convert `y` to `K2`, but only +// its type `V` can. +fn Compound3(V:! K2, y: V) { + // CHECK:STDERR: fail_caller_instance_interface_not.carbon:[[@LINE+7]]:3: error: cannot implicitly convert non-type value of type `V` into type implementing `K2` [ConversionFailureNonTypeToFacet] + // CHECK:STDERR: y.(K2.Q2)(); + // CHECK:STDERR: ^~~~~~~~~ + // CHECK:STDERR: fail_caller_instance_interface_not.carbon:[[@LINE+4]]:3: note: type `V` does not implement interface `Core.ImplicitAs(K2)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: y.(K2.Q2)(); + // CHECK:STDERR: ^~~~~~~~~ + // CHECK:STDERR: + y.(K2.Q2)(); +} + +// --- instance.carbon +library "[[@TEST_NAME]]"; + +interface L1 { + fn R1[self: Self](); + fn S1[ref self: Self](); +} + +// Simple member access. +fn Simple4(T:! L1, x: T, p: T*) { + x.R1(); + p->S1(); +} + +// This should be equivalent to `Simple4` above, but using compound member access. +fn Compound4(V:! L1, y: V, p: V*) { + y.(L1.R1)(); + p->(L1.S1)(); +} + +// --- fail_interface_instance_caller_not.carbon + +library "[[@TEST_NAME]]"; + +interface L2 { + fn R2[self: Self](); + fn S2[ref self: Self](); +} + +// Simple member access. Fails since calling an instance method without an object. +fn Simple5(T:! L2) { + // CHECK:STDERR: fail_interface_instance_caller_not.carbon:[[@LINE+7]]:3: error: missing object argument in method call [MissingObjectInMethodCall] + // CHECK:STDERR: T.R2(); + // CHECK:STDERR: ^~~~~~ + // CHECK:STDERR: fail_interface_instance_caller_not.carbon:[[@LINE-9]]:3: note: calling function declared here [InCallToFunction] + // CHECK:STDERR: fn R2[self: Self](); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + T.R2(); + // CHECK:STDERR: fail_interface_instance_caller_not.carbon:[[@LINE+7]]:3: error: missing object argument in method call [MissingObjectInMethodCall] + // CHECK:STDERR: T.S2(); + // CHECK:STDERR: ^~~~~~ + // CHECK:STDERR: fail_interface_instance_caller_not.carbon:[[@LINE-16]]:3: note: calling function declared here [InCallToFunction] + // CHECK:STDERR: fn S2[ref self: Self](); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + T.S2(); +} + +// TODO: Expected to fail in the same way as `Simple5`. +fn Compound5(V:! L2) { + // CHECK:STDERR: fail_interface_instance_caller_not.carbon:[[@LINE+4]]:3: error: cannot access member of interface `L2` in type `L2` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: V.(L2.R2)(); + // CHECK:STDERR: ^~~~~~~~~ + // CHECK:STDERR: + V.(L2.R2)(); + // CHECK:STDERR: fail_interface_instance_caller_not.carbon:[[@LINE+4]]:3: error: cannot access member of interface `L2` in type `L2` that does not implement that interface [MissingImplInMemberAccess] + // CHECK:STDERR: V.(L2.S2)(); + // CHECK:STDERR: ^~~~~~~~~ + // CHECK:STDERR: + V.(L2.S2)(); +} + +// --- fail_combine_non_instance.carbon +library "[[@TEST_NAME]]"; + +interface A { + fn G(); +} + +class C {} +impl C as A { + fn G() {} +} + +// Since `A.G` is a non-instance method, compound member access may only be +// used with a type, not an instance. +fn Fails() { + // CHECK:STDERR: fail_combine_non_instance.carbon:[[@LINE+7]]:3: error: cannot implicitly convert non-type value of type `C` into type implementing `A` [ConversionFailureNonTypeToFacet] + // CHECK:STDERR: ({} as C).((A & A).G)(); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_combine_non_instance.carbon:[[@LINE+4]]:3: note: type `C` does not implement interface `Core.ImplicitAs(A)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: ({} as C).((A & A).G)(); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + ({} as C).((A & A).G)(); + // CHECK:STDERR: fail_combine_non_instance.carbon:[[@LINE+7]]:3: error: cannot implicitly convert non-type value of type `C` into type implementing `A` [ConversionFailureNonTypeToFacet] + // CHECK:STDERR: (({} as C) as (C as (A & A))).((A & A).G)(); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_combine_non_instance.carbon:[[@LINE+4]]:3: note: type `C` does not implement interface `Core.ImplicitAs(A)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: (({} as C) as (C as (A & A))).((A & A).G)(); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + (({} as C) as (C as (A & A))).((A & A).G)(); + // CHECK:STDERR: fail_combine_non_instance.carbon:[[@LINE+7]]:3: error: cannot implicitly convert non-type value of type `C` into type implementing `A` [ConversionFailureNonTypeToFacet] + // CHECK:STDERR: (({} as C) as (C as (A & A))).(A.G)(); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: fail_combine_non_instance.carbon:[[@LINE+4]]:3: note: type `C` does not implement interface `Core.ImplicitAs(A)` [MissingImplInMemberAccessNote] + // CHECK:STDERR: (({} as C) as (C as (A & A))).(A.G)(); + // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // CHECK:STDERR: + (({} as C) as (C as (A & A))).(A.G)(); +} + +// --- allowed_combine_non_instance.carbon +library "[[@TEST_NAME]]"; + +interface A { + fn G(); +} + +class C {} +impl C as A { + fn G() {} +} + +fn Works() { + C.((A & A).G)(); + (C as (A & A)).((A & A).G)(); + (C as (A & A)).(A.G)(); +} + +// CHECK:STDOUT: --- associated_constant.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %J.type: type = facet_type <@J> [concrete] +// CHECK:STDOUT: %Self: %J.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %J.assoc_type: type = assoc_entity_type @J [concrete] +// CHECK:STDOUT: %assoc0: %J.assoc_type = assoc_entity element0, @J.%U [concrete] +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %T: %J.type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %pattern_type.84b: type = pattern_type %J.type [concrete] +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T [symbolic] +// CHECK:STDOUT: %J.lookup_impl_witness.cd2552.1: = lookup_impl_witness %T, @J [symbolic] +// CHECK:STDOUT: %impl.elem0.fa9e71.1: type = impl_witness_access %J.lookup_impl_witness.cd2552.1, element0 [symbolic] +// CHECK:STDOUT: %S: %impl.elem0.fa9e71.1 = symbolic_binding S, 1 [symbolic] +// CHECK:STDOUT: %pattern_type.345548.1: type = pattern_type %impl.elem0.fa9e71.1 [symbolic] +// CHECK:STDOUT: %Simple1.type: type = fn_type @Simple1 [concrete] +// CHECK:STDOUT: %Simple1: %Simple1.type = struct_value () [concrete] +// CHECK:STDOUT: %V: %J.type = symbolic_binding V, 0 [symbolic] +// CHECK:STDOUT: %J.lookup_impl_witness.cd2552.2: = lookup_impl_witness %V, @J [symbolic] +// CHECK:STDOUT: %impl.elem0.fa9e71.2: type = impl_witness_access %J.lookup_impl_witness.cd2552.2, element0 [symbolic] +// CHECK:STDOUT: %W: %impl.elem0.fa9e71.2 = symbolic_binding W, 1 [symbolic] +// CHECK:STDOUT: %pattern_type.345548.2: type = pattern_type %impl.elem0.fa9e71.2 [symbolic] +// CHECK:STDOUT: %Compound1.type: type = fn_type @Compound1 [concrete] +// CHECK:STDOUT: %Compound1: %Compound1.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .J = %J.decl +// CHECK:STDOUT: .Simple1 = %Simple1.decl +// CHECK:STDOUT: .Compound1 = %Compound1.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %J.decl: type = interface_decl @J [concrete = constants.%J.type] {} {} +// CHECK:STDOUT: %Simple1.decl: %Simple1.type = fn_decl @Simple1 [concrete = constants.%Simple1] { +// CHECK:STDOUT: %T.patt: %pattern_type.84b = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %S.patt: @Simple1.%pattern_type (%pattern_type.345548.1) = symbolic_binding_pattern S, 1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc8_16: type = splice_block %J.ref [concrete = constants.%J.type] { +// CHECK:STDOUT: %.Self.2: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.loc8_12.2: %J.type = symbolic_binding T, 0 [symbolic = %T.loc8_12.1 (constants.%T)] +// CHECK:STDOUT: %.loc8_24.1: type = splice_block %impl.elem0.loc8_24.2 [symbolic = %impl.elem0.loc8_24.1 (constants.%impl.elem0.fa9e71.1)] { +// CHECK:STDOUT: %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %T.ref: %J.type = name_ref T, %T.loc8_12.2 [symbolic = %T.loc8_12.1 (constants.%T)] +// CHECK:STDOUT: %U.ref: %J.assoc_type = name_ref U, @U.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T.ref [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %.loc8_24.2: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %impl.elem0.loc8_24.2: type = impl_witness_access constants.%J.lookup_impl_witness.cd2552.1, element0 [symbolic = %impl.elem0.loc8_24.1 (constants.%impl.elem0.fa9e71.1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %S.loc8_19.2: @Simple1.%impl.elem0.loc8_24.1 (%impl.elem0.fa9e71.1) = symbolic_binding S, 1 [symbolic = %S.loc8_19.1 (constants.%S)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %Compound1.decl: %Compound1.type = fn_decl @Compound1 [concrete = constants.%Compound1] { +// CHECK:STDOUT: %V.patt: %pattern_type.84b = symbolic_binding_pattern V, 0 [concrete] +// CHECK:STDOUT: %W.patt: @Compound1.%pattern_type (%pattern_type.345548.2) = symbolic_binding_pattern W, 1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc11_18: type = splice_block %J.ref.loc11_18 [concrete = constants.%J.type] { +// CHECK:STDOUT: %.Self.2: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %J.ref.loc11_18: type = name_ref J, file.%J.decl [concrete = constants.%J.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %V.loc11_14.2: %J.type = symbolic_binding V, 0 [symbolic = %V.loc11_14.1 (constants.%V)] +// CHECK:STDOUT: %.loc11_26: type = splice_block %impl.elem0.loc11_26.2 [symbolic = %impl.elem0.loc11_26.1 (constants.%impl.elem0.fa9e71.2)] { +// CHECK:STDOUT: %.Self.1: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %V.ref: %J.type = name_ref V, %V.loc11_14.2 [symbolic = %V.loc11_14.1 (constants.%V)] +// CHECK:STDOUT: %J.ref.loc11_28: type = name_ref J, file.%J.decl [concrete = constants.%J.type] +// CHECK:STDOUT: %U.ref: %J.assoc_type = name_ref U, @U.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %impl.elem0.loc11_26.2: type = impl_witness_access constants.%J.lookup_impl_witness.cd2552.2, element0 [symbolic = %impl.elem0.loc11_26.1 (constants.%impl.elem0.fa9e71.2)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %W.loc11_21.2: @Compound1.%impl.elem0.loc11_26.1 (%impl.elem0.fa9e71.2) = symbolic_binding W, 1 [symbolic = %W.loc11_21.1 (constants.%W)] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @J { +// CHECK:STDOUT: %Self: %J.type = symbolic_binding Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %U: type = assoc_const_decl @U [concrete] { +// CHECK:STDOUT: %assoc0: %J.assoc_type = assoc_entity element0, @J.%U [concrete = constants.%assoc0] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .U = @U.%assoc0 +// CHECK:STDOUT: witness = (%U) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic assoc_const @U(@J.%Self: %J.type) { +// CHECK:STDOUT: assoc_const U:! type; +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Simple1(%T.loc8_12.2: %J.type, %S.loc8_19.2: @Simple1.%impl.elem0.loc8_24.1 (%impl.elem0.fa9e71.1)) { +// CHECK:STDOUT: %T.loc8_12.1: %J.type = symbolic_binding T, 0 [symbolic = %T.loc8_12.1 (constants.%T)] +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T.loc8_12.1 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %J.lookup_impl_witness: = lookup_impl_witness %T.loc8_12.1, @J [symbolic = %J.lookup_impl_witness (constants.%J.lookup_impl_witness.cd2552.1)] +// CHECK:STDOUT: %impl.elem0.loc8_24.1: type = impl_witness_access %J.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc8_24.1 (constants.%impl.elem0.fa9e71.1)] +// CHECK:STDOUT: %S.loc8_19.1: @Simple1.%impl.elem0.loc8_24.1 (%impl.elem0.fa9e71.1) = symbolic_binding S, 1 [symbolic = %S.loc8_19.1 (constants.%S)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %impl.elem0.loc8_24.1 [symbolic = %pattern_type (constants.%pattern_type.345548.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Compound1(%V.loc11_14.2: %J.type, %W.loc11_21.2: @Compound1.%impl.elem0.loc11_26.1 (%impl.elem0.fa9e71.2)) { +// CHECK:STDOUT: %V.loc11_14.1: %J.type = symbolic_binding V, 0 [symbolic = %V.loc11_14.1 (constants.%V)] +// CHECK:STDOUT: %J.lookup_impl_witness: = lookup_impl_witness %V.loc11_14.1, @J [symbolic = %J.lookup_impl_witness (constants.%J.lookup_impl_witness.cd2552.2)] +// CHECK:STDOUT: %impl.elem0.loc11_26.1: type = impl_witness_access %J.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc11_26.1 (constants.%impl.elem0.fa9e71.2)] +// CHECK:STDOUT: %W.loc11_21.1: @Compound1.%impl.elem0.loc11_26.1 (%impl.elem0.fa9e71.2) = symbolic_binding W, 1 [symbolic = %W.loc11_21.1 (constants.%W)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %impl.elem0.loc11_26.1 [symbolic = %pattern_type (constants.%pattern_type.345548.2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @U(constants.%Self) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @U(constants.%T) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Simple1(constants.%T, constants.%S) { +// CHECK:STDOUT: %T.loc8_12.1 => constants.%T +// CHECK:STDOUT: %T.binding.as_type => constants.%T.binding.as_type +// CHECK:STDOUT: %J.lookup_impl_witness => constants.%J.lookup_impl_witness.cd2552.1 +// CHECK:STDOUT: %impl.elem0.loc8_24.1 => constants.%impl.elem0.fa9e71.1 +// CHECK:STDOUT: %S.loc8_19.1 => constants.%S +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.345548.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @U(constants.%V) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Compound1(constants.%V, constants.%W) { +// CHECK:STDOUT: %V.loc11_14.1 => constants.%V +// CHECK:STDOUT: %J.lookup_impl_witness => constants.%J.lookup_impl_witness.cd2552.2 +// CHECK:STDOUT: %impl.elem0.loc11_26.1 => constants.%impl.elem0.fa9e71.2 +// CHECK:STDOUT: %W.loc11_21.1 => constants.%W +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.345548.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- non_instance.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %K1.type: type = facet_type <@K1> [concrete] +// CHECK:STDOUT: %Self: %K1.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %K1.Q1.type: type = fn_type @K1.Q1 [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %K1.Q1: %K1.Q1.type = struct_value () [concrete] +// CHECK:STDOUT: %K1.assoc_type: type = assoc_entity_type @K1 [concrete] +// CHECK:STDOUT: %assoc0: %K1.assoc_type = assoc_entity element0, @K1.%K1.Q1.decl [concrete] +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %T: %K1.type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %pattern_type: type = pattern_type %K1.type [concrete] +// CHECK:STDOUT: %Simple2.type: type = fn_type @Simple2 [concrete] +// CHECK:STDOUT: %Simple2: %Simple2.type = struct_value () [concrete] +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T [symbolic] +// CHECK:STDOUT: %K1.lookup_impl_witness.a3a3f1.1: = lookup_impl_witness %T, @K1 [symbolic] +// CHECK:STDOUT: %.48862d.1: type = fn_type_with_self_type %K1.Q1.type, %T [symbolic] +// CHECK:STDOUT: %impl.elem0.33f0bc.1: %.48862d.1 = impl_witness_access %K1.lookup_impl_witness.a3a3f1.1, element0 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.dd96c4.1: = specific_impl_function %impl.elem0.33f0bc.1, @K1.Q1(%T) [symbolic] +// CHECK:STDOUT: %V: %K1.type = symbolic_binding V, 0 [symbolic] +// CHECK:STDOUT: %Compound2.type: type = fn_type @Compound2 [concrete] +// CHECK:STDOUT: %Compound2: %Compound2.type = struct_value () [concrete] +// CHECK:STDOUT: %K1.lookup_impl_witness.a3a3f1.2: = lookup_impl_witness %V, @K1 [symbolic] +// CHECK:STDOUT: %.48862d.2: type = fn_type_with_self_type %K1.Q1.type, %V [symbolic] +// CHECK:STDOUT: %impl.elem0.33f0bc.2: %.48862d.2 = impl_witness_access %K1.lookup_impl_witness.a3a3f1.2, element0 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.dd96c4.2: = specific_impl_function %impl.elem0.33f0bc.2, @K1.Q1(%V) [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .K1 = %K1.decl +// CHECK:STDOUT: .Simple2 = %Simple2.decl +// CHECK:STDOUT: .Compound2 = %Compound2.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %K1.decl: type = interface_decl @K1 [concrete = constants.%K1.type] {} {} +// CHECK:STDOUT: %Simple2.decl: %Simple2.type = fn_decl @Simple2 [concrete = constants.%Simple2] { +// CHECK:STDOUT: %T.patt: %pattern_type = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc8: type = splice_block %K1.ref [concrete = constants.%K1.type] { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %K1.ref: type = name_ref K1, file.%K1.decl [concrete = constants.%K1.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.loc8_12.2: %K1.type = symbolic_binding T, 0 [symbolic = %T.loc8_12.1 (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %Compound2.decl: %Compound2.type = fn_decl @Compound2 [concrete = constants.%Compound2] { +// CHECK:STDOUT: %V.patt: %pattern_type = symbolic_binding_pattern V, 0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc13: type = splice_block %K1.ref.loc13 [concrete = constants.%K1.type] { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %K1.ref.loc13: type = name_ref K1, file.%K1.decl [concrete = constants.%K1.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %V.loc13_14.2: %K1.type = symbolic_binding V, 0 [symbolic = %V.loc13_14.1 (constants.%V)] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @K1 { +// CHECK:STDOUT: %Self: %K1.type = symbolic_binding Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %K1.Q1.decl: %K1.Q1.type = fn_decl @K1.Q1 [concrete = constants.%K1.Q1] {} {} +// CHECK:STDOUT: %assoc0: %K1.assoc_type = assoc_entity element0, %K1.Q1.decl [concrete = constants.%assoc0] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .Q1 = %assoc0 +// CHECK:STDOUT: witness = (%K1.Q1.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @K1.Q1(@K1.%Self: %K1.type) { +// CHECK:STDOUT: fn(); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Simple2(%T.loc8_12.2: %K1.type) { +// CHECK:STDOUT: %T.loc8_12.1: %K1.type = symbolic_binding T, 0 [symbolic = %T.loc8_12.1 (constants.%T)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T.loc8_12.1 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %K1.lookup_impl_witness: = lookup_impl_witness %T.loc8_12.1, @K1 [symbolic = %K1.lookup_impl_witness (constants.%K1.lookup_impl_witness.a3a3f1.1)] +// CHECK:STDOUT: %.loc9_4.2: type = fn_type_with_self_type constants.%K1.Q1.type, %T.loc8_12.1 [symbolic = %.loc9_4.2 (constants.%.48862d.1)] +// CHECK:STDOUT: %impl.elem0.loc9_4.2: @Simple2.%.loc9_4.2 (%.48862d.1) = impl_witness_access %K1.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc9_4.2 (constants.%impl.elem0.33f0bc.1)] +// CHECK:STDOUT: %specific_impl_fn.loc9_4.2: = specific_impl_function %impl.elem0.loc9_4.2, @K1.Q1(%T.loc8_12.1) [symbolic = %specific_impl_fn.loc9_4.2 (constants.%specific_impl_fn.dd96c4.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %T.ref: %K1.type = name_ref T, %T.loc8_12.2 [symbolic = %T.loc8_12.1 (constants.%T)] +// CHECK:STDOUT: %Q1.ref: %K1.assoc_type = name_ref Q1, @K1.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T.ref [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %.loc9_4.1: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %impl.elem0.loc9_4.1: @Simple2.%.loc9_4.2 (%.48862d.1) = impl_witness_access constants.%K1.lookup_impl_witness.a3a3f1.1, element0 [symbolic = %impl.elem0.loc9_4.2 (constants.%impl.elem0.33f0bc.1)] +// CHECK:STDOUT: %specific_impl_fn.loc9_4.1: = specific_impl_function %impl.elem0.loc9_4.1, @K1.Q1(constants.%T) [symbolic = %specific_impl_fn.loc9_4.2 (constants.%specific_impl_fn.dd96c4.1)] +// CHECK:STDOUT: %.loc9_8: init %empty_tuple.type = call %specific_impl_fn.loc9_4.1() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Compound2(%V.loc13_14.2: %K1.type) { +// CHECK:STDOUT: %V.loc13_14.1: %K1.type = symbolic_binding V, 0 [symbolic = %V.loc13_14.1 (constants.%V)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %K1.lookup_impl_witness: = lookup_impl_witness %V.loc13_14.1, @K1 [symbolic = %K1.lookup_impl_witness (constants.%K1.lookup_impl_witness.a3a3f1.2)] +// CHECK:STDOUT: %.loc14_4: type = fn_type_with_self_type constants.%K1.Q1.type, %V.loc13_14.1 [symbolic = %.loc14_4 (constants.%.48862d.2)] +// CHECK:STDOUT: %impl.elem0.loc14_4.2: @Compound2.%.loc14_4 (%.48862d.2) = impl_witness_access %K1.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc14_4.2 (constants.%impl.elem0.33f0bc.2)] +// CHECK:STDOUT: %specific_impl_fn.loc14_4.2: = specific_impl_function %impl.elem0.loc14_4.2, @K1.Q1(%V.loc13_14.1) [symbolic = %specific_impl_fn.loc14_4.2 (constants.%specific_impl_fn.dd96c4.2)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %V.ref: %K1.type = name_ref V, %V.loc13_14.2 [symbolic = %V.loc13_14.1 (constants.%V)] +// CHECK:STDOUT: %K1.ref.loc14: type = name_ref K1, file.%K1.decl [concrete = constants.%K1.type] +// CHECK:STDOUT: %Q1.ref: %K1.assoc_type = name_ref Q1, @K1.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %impl.elem0.loc14_4.1: @Compound2.%.loc14_4 (%.48862d.2) = impl_witness_access constants.%K1.lookup_impl_witness.a3a3f1.2, element0 [symbolic = %impl.elem0.loc14_4.2 (constants.%impl.elem0.33f0bc.2)] +// CHECK:STDOUT: %specific_impl_fn.loc14_4.1: = specific_impl_function %impl.elem0.loc14_4.1, @K1.Q1(constants.%V) [symbolic = %specific_impl_fn.loc14_4.2 (constants.%specific_impl_fn.dd96c4.2)] +// CHECK:STDOUT: %.loc14_13: init %empty_tuple.type = call %specific_impl_fn.loc14_4.1() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @K1.Q1(constants.%Self) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Simple2(constants.%T) { +// CHECK:STDOUT: %T.loc8_12.1 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @K1.Q1(constants.%T) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Compound2(constants.%V) { +// CHECK:STDOUT: %V.loc13_14.1 => constants.%V +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @K1.Q1(constants.%V) {} +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_caller_instance_interface_not.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %K2.type: type = facet_type <@K2> [concrete] +// CHECK:STDOUT: %Self.98c: %K2.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %K2.Q2.type: type = fn_type @K2.Q2 [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %K2.Q2: %K2.Q2.type = struct_value () [concrete] +// CHECK:STDOUT: %K2.assoc_type: type = assoc_entity_type @K2 [concrete] +// CHECK:STDOUT: %assoc0.d67: %K2.assoc_type = assoc_entity element0, @K2.%K2.Q2.decl [concrete] +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %T: %K2.type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %pattern_type.4d9: type = pattern_type %K2.type [concrete] +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T [symbolic] +// CHECK:STDOUT: %pattern_type.91df25.1: type = pattern_type %T.binding.as_type [symbolic] +// CHECK:STDOUT: %Simple3.type: type = fn_type @Simple3 [concrete] +// CHECK:STDOUT: %Simple3: %Simple3.type = struct_value () [concrete] +// CHECK:STDOUT: %require_complete.5fb80b.1: = require_complete_type %T.binding.as_type [symbolic] +// CHECK:STDOUT: %K2.lookup_impl_witness: = lookup_impl_witness %T, @K2 [symbolic] +// CHECK:STDOUT: %.19f: type = fn_type_with_self_type %K2.Q2.type, %T [symbolic] +// CHECK:STDOUT: %impl.elem0: %.19f = impl_witness_access %K2.lookup_impl_witness, element0 [symbolic] +// CHECK:STDOUT: %specific_impl_fn: = specific_impl_function %impl.elem0, @K2.Q2(%T) [symbolic] +// CHECK:STDOUT: %V: %K2.type = symbolic_binding V, 0 [symbolic] +// CHECK:STDOUT: %V.binding.as_type: type = symbolic_binding_type V, 0, %V [symbolic] +// CHECK:STDOUT: %pattern_type.91df25.2: type = pattern_type %V.binding.as_type [symbolic] +// CHECK:STDOUT: %Compound3.type: type = fn_type @Compound3 [concrete] +// CHECK:STDOUT: %Compound3: %Compound3.type = struct_value () [concrete] +// CHECK:STDOUT: %require_complete.5fb80b.2: = require_complete_type %V.binding.as_type [symbolic] +// CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] +// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .K2 = %K2.decl +// CHECK:STDOUT: .Simple3 = %Simple3.decl +// CHECK:STDOUT: .Compound3 = %Compound3.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %K2.decl: type = interface_decl @K2 [concrete = constants.%K2.type] {} {} +// CHECK:STDOUT: %Simple3.decl: %Simple3.type = fn_decl @Simple3 [concrete = constants.%Simple3] { +// CHECK:STDOUT: %T.patt: %pattern_type.4d9 = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %x.patt: @Simple3.%pattern_type (%pattern_type.91df25.1) = value_binding_pattern x [concrete] +// CHECK:STDOUT: %x.param_patt: @Simple3.%pattern_type (%pattern_type.91df25.1) = value_param_pattern %x.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc8_16: type = splice_block %K2.ref [concrete = constants.%K2.type] { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %K2.ref: type = name_ref K2, file.%K2.decl [concrete = constants.%K2.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.loc8_12.2: %K2.type = symbolic_binding T, 0 [symbolic = %T.loc8_12.1 (constants.%T)] +// CHECK:STDOUT: %x.param: @Simple3.%T.binding.as_type (%T.binding.as_type) = value_param call_param0 +// CHECK:STDOUT: %.loc8_23.1: type = splice_block %.loc8_23.2 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] { +// CHECK:STDOUT: %T.ref: %K2.type = name_ref T, %T.loc8_12.2 [symbolic = %T.loc8_12.1 (constants.%T)] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T.ref [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %.loc8_23.2: type = converted %T.ref, %T.as_type [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: @Simple3.%T.binding.as_type (%T.binding.as_type) = value_binding x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %Compound3.decl: %Compound3.type = fn_decl @Compound3 [concrete = constants.%Compound3] { +// CHECK:STDOUT: %V.patt: %pattern_type.4d9 = symbolic_binding_pattern V, 0 [concrete] +// CHECK:STDOUT: %y.patt: @Compound3.%pattern_type (%pattern_type.91df25.2) = value_binding_pattern y [concrete] +// CHECK:STDOUT: %y.param_patt: @Compound3.%pattern_type (%pattern_type.91df25.2) = value_param_pattern %y.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc14_18: type = splice_block %K2.ref.loc14 [concrete = constants.%K2.type] { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %K2.ref.loc14: type = name_ref K2, file.%K2.decl [concrete = constants.%K2.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %V.loc14_14.2: %K2.type = symbolic_binding V, 0 [symbolic = %V.loc14_14.1 (constants.%V)] +// CHECK:STDOUT: %y.param: @Compound3.%V.binding.as_type (%V.binding.as_type) = value_param call_param0 +// CHECK:STDOUT: %.loc14_25.1: type = splice_block %.loc14_25.2 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] { +// CHECK:STDOUT: %V.ref: %K2.type = name_ref V, %V.loc14_14.2 [symbolic = %V.loc14_14.1 (constants.%V)] +// CHECK:STDOUT: %V.as_type: type = facet_access_type %V.ref [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] +// CHECK:STDOUT: %.loc14_25.2: type = converted %V.ref, %V.as_type [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %y: @Compound3.%V.binding.as_type (%V.binding.as_type) = value_binding y, %y.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @K2 { +// CHECK:STDOUT: %Self: %K2.type = symbolic_binding Self, 0 [symbolic = constants.%Self.98c] +// CHECK:STDOUT: %K2.Q2.decl: %K2.Q2.type = fn_decl @K2.Q2 [concrete = constants.%K2.Q2] {} {} +// CHECK:STDOUT: %assoc0: %K2.assoc_type = assoc_entity element0, %K2.Q2.decl [concrete = constants.%assoc0.d67] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .Q2 = %assoc0 +// CHECK:STDOUT: witness = (%K2.Q2.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @K2.Q2(@K2.%Self: %K2.type) { +// CHECK:STDOUT: fn(); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Simple3(%T.loc8_12.2: %K2.type) { +// CHECK:STDOUT: %T.loc8_12.1: %K2.type = symbolic_binding T, 0 [symbolic = %T.loc8_12.1 (constants.%T)] +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T.loc8_12.1 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %T.binding.as_type [symbolic = %pattern_type (constants.%pattern_type.91df25.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type %T.binding.as_type [symbolic = %require_complete (constants.%require_complete.5fb80b.1)] +// CHECK:STDOUT: %K2.lookup_impl_witness: = lookup_impl_witness %T.loc8_12.1, @K2 [symbolic = %K2.lookup_impl_witness (constants.%K2.lookup_impl_witness)] +// CHECK:STDOUT: %.loc9_4: type = fn_type_with_self_type constants.%K2.Q2.type, %T.loc8_12.1 [symbolic = %.loc9_4 (constants.%.19f)] +// CHECK:STDOUT: %impl.elem0.loc9_4.2: @Simple3.%.loc9_4 (%.19f) = impl_witness_access %K2.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc9_4.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %specific_impl_fn.loc9_4.2: = specific_impl_function %impl.elem0.loc9_4.2, @K2.Q2(%T.loc8_12.1) [symbolic = %specific_impl_fn.loc9_4.2 (constants.%specific_impl_fn)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param: @Simple3.%T.binding.as_type (%T.binding.as_type)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %x.ref: @Simple3.%T.binding.as_type (%T.binding.as_type) = name_ref x, %x +// CHECK:STDOUT: %Q2.ref: %K2.assoc_type = name_ref Q2, @K2.%assoc0 [concrete = constants.%assoc0.d67] +// CHECK:STDOUT: %impl.elem0.loc9_4.1: @Simple3.%.loc9_4 (%.19f) = impl_witness_access constants.%K2.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc9_4.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %specific_impl_fn.loc9_4.1: = specific_impl_function %impl.elem0.loc9_4.1, @K2.Q2(constants.%T) [symbolic = %specific_impl_fn.loc9_4.2 (constants.%specific_impl_fn)] +// CHECK:STDOUT: %.loc9_8: init %empty_tuple.type = call %specific_impl_fn.loc9_4.1() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Compound3(%V.loc14_14.2: %K2.type) { +// CHECK:STDOUT: %V.loc14_14.1: %K2.type = symbolic_binding V, 0 [symbolic = %V.loc14_14.1 (constants.%V)] +// CHECK:STDOUT: %V.binding.as_type: type = symbolic_binding_type V, 0, %V.loc14_14.1 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %V.binding.as_type [symbolic = %pattern_type (constants.%pattern_type.91df25.2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type %V.binding.as_type [symbolic = %require_complete (constants.%require_complete.5fb80b.2)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%y.param: @Compound3.%V.binding.as_type (%V.binding.as_type)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %y.ref: @Compound3.%V.binding.as_type (%V.binding.as_type) = name_ref y, %y +// CHECK:STDOUT: %K2.ref.loc22: type = name_ref K2, file.%K2.decl [concrete = constants.%K2.type] +// CHECK:STDOUT: %Q2.ref: %K2.assoc_type = name_ref Q2, @K2.%assoc0 [concrete = constants.%assoc0.d67] +// CHECK:STDOUT: %.loc22: %K2.type = converted %y.ref, [concrete = ] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @K2.Q2(constants.%Self.98c) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Simple3(constants.%T) { +// CHECK:STDOUT: %T.loc8_12.1 => constants.%T +// CHECK:STDOUT: %T.binding.as_type => constants.%T.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.91df25.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @K2.Q2(constants.%T) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Compound3(constants.%V) { +// CHECK:STDOUT: %V.loc14_14.1 => constants.%V +// CHECK:STDOUT: %V.binding.as_type => constants.%V.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.91df25.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- instance.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %L1.type: type = facet_type <@L1> [concrete] +// CHECK:STDOUT: %Self: %L1.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic] +// CHECK:STDOUT: %pattern_type.510a66.1: type = pattern_type %Self.binding.as_type [symbolic] +// CHECK:STDOUT: %L1.R1.type: type = fn_type @L1.R1 [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %L1.R1: %L1.R1.type = struct_value () [concrete] +// CHECK:STDOUT: %L1.assoc_type: type = assoc_entity_type @L1 [concrete] +// CHECK:STDOUT: %assoc0: %L1.assoc_type = assoc_entity element0, @L1.%L1.R1.decl [concrete] +// CHECK:STDOUT: %L1.S1.type: type = fn_type @L1.S1 [concrete] +// CHECK:STDOUT: %L1.S1: %L1.S1.type = struct_value () [concrete] +// CHECK:STDOUT: %assoc1: %L1.assoc_type = assoc_entity element1, @L1.%L1.S1.decl [concrete] +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %T: %L1.type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %pattern_type.e3e: type = pattern_type %L1.type [concrete] +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T [symbolic] +// CHECK:STDOUT: %pattern_type.510a66.2: type = pattern_type %T.binding.as_type [symbolic] +// CHECK:STDOUT: %ptr.5db4e7.1: type = ptr_type %T.binding.as_type [symbolic] +// CHECK:STDOUT: %pattern_type.f1f60b.1: type = pattern_type %ptr.5db4e7.1 [symbolic] +// CHECK:STDOUT: %Simple4.type: type = fn_type @Simple4 [concrete] +// CHECK:STDOUT: %Simple4: %Simple4.type = struct_value () [concrete] +// CHECK:STDOUT: %require_complete.b98a62.1: = require_complete_type %T.binding.as_type [symbolic] +// CHECK:STDOUT: %require_complete.80837b.1: = require_complete_type %ptr.5db4e7.1 [symbolic] +// CHECK:STDOUT: %L1.lookup_impl_witness.497b38.1: = lookup_impl_witness %T, @L1 [symbolic] +// CHECK:STDOUT: %.2c3978.1: type = fn_type_with_self_type %L1.R1.type, %T [symbolic] +// CHECK:STDOUT: %impl.elem0.d3a613.1: %.2c3978.1 = impl_witness_access %L1.lookup_impl_witness.497b38.1, element0 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.f8ac37.1: = specific_impl_function %impl.elem0.d3a613.1, @L1.R1(%T) [symbolic] +// CHECK:STDOUT: %.45c8db.1: type = fn_type_with_self_type %L1.S1.type, %T [symbolic] +// CHECK:STDOUT: %impl.elem1.c3a14a.1: %.45c8db.1 = impl_witness_access %L1.lookup_impl_witness.497b38.1, element1 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.c2ec1e.1: = specific_impl_function %impl.elem1.c3a14a.1, @L1.S1(%T) [symbolic] +// CHECK:STDOUT: %V: %L1.type = symbolic_binding V, 0 [symbolic] +// CHECK:STDOUT: %V.binding.as_type: type = symbolic_binding_type V, 0, %V [symbolic] +// CHECK:STDOUT: %pattern_type.510a66.3: type = pattern_type %V.binding.as_type [symbolic] +// CHECK:STDOUT: %ptr.5db4e7.2: type = ptr_type %V.binding.as_type [symbolic] +// CHECK:STDOUT: %pattern_type.f1f60b.2: type = pattern_type %ptr.5db4e7.2 [symbolic] +// CHECK:STDOUT: %Compound4.type: type = fn_type @Compound4 [concrete] +// CHECK:STDOUT: %Compound4: %Compound4.type = struct_value () [concrete] +// CHECK:STDOUT: %require_complete.b98a62.2: = require_complete_type %V.binding.as_type [symbolic] +// CHECK:STDOUT: %require_complete.80837b.2: = require_complete_type %ptr.5db4e7.2 [symbolic] +// CHECK:STDOUT: %L1.lookup_impl_witness.497b38.2: = lookup_impl_witness %V, @L1 [symbolic] +// CHECK:STDOUT: %.2c3978.2: type = fn_type_with_self_type %L1.R1.type, %V [symbolic] +// CHECK:STDOUT: %impl.elem0.d3a613.2: %.2c3978.2 = impl_witness_access %L1.lookup_impl_witness.497b38.2, element0 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.f8ac37.2: = specific_impl_function %impl.elem0.d3a613.2, @L1.R1(%V) [symbolic] +// CHECK:STDOUT: %.45c8db.2: type = fn_type_with_self_type %L1.S1.type, %V [symbolic] +// CHECK:STDOUT: %impl.elem1.c3a14a.2: %.45c8db.2 = impl_witness_access %L1.lookup_impl_witness.497b38.2, element1 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.c2ec1e.2: = specific_impl_function %impl.elem1.c3a14a.2, @L1.S1(%V) [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .L1 = %L1.decl +// CHECK:STDOUT: .Simple4 = %Simple4.decl +// CHECK:STDOUT: .Compound4 = %Compound4.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %L1.decl: type = interface_decl @L1 [concrete = constants.%L1.type] {} {} +// CHECK:STDOUT: %Simple4.decl: %Simple4.type = fn_decl @Simple4 [concrete = constants.%Simple4] { +// CHECK:STDOUT: %T.patt: %pattern_type.e3e = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: %x.patt: @Simple4.%pattern_type.loc9_20 (%pattern_type.510a66.2) = value_binding_pattern x [concrete] +// CHECK:STDOUT: %x.param_patt: @Simple4.%pattern_type.loc9_20 (%pattern_type.510a66.2) = value_param_pattern %x.patt, call_param0 [concrete] +// CHECK:STDOUT: %p.patt: @Simple4.%pattern_type.loc9_26 (%pattern_type.f1f60b.1) = value_binding_pattern p [concrete] +// CHECK:STDOUT: %p.param_patt: @Simple4.%pattern_type.loc9_26 (%pattern_type.f1f60b.1) = value_param_pattern %p.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc9_16: type = splice_block %L1.ref [concrete = constants.%L1.type] { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %L1.ref: type = name_ref L1, file.%L1.decl [concrete = constants.%L1.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.loc9_12.2: %L1.type = symbolic_binding T, 0 [symbolic = %T.loc9_12.1 (constants.%T)] +// CHECK:STDOUT: %x.param: @Simple4.%T.binding.as_type (%T.binding.as_type) = value_param call_param0 +// CHECK:STDOUT: %.loc9_23.1: type = splice_block %.loc9_23.2 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] { +// CHECK:STDOUT: %T.ref.loc9_23: %L1.type = name_ref T, %T.loc9_12.2 [symbolic = %T.loc9_12.1 (constants.%T)] +// CHECK:STDOUT: %T.as_type.loc9_23: type = facet_access_type %T.ref.loc9_23 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %.loc9_23.2: type = converted %T.ref.loc9_23, %T.as_type.loc9_23 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: @Simple4.%T.binding.as_type (%T.binding.as_type) = value_binding x, %x.param +// CHECK:STDOUT: %p.param: @Simple4.%ptr.loc9_30.1 (%ptr.5db4e7.1) = value_param call_param1 +// CHECK:STDOUT: %.loc9_30.1: type = splice_block %ptr.loc9_30.2 [symbolic = %ptr.loc9_30.1 (constants.%ptr.5db4e7.1)] { +// CHECK:STDOUT: %T.ref.loc9_29: %L1.type = name_ref T, %T.loc9_12.2 [symbolic = %T.loc9_12.1 (constants.%T)] +// CHECK:STDOUT: %T.as_type.loc9_30: type = facet_access_type %T.ref.loc9_29 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %.loc9_30.2: type = converted %T.ref.loc9_29, %T.as_type.loc9_30 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %ptr.loc9_30.2: type = ptr_type %.loc9_30.2 [symbolic = %ptr.loc9_30.1 (constants.%ptr.5db4e7.1)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %p: @Simple4.%ptr.loc9_30.1 (%ptr.5db4e7.1) = value_binding p, %p.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %Compound4.decl: %Compound4.type = fn_decl @Compound4 [concrete = constants.%Compound4] { +// CHECK:STDOUT: %V.patt: %pattern_type.e3e = symbolic_binding_pattern V, 0 [concrete] +// CHECK:STDOUT: %y.patt: @Compound4.%pattern_type.loc15_22 (%pattern_type.510a66.3) = value_binding_pattern y [concrete] +// CHECK:STDOUT: %y.param_patt: @Compound4.%pattern_type.loc15_22 (%pattern_type.510a66.3) = value_param_pattern %y.patt, call_param0 [concrete] +// CHECK:STDOUT: %p.patt: @Compound4.%pattern_type.loc15_28 (%pattern_type.f1f60b.2) = value_binding_pattern p [concrete] +// CHECK:STDOUT: %p.param_patt: @Compound4.%pattern_type.loc15_28 (%pattern_type.f1f60b.2) = value_param_pattern %p.patt, call_param1 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc15_18: type = splice_block %L1.ref.loc15 [concrete = constants.%L1.type] { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %L1.ref.loc15: type = name_ref L1, file.%L1.decl [concrete = constants.%L1.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %V.loc15_14.2: %L1.type = symbolic_binding V, 0 [symbolic = %V.loc15_14.1 (constants.%V)] +// CHECK:STDOUT: %y.param: @Compound4.%V.binding.as_type (%V.binding.as_type) = value_param call_param0 +// CHECK:STDOUT: %.loc15_25.1: type = splice_block %.loc15_25.2 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] { +// CHECK:STDOUT: %V.ref.loc15_25: %L1.type = name_ref V, %V.loc15_14.2 [symbolic = %V.loc15_14.1 (constants.%V)] +// CHECK:STDOUT: %V.as_type.loc15_25: type = facet_access_type %V.ref.loc15_25 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] +// CHECK:STDOUT: %.loc15_25.2: type = converted %V.ref.loc15_25, %V.as_type.loc15_25 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %y: @Compound4.%V.binding.as_type (%V.binding.as_type) = value_binding y, %y.param +// CHECK:STDOUT: %p.param: @Compound4.%ptr.loc15_32.1 (%ptr.5db4e7.2) = value_param call_param1 +// CHECK:STDOUT: %.loc15_32.1: type = splice_block %ptr.loc15_32.2 [symbolic = %ptr.loc15_32.1 (constants.%ptr.5db4e7.2)] { +// CHECK:STDOUT: %V.ref.loc15_31: %L1.type = name_ref V, %V.loc15_14.2 [symbolic = %V.loc15_14.1 (constants.%V)] +// CHECK:STDOUT: %V.as_type.loc15_32: type = facet_access_type %V.ref.loc15_31 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] +// CHECK:STDOUT: %.loc15_32.2: type = converted %V.ref.loc15_31, %V.as_type.loc15_32 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] +// CHECK:STDOUT: %ptr.loc15_32.2: type = ptr_type %.loc15_32.2 [symbolic = %ptr.loc15_32.1 (constants.%ptr.5db4e7.2)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %p: @Compound4.%ptr.loc15_32.1 (%ptr.5db4e7.2) = value_binding p, %p.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @L1 { +// CHECK:STDOUT: %Self: %L1.type = symbolic_binding Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %L1.R1.decl: %L1.R1.type = fn_decl @L1.R1 [concrete = constants.%L1.R1] { +// CHECK:STDOUT: %self.patt: @L1.R1.%pattern_type (%pattern_type.510a66.1) = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @L1.R1.%pattern_type (%pattern_type.510a66.1) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @L1.R1.%Self.binding.as_type (%Self.binding.as_type) = value_param call_param0 +// CHECK:STDOUT: %.loc4_15.1: type = splice_block %.loc4_15.2 [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] { +// CHECK:STDOUT: %Self.ref: %L1.type = name_ref Self, @L1.%Self [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.ref [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %.loc4_15.2: type = converted %Self.ref, %Self.as_type [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @L1.R1.%Self.binding.as_type (%Self.binding.as_type) = value_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc0: %L1.assoc_type = assoc_entity element0, %L1.R1.decl [concrete = constants.%assoc0] +// CHECK:STDOUT: %L1.S1.decl: %L1.S1.type = fn_decl @L1.S1 [concrete = constants.%L1.S1] { +// CHECK:STDOUT: %self.patt: @L1.S1.%pattern_type (%pattern_type.510a66.1) = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @L1.S1.%pattern_type (%pattern_type.510a66.1) = ref_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: ref @L1.S1.%Self.binding.as_type (%Self.binding.as_type) = ref_param call_param0 +// CHECK:STDOUT: %.loc5_19.1: type = splice_block %.loc5_19.2 [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] { +// CHECK:STDOUT: %Self.ref: %L1.type = name_ref Self, @L1.%Self [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.ref [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %.loc5_19.2: type = converted %Self.ref, %Self.as_type [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: ref @L1.S1.%Self.binding.as_type (%Self.binding.as_type) = ref_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc1: %L1.assoc_type = assoc_entity element1, %L1.S1.decl [concrete = constants.%assoc1] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .R1 = %assoc0 +// CHECK:STDOUT: .S1 = %assoc1 +// CHECK:STDOUT: witness = (%L1.R1.decl, %L1.S1.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @L1.R1(@L1.%Self: %L1.type) { +// CHECK:STDOUT: %Self: %L1.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %Self.binding.as_type [symbolic = %pattern_type (constants.%pattern_type.510a66.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @L1.R1.%Self.binding.as_type (%Self.binding.as_type)); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @L1.S1(@L1.%Self: %L1.type) { +// CHECK:STDOUT: %Self: %L1.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %Self.binding.as_type [symbolic = %pattern_type (constants.%pattern_type.510a66.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @L1.S1.%Self.binding.as_type (%Self.binding.as_type)); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Simple4(%T.loc9_12.2: %L1.type) { +// CHECK:STDOUT: %T.loc9_12.1: %L1.type = symbolic_binding T, 0 [symbolic = %T.loc9_12.1 (constants.%T)] +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T.loc9_12.1 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %pattern_type.loc9_20: type = pattern_type %T.binding.as_type [symbolic = %pattern_type.loc9_20 (constants.%pattern_type.510a66.2)] +// CHECK:STDOUT: %ptr.loc9_30.1: type = ptr_type %T.binding.as_type [symbolic = %ptr.loc9_30.1 (constants.%ptr.5db4e7.1)] +// CHECK:STDOUT: %pattern_type.loc9_26: type = pattern_type %ptr.loc9_30.1 [symbolic = %pattern_type.loc9_26 (constants.%pattern_type.f1f60b.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete.loc9_21: = require_complete_type %T.binding.as_type [symbolic = %require_complete.loc9_21 (constants.%require_complete.b98a62.1)] +// CHECK:STDOUT: %require_complete.loc9_27: = require_complete_type %ptr.loc9_30.1 [symbolic = %require_complete.loc9_27 (constants.%require_complete.80837b.1)] +// CHECK:STDOUT: %L1.lookup_impl_witness: = lookup_impl_witness %T.loc9_12.1, @L1 [symbolic = %L1.lookup_impl_witness (constants.%L1.lookup_impl_witness.497b38.1)] +// CHECK:STDOUT: %.loc10_4: type = fn_type_with_self_type constants.%L1.R1.type, %T.loc9_12.1 [symbolic = %.loc10_4 (constants.%.2c3978.1)] +// CHECK:STDOUT: %impl.elem0.loc10_4.2: @Simple4.%.loc10_4 (%.2c3978.1) = impl_witness_access %L1.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc10_4.2 (constants.%impl.elem0.d3a613.1)] +// CHECK:STDOUT: %specific_impl_fn.loc10_4.2: = specific_impl_function %impl.elem0.loc10_4.2, @L1.R1(%T.loc9_12.1) [symbolic = %specific_impl_fn.loc10_4.2 (constants.%specific_impl_fn.f8ac37.1)] +// CHECK:STDOUT: %.loc11_4.2: type = fn_type_with_self_type constants.%L1.S1.type, %T.loc9_12.1 [symbolic = %.loc11_4.2 (constants.%.45c8db.1)] +// CHECK:STDOUT: %impl.elem1.loc11_4.2: @Simple4.%.loc11_4.2 (%.45c8db.1) = impl_witness_access %L1.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc11_4.2 (constants.%impl.elem1.c3a14a.1)] +// CHECK:STDOUT: %specific_impl_fn.loc11_4.2: = specific_impl_function %impl.elem1.loc11_4.2, @L1.S1(%T.loc9_12.1) [symbolic = %specific_impl_fn.loc11_4.2 (constants.%specific_impl_fn.c2ec1e.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%x.param: @Simple4.%T.binding.as_type (%T.binding.as_type), %p.param: @Simple4.%ptr.loc9_30.1 (%ptr.5db4e7.1)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %x.ref: @Simple4.%T.binding.as_type (%T.binding.as_type) = name_ref x, %x +// CHECK:STDOUT: %R1.ref: %L1.assoc_type = name_ref R1, @L1.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %impl.elem0.loc10_4.1: @Simple4.%.loc10_4 (%.2c3978.1) = impl_witness_access constants.%L1.lookup_impl_witness.497b38.1, element0 [symbolic = %impl.elem0.loc10_4.2 (constants.%impl.elem0.d3a613.1)] +// CHECK:STDOUT: %bound_method.loc10_4: = bound_method %x.ref, %impl.elem0.loc10_4.1 +// CHECK:STDOUT: %specific_impl_fn.loc10_4.1: = specific_impl_function %impl.elem0.loc10_4.1, @L1.R1(constants.%T) [symbolic = %specific_impl_fn.loc10_4.2 (constants.%specific_impl_fn.f8ac37.1)] +// CHECK:STDOUT: %bound_method.loc10_8: = bound_method %x.ref, %specific_impl_fn.loc10_4.1 +// CHECK:STDOUT: %.loc10_8: init %empty_tuple.type = call %bound_method.loc10_8(%x.ref) +// CHECK:STDOUT: %p.ref: @Simple4.%ptr.loc9_30.1 (%ptr.5db4e7.1) = name_ref p, %p +// CHECK:STDOUT: %.loc11_4.1: ref @Simple4.%T.binding.as_type (%T.binding.as_type) = deref %p.ref +// CHECK:STDOUT: %S1.ref: %L1.assoc_type = name_ref S1, @L1.%assoc1 [concrete = constants.%assoc1] +// CHECK:STDOUT: %impl.elem1.loc11_4.1: @Simple4.%.loc11_4.2 (%.45c8db.1) = impl_witness_access constants.%L1.lookup_impl_witness.497b38.1, element1 [symbolic = %impl.elem1.loc11_4.2 (constants.%impl.elem1.c3a14a.1)] +// CHECK:STDOUT: %bound_method.loc11_4: = bound_method %.loc11_4.1, %impl.elem1.loc11_4.1 +// CHECK:STDOUT: %specific_impl_fn.loc11_4.1: = specific_impl_function %impl.elem1.loc11_4.1, @L1.S1(constants.%T) [symbolic = %specific_impl_fn.loc11_4.2 (constants.%specific_impl_fn.c2ec1e.1)] +// CHECK:STDOUT: %bound_method.loc11_9: = bound_method %.loc11_4.1, %specific_impl_fn.loc11_4.1 +// CHECK:STDOUT: %.loc11_9: init %empty_tuple.type = call %bound_method.loc11_9(%.loc11_4.1) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Compound4(%V.loc15_14.2: %L1.type) { +// CHECK:STDOUT: %V.loc15_14.1: %L1.type = symbolic_binding V, 0 [symbolic = %V.loc15_14.1 (constants.%V)] +// CHECK:STDOUT: %V.binding.as_type: type = symbolic_binding_type V, 0, %V.loc15_14.1 [symbolic = %V.binding.as_type (constants.%V.binding.as_type)] +// CHECK:STDOUT: %pattern_type.loc15_22: type = pattern_type %V.binding.as_type [symbolic = %pattern_type.loc15_22 (constants.%pattern_type.510a66.3)] +// CHECK:STDOUT: %ptr.loc15_32.1: type = ptr_type %V.binding.as_type [symbolic = %ptr.loc15_32.1 (constants.%ptr.5db4e7.2)] +// CHECK:STDOUT: %pattern_type.loc15_28: type = pattern_type %ptr.loc15_32.1 [symbolic = %pattern_type.loc15_28 (constants.%pattern_type.f1f60b.2)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete.loc15_23: = require_complete_type %V.binding.as_type [symbolic = %require_complete.loc15_23 (constants.%require_complete.b98a62.2)] +// CHECK:STDOUT: %require_complete.loc15_29: = require_complete_type %ptr.loc15_32.1 [symbolic = %require_complete.loc15_29 (constants.%require_complete.80837b.2)] +// CHECK:STDOUT: %L1.lookup_impl_witness: = lookup_impl_witness %V.loc15_14.1, @L1 [symbolic = %L1.lookup_impl_witness (constants.%L1.lookup_impl_witness.497b38.2)] +// CHECK:STDOUT: %.loc16_4: type = fn_type_with_self_type constants.%L1.R1.type, %V.loc15_14.1 [symbolic = %.loc16_4 (constants.%.2c3978.2)] +// CHECK:STDOUT: %impl.elem0.loc16_4.2: @Compound4.%.loc16_4 (%.2c3978.2) = impl_witness_access %L1.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc16_4.2 (constants.%impl.elem0.d3a613.2)] +// CHECK:STDOUT: %specific_impl_fn.loc16_4.2: = specific_impl_function %impl.elem0.loc16_4.2, @L1.R1(%V.loc15_14.1) [symbolic = %specific_impl_fn.loc16_4.2 (constants.%specific_impl_fn.f8ac37.2)] +// CHECK:STDOUT: %.loc17_4.2: type = fn_type_with_self_type constants.%L1.S1.type, %V.loc15_14.1 [symbolic = %.loc17_4.2 (constants.%.45c8db.2)] +// CHECK:STDOUT: %impl.elem1.loc17_4.2: @Compound4.%.loc17_4.2 (%.45c8db.2) = impl_witness_access %L1.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc17_4.2 (constants.%impl.elem1.c3a14a.2)] +// CHECK:STDOUT: %specific_impl_fn.loc17_4.2: = specific_impl_function %impl.elem1.loc17_4.2, @L1.S1(%V.loc15_14.1) [symbolic = %specific_impl_fn.loc17_4.2 (constants.%specific_impl_fn.c2ec1e.2)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%y.param: @Compound4.%V.binding.as_type (%V.binding.as_type), %p.param: @Compound4.%ptr.loc15_32.1 (%ptr.5db4e7.2)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %y.ref: @Compound4.%V.binding.as_type (%V.binding.as_type) = name_ref y, %y +// CHECK:STDOUT: %L1.ref.loc16: type = name_ref L1, file.%L1.decl [concrete = constants.%L1.type] +// CHECK:STDOUT: %R1.ref: %L1.assoc_type = name_ref R1, @L1.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %impl.elem0.loc16_4.1: @Compound4.%.loc16_4 (%.2c3978.2) = impl_witness_access constants.%L1.lookup_impl_witness.497b38.2, element0 [symbolic = %impl.elem0.loc16_4.2 (constants.%impl.elem0.d3a613.2)] +// CHECK:STDOUT: %bound_method.loc16_4: = bound_method %y.ref, %impl.elem0.loc16_4.1 +// CHECK:STDOUT: %specific_impl_fn.loc16_4.1: = specific_impl_function %impl.elem0.loc16_4.1, @L1.R1(constants.%V) [symbolic = %specific_impl_fn.loc16_4.2 (constants.%specific_impl_fn.f8ac37.2)] +// CHECK:STDOUT: %bound_method.loc16_13: = bound_method %y.ref, %specific_impl_fn.loc16_4.1 +// CHECK:STDOUT: %.loc16_13: init %empty_tuple.type = call %bound_method.loc16_13(%y.ref) +// CHECK:STDOUT: %p.ref: @Compound4.%ptr.loc15_32.1 (%ptr.5db4e7.2) = name_ref p, %p +// CHECK:STDOUT: %L1.ref.loc17: type = name_ref L1, file.%L1.decl [concrete = constants.%L1.type] +// CHECK:STDOUT: %S1.ref: %L1.assoc_type = name_ref S1, @L1.%assoc1 [concrete = constants.%assoc1] +// CHECK:STDOUT: %.loc17_4.1: ref @Compound4.%V.binding.as_type (%V.binding.as_type) = deref %p.ref +// CHECK:STDOUT: %impl.elem1.loc17_4.1: @Compound4.%.loc17_4.2 (%.45c8db.2) = impl_witness_access constants.%L1.lookup_impl_witness.497b38.2, element1 [symbolic = %impl.elem1.loc17_4.2 (constants.%impl.elem1.c3a14a.2)] +// CHECK:STDOUT: %bound_method.loc17_4: = bound_method %.loc17_4.1, %impl.elem1.loc17_4.1 +// CHECK:STDOUT: %specific_impl_fn.loc17_4.1: = specific_impl_function %impl.elem1.loc17_4.1, @L1.S1(constants.%V) [symbolic = %specific_impl_fn.loc17_4.2 (constants.%specific_impl_fn.c2ec1e.2)] +// CHECK:STDOUT: %bound_method.loc17_14: = bound_method %.loc17_4.1, %specific_impl_fn.loc17_4.1 +// CHECK:STDOUT: %.loc17_14: init %empty_tuple.type = call %bound_method.loc17_14(%.loc17_4.1) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L1.R1(constants.%Self) { +// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.510a66.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L1.S1(constants.%Self) { +// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.510a66.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Simple4(constants.%T) { +// CHECK:STDOUT: %T.loc9_12.1 => constants.%T +// CHECK:STDOUT: %T.binding.as_type => constants.%T.binding.as_type +// CHECK:STDOUT: %pattern_type.loc9_20 => constants.%pattern_type.510a66.2 +// CHECK:STDOUT: %ptr.loc9_30.1 => constants.%ptr.5db4e7.1 +// CHECK:STDOUT: %pattern_type.loc9_26 => constants.%pattern_type.f1f60b.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L1.R1(constants.%T) { +// CHECK:STDOUT: %Self => constants.%T +// CHECK:STDOUT: %Self.binding.as_type => constants.%T.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.510a66.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L1.S1(constants.%T) { +// CHECK:STDOUT: %Self => constants.%T +// CHECK:STDOUT: %Self.binding.as_type => constants.%T.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.510a66.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Compound4(constants.%V) { +// CHECK:STDOUT: %V.loc15_14.1 => constants.%V +// CHECK:STDOUT: %V.binding.as_type => constants.%V.binding.as_type +// CHECK:STDOUT: %pattern_type.loc15_22 => constants.%pattern_type.510a66.3 +// CHECK:STDOUT: %ptr.loc15_32.1 => constants.%ptr.5db4e7.2 +// CHECK:STDOUT: %pattern_type.loc15_28 => constants.%pattern_type.f1f60b.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L1.R1(constants.%V) { +// CHECK:STDOUT: %Self => constants.%V +// CHECK:STDOUT: %Self.binding.as_type => constants.%V.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.510a66.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L1.S1(constants.%V) { +// CHECK:STDOUT: %Self => constants.%V +// CHECK:STDOUT: %Self.binding.as_type => constants.%V.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.510a66.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_interface_instance_caller_not.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %L2.type: type = facet_type <@L2> [concrete] +// CHECK:STDOUT: %Self: %L2.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic] +// CHECK:STDOUT: %pattern_type.c87c75.1: type = pattern_type %Self.binding.as_type [symbolic] +// CHECK:STDOUT: %L2.R2.type: type = fn_type @L2.R2 [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %L2.R2: %L2.R2.type = struct_value () [concrete] +// CHECK:STDOUT: %L2.assoc_type: type = assoc_entity_type @L2 [concrete] +// CHECK:STDOUT: %assoc0: %L2.assoc_type = assoc_entity element0, @L2.%L2.R2.decl [concrete] +// CHECK:STDOUT: %L2.S2.type: type = fn_type @L2.S2 [concrete] +// CHECK:STDOUT: %L2.S2: %L2.S2.type = struct_value () [concrete] +// CHECK:STDOUT: %assoc1: %L2.assoc_type = assoc_entity element1, @L2.%L2.S2.decl [concrete] +// CHECK:STDOUT: %type: type = facet_type [concrete] +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self] +// CHECK:STDOUT: %T: %L2.type = symbolic_binding T, 0 [symbolic] +// CHECK:STDOUT: %pattern_type.38f: type = pattern_type %L2.type [concrete] +// CHECK:STDOUT: %Simple5.type: type = fn_type @Simple5 [concrete] +// CHECK:STDOUT: %Simple5: %Simple5.type = struct_value () [concrete] +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T [symbolic] +// CHECK:STDOUT: %L2.lookup_impl_witness: = lookup_impl_witness %T, @L2 [symbolic] +// CHECK:STDOUT: %.6fc: type = fn_type_with_self_type %L2.R2.type, %T [symbolic] +// CHECK:STDOUT: %impl.elem0: %.6fc = impl_witness_access %L2.lookup_impl_witness, element0 [symbolic] +// CHECK:STDOUT: %pattern_type.c87c75.2: type = pattern_type %T.binding.as_type [symbolic] +// CHECK:STDOUT: %specific_impl_fn.a65: = specific_impl_function %impl.elem0, @L2.R2(%T) [symbolic] +// CHECK:STDOUT: %.0b4: type = fn_type_with_self_type %L2.S2.type, %T [symbolic] +// CHECK:STDOUT: %impl.elem1: %.0b4 = impl_witness_access %L2.lookup_impl_witness, element1 [symbolic] +// CHECK:STDOUT: %specific_impl_fn.b7b: = specific_impl_function %impl.elem1, @L2.S2(%T) [symbolic] +// CHECK:STDOUT: %V: %L2.type = symbolic_binding V, 0 [symbolic] +// CHECK:STDOUT: %Compound5.type: type = fn_type @Compound5 [concrete] +// CHECK:STDOUT: %Compound5: %Compound5.type = struct_value () [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .L2 = %L2.decl +// CHECK:STDOUT: .Simple5 = %Simple5.decl +// CHECK:STDOUT: .Compound5 = %Compound5.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %L2.decl: type = interface_decl @L2 [concrete = constants.%L2.type] {} {} +// CHECK:STDOUT: %Simple5.decl: %Simple5.type = fn_decl @Simple5 [concrete = constants.%Simple5] { +// CHECK:STDOUT: %T.patt: %pattern_type.38f = symbolic_binding_pattern T, 0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc10: type = splice_block %L2.ref [concrete = constants.%L2.type] { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %L2.ref: type = name_ref L2, file.%L2.decl [concrete = constants.%L2.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %T.loc10_12.2: %L2.type = symbolic_binding T, 0 [symbolic = %T.loc10_12.1 (constants.%T)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %Compound5.decl: %Compound5.type = fn_decl @Compound5 [concrete = constants.%Compound5] { +// CHECK:STDOUT: %V.patt: %pattern_type.38f = symbolic_binding_pattern V, 0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %.loc30: type = splice_block %L2.ref.loc30 [concrete = constants.%L2.type] { +// CHECK:STDOUT: %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self] +// CHECK:STDOUT: %L2.ref.loc30: type = name_ref L2, file.%L2.decl [concrete = constants.%L2.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %V.loc30_14.2: %L2.type = symbolic_binding V, 0 [symbolic = %V.loc30_14.1 (constants.%V)] +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @L2 { +// CHECK:STDOUT: %Self: %L2.type = symbolic_binding Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %L2.R2.decl: %L2.R2.type = fn_decl @L2.R2 [concrete = constants.%L2.R2] { +// CHECK:STDOUT: %self.patt: @L2.R2.%pattern_type (%pattern_type.c87c75.1) = value_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @L2.R2.%pattern_type (%pattern_type.c87c75.1) = value_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: @L2.R2.%Self.binding.as_type (%Self.binding.as_type) = value_param call_param0 +// CHECK:STDOUT: %.loc5_15.1: type = splice_block %.loc5_15.2 [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] { +// CHECK:STDOUT: %Self.ref: %L2.type = name_ref Self, @L2.%Self [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.ref [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %.loc5_15.2: type = converted %Self.ref, %Self.as_type [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: @L2.R2.%Self.binding.as_type (%Self.binding.as_type) = value_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc0: %L2.assoc_type = assoc_entity element0, %L2.R2.decl [concrete = constants.%assoc0] +// CHECK:STDOUT: %L2.S2.decl: %L2.S2.type = fn_decl @L2.S2 [concrete = constants.%L2.S2] { +// CHECK:STDOUT: %self.patt: @L2.S2.%pattern_type (%pattern_type.c87c75.1) = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: @L2.S2.%pattern_type (%pattern_type.c87c75.1) = ref_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: ref @L2.S2.%Self.binding.as_type (%Self.binding.as_type) = ref_param call_param0 +// CHECK:STDOUT: %.loc6_19.1: type = splice_block %.loc6_19.2 [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] { +// CHECK:STDOUT: %Self.ref: %L2.type = name_ref Self, @L2.%Self [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.ref [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %.loc6_19.2: type = converted %Self.ref, %Self.as_type [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %self: ref @L2.S2.%Self.binding.as_type (%Self.binding.as_type) = ref_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %assoc1: %L2.assoc_type = assoc_entity element1, %L2.S2.decl [concrete = constants.%assoc1] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .R2 = %assoc0 +// CHECK:STDOUT: .S2 = %assoc1 +// CHECK:STDOUT: witness = (%L2.R2.decl, %L2.S2.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @L2.R2(@L2.%Self: %L2.type) { +// CHECK:STDOUT: %Self: %L2.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %Self.binding.as_type [symbolic = %pattern_type (constants.%pattern_type.c87c75.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @L2.R2.%Self.binding.as_type (%Self.binding.as_type)); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @L2.S2(@L2.%Self: %L2.type) { +// CHECK:STDOUT: %Self: %L2.type = symbolic_binding Self, 0 [symbolic = %Self (constants.%Self)] +// CHECK:STDOUT: %Self.binding.as_type: type = symbolic_binding_type Self, 0, %Self [symbolic = %Self.binding.as_type (constants.%Self.binding.as_type)] +// CHECK:STDOUT: %pattern_type: type = pattern_type %Self.binding.as_type [symbolic = %pattern_type (constants.%pattern_type.c87c75.1)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn(%self.param: @L2.S2.%Self.binding.as_type (%Self.binding.as_type)); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Simple5(%T.loc10_12.2: %L2.type) { +// CHECK:STDOUT: %T.loc10_12.1: %L2.type = symbolic_binding T, 0 [symbolic = %T.loc10_12.1 (constants.%T)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %T.binding.as_type: type = symbolic_binding_type T, 0, %T.loc10_12.1 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %L2.lookup_impl_witness: = lookup_impl_witness %T.loc10_12.1, @L2 [symbolic = %L2.lookup_impl_witness (constants.%L2.lookup_impl_witness)] +// CHECK:STDOUT: %.loc18_4.2: type = fn_type_with_self_type constants.%L2.R2.type, %T.loc10_12.1 [symbolic = %.loc18_4.2 (constants.%.6fc)] +// CHECK:STDOUT: %impl.elem0.loc18_4.2: @Simple5.%.loc18_4.2 (%.6fc) = impl_witness_access %L2.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %specific_impl_fn.loc18_4.2: = specific_impl_function %impl.elem0.loc18_4.2, @L2.R2(%T.loc10_12.1) [symbolic = %specific_impl_fn.loc18_4.2 (constants.%specific_impl_fn.a65)] +// CHECK:STDOUT: %.loc26_4.2: type = fn_type_with_self_type constants.%L2.S2.type, %T.loc10_12.1 [symbolic = %.loc26_4.2 (constants.%.0b4)] +// CHECK:STDOUT: %impl.elem1.loc26_4.2: @Simple5.%.loc26_4.2 (%.0b4) = impl_witness_access %L2.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc26_4.2 (constants.%impl.elem1)] +// CHECK:STDOUT: %specific_impl_fn.loc26_4.2: = specific_impl_function %impl.elem1.loc26_4.2, @L2.S2(%T.loc10_12.1) [symbolic = %specific_impl_fn.loc26_4.2 (constants.%specific_impl_fn.b7b)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %T.ref.loc18: %L2.type = name_ref T, %T.loc10_12.2 [symbolic = %T.loc10_12.1 (constants.%T)] +// CHECK:STDOUT: %R2.ref: %L2.assoc_type = name_ref R2, @L2.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %T.as_type.loc18: type = facet_access_type %T.ref.loc18 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %.loc18_4.1: type = converted %T.ref.loc18, %T.as_type.loc18 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %impl.elem0.loc18_4.1: @Simple5.%.loc18_4.2 (%.6fc) = impl_witness_access constants.%L2.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc18_4.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %specific_impl_fn.loc18_4.1: = specific_impl_function %impl.elem0.loc18_4.1, @L2.R2(constants.%T) [symbolic = %specific_impl_fn.loc18_4.2 (constants.%specific_impl_fn.a65)] +// CHECK:STDOUT: %.loc18_8: init %empty_tuple.type = call %specific_impl_fn.loc18_4.1() [concrete = ] +// CHECK:STDOUT: %T.ref.loc26: %L2.type = name_ref T, %T.loc10_12.2 [symbolic = %T.loc10_12.1 (constants.%T)] +// CHECK:STDOUT: %S2.ref: %L2.assoc_type = name_ref S2, @L2.%assoc1 [concrete = constants.%assoc1] +// CHECK:STDOUT: %T.as_type.loc26: type = facet_access_type %T.ref.loc26 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %.loc26_4.1: type = converted %T.ref.loc26, %T.as_type.loc26 [symbolic = %T.binding.as_type (constants.%T.binding.as_type)] +// CHECK:STDOUT: %impl.elem1.loc26_4.1: @Simple5.%.loc26_4.2 (%.0b4) = impl_witness_access constants.%L2.lookup_impl_witness, element1 [symbolic = %impl.elem1.loc26_4.2 (constants.%impl.elem1)] +// CHECK:STDOUT: %specific_impl_fn.loc26_4.1: = specific_impl_function %impl.elem1.loc26_4.1, @L2.S2(constants.%T) [symbolic = %specific_impl_fn.loc26_4.2 (constants.%specific_impl_fn.b7b)] +// CHECK:STDOUT: %.loc26_8: init %empty_tuple.type = call %specific_impl_fn.loc26_4.1() [concrete = ] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Compound5(%V.loc30_14.2: %L2.type) { +// CHECK:STDOUT: %V.loc30_14.1: %L2.type = symbolic_binding V, 0 [symbolic = %V.loc30_14.1 (constants.%V)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: +// CHECK:STDOUT: fn() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %V.ref.loc35: %L2.type = name_ref V, %V.loc30_14.2 [symbolic = %V.loc30_14.1 (constants.%V)] +// CHECK:STDOUT: %L2.ref.loc35: type = name_ref L2, file.%L2.decl [concrete = constants.%L2.type] +// CHECK:STDOUT: %R2.ref: %L2.assoc_type = name_ref R2, @L2.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %V.ref.loc40: %L2.type = name_ref V, %V.loc30_14.2 [symbolic = %V.loc30_14.1 (constants.%V)] +// CHECK:STDOUT: %L2.ref.loc40: type = name_ref L2, file.%L2.decl [concrete = constants.%L2.type] +// CHECK:STDOUT: %S2.ref: %L2.assoc_type = name_ref S2, @L2.%assoc1 [concrete = constants.%assoc1] +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L2.R2(constants.%Self) { +// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.c87c75.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L2.S2(constants.%Self) { +// CHECK:STDOUT: %Self => constants.%Self +// CHECK:STDOUT: %Self.binding.as_type => constants.%Self.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.c87c75.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Simple5(constants.%T) { +// CHECK:STDOUT: %T.loc10_12.1 => constants.%T +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L2.R2(constants.%T) { +// CHECK:STDOUT: %Self => constants.%T +// CHECK:STDOUT: %Self.binding.as_type => constants.%T.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.c87c75.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @L2.S2(constants.%T) { +// CHECK:STDOUT: %Self => constants.%T +// CHECK:STDOUT: %Self.binding.as_type => constants.%T.binding.as_type +// CHECK:STDOUT: %pattern_type => constants.%pattern_type.c87c75.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Compound5(constants.%V) { +// CHECK:STDOUT: %V.loc30_14.1 => constants.%V +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_combine_non_instance.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %A.type: type = facet_type <@A> [concrete] +// CHECK:STDOUT: %Self.803: %A.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %A.G.type: type = fn_type @A.G [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %A.G: %A.G.type = struct_value () [concrete] +// CHECK:STDOUT: %A.assoc_type: type = assoc_entity_type @A [concrete] +// CHECK:STDOUT: %assoc0.d52: %A.assoc_type = assoc_entity element0, @A.%A.G.decl [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type.357: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %A.impl_witness: = impl_witness file.%A.impl_witness_table [concrete] +// CHECK:STDOUT: %C.as.A.impl.G.type: type = fn_type @C.as.A.impl.G [concrete] +// CHECK:STDOUT: %C.as.A.impl.G: %C.as.A.impl.G.type = struct_value () [concrete] +// CHECK:STDOUT: %A.facet: %A.type = facet_value %C, (%A.impl_witness) [concrete] +// CHECK:STDOUT: %Fails.type: type = fn_type @Fails [concrete] +// CHECK:STDOUT: %Fails: %Fails.type = struct_value () [concrete] +// CHECK:STDOUT: %C.val: %C = struct_value () [concrete] +// CHECK:STDOUT: %BitAndWith.type.f2e: type = generic_interface_type @BitAndWith [concrete] +// CHECK:STDOUT: %BitAndWith.generic: %BitAndWith.type.f2e = struct_value () [concrete] +// CHECK:STDOUT: %BitAndWith.type.8a6: type = facet_type <@BitAndWith, @BitAndWith(type)> [concrete] +// CHECK:STDOUT: %BitAndWith.Op.type.9a3: type = fn_type @BitAndWith.Op, @BitAndWith(type) [concrete] +// CHECK:STDOUT: %BitAndWith.impl_witness: = impl_witness imports.%BitAndWith.impl_witness_table [concrete] +// CHECK:STDOUT: %BitAndWith.facet: %BitAndWith.type.8a6 = facet_value type, (%BitAndWith.impl_witness) [concrete] +// CHECK:STDOUT: %.fa7: type = fn_type_with_self_type %BitAndWith.Op.type.9a3, %BitAndWith.facet [concrete] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.type: type = fn_type @type.as.BitAndWith.impl.Op [concrete] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op: %type.as.BitAndWith.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.bound: = bound_method %A.type, %type.as.BitAndWith.impl.Op [concrete] +// CHECK:STDOUT: %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete] +// CHECK:STDOUT: %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete] +// CHECK:STDOUT: %Destroy.type: type = facet_type <@Destroy> [concrete] +// CHECK:STDOUT: %type_where: type = facet_type > [concrete] +// CHECK:STDOUT: %facet_value: %type_where = facet_value %C, () [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.eeb: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.88a: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.eeb = struct_value () [concrete] +// CHECK:STDOUT: %ptr.019: type = ptr_type %C [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn: = specific_function %DestroyT.binding.as_type.as.Destroy.impl.Op.88a, @DestroyT.binding.as_type.as.Destroy.impl.Op(%facet_value) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .BitAndWith = %Core.BitAndWith +// CHECK:STDOUT: .ImplicitAs = %Core.ImplicitAs +// CHECK:STDOUT: .Destroy = %Core.Destroy +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.BitAndWith: %BitAndWith.type.f2e = import_ref Core//prelude/parts/as, BitAndWith, loaded [concrete = constants.%BitAndWith.generic] +// CHECK:STDOUT: %Core.import_ref.636: %type.as.BitAndWith.impl.Op.type = import_ref Core//prelude/parts/as, loc{{\d+_\d+}}, loaded [concrete = constants.%type.as.BitAndWith.impl.Op] +// CHECK:STDOUT: %BitAndWith.impl_witness_table = impl_witness_table (%Core.import_ref.636), @type.as.BitAndWith.impl [concrete] +// CHECK:STDOUT: %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic] +// CHECK:STDOUT: %Core.Destroy: type = import_ref Core//prelude/parts/destroy, Destroy, loaded [concrete = constants.%Destroy.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .A = %A.decl +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Fails = %Fails.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %A.decl: type = interface_decl @A [concrete = constants.%A.type] {} {} +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: impl_decl @C.as.A.impl [concrete] {} { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %A.impl_witness_table = impl_witness_table (@C.as.A.impl.%C.as.A.impl.G.decl), @C.as.A.impl [concrete] +// CHECK:STDOUT: %A.impl_witness: = impl_witness %A.impl_witness_table [concrete = constants.%A.impl_witness] +// CHECK:STDOUT: %Fails.decl: %Fails.type = fn_decl @Fails [concrete = constants.%Fails] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @A { +// CHECK:STDOUT: %Self: %A.type = symbolic_binding Self, 0 [symbolic = constants.%Self.803] +// CHECK:STDOUT: %A.G.decl: %A.G.type = fn_decl @A.G [concrete = constants.%A.G] {} {} +// CHECK:STDOUT: %assoc0: %A.assoc_type = assoc_entity element0, %A.G.decl [concrete = constants.%assoc0.d52] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .G = %assoc0 +// CHECK:STDOUT: witness = (%A.G.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.A.impl: %C.ref as %A.ref { +// CHECK:STDOUT: %C.as.A.impl.G.decl: %C.as.A.impl.G.type = fn_decl @C.as.A.impl.G [concrete = constants.%C.as.A.impl.G] {} {} +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .G = %C.as.A.impl.G.decl +// CHECK:STDOUT: witness = file.%A.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type.357] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @A.G(@A.%Self: %A.type) { +// CHECK:STDOUT: fn(); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.A.impl.G() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Fails() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc22_5.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %C.ref.loc22: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %.loc22_5.2: ref %C = temporary_storage +// CHECK:STDOUT: %.loc22_5.3: init %C = class_init (), %.loc22_5.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc22_5.4: ref %C = temporary %.loc22_5.2, %.loc22_5.3 +// CHECK:STDOUT: %.loc22_7: ref %C = converted %.loc22_5.1, %.loc22_5.4 +// CHECK:STDOUT: %A.ref.loc22_15: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %A.ref.loc22_19: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %impl.elem0.loc22: %.fa7 = impl_witness_access constants.%BitAndWith.impl_witness, element0 [concrete = constants.%type.as.BitAndWith.impl.Op] +// CHECK:STDOUT: %bound_method.loc22_17: = bound_method %A.ref.loc22_15, %impl.elem0.loc22 [concrete = constants.%type.as.BitAndWith.impl.Op.bound] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.call.loc22: init type = call %bound_method.loc22_17(%A.ref.loc22_15, %A.ref.loc22_19) [concrete = constants.%A.type] +// CHECK:STDOUT: %G.ref.loc22: %A.assoc_type = name_ref G, @A.%assoc0 [concrete = constants.%assoc0.d52] +// CHECK:STDOUT: %.loc22_12: %A.type = converted %.loc22_7, [concrete = ] +// CHECK:STDOUT: %.loc30_6.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %C.ref.loc30_11: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %.loc30_6.2: ref %C = temporary_storage +// CHECK:STDOUT: %.loc30_6.3: init %C = class_init (), %.loc30_6.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc30_6.4: ref %C = temporary %.loc30_6.2, %.loc30_6.3 +// CHECK:STDOUT: %.loc30_8: ref %C = converted %.loc30_6.1, %.loc30_6.4 +// CHECK:STDOUT: %C.ref.loc30_18: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %A.ref.loc30_24: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %A.ref.loc30_28: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %impl.elem0.loc30_26: %.fa7 = impl_witness_access constants.%BitAndWith.impl_witness, element0 [concrete = constants.%type.as.BitAndWith.impl.Op] +// CHECK:STDOUT: %bound_method.loc30_26: = bound_method %A.ref.loc30_24, %impl.elem0.loc30_26 [concrete = constants.%type.as.BitAndWith.impl.Op.bound] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.call.loc30_26: init type = call %bound_method.loc30_26(%A.ref.loc30_24, %A.ref.loc30_28) [concrete = constants.%A.type] +// CHECK:STDOUT: %.loc30_29.1: type = value_of_initializer %type.as.BitAndWith.impl.Op.call.loc30_26 [concrete = constants.%A.type] +// CHECK:STDOUT: %.loc30_29.2: type = converted %type.as.BitAndWith.impl.Op.call.loc30_26, %.loc30_29.1 [concrete = constants.%A.type] +// CHECK:STDOUT: %A.facet.loc30: %A.type = facet_value %C.ref.loc30_18, (constants.%A.impl_witness) [concrete = constants.%A.facet] +// CHECK:STDOUT: %.loc30_20: %A.type = converted %C.ref.loc30_18, %A.facet.loc30 [concrete = constants.%A.facet] +// CHECK:STDOUT: %as_type.loc30: type = facet_access_type %.loc30_20 [concrete = constants.%C] +// CHECK:STDOUT: %.loc30_30: type = converted %.loc30_20, %as_type.loc30 [concrete = constants.%C] +// CHECK:STDOUT: %A.ref.loc30_35: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %A.ref.loc30_39: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %impl.elem0.loc30_37: %.fa7 = impl_witness_access constants.%BitAndWith.impl_witness, element0 [concrete = constants.%type.as.BitAndWith.impl.Op] +// CHECK:STDOUT: %bound_method.loc30_37: = bound_method %A.ref.loc30_35, %impl.elem0.loc30_37 [concrete = constants.%type.as.BitAndWith.impl.Op.bound] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.call.loc30_37: init type = call %bound_method.loc30_37(%A.ref.loc30_35, %A.ref.loc30_39) [concrete = constants.%A.type] +// CHECK:STDOUT: %G.ref.loc30: %A.assoc_type = name_ref G, @A.%assoc0 [concrete = constants.%assoc0.d52] +// CHECK:STDOUT: %.loc30_32: %A.type = converted %.loc30_8, [concrete = ] +// CHECK:STDOUT: %.loc38_6.1: %empty_struct_type = struct_literal () +// CHECK:STDOUT: %C.ref.loc38_11: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %.loc38_6.2: ref %C = temporary_storage +// CHECK:STDOUT: %.loc38_6.3: init %C = class_init (), %.loc38_6.2 [concrete = constants.%C.val] +// CHECK:STDOUT: %.loc38_6.4: ref %C = temporary %.loc38_6.2, %.loc38_6.3 +// CHECK:STDOUT: %.loc38_8: ref %C = converted %.loc38_6.1, %.loc38_6.4 +// CHECK:STDOUT: %C.ref.loc38_18: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %A.ref.loc38_24: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %A.ref.loc38_28: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %impl.elem0.loc38: %.fa7 = impl_witness_access constants.%BitAndWith.impl_witness, element0 [concrete = constants.%type.as.BitAndWith.impl.Op] +// CHECK:STDOUT: %bound_method.loc38_26: = bound_method %A.ref.loc38_24, %impl.elem0.loc38 [concrete = constants.%type.as.BitAndWith.impl.Op.bound] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.call.loc38: init type = call %bound_method.loc38_26(%A.ref.loc38_24, %A.ref.loc38_28) [concrete = constants.%A.type] +// CHECK:STDOUT: %.loc38_29.1: type = value_of_initializer %type.as.BitAndWith.impl.Op.call.loc38 [concrete = constants.%A.type] +// CHECK:STDOUT: %.loc38_29.2: type = converted %type.as.BitAndWith.impl.Op.call.loc38, %.loc38_29.1 [concrete = constants.%A.type] +// CHECK:STDOUT: %A.facet.loc38: %A.type = facet_value %C.ref.loc38_18, (constants.%A.impl_witness) [concrete = constants.%A.facet] +// CHECK:STDOUT: %.loc38_20: %A.type = converted %C.ref.loc38_18, %A.facet.loc38 [concrete = constants.%A.facet] +// CHECK:STDOUT: %as_type.loc38: type = facet_access_type %.loc38_20 [concrete = constants.%C] +// CHECK:STDOUT: %.loc38_30: type = converted %.loc38_20, %as_type.loc38 [concrete = constants.%C] +// CHECK:STDOUT: %A.ref.loc38_34: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %G.ref.loc38: %A.assoc_type = name_ref G, @A.%assoc0 [concrete = constants.%assoc0.d52] +// CHECK:STDOUT: %.loc38_32: %A.type = converted %.loc38_8, [concrete = ] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc38: = bound_method %.loc38_6.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.88a +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.88a, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc38_6: = bound_method %.loc38_6.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.1 +// CHECK:STDOUT: %addr.loc38: %ptr.019 = addr_of %.loc38_6.4 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc38: init %empty_tuple.type = call %bound_method.loc38_6(%addr.loc38) +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc30: = bound_method %.loc30_6.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.88a +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.88a, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc30_6: = bound_method %.loc30_6.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.2 +// CHECK:STDOUT: %addr.loc30: %ptr.019 = addr_of %.loc30_6.4 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc30: init %empty_tuple.type = call %bound_method.loc30_6(%addr.loc30) +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc22: = bound_method %.loc22_5.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.88a +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.3: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.88a, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn] +// CHECK:STDOUT: %bound_method.loc22_5: = bound_method %.loc22_5.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.3 +// CHECK:STDOUT: %addr.loc22: %ptr.019 = addr_of %.loc22_5.4 +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc22: init %empty_tuple.type = call %bound_method.loc22_5(%addr.loc22) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.G(constants.%Self.803) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.G(constants.%A.facet) {} +// CHECK:STDOUT: +// CHECK:STDOUT: --- allowed_combine_non_instance.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %A.type: type = facet_type <@A> [concrete] +// CHECK:STDOUT: %Self.803: %A.type = symbolic_binding Self, 0 [symbolic] +// CHECK:STDOUT: %A.G.type: type = fn_type @A.G [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %A.G: %A.G.type = struct_value () [concrete] +// CHECK:STDOUT: %A.assoc_type: type = assoc_entity_type @A [concrete] +// CHECK:STDOUT: %assoc0.d52: %A.assoc_type = assoc_entity element0, @A.%A.G.decl [concrete] +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete] +// CHECK:STDOUT: %complete_type: = complete_type_witness %empty_struct_type [concrete] +// CHECK:STDOUT: %A.impl_witness: = impl_witness file.%A.impl_witness_table [concrete] +// CHECK:STDOUT: %C.as.A.impl.G.type: type = fn_type @C.as.A.impl.G [concrete] +// CHECK:STDOUT: %C.as.A.impl.G: %C.as.A.impl.G.type = struct_value () [concrete] +// CHECK:STDOUT: %A.facet: %A.type = facet_value %C, (%A.impl_witness) [concrete] +// CHECK:STDOUT: %Works.type: type = fn_type @Works [concrete] +// CHECK:STDOUT: %Works: %Works.type = struct_value () [concrete] +// CHECK:STDOUT: %BitAndWith.type.f2e: type = generic_interface_type @BitAndWith [concrete] +// CHECK:STDOUT: %BitAndWith.generic: %BitAndWith.type.f2e = struct_value () [concrete] +// CHECK:STDOUT: %BitAndWith.type.8a6: type = facet_type <@BitAndWith, @BitAndWith(type)> [concrete] +// CHECK:STDOUT: %BitAndWith.Op.type.9a3: type = fn_type @BitAndWith.Op, @BitAndWith(type) [concrete] +// CHECK:STDOUT: %BitAndWith.impl_witness: = impl_witness imports.%BitAndWith.impl_witness_table [concrete] +// CHECK:STDOUT: %BitAndWith.facet: %BitAndWith.type.8a6 = facet_value type, (%BitAndWith.impl_witness) [concrete] +// CHECK:STDOUT: %.fa7: type = fn_type_with_self_type %BitAndWith.Op.type.9a3, %BitAndWith.facet [concrete] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.type: type = fn_type @type.as.BitAndWith.impl.Op [concrete] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op: %type.as.BitAndWith.impl.Op.type = struct_value () [concrete] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.bound: = bound_method %A.type, %type.as.BitAndWith.impl.Op [concrete] +// CHECK:STDOUT: %.69a: type = fn_type_with_self_type %A.G.type, %A.facet [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core: = namespace file.%Core.import, [concrete] { +// CHECK:STDOUT: .BitAndWith = %Core.BitAndWith +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/... +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.BitAndWith: %BitAndWith.type.f2e = import_ref Core//prelude/parts/as, BitAndWith, loaded [concrete = constants.%BitAndWith.generic] +// CHECK:STDOUT: %Core.import_ref.636: %type.as.BitAndWith.impl.Op.type = import_ref Core//prelude/parts/as, loc{{\d+_\d+}}, loaded [concrete = constants.%type.as.BitAndWith.impl.Op] +// CHECK:STDOUT: %BitAndWith.impl_witness_table = impl_witness_table (%Core.import_ref.636), @type.as.BitAndWith.impl [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .Core = imports.%Core +// CHECK:STDOUT: .A = %A.decl +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Works = %Works.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %A.decl: type = interface_decl @A [concrete = constants.%A.type] {} {} +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: impl_decl @C.as.A.impl [concrete] {} { +// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %A.ref: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: } +// CHECK:STDOUT: %A.impl_witness_table = impl_witness_table (@C.as.A.impl.%C.as.A.impl.G.decl), @C.as.A.impl [concrete] +// CHECK:STDOUT: %A.impl_witness: = impl_witness %A.impl_witness_table [concrete = constants.%A.impl_witness] +// CHECK:STDOUT: %Works.decl: %Works.type = fn_decl @Works [concrete = constants.%Works] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @A { +// CHECK:STDOUT: %Self: %A.type = symbolic_binding Self, 0 [symbolic = constants.%Self.803] +// CHECK:STDOUT: %A.G.decl: %A.G.type = fn_decl @A.G [concrete = constants.%A.G] {} {} +// CHECK:STDOUT: %assoc0: %A.assoc_type = assoc_entity element0, %A.G.decl [concrete = constants.%assoc0.d52] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .G = %assoc0 +// CHECK:STDOUT: witness = (%A.G.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: impl @C.as.A.impl: %C.ref as %A.ref { +// CHECK:STDOUT: %C.as.A.impl.G.decl: %C.as.A.impl.G.type = fn_decl @C.as.A.impl.G [concrete = constants.%C.as.A.impl.G] {} {} +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .G = %C.as.A.impl.G.decl +// CHECK:STDOUT: witness = file.%A.impl_witness +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// 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: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @A.G(@A.%Self: %A.type) { +// CHECK:STDOUT: fn(); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.as.A.impl.G() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Works() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %C.ref.loc13: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %A.ref.loc13_7: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %A.ref.loc13_11: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %impl.elem0.loc13_9: %.fa7 = impl_witness_access constants.%BitAndWith.impl_witness, element0 [concrete = constants.%type.as.BitAndWith.impl.Op] +// CHECK:STDOUT: %bound_method.loc13: = bound_method %A.ref.loc13_7, %impl.elem0.loc13_9 [concrete = constants.%type.as.BitAndWith.impl.Op.bound] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.call.loc13: init type = call %bound_method.loc13(%A.ref.loc13_7, %A.ref.loc13_11) [concrete = constants.%A.type] +// CHECK:STDOUT: %G.ref.loc13: %A.assoc_type = name_ref G, @A.%assoc0 [concrete = constants.%assoc0.d52] +// CHECK:STDOUT: %A.facet.loc13: %A.type = facet_value %C.ref.loc13, (constants.%A.impl_witness) [concrete = constants.%A.facet] +// CHECK:STDOUT: %.loc13: %A.type = converted %C.ref.loc13, %A.facet.loc13 [concrete = constants.%A.facet] +// CHECK:STDOUT: %impl.elem0.loc13_4: %.69a = impl_witness_access constants.%A.impl_witness, element0 [concrete = constants.%C.as.A.impl.G] +// CHECK:STDOUT: %C.as.A.impl.G.call.loc13: init %empty_tuple.type = call %impl.elem0.loc13_4() +// CHECK:STDOUT: %C.ref.loc14: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %A.ref.loc14_10: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %A.ref.loc14_14: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %impl.elem0.loc14_12: %.fa7 = impl_witness_access constants.%BitAndWith.impl_witness, element0 [concrete = constants.%type.as.BitAndWith.impl.Op] +// CHECK:STDOUT: %bound_method.loc14_12: = bound_method %A.ref.loc14_10, %impl.elem0.loc14_12 [concrete = constants.%type.as.BitAndWith.impl.Op.bound] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.call.loc14_12: init type = call %bound_method.loc14_12(%A.ref.loc14_10, %A.ref.loc14_14) [concrete = constants.%A.type] +// CHECK:STDOUT: %.loc14_15.1: type = value_of_initializer %type.as.BitAndWith.impl.Op.call.loc14_12 [concrete = constants.%A.type] +// CHECK:STDOUT: %.loc14_15.2: type = converted %type.as.BitAndWith.impl.Op.call.loc14_12, %.loc14_15.1 [concrete = constants.%A.type] +// CHECK:STDOUT: %A.facet.loc14: %A.type = facet_value %C.ref.loc14, (constants.%A.impl_witness) [concrete = constants.%A.facet] +// CHECK:STDOUT: %.loc14_6: %A.type = converted %C.ref.loc14, %A.facet.loc14 [concrete = constants.%A.facet] +// CHECK:STDOUT: %A.ref.loc14_20: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %A.ref.loc14_24: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %impl.elem0.loc14_22: %.fa7 = impl_witness_access constants.%BitAndWith.impl_witness, element0 [concrete = constants.%type.as.BitAndWith.impl.Op] +// CHECK:STDOUT: %bound_method.loc14_22: = bound_method %A.ref.loc14_20, %impl.elem0.loc14_22 [concrete = constants.%type.as.BitAndWith.impl.Op.bound] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.call.loc14_22: init type = call %bound_method.loc14_22(%A.ref.loc14_20, %A.ref.loc14_24) [concrete = constants.%A.type] +// CHECK:STDOUT: %G.ref.loc14: %A.assoc_type = name_ref G, @A.%assoc0 [concrete = constants.%assoc0.d52] +// CHECK:STDOUT: %impl.elem0.loc14_17: %.69a = impl_witness_access constants.%A.impl_witness, element0 [concrete = constants.%C.as.A.impl.G] +// CHECK:STDOUT: %C.as.A.impl.G.call.loc14: init %empty_tuple.type = call %impl.elem0.loc14_17() +// CHECK:STDOUT: %C.ref.loc15: type = name_ref C, file.%C.decl [concrete = constants.%C] +// CHECK:STDOUT: %A.ref.loc15_10: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %A.ref.loc15_14: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %impl.elem0.loc15_12: %.fa7 = impl_witness_access constants.%BitAndWith.impl_witness, element0 [concrete = constants.%type.as.BitAndWith.impl.Op] +// CHECK:STDOUT: %bound_method.loc15: = bound_method %A.ref.loc15_10, %impl.elem0.loc15_12 [concrete = constants.%type.as.BitAndWith.impl.Op.bound] +// CHECK:STDOUT: %type.as.BitAndWith.impl.Op.call.loc15: init type = call %bound_method.loc15(%A.ref.loc15_10, %A.ref.loc15_14) [concrete = constants.%A.type] +// CHECK:STDOUT: %.loc15_15.1: type = value_of_initializer %type.as.BitAndWith.impl.Op.call.loc15 [concrete = constants.%A.type] +// CHECK:STDOUT: %.loc15_15.2: type = converted %type.as.BitAndWith.impl.Op.call.loc15, %.loc15_15.1 [concrete = constants.%A.type] +// CHECK:STDOUT: %A.facet.loc15: %A.type = facet_value %C.ref.loc15, (constants.%A.impl_witness) [concrete = constants.%A.facet] +// CHECK:STDOUT: %.loc15_6: %A.type = converted %C.ref.loc15, %A.facet.loc15 [concrete = constants.%A.facet] +// CHECK:STDOUT: %A.ref.loc15_19: type = name_ref A, file.%A.decl [concrete = constants.%A.type] +// CHECK:STDOUT: %G.ref.loc15: %A.assoc_type = name_ref G, @A.%assoc0 [concrete = constants.%assoc0.d52] +// CHECK:STDOUT: %impl.elem0.loc15_17: %.69a = impl_witness_access constants.%A.impl_witness, element0 [concrete = constants.%C.as.A.impl.G] +// CHECK:STDOUT: %C.as.A.impl.G.call.loc15: init %empty_tuple.type = call %impl.elem0.loc15_17() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.G(constants.%Self.803) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @A.G(constants.%A.facet) {} +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/let/ref.carbon b/toolchain/check/testdata/let/ref.carbon new file mode 100644 index 000000000000..ce2a58f2a041 --- /dev/null +++ b/toolchain/check/testdata/let/ref.carbon @@ -0,0 +1,302 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/let/ref.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/let/ref.carbon + +// --- local.carbon + +library "[[@TEST_NAME]]"; + +fn F(a: i32) { + var b: i32 = a; + //@dump-sem-ir-begin + let ref c: i32 = b; + let (ref d: i32, ref e: i32) = (b, c); + //@dump-sem-ir-end +} + +// --- param.carbon + +library "[[@TEST_NAME]]"; + +//@dump-sem-ir-begin +fn F(ref a: i32) { + a = 1; +} + +fn G() { + var x: i32 = 0; + F(x); +} +//@dump-sem-ir-end + +// --- self.carbon + +library "[[@TEST_NAME]]"; + +//@dump-sem-ir-begin +class C { + var a: i32; + + fn F[ref self: Self]() { + self.a = 1; + } +} +//@dump-sem-ir-end + +// --- fail_ref_to_value.carbon + +library "[[@TEST_NAME]]"; + +fn F(a: i32) { + // CHECK:STDERR: fail_ref_to_value.carbon:[[@LINE+4]]:20: error: cannot bind durable reference to non-reference value of type `i32` [ConversionFailureNonRefToRef] + // CHECK:STDERR: let ref b: i32 = a; + // CHECK:STDERR: ^ + // CHECK:STDERR: + let ref b: i32 = a; +} + +// --- fail_ref_to_temporary.carbon + +library "[[@TEST_NAME]]"; + +fn G() -> i32; + +fn F() { + // CHECK:STDERR: fail_ref_to_temporary.carbon:[[@LINE+4]]:20: error: cannot bind durable reference to non-reference value of type `i32` [ConversionFailureNonRefToRef] + // CHECK:STDERR: let ref a: i32 = G(); + // CHECK:STDERR: ^~~ + // CHECK:STDERR: + let ref a: i32 = G(); +} + +// CHECK:STDOUT: --- local.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] +// CHECK:STDOUT: %tuple.type.d07: type = tuple_type (%i32, %i32) [concrete] +// CHECK:STDOUT: %pattern_type.511: type = pattern_type %tuple.type.d07 [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(%a.param: %i32) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %c.patt: %pattern_type.7ce = ref_binding_pattern c [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %b.ref.loc7: ref %i32 = name_ref b, %b +// CHECK:STDOUT: %.loc7: type = splice_block %i32.loc7 [concrete = constants.%i32] { +// CHECK:STDOUT: %int_32.loc7: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc7: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: } +// CHECK:STDOUT: %c: ref %i32 = ref_binding c, %b.ref.loc7 +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %d.patt: %pattern_type.7ce = ref_binding_pattern d [concrete] +// CHECK:STDOUT: %e.patt: %pattern_type.7ce = ref_binding_pattern e [concrete] +// CHECK:STDOUT: %.loc8_30: %pattern_type.511 = tuple_pattern (%d.patt, %e.patt) [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %b.ref.loc8: ref %i32 = name_ref b, %b +// CHECK:STDOUT: %c.ref: ref %i32 = name_ref c, %c +// CHECK:STDOUT: %.loc8_39: %tuple.type.d07 = tuple_literal (%b.ref.loc8, %c.ref) +// CHECK:STDOUT: %.loc8_15: type = splice_block %i32.loc8_15 [concrete = constants.%i32] { +// CHECK:STDOUT: %int_32.loc8_15: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc8_15: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: } +// CHECK:STDOUT: %d: ref %i32 = ref_binding d, %b.ref.loc8 +// CHECK:STDOUT: %.loc8_27: type = splice_block %i32.loc8_27 [concrete = constants.%i32] { +// CHECK:STDOUT: %int_32.loc8_27: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32.loc8_27: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: } +// CHECK:STDOUT: %e: ref %i32 = ref_binding e, %c.ref +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- param.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %pattern_type.7ce: type = pattern_type %i32 [concrete] +// CHECK:STDOUT: %F.type: type = fn_type @F [concrete] +// CHECK:STDOUT: %F: %F.type = struct_value () [concrete] +// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] +// CHECK:STDOUT: %ImplicitAs.type.d14: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] +// CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.2a1: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51 = struct_value () [symbolic] +// CHECK:STDOUT: %ImplicitAs.impl_witness.bc9: = impl_witness imports.%ImplicitAs.impl_witness_table.132, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.51e: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.51e = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.d14 = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.bc9) [concrete] +// CHECK:STDOUT: %.322: type = fn_type_with_self_type %ImplicitAs.Convert.type.1b6, %ImplicitAs.facet [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.265: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] +// CHECK:STDOUT: %bound_method.dfc: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] +// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] +// CHECK:STDOUT: %G.type: type = fn_type @G [concrete] +// CHECK:STDOUT: %G: %G.type = struct_value () [concrete] +// CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.0b3: = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b [concrete] +// CHECK:STDOUT: %bound_method.9be: = bound_method %int_0.5c6, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] +// CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete] +// CHECK:STDOUT: %type_where: type = facet_type > [concrete] +// CHECK:STDOUT: %facet_value: %type_where = facet_value %i32, () [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.d4e: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.424: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.d4e = struct_value () [concrete] +// CHECK:STDOUT: %ptr.235: type = ptr_type %i32 [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core.import_ref.e24: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.2a1)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table.132 = impl_witness_table (%Core.import_ref.e24), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] { +// CHECK:STDOUT: %a.patt: %pattern_type.7ce = ref_binding_pattern a [concrete] +// CHECK:STDOUT: %a.param_patt: %pattern_type.7ce = ref_param_pattern %a.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %a.param: ref %i32 = ref_param call_param0 +// CHECK:STDOUT: %.loc5: type = splice_block %i32 [concrete = constants.%i32] { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: } +// CHECK:STDOUT: %a: ref %i32 = ref_binding a, %a.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %G.decl: %G.type = fn_decl @G [concrete = constants.%G] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F(%a.param: %i32) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %a.ref: ref %i32 = name_ref a, %a +// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %impl.elem0: %.322 = impl_witness_access constants.%ImplicitAs.impl_witness.bc9, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b] +// CHECK:STDOUT: %bound_method.loc6_5.1: = bound_method %int_1, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.265] +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc6_5.2: = bound_method %int_1, %specific_fn [concrete = constants.%bound_method.dfc] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc6_5.2(%int_1) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc6: init %i32 = converted %int_1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: assign %a.ref, %.loc6 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @G() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %x.patt: %pattern_type.7ce = ref_binding_pattern x [concrete] +// CHECK:STDOUT: %x.var_patt: %pattern_type.7ce = var_pattern %x.patt [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x.var: ref %i32 = var %x.var_patt +// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6] +// CHECK:STDOUT: %impl.elem0: %.322 = impl_witness_access constants.%ImplicitAs.impl_witness.bc9, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b] +// CHECK:STDOUT: %bound_method.loc10_3.1: = bound_method %int_0, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.0b3] +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc10_3.2: = bound_method %int_0, %specific_fn [concrete = constants.%bound_method.9be] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc10_3.2(%int_0) [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: %.loc10_3: init %i32 = converted %int_0, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_0.6a9] +// CHECK:STDOUT: assign %x.var, %.loc10_3 +// CHECK:STDOUT: %.loc10_10: type = splice_block %i32 [concrete = constants.%i32] { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: ref %i32 = ref_binding x, %x.var +// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F] +// CHECK:STDOUT: %x.ref: ref %i32 = name_ref x, %x +// CHECK:STDOUT: %F.call: init %empty_tuple.type = call %F.ref(%x.ref) +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: = bound_method %x.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.424 +// CHECK:STDOUT: +// CHECK:STDOUT: %bound_method.loc10_3.3: = bound_method %x.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %addr: %ptr.235 = addr_of %x.var +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc10_3.3(%addr) +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- self.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [concrete] +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete] +// CHECK:STDOUT: %C.elem: type = unbound_element_type %C, %i32 [concrete] +// CHECK:STDOUT: %pattern_type.c48: type = pattern_type %C [concrete] +// CHECK:STDOUT: %C.F.type: type = fn_type @C.F [concrete] +// CHECK:STDOUT: %C.F: %C.F.type = struct_value () [concrete] +// CHECK:STDOUT: %struct_type.a: type = struct_type {.a: %i32} [concrete] +// CHECK:STDOUT: %complete_type.fd7: = complete_type_witness %struct_type.a [concrete] +// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [concrete] +// CHECK:STDOUT: %ImplicitAs.type.d14: type = facet_type <@ImplicitAs, @ImplicitAs(%i32)> [concrete] +// CHECK:STDOUT: %ImplicitAs.Convert.type.1b6: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%i32) [concrete] +// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%To) [symbolic] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.2a1: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51 = struct_value () [symbolic] +// CHECK:STDOUT: %ImplicitAs.impl_witness.bc9: = impl_witness imports.%ImplicitAs.impl_witness_table.132, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.51e: type = fn_type @Core.IntLiteral.as.ImplicitAs.impl.Convert, @Core.IntLiteral.as.ImplicitAs.impl(%int_32) [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b: %Core.IntLiteral.as.ImplicitAs.impl.Convert.type.51e = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.d14 = facet_value Core.IntLiteral, (%ImplicitAs.impl_witness.bc9) [concrete] +// CHECK:STDOUT: %.322: type = fn_type_with_self_type %ImplicitAs.Convert.type.1b6, %ImplicitAs.facet [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.bound: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b [concrete] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn: = specific_function %Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b, @Core.IntLiteral.as.ImplicitAs.impl.Convert(%int_32) [concrete] +// CHECK:STDOUT: %bound_method: = bound_method %int_1.5b8, %Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn [concrete] +// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %Core.import_ref.e24: @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert.type (%Core.IntLiteral.as.ImplicitAs.impl.Convert.type.f51) = import_ref Core//prelude/parts/int, loc{{\d+_\d+}}, loaded [symbolic = @Core.IntLiteral.as.ImplicitAs.impl.%Core.IntLiteral.as.ImplicitAs.impl.Convert (constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.2a1)] +// CHECK:STDOUT: %ImplicitAs.impl_witness_table.132 = impl_witness_table (%Core.import_ref.e24), @Core.IntLiteral.as.ImplicitAs.impl [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {} +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32] +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32] +// CHECK:STDOUT: %.loc6: %C.elem = field_decl a, element0 [concrete] +// CHECK:STDOUT: %C.F.decl: %C.F.type = fn_decl @C.F [concrete = constants.%C.F] { +// CHECK:STDOUT: %self.patt: %pattern_type.c48 = ref_binding_pattern self [concrete] +// CHECK:STDOUT: %self.param_patt: %pattern_type.c48 = ref_param_pattern %self.patt, call_param0 [concrete] +// CHECK:STDOUT: } { +// CHECK:STDOUT: %self.param: ref %C = ref_param call_param0 +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%C [concrete = constants.%C] +// CHECK:STDOUT: %self: ref %C = ref_binding self, %self.param +// CHECK:STDOUT: } +// CHECK:STDOUT: %complete_type: = complete_type_witness constants.%struct_type.a [concrete = constants.%complete_type.fd7] +// CHECK:STDOUT: complete_type_witness = %complete_type +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: .a = %.loc6 +// CHECK:STDOUT: .F = %C.F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @C.F(%self.param: %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %self.ref: ref %C = name_ref self, %self +// CHECK:STDOUT: %a.ref: %C.elem = name_ref a, @C.%.loc6 [concrete = @C.%.loc6] +// CHECK:STDOUT: %.loc9_9: ref %i32 = class_element_access %self.ref, element0 +// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8] +// CHECK:STDOUT: %impl.elem0: %.322 = impl_witness_access constants.%ImplicitAs.impl_witness.bc9, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e9b] +// CHECK:STDOUT: %bound_method.loc9_12.1: = bound_method %int_1, %impl.elem0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound] +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn] +// CHECK:STDOUT: %bound_method.loc9_12.2: = bound_method %int_1, %specific_fn [concrete = constants.%bound_method] +// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call: init %i32 = call %bound_method.loc9_12.2(%int_1) [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: %.loc9_12: init %i32 = converted %int_1, %Core.IntLiteral.as.ImplicitAs.impl.Convert.call [concrete = constants.%int_1.5d2] +// CHECK:STDOUT: assign %.loc9_9, %.loc9_12 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/thunk.cpp b/toolchain/check/thunk.cpp index 79eb9624ef6a..db7fb3719c90 100644 --- a/toolchain/check/thunk.cpp +++ b/toolchain/check/thunk.cpp @@ -296,7 +296,10 @@ static auto BuildPatternRef(Context& context, .first; auto pattern_ref_id = SemIR::InstId::None; - if (auto value_param = pattern.TryAs()) { + if (auto value_param = pattern.TryAs(); + value_param.has_value() && + (value_param->kind == SemIR::ValueParamPattern::Kind || + value_param->kind == SemIR::RefParamPattern::Kind)) { pattern_ref_id = arg_ids[value_param->index.index]; } else { if (pattern_id != SemIR::ErrorInst::InstId) { diff --git a/toolchain/diagnostics/coverage_test.cpp b/toolchain/diagnostics/coverage_test.cpp index 645781ccfea3..626fd25e3c26 100644 --- a/toolchain/diagnostics/coverage_test.cpp +++ b/toolchain/diagnostics/coverage_test.cpp @@ -62,13 +62,6 @@ constexpr Kind UntestedKinds[] = { // - Require all diagnostics produced by compiling have their first location // be in the file being compiled, never an import. Kind::LanguageServerDiagnosticInWrongFile, - - // TODO: This can only fire if we attempt to convert a non-reference - // expression to a durable reference binding. At the moment, the only time - // we attempt reference binding is within a `var` pattern, where the - // conversion cannot fail. This should be covered once we support `ref` - // binding syntax. - Kind::ConversionFailureNonRefToRef, }; // Looks for diagnostic kinds that aren't covered by a file_test. diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index 3969f3623fd3..55ca39faa173 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -101,6 +101,7 @@ CARBON_DIAGNOSTIC_KIND(ExpectedIdentifierOrSelfAfterPeriod) CARBON_DIAGNOSTIC_KIND(ExpectedBindingPattern) CARBON_DIAGNOSTIC_KIND(ExpectedGenericBindingPatternAfterTemplate) CARBON_DIAGNOSTIC_KIND(ExpectedParenAfter) +CARBON_DIAGNOSTIC_KIND(ExpectedRuntimeBindingPatternAfterRef) CARBON_DIAGNOSTIC_KIND(ExpectedExprSemi) CARBON_DIAGNOSTIC_KIND(ExpectedStatementSemi) CARBON_DIAGNOSTIC_KIND(ExpectedStructLiteralField) @@ -109,6 +110,7 @@ CARBON_DIAGNOSTIC_KIND(ExpectedChoiceDefinition) CARBON_DIAGNOSTIC_KIND(ExpectedChoiceAlternativeName) CARBON_DIAGNOSTIC_KIND(NestedVar) CARBON_DIAGNOSTIC_KIND(OperatorRequiresParentheses) +CARBON_DIAGNOSTIC_KIND(RefInsideVar) CARBON_DIAGNOSTIC_KIND(StatementOperatorAsSubExpr) CARBON_DIAGNOSTIC_KIND(UnaryOperatorRequiresParentheses) CARBON_DIAGNOSTIC_KIND(UnaryOperatorHasWhitespace) @@ -255,6 +257,7 @@ CARBON_DIAGNOSTIC_KIND(InCallToFunction) CARBON_DIAGNOSTIC_KIND(InCallToFunctionParam) CARBON_DIAGNOSTIC_KIND(MissingObjectInMethodCall) CARBON_DIAGNOSTIC_KIND(SelfParameterNotAllowed) +CARBON_DIAGNOSTIC_KIND(ValueForRefParam) // Function declaration checking. CARBON_DIAGNOSTIC_KIND(DefinedAbstractFunction) diff --git a/toolchain/lex/token_kind.def b/toolchain/lex/token_kind.def index bc124d51b083..ac07eec5dca5 100644 --- a/toolchain/lex/token_kind.def +++ b/toolchain/lex/token_kind.def @@ -203,6 +203,7 @@ CARBON_KEYWORD_TOKEN(Override, "override") CARBON_KEYWORD_TOKEN(Partial, "partial") CARBON_KEYWORD_TOKEN(Private, "private") CARBON_KEYWORD_TOKEN(Protected, "protected") +CARBON_KEYWORD_TOKEN(Ref, "ref") CARBON_KEYWORD_TOKEN(Require, "require") CARBON_KEYWORD_TOKEN(Return, "return") CARBON_KEYWORD_TOKEN(Returned, "returned") diff --git a/toolchain/lower/file_context.cpp b/toolchain/lower/file_context.cpp index 6406bf7bede7..3c3068dbc27e 100644 --- a/toolchain/lower/file_context.cpp +++ b/toolchain/lower/file_context.cpp @@ -356,7 +356,7 @@ auto FileContext::BuildFunctionTypeInfo(const SemIR::Function& function, } // TODO: Use a more general mechanism to determine if the binding is a // reference binding. - if (param_pattern_info->var_pattern_id.has_value()) { + if (param_pattern_info->inst.kind == SemIR::RefParamPattern::Kind) { param_types.push_back( llvm::PointerType::get(llvm_context(), /*AddressSpace=*/0)); param_inst_ids.push_back(param_pattern_id); diff --git a/toolchain/lower/testdata/array/field.carbon b/toolchain/lower/testdata/array/field.carbon index 0f4cae83cfce..106b19dec888 100644 --- a/toolchain/lower/testdata/array/field.carbon +++ b/toolchain/lower/testdata/array/field.carbon @@ -19,9 +19,9 @@ class A { return self.v[0]; } - fn Use[addr self: Self*]() -> i32 { - self->v[0] = 1; - return self->v[1]; + fn Use[ref self: Self]() -> i32 { + self.v[0] = 1; + return self.v[1]; } } @@ -49,13 +49,13 @@ class A { // CHECK:STDOUT: // CHECK:STDOUT: define i32 @_CUse.A.Main(ptr %self) !dbg !13 { // CHECK:STDOUT: entry: -// CHECK:STDOUT: %.loc23_9.2.v = getelementptr inbounds nuw { [2 x i32] }, ptr %self, i32 0, i32 0, !dbg !14 -// CHECK:STDOUT: %.loc23_14.array.index = getelementptr inbounds [2 x i32], ptr %.loc23_9.2.v, i32 0, i32 0, !dbg !14 -// CHECK:STDOUT: store i32 1, ptr %.loc23_14.array.index, align 4, !dbg !14 -// CHECK:STDOUT: %.loc24_16.2.v = getelementptr inbounds nuw { [2 x i32] }, ptr %self, i32 0, i32 0, !dbg !15 -// CHECK:STDOUT: %.loc24_21.1.array.index = getelementptr inbounds [2 x i32], ptr %.loc24_16.2.v, i32 0, i32 1, !dbg !15 -// CHECK:STDOUT: %.loc24_21.2 = load i32, ptr %.loc24_21.1.array.index, align 4, !dbg !15 -// CHECK:STDOUT: ret i32 %.loc24_21.2, !dbg !16 +// CHECK:STDOUT: %.loc23_9.v = getelementptr inbounds nuw { [2 x i32] }, ptr %self, i32 0, i32 0, !dbg !14 +// CHECK:STDOUT: %.loc23_13.array.index = getelementptr inbounds [2 x i32], ptr %.loc23_9.v, i32 0, i32 0, !dbg !14 +// CHECK:STDOUT: store i32 1, ptr %.loc23_13.array.index, align 4, !dbg !14 +// CHECK:STDOUT: %.loc24_16.v = getelementptr inbounds nuw { [2 x i32] }, ptr %self, i32 0, i32 0, !dbg !15 +// CHECK:STDOUT: %.loc24_20.1.array.index = getelementptr inbounds [2 x i32], ptr %.loc24_16.v, i32 0, i32 1, !dbg !15 +// CHECK:STDOUT: %.loc24_20.2 = load i32, ptr %.loc24_20.1.array.index, align 4, !dbg !15 +// CHECK:STDOUT: ret i32 %.loc24_20.2, !dbg !16 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) diff --git a/toolchain/lower/testdata/array/field_addr.carbon b/toolchain/lower/testdata/array/field_addr.carbon new file mode 100644 index 000000000000..dbe1fbd9f284 --- /dev/null +++ b/toolchain/lower/testdata/array/field_addr.carbon @@ -0,0 +1,85 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/array/field_addr.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/array/field_addr.carbon + +class A { + var v: array(i32, 2); + + fn Init() -> A { return {.v = (1, 2)}; } + + fn Access[self: Self]() -> i32 { + return self.v[0]; + } + + fn Use[addr self: Self*]() -> i32 { + self->v[0] = 1; + return self->v[1]; + } +} + +// CHECK:STDOUT: ; ModuleID = 'field_addr.carbon' +// CHECK:STDOUT: source_filename = "field_addr.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: @A.val.loc16_40 = internal constant { [2 x i32] } { [2 x i32] [i32 1, i32 2] } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CInit.A.Main(ptr sret({ [2 x i32] }) %return) !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc16_39.2.v = getelementptr inbounds nuw { [2 x i32] }, ptr %return, i32 0, i32 0, !dbg !7 +// CHECK:STDOUT: %.loc16_38.3.array.index = getelementptr inbounds [2 x i32], ptr %.loc16_39.2.v, i32 0, i64 0, !dbg !8 +// CHECK:STDOUT: %.loc16_38.6.array.index = getelementptr inbounds [2 x i32], ptr %.loc16_39.2.v, i32 0, i64 1, !dbg !8 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %return, ptr align 4 @A.val.loc16_40, i64 8, i1 false), !dbg !9 +// CHECK:STDOUT: ret void, !dbg !9 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define i32 @_CAccess.A.Main(ptr %self) !dbg !10 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc19_16.1.v = getelementptr inbounds nuw { [2 x i32] }, ptr %self, i32 0, i32 0, !dbg !11 +// CHECK:STDOUT: %.loc19_20.2.array.index = getelementptr inbounds [2 x i32], ptr %.loc19_16.1.v, i32 0, i32 0, !dbg !11 +// CHECK:STDOUT: %.loc19_20.3 = load i32, ptr %.loc19_20.2.array.index, align 4, !dbg !11 +// CHECK:STDOUT: ret i32 %.loc19_20.3, !dbg !12 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define i32 @_CUse.A.Main(ptr %self) !dbg !13 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc23_9.2.v = getelementptr inbounds nuw { [2 x i32] }, ptr %self, i32 0, i32 0, !dbg !14 +// CHECK:STDOUT: %.loc23_14.array.index = getelementptr inbounds [2 x i32], ptr %.loc23_9.2.v, i32 0, i32 0, !dbg !14 +// CHECK:STDOUT: store i32 1, ptr %.loc23_14.array.index, align 4, !dbg !14 +// CHECK:STDOUT: %.loc24_16.2.v = getelementptr inbounds nuw { [2 x i32] }, ptr %self, i32 0, i32 0, !dbg !15 +// CHECK:STDOUT: %.loc24_21.1.array.index = getelementptr inbounds [2 x i32], ptr %.loc24_16.2.v, i32 0, i32 1, !dbg !15 +// CHECK:STDOUT: %.loc24_21.2 = load i32, ptr %.loc24_21.1.array.index, align 4, !dbg !15 +// CHECK:STDOUT: ret i32 %.loc24_21.2, !dbg !16 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #0 +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.module.flags = !{!0, !1} +// CHECK:STDOUT: !llvm.dbg.cu = !{!2} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !3 = !DIFile(filename: "field_addr.carbon", directory: "") +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Init", linkageName: "_CInit.A.Main", scope: null, file: !3, line: 16, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{} +// CHECK:STDOUT: !7 = !DILocation(line: 16, column: 27, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 16, column: 33, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 16, column: 20, scope: !4) +// CHECK:STDOUT: !10 = distinct !DISubprogram(name: "Access", linkageName: "_CAccess.A.Main", scope: null, file: !3, line: 18, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !11 = !DILocation(line: 19, column: 12, scope: !10) +// CHECK:STDOUT: !12 = !DILocation(line: 19, column: 5, scope: !10) +// CHECK:STDOUT: !13 = distinct !DISubprogram(name: "Use", linkageName: "_CUse.A.Main", scope: null, file: !3, line: 22, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !14 = !DILocation(line: 23, column: 5, scope: !13) +// CHECK:STDOUT: !15 = !DILocation(line: 24, column: 12, scope: !13) +// CHECK:STDOUT: !16 = !DILocation(line: 24, column: 5, scope: !13) diff --git a/toolchain/lower/testdata/class/method.carbon b/toolchain/lower/testdata/class/method.carbon index 6cffd8d341cf..c64a703445aa 100644 --- a/toolchain/lower/testdata/class/method.carbon +++ b/toolchain/lower/testdata/class/method.carbon @@ -14,7 +14,7 @@ class C { var a: i32; fn Get[self: C]() -> i32; - fn Set[addr self: C*](n: i32); + fn Set[ref self: C](n: i32); } fn F(p: C*) { diff --git a/toolchain/lower/testdata/class/method_addr.carbon b/toolchain/lower/testdata/class/method_addr.carbon new file mode 100644 index 000000000000..d9a6e1554a91 --- /dev/null +++ b/toolchain/lower/testdata/class/method_addr.carbon @@ -0,0 +1,51 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/class/method_addr.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/class/method_addr.carbon + +class C { + var a: i32; + + fn Get[self: C]() -> i32; + fn Set[addr self: C*](n: i32); +} + +fn F(p: C*) { + let n: i32 = (*p).Get(); + (*p).Set(n); +} + +// CHECK:STDOUT: ; ModuleID = 'method_addr.carbon' +// CHECK:STDOUT: source_filename = "method_addr.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: declare i32 @_CGet.C.Main(ptr) +// CHECK:STDOUT: +// CHECK:STDOUT: declare void @_CSet.C.Main(ptr, i32) +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CF.Main(ptr %p) !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %C.Get.call = call i32 @_CGet.C.Main(ptr %p), !dbg !7 +// CHECK:STDOUT: call void @_CSet.C.Main(ptr %p, i32 %C.Get.call), !dbg !8 +// CHECK:STDOUT: ret void, !dbg !9 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.module.flags = !{!0, !1} +// CHECK:STDOUT: !llvm.dbg.cu = !{!2} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !3 = !DIFile(filename: "method_addr.carbon", directory: "") +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main", scope: null, file: !3, line: 20, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{} +// CHECK:STDOUT: !7 = !DILocation(line: 21, column: 16, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 22, column: 3, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 20, column: 1, scope: !4) diff --git a/toolchain/lower/testdata/class/self.carbon b/toolchain/lower/testdata/class/self.carbon index 7cef9fd9c5af..5e652f63e61b 100644 --- a/toolchain/lower/testdata/class/self.carbon +++ b/toolchain/lower/testdata/class/self.carbon @@ -14,15 +14,15 @@ class C { var a: i32; fn Get[self: C]() -> i32; - fn Set[addr self: C*](); + fn Set[ref self: C](); } fn C.Get[self: C]() -> i32 { return self.a; } -fn C.Set[addr self: C*]() { - (*self).a = 1; +fn C.Set[ref self: C]() { + self.a = 1; } // CHECK:STDOUT: ; ModuleID = 'self.carbon' @@ -37,8 +37,8 @@ fn C.Set[addr self: C*]() { // CHECK:STDOUT: // CHECK:STDOUT: define void @_CSet.C.Main(ptr %self) !dbg !9 { // CHECK:STDOUT: entry: -// CHECK:STDOUT: %.loc25_10.a = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !10 -// CHECK:STDOUT: store i32 1, ptr %.loc25_10.a, align 4, !dbg !10 +// CHECK:STDOUT: %.loc25_7.a = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !10 +// CHECK:STDOUT: store i32 1, ptr %.loc25_7.a, align 4, !dbg !10 // CHECK:STDOUT: ret void, !dbg !11 // CHECK:STDOUT: } // CHECK:STDOUT: diff --git a/toolchain/lower/testdata/class/self_addr.carbon b/toolchain/lower/testdata/class/self_addr.carbon new file mode 100644 index 000000000000..860f228e302b --- /dev/null +++ b/toolchain/lower/testdata/class/self_addr.carbon @@ -0,0 +1,59 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/class/self_addr.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/class/self_addr.carbon + +class C { + var a: i32; + + fn Get[self: C]() -> i32; + fn Set[addr self: C*](); +} + +fn C.Get[self: C]() -> i32 { + return self.a; +} + +fn C.Set[addr self: C*]() { + (*self).a = 1; +} + +// CHECK:STDOUT: ; ModuleID = 'self_addr.carbon' +// CHECK:STDOUT: source_filename = "self_addr.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: define i32 @_CGet.C.Main(ptr %self) !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc21_14.1.a = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !7 +// CHECK:STDOUT: %.loc21_14.2 = load i32, ptr %.loc21_14.1.a, align 4, !dbg !7 +// CHECK:STDOUT: ret i32 %.loc21_14.2, !dbg !8 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CSet.C.Main(ptr %self) !dbg !9 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %.loc25_10.a = getelementptr inbounds nuw { i32 }, ptr %self, i32 0, i32 0, !dbg !10 +// CHECK:STDOUT: store i32 1, ptr %.loc25_10.a, align 4, !dbg !10 +// CHECK:STDOUT: ret void, !dbg !11 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.module.flags = !{!0, !1} +// CHECK:STDOUT: !llvm.dbg.cu = !{!2} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !3 = !DIFile(filename: "self_addr.carbon", directory: "") +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Get", linkageName: "_CGet.C.Main", scope: null, file: !3, line: 20, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{} +// CHECK:STDOUT: !7 = !DILocation(line: 21, column: 10, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 21, column: 3, scope: !4) +// CHECK:STDOUT: !9 = distinct !DISubprogram(name: "Set", linkageName: "_CSet.C.Main", scope: null, file: !3, line: 24, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !10 = !DILocation(line: 25, column: 3, scope: !9) +// CHECK:STDOUT: !11 = !DILocation(line: 24, column: 1, scope: !9) diff --git a/toolchain/lower/testdata/function/call/ref_param.carbon b/toolchain/lower/testdata/function/call/ref_param.carbon new file mode 100644 index 000000000000..665ebd1ff36a --- /dev/null +++ b/toolchain/lower/testdata/function/call/ref_param.carbon @@ -0,0 +1,56 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/function/call/ref_param.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/function/call/ref_param.carbon + +fn DoNothing(ref a: i32) {} + +fn Main() { + var a: i32 = 0; + DoNothing(a); +} + +// CHECK:STDOUT: ; ModuleID = 'ref_param.carbon' +// CHECK:STDOUT: source_filename = "ref_param.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CDoNothing.Main(ptr %a) !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret void, !dbg !7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define void @_CMain.Main() !dbg !8 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %a.var = alloca i32, align 4, !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %a.var), !dbg !9 +// CHECK:STDOUT: store i32 0, ptr %a.var, align 4, !dbg !9 +// CHECK:STDOUT: call void @_CDoNothing.Main(ptr %a.var), !dbg !10 +// CHECK:STDOUT: ret void, !dbg !11 +// 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)) #0 +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.module.flags = !{!0, !1} +// CHECK:STDOUT: !llvm.dbg.cu = !{!2} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !3 = !DIFile(filename: "ref_param.carbon", directory: "") +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "DoNothing", linkageName: "_CDoNothing.Main", scope: null, file: !3, line: 13, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{} +// CHECK:STDOUT: !7 = !DILocation(line: 13, column: 1, scope: !4) +// CHECK:STDOUT: !8 = distinct !DISubprogram(name: "Main", linkageName: "_CMain.Main", scope: null, file: !3, line: 15, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !9 = !DILocation(line: 16, column: 3, scope: !8) +// CHECK:STDOUT: !10 = !DILocation(line: 17, column: 3, scope: !8) +// CHECK:STDOUT: !11 = !DILocation(line: 15, column: 1, scope: !8) diff --git a/toolchain/lower/testdata/impl/instance_method.carbon b/toolchain/lower/testdata/impl/instance_method.carbon index 53b834cbae69..b530b4a171e5 100644 --- a/toolchain/lower/testdata/impl/instance_method.carbon +++ b/toolchain/lower/testdata/impl/instance_method.carbon @@ -13,13 +13,13 @@ class A; interface GetSelf { - fn Get[addr self: Self*]() -> Self*; + fn Get[ref self: Self]() -> Self*; } class A { extend impl as GetSelf { - fn Get[addr self: Self*]() -> Self* { - return self; + fn Get[ref self: Self]() -> Self* { + return &self; } } } diff --git a/toolchain/lower/testdata/impl/instance_method_addr.carbon b/toolchain/lower/testdata/impl/instance_method_addr.carbon new file mode 100644 index 000000000000..502ea56a5e31 --- /dev/null +++ b/toolchain/lower/testdata/impl/instance_method_addr.carbon @@ -0,0 +1,58 @@ +// 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/impl/instance_method_addr.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/impl/instance_method_addr.carbon + +class A; + +interface GetSelf { + fn Get[addr self: Self*]() -> Self*; +} + +class A { + extend impl as GetSelf { + fn Get[addr self: Self*]() -> Self* { + return self; + } + } +} + +fn Call(a: A*) -> A* { + return (*a).Get(); +} + +// CHECK:STDOUT: ; ModuleID = 'instance_method_addr.carbon' +// CHECK:STDOUT: source_filename = "instance_method_addr.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: define ptr @"_CGet.A.Main:GetSelf.Main"(ptr %self) !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: ret ptr %self, !dbg !7 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: define ptr @_CCall.Main(ptr %a) !dbg !8 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %A.as.GetSelf.impl.Get.call = call ptr @"_CGet.A.Main:GetSelf.Main"(ptr %a), !dbg !9 +// CHECK:STDOUT: ret ptr %A.as.GetSelf.impl.Get.call, !dbg !10 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !llvm.module.flags = !{!0, !1} +// CHECK:STDOUT: !llvm.dbg.cu = !{!2} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !3 = !DIFile(filename: "instance_method_addr.carbon", directory: "") +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Get", linkageName: "_CGet.A.Main:GetSelf.Main", scope: null, file: !3, line: 21, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{} +// CHECK:STDOUT: !7 = !DILocation(line: 22, column: 7, scope: !4) +// CHECK:STDOUT: !8 = distinct !DISubprogram(name: "Call", linkageName: "_CCall.Main", scope: null, file: !3, line: 27, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !9 = !DILocation(line: 28, column: 10, scope: !8) +// CHECK:STDOUT: !10 = !DILocation(line: 28, column: 3, scope: !8) diff --git a/toolchain/parse/handle_binding_pattern.cpp b/toolchain/parse/handle_binding_pattern.cpp index 7a6aa1609034..6f321ae0d0d1 100644 --- a/toolchain/parse/handle_binding_pattern.cpp +++ b/toolchain/parse/handle_binding_pattern.cpp @@ -34,6 +34,12 @@ auto HandleBindingPattern(Context& context) -> void { // A `template` keyword may precede the name. auto template_token = context.ConsumeIf(Lex::TokenKind::Template); + auto ref_token = context.ConsumeIf(Lex::TokenKind::Ref); + if (ref_token && state.in_var_pattern) { + CARBON_DIAGNOSTIC(RefInsideVar, Error, "found `ref` inside `var` pattern"); + context.emitter().Emit(*ref_token, RefInsideVar); + state.has_error = true; + } // The first item should be an identifier, the placeholder `_`, or `self`. if (auto identifier = context.ConsumeIf(Lex::TokenKind::Identifier)) { @@ -67,6 +73,16 @@ auto HandleBindingPattern(Context& context) -> void { context.AddNode(NodeKind::TemplateBindingName, *template_token, state.has_error); } + if (ref_token) { + if (token_kind != Lex::TokenKind::Colon && !state.has_error) { + CARBON_DIAGNOSTIC(ExpectedRuntimeBindingPatternAfterRef, Error, + "expected `:` binding after `ref`"); + context.emitter().Emit(*ref_token, + ExpectedRuntimeBindingPatternAfterRef); + state.has_error = true; + } + context.AddNode(NodeKind::RefBindingName, *ref_token, state.has_error); + } state.kind = token_kind == Lex::TokenKind::Colon ? StateKind::BindingPatternFinishAsRegular diff --git a/toolchain/parse/node_kind.def b/toolchain/parse/node_kind.def index f09f17a8e072..db86dbe92082 100644 --- a/toolchain/parse/node_kind.def +++ b/toolchain/parse/node_kind.def @@ -167,6 +167,7 @@ CARBON_PARSE_NODE_KIND(ArrayExprKeyword) CARBON_PARSE_NODE_KIND(ArrayExprComma) CARBON_PARSE_NODE_KIND(ArrayExpr) +CARBON_PARSE_NODE_KIND(RefBindingName) CARBON_PARSE_NODE_KIND(LetBindingPattern) CARBON_PARSE_NODE_KIND(AssociatedConstantNameAndType) CARBON_PARSE_NODE_KIND(VarBindingPattern) diff --git a/toolchain/parse/state.def b/toolchain/parse/state.def index b161007612c7..e64efe3f8785 100644 --- a/toolchain/parse/state.def +++ b/toolchain/parse/state.def @@ -1011,11 +1011,11 @@ CARBON_PARSE_STATE(Pattern) // // THEN // -// name: ... +// [ref] name: ... // ^~~~~ -// self: ... +// [ref] self: ... // ^~~~~ -// _: ... +// [ref] _: ... // ^~ // 1. Expr // 2. BindingPatternFinishAsRegular diff --git a/toolchain/parse/testdata/let/fail_generic_ref.carbon b/toolchain/parse/testdata/let/fail_generic_ref.carbon new file mode 100644 index 000000000000..677587889f97 --- /dev/null +++ b/toolchain/parse/testdata/let/fail_generic_ref.carbon @@ -0,0 +1,30 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/let/fail_generic_ref.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/let/fail_generic_ref.carbon + +// CHECK:STDERR: fail_generic_ref.carbon:[[@LINE+4]]:5: error: expected `:` binding after `ref` [ExpectedRuntimeBindingPatternAfterRef] +// CHECK:STDERR: let ref X:! i32 = 0; +// CHECK:STDERR: ^~~ +// CHECK:STDERR: +let ref X:! i32 = 0; + +// CHECK:STDOUT: - filename: fail_generic_ref.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'LetIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'X'}, +// CHECK:STDOUT: {kind: 'RefBindingName', text: 'ref', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':!', has_error: yes, subtree_size: 3}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':!', has_error: yes, subtree_size: 5}, +// CHECK:STDOUT: {kind: 'LetInitializer', text: '='}, +// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'}, +// CHECK:STDOUT: {kind: 'LetDecl', text: ';', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/let/let_ref.carbon b/toolchain/parse/testdata/let/let_ref.carbon new file mode 100644 index 000000000000..c853380b4498 --- /dev/null +++ b/toolchain/parse/testdata/let/let_ref.carbon @@ -0,0 +1,60 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/let/let_ref.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/let/let_ref.carbon + +let ref v: i32 = 0; +let ref _: i32 = 1; +fn F() { + let ref s: str = "hello"; + let ref _: str = "goodbye"; +} + +// CHECK:STDOUT: - filename: let_ref.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'LetIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'v'}, +// CHECK:STDOUT: {kind: 'RefBindingName', text: 'ref', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'LetInitializer', text: '='}, +// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'}, +// CHECK:STDOUT: {kind: 'LetDecl', text: ';', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'LetIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'UnderscoreName', text: '_'}, +// CHECK:STDOUT: {kind: 'RefBindingName', text: 'ref', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'LetInitializer', text: '='}, +// CHECK:STDOUT: {kind: 'IntLiteral', text: '1'}, +// CHECK:STDOUT: {kind: 'LetDecl', text: ';', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'FunctionIntroducer', text: 'fn'}, +// CHECK:STDOUT: {kind: 'IdentifierNameBeforeParams', text: 'F'}, +// CHECK:STDOUT: {kind: 'ExplicitParamListStart', text: '('}, +// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'FunctionDefinitionStart', text: '{', subtree_size: 5}, +// CHECK:STDOUT: {kind: 'LetIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 's'}, +// CHECK:STDOUT: {kind: 'RefBindingName', text: 'ref', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'StringTypeLiteral', text: 'str'}, +// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'LetInitializer', text: '='}, +// CHECK:STDOUT: {kind: 'StringLiteral', text: '"hello"'}, +// CHECK:STDOUT: {kind: 'LetDecl', text: ';', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'LetIntroducer', text: 'let'}, +// CHECK:STDOUT: {kind: 'UnderscoreName', text: '_'}, +// CHECK:STDOUT: {kind: 'RefBindingName', text: 'ref', subtree_size: 2}, +// CHECK:STDOUT: {kind: 'StringTypeLiteral', text: 'str'}, +// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 4}, +// CHECK:STDOUT: {kind: 'LetInitializer', text: '='}, +// CHECK:STDOUT: {kind: 'StringLiteral', text: '"goodbye"'}, +// CHECK:STDOUT: {kind: 'LetDecl', text: ';', subtree_size: 8}, +// CHECK:STDOUT: {kind: 'FunctionDefinition', text: '}', subtree_size: 22}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] diff --git a/toolchain/parse/testdata/var/fail_ref.carbon b/toolchain/parse/testdata/var/fail_ref.carbon new file mode 100644 index 000000000000..d4d0f9b482a9 --- /dev/null +++ b/toolchain/parse/testdata/var/fail_ref.carbon @@ -0,0 +1,30 @@ +// 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 +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/var/fail_ref.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/var/fail_ref.carbon + +// CHECK:STDERR: fail_ref.carbon:[[@LINE+4]]:5: error: found `ref` inside `var` pattern [RefInsideVar] +// CHECK:STDERR: var ref x: i32 = 0; +// CHECK:STDERR: ^~~ +// CHECK:STDERR: +var ref x: i32 = 0; + +// CHECK:STDOUT: - filename: fail_ref.carbon +// CHECK:STDOUT: parse_tree: [ +// CHECK:STDOUT: {kind: 'FileStart', text: ''}, +// CHECK:STDOUT: {kind: 'VariableIntroducer', text: 'var'}, +// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeParams', text: 'x'}, +// CHECK:STDOUT: {kind: 'RefBindingName', text: 'ref', has_error: yes, subtree_size: 2}, +// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'}, +// CHECK:STDOUT: {kind: 'VarBindingPattern', text: ':', has_error: yes, subtree_size: 4}, +// CHECK:STDOUT: {kind: 'VariablePattern', text: 'var', has_error: yes, subtree_size: 5}, +// CHECK:STDOUT: {kind: 'VariableInitializer', text: '='}, +// CHECK:STDOUT: {kind: 'IntLiteral', text: '0'}, +// CHECK:STDOUT: {kind: 'VariableDecl', text: ';', subtree_size: 9}, +// CHECK:STDOUT: {kind: 'FileEnd', text: ''}, +// CHECK:STDOUT: ] diff --git a/toolchain/parse/typed_nodes.h b/toolchain/parse/typed_nodes.h index a866b4c3f8b5..fa125cba22f1 100644 --- a/toolchain/parse/typed_nodes.h +++ b/toolchain/parse/typed_nodes.h @@ -322,17 +322,29 @@ struct Namespace { // Pattern nodes // ------------- -// A pattern binding, such as `name: Type`, that isn't inside a `var` pattern. +// A ref binding name: `ref name`. +struct RefBindingName { + static constexpr auto Kind = + NodeKind::RefBindingName.Define({.child_count = 1}); + + Lex::RefTokenIndex token; + AnyRuntimeBindingPatternName name; +}; + +// A binding pattern, such as `name: Type`, that isn't inside a `var` pattern. struct LetBindingPattern { static constexpr auto Kind = NodeKind::LetBindingPattern.Define( {.category = NodeCategory::Pattern, .child_count = 2}); - AnyRuntimeBindingPatternName name; + // TODO: is there some way to reuse AnyRuntimeBindingPatternName here? + NodeIdOneOf + name; Lex::ColonTokenIndex token; AnyExprId type; }; -// A pattern binding, such as `name: Type`, that is inside a `var` pattern. +// A binding pattern, such as `name: Type`, that is inside a `var` pattern. struct VarBindingPattern { static constexpr auto Kind = NodeKind::VarBindingPattern.Define( {.category = NodeCategory::Pattern, .child_count = 2}); diff --git a/toolchain/sem_ir/function.cpp b/toolchain/sem_ir/function.cpp index 0a38d24aebbb..59da7397469e 100644 --- a/toolchain/sem_ir/function.cpp +++ b/toolchain/sem_ir/function.cpp @@ -114,8 +114,7 @@ auto Function::GetParamPatternInfoFromPatternId(const File& sem_ir, auto inst = sem_ir.insts().Get(inst_id); sem_ir.insts().TryUnwrap(inst, inst_id, &AddrPattern::inner_id); - auto [var_pattern, var_pattern_id] = - sem_ir.insts().TryUnwrap(inst, inst_id, &VarPattern::subpattern_id); + sem_ir.insts().TryUnwrap(inst, inst_id, &VarPattern::subpattern_id); auto [param_pattern, param_pattern_id] = sem_ir.insts().TryUnwrap(inst, inst_id, &AnyParamPattern::subpattern_id); if (!param_pattern) { @@ -125,8 +124,7 @@ auto Function::GetParamPatternInfoFromPatternId(const File& sem_ir, auto binding_pattern = inst.As(); return {{.inst_id = param_pattern_id, .inst = *param_pattern, - .entity_name_id = binding_pattern.entity_name_id, - .var_pattern_id = var_pattern_id}}; + .entity_name_id = binding_pattern.entity_name_id}}; } auto Function::GetDeclaredReturnType(const File& file, diff --git a/toolchain/sem_ir/function.h b/toolchain/sem_ir/function.h index 6610e53f5bf0..8a6b506feac0 100644 --- a/toolchain/sem_ir/function.h +++ b/toolchain/sem_ir/function.h @@ -94,7 +94,6 @@ struct Function : public EntityWithParamsBase, InstId inst_id; AnyParamPattern inst; EntityNameId entity_name_id; - KnownInstId var_pattern_id; }; auto Print(llvm::raw_ostream& out) const -> void {