From 288cffd19a887b4e21b998ab3499101131b56d47 Mon Sep 17 00:00:00 2001 From: danakj Date: Mon, 3 Mar 2025 14:24:23 -0500 Subject: [PATCH 1/3] Perform member lookup on FacetAccessType The name scope lookup and member name lookup both need to handle the case where the base inst is a FacetAccessType. Then we move from the FacetAccessType to the FacetType which is the type of the instruction inside the FacetAccessType. We do name lookup on FacetType already, so "unwrapping" the FacetAccessType to the FacetType just makes use of that path. Similarly we do member access on FacetType already, so we can reuse that codepath with the FacetType found in the FacetAccessType. --- toolchain/check/member_access.cpp | 20 ++++++++++--- toolchain/check/name_lookup.cpp | 13 +++++++++ .../testdata/facet/no_prelude/access.carbon | 29 +++++++++++++++---- 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/toolchain/check/member_access.cpp b/toolchain/check/member_access.cpp index fc1afe6f78fff..073621f00b85f 100644 --- a/toolchain/check/member_access.cpp +++ b/toolchain/check/member_access.cpp @@ -287,8 +287,16 @@ static auto LookupMemberNameInScope(Context& context, SemIR::LocId loc_id, context.types().TryGetAs(type_id)) { if (lookup_in_type_of_base) { SemIR::TypeId base_type_id = context.insts().Get(base_id).type_id(); - if (base_type_id != SemIR::TypeType::SingletonTypeId && - context.types().IsFacetType(base_type_id)) { + if (auto facet_access_type = + context.types().TryGetAs(base_type_id)) { + // Move from the type of a symbolic facet value up in typish-ness to its + // FacetType to find the type to work with. + base_id = facet_access_type->facet_value_inst_id; + base_type_id = context.insts().Get(base_id).type_id(); + } + + if (auto facet_type = + context.types().TryGetAs(base_type_id)) { // Handles `T.F` when `T` is a non-type facet. auto base_as_type = ExprAsType(context, loc_id, base_id); @@ -301,9 +309,8 @@ static auto LookupMemberNameInScope(Context& context, SemIR::LocId loc_id, // First look for `*assoc_interface` in the type of the base. If it is // found, get the witness that the interface is implemented from // `base_id`. - auto facet_type = context.types().GetAs(base_type_id); const auto& facet_type_info = - context.facet_types().Get(facet_type.facet_type_id); + context.facet_types().Get(facet_type->facet_type_id); // Witness that `T` implements the `*assoc_interface`. SemIR::InstId witness_inst_id = SemIR::InstId::None; for (auto base_interface : facet_type_info.impls_constraints) { @@ -496,6 +503,11 @@ auto PerformMemberAccess(Context& context, SemIR::LocId loc_id, return SemIR::ErrorInst::SingletonInstId; } + if (auto facet_type = context.insts().TryGetAs( + context.constant_values().GetInstId(base_type_const_id))) { + llvm::errs() << "hi\n"; + } + if (base_type_id != SemIR::ErrorInst::SingletonTypeId) { CARBON_DIAGNOSTIC(QualifiedExprUnsupported, Error, "type {0} does not support qualified expressions", diff --git a/toolchain/check/name_lookup.cpp b/toolchain/check/name_lookup.cpp index 2662355cf5736..b7893051eab11 100644 --- a/toolchain/check/name_lookup.cpp +++ b/toolchain/check/name_lookup.cpp @@ -234,6 +234,19 @@ auto AppendLookupScopesForConstant(Context& context, SemIR::LocId loc_id, -> bool { auto base_id = context.constant_values().GetInstId(base_const_id); auto base = context.insts().Get(base_id); + + if (auto base_as_facet_access_type = base.TryAs()) { + // Move from the symbolic facet value up in typish-ness to its FacetType to + // find a lookup scope. + auto facet_type_type_id = + context.insts() + .Get(base_as_facet_access_type->facet_value_inst_id) + .type_id(); + base_const_id = context.types().GetConstantId(facet_type_type_id); + base_id = context.constant_values().GetInstId(base_const_id); + base = context.insts().Get(base_id); + } + if (auto base_as_namespace = base.TryAs()) { scopes->push_back( LookupScope{.name_scope_id = base_as_namespace->name_scope_id, diff --git a/toolchain/check/testdata/facet/no_prelude/access.carbon b/toolchain/check/testdata/facet/no_prelude/access.carbon index de26cc80c6529..d37a36e3405ba 100644 --- a/toolchain/check/testdata/facet/no_prelude/access.carbon +++ b/toolchain/check/testdata/facet/no_prelude/access.carbon @@ -41,10 +41,6 @@ interface I { } fn Use[T:! I](x: T) -> T { - // CHECK:STDERR: fail_todo_access_assoc_method.carbon:[[@LINE+4]]:10: error: type `T` does not support qualified expressions [QualifiedExprUnsupported] - // CHECK:STDERR: return x.Copy(); - // CHECK:STDERR: ^~~~~~ - // CHECK:STDERR: return x.Copy(); } @@ -286,6 +282,10 @@ fn UseIndirect[T:! I](x: T) -> T { // CHECK:STDOUT: %Use.type: type = fn_type @Use [concrete] // CHECK:STDOUT: %Use: %Use.type = struct_value () [concrete] // CHECK:STDOUT: %require_complete: = require_complete_type %T.as_type [symbolic] +// CHECK:STDOUT: %T.as_wit: = facet_access_witness %T [symbolic] +// CHECK:STDOUT: %I.facet: %I.type = facet_value %T.as_type, %T.as_wit [symbolic] +// CHECK:STDOUT: %.4ef: type = fn_type_with_self_type %Copy.type, %I.facet [symbolic] +// CHECK:STDOUT: %impl.elem0: %.4ef = impl_witness_access %T.as_wit, element0 [symbolic] // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: file { @@ -363,11 +363,25 @@ fn UseIndirect[T:! I](x: T) -> T { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete: = require_complete_type @Use.%T.as_type.loc8_18.2 (%T.as_type) [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: %T.as_wit.loc13_11.2: = facet_access_witness %T.loc8_8.2 [symbolic = %T.as_wit.loc13_11.2 (constants.%T.as_wit)] +// CHECK:STDOUT: %I.facet: %I.type = facet_value %T.as_type.loc8_18.2, %T.as_wit.loc13_11.2 [symbolic = %I.facet (constants.%I.facet)] +// CHECK:STDOUT: %.loc13_11.2: type = fn_type_with_self_type constants.%Copy.type, %I.facet [symbolic = %.loc13_11.2 (constants.%.4ef)] +// CHECK:STDOUT: %impl.elem0.loc13_11.2: @Use.%.loc13_11.2 (%.4ef) = impl_witness_access %T.as_wit.loc13_11.2, element0 [symbolic = %impl.elem0.loc13_11.2 (constants.%impl.elem0)] // CHECK:STDOUT: // CHECK:STDOUT: fn[%T.param_patt: %I.type](%x.param_patt: @Use.%T.as_type.loc8_18.2 (%T.as_type)) -> @Use.%T.as_type.loc8_18.2 (%T.as_type) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %x.ref: @Use.%T.as_type.loc8_18.2 (%T.as_type) = name_ref x, %x -// CHECK:STDOUT: return +// CHECK:STDOUT: %Copy.ref: %I.assoc_type = name_ref Copy, @I.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %T.as_type.loc13: type = facet_access_type constants.%T [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc13_11.1: type = converted constants.%T, %T.as_type.loc13 [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: %T.as_wit.loc13_11.1: = facet_access_witness constants.%T [symbolic = %T.as_wit.loc13_11.2 (constants.%T.as_wit)] +// CHECK:STDOUT: %impl.elem0.loc13_11.1: @Use.%.loc13_11.2 (%.4ef) = impl_witness_access %T.as_wit.loc13_11.1, element0 [symbolic = %impl.elem0.loc13_11.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %bound_method: = bound_method %x.ref, %impl.elem0.loc13_11.1 +// CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Copy(constants.%I.facet) +// CHECK:STDOUT: %Copy.call: init @Use.%T.as_type.loc8_18.2 (%T.as_type) = call %specific_fn(%x.ref) +// CHECK:STDOUT: %.loc13_18.1: @Use.%T.as_type.loc8_18.2 (%T.as_type) = value_of_initializer %Copy.call +// CHECK:STDOUT: %.loc13_18.2: @Use.%T.as_type.loc8_18.2 (%T.as_type) = converted %Copy.call, %.loc13_18.1 +// CHECK:STDOUT: return %.loc13_18.2 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -382,6 +396,11 @@ fn UseIndirect[T:! I](x: T) -> T { // CHECK:STDOUT: %T.as_type.loc8_18.2 => constants.%T.as_type // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: specific @Copy(constants.%I.facet) { +// CHECK:STDOUT: %Self => constants.%I.facet +// CHECK:STDOUT: %Self.as_type.loc5_17.1 => constants.%T.as_type +// CHECK:STDOUT: } +// CHECK:STDOUT: // CHECK:STDOUT: --- access_assoc_method_indirect.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { From 302f4331a2441665102c9c3ee3a9762c3c6211bf Mon Sep 17 00:00:00 2001 From: danakj Date: Mon, 3 Mar 2025 14:45:33 -0500 Subject: [PATCH 2/3] rename-test-and-add-selfless --- .../testdata/facet/no_prelude/access.carbon | 142 ++++++++++++++++-- 1 file changed, 128 insertions(+), 14 deletions(-) diff --git a/toolchain/check/testdata/facet/no_prelude/access.carbon b/toolchain/check/testdata/facet/no_prelude/access.carbon index d37a36e3405ba..a3efc091e98dc 100644 --- a/toolchain/check/testdata/facet/no_prelude/access.carbon +++ b/toolchain/check/testdata/facet/no_prelude/access.carbon @@ -32,7 +32,7 @@ fn Use(T:! I) -> T { return T.Make(); } -// --- fail_todo_access_assoc_method.carbon +// --- access_assoc_method.carbon library "[[@TEST_NAME]]"; @@ -44,6 +44,18 @@ fn Use[T:! I](x: T) -> T { return x.Copy(); } +// --- access_selfless_method.carbon + +library "[[@TEST_NAME]]"; + +interface I { + fn Hello(); +} + +fn Use[T:! I](x: T){ + x.Hello(); +} + // --- access_assoc_method_indirect.carbon library "[[@TEST_NAME]]"; @@ -266,7 +278,7 @@ fn UseIndirect[T:! I](x: T) -> T { // CHECK:STDOUT: // CHECK:STDOUT: specific @Make(@Use.%I.facet) {} // CHECK:STDOUT: -// CHECK:STDOUT: --- fail_todo_access_assoc_method.carbon +// CHECK:STDOUT: --- access_assoc_method.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { // CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] @@ -363,25 +375,25 @@ fn UseIndirect[T:! I](x: T) -> T { // CHECK:STDOUT: // CHECK:STDOUT: !definition: // CHECK:STDOUT: %require_complete: = require_complete_type @Use.%T.as_type.loc8_18.2 (%T.as_type) [symbolic = %require_complete (constants.%require_complete)] -// CHECK:STDOUT: %T.as_wit.loc13_11.2: = facet_access_witness %T.loc8_8.2 [symbolic = %T.as_wit.loc13_11.2 (constants.%T.as_wit)] -// CHECK:STDOUT: %I.facet: %I.type = facet_value %T.as_type.loc8_18.2, %T.as_wit.loc13_11.2 [symbolic = %I.facet (constants.%I.facet)] -// CHECK:STDOUT: %.loc13_11.2: type = fn_type_with_self_type constants.%Copy.type, %I.facet [symbolic = %.loc13_11.2 (constants.%.4ef)] -// CHECK:STDOUT: %impl.elem0.loc13_11.2: @Use.%.loc13_11.2 (%.4ef) = impl_witness_access %T.as_wit.loc13_11.2, element0 [symbolic = %impl.elem0.loc13_11.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %T.as_wit.loc9_11.2: = facet_access_witness %T.loc8_8.2 [symbolic = %T.as_wit.loc9_11.2 (constants.%T.as_wit)] +// CHECK:STDOUT: %I.facet: %I.type = facet_value %T.as_type.loc8_18.2, %T.as_wit.loc9_11.2 [symbolic = %I.facet (constants.%I.facet)] +// CHECK:STDOUT: %.loc9_11.2: type = fn_type_with_self_type constants.%Copy.type, %I.facet [symbolic = %.loc9_11.2 (constants.%.4ef)] +// CHECK:STDOUT: %impl.elem0.loc9_11.2: @Use.%.loc9_11.2 (%.4ef) = impl_witness_access %T.as_wit.loc9_11.2, element0 [symbolic = %impl.elem0.loc9_11.2 (constants.%impl.elem0)] // CHECK:STDOUT: // CHECK:STDOUT: fn[%T.param_patt: %I.type](%x.param_patt: @Use.%T.as_type.loc8_18.2 (%T.as_type)) -> @Use.%T.as_type.loc8_18.2 (%T.as_type) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %x.ref: @Use.%T.as_type.loc8_18.2 (%T.as_type) = name_ref x, %x // CHECK:STDOUT: %Copy.ref: %I.assoc_type = name_ref Copy, @I.%assoc0 [concrete = constants.%assoc0] -// CHECK:STDOUT: %T.as_type.loc13: type = facet_access_type constants.%T [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] -// CHECK:STDOUT: %.loc13_11.1: type = converted constants.%T, %T.as_type.loc13 [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] -// CHECK:STDOUT: %T.as_wit.loc13_11.1: = facet_access_witness constants.%T [symbolic = %T.as_wit.loc13_11.2 (constants.%T.as_wit)] -// CHECK:STDOUT: %impl.elem0.loc13_11.1: @Use.%.loc13_11.2 (%.4ef) = impl_witness_access %T.as_wit.loc13_11.1, element0 [symbolic = %impl.elem0.loc13_11.2 (constants.%impl.elem0)] -// CHECK:STDOUT: %bound_method: = bound_method %x.ref, %impl.elem0.loc13_11.1 +// CHECK:STDOUT: %T.as_type.loc9: type = facet_access_type constants.%T [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc9_11.1: type = converted constants.%T, %T.as_type.loc9 [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: %T.as_wit.loc9_11.1: = facet_access_witness constants.%T [symbolic = %T.as_wit.loc9_11.2 (constants.%T.as_wit)] +// CHECK:STDOUT: %impl.elem0.loc9_11.1: @Use.%.loc9_11.2 (%.4ef) = impl_witness_access %T.as_wit.loc9_11.1, element0 [symbolic = %impl.elem0.loc9_11.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %bound_method: = bound_method %x.ref, %impl.elem0.loc9_11.1 // CHECK:STDOUT: %specific_fn: = specific_function %bound_method, @Copy(constants.%I.facet) // CHECK:STDOUT: %Copy.call: init @Use.%T.as_type.loc8_18.2 (%T.as_type) = call %specific_fn(%x.ref) -// CHECK:STDOUT: %.loc13_18.1: @Use.%T.as_type.loc8_18.2 (%T.as_type) = value_of_initializer %Copy.call -// CHECK:STDOUT: %.loc13_18.2: @Use.%T.as_type.loc8_18.2 (%T.as_type) = converted %Copy.call, %.loc13_18.1 -// CHECK:STDOUT: return %.loc13_18.2 +// CHECK:STDOUT: %.loc9_18.1: @Use.%T.as_type.loc8_18.2 (%T.as_type) = value_of_initializer %Copy.call +// CHECK:STDOUT: %.loc9_18.2: @Use.%T.as_type.loc8_18.2 (%T.as_type) = converted %Copy.call, %.loc9_18.1 +// CHECK:STDOUT: return %.loc9_18.2 // CHECK:STDOUT: } // CHECK:STDOUT: } // CHECK:STDOUT: @@ -401,6 +413,108 @@ fn UseIndirect[T:! I](x: T) -> T { // CHECK:STDOUT: %Self.as_type.loc5_17.1 => constants.%T.as_type // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: --- access_selfless_method.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete] +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic] +// CHECK:STDOUT: %Hello.type: type = fn_type @Hello [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %Hello: %Hello.type = struct_value () [concrete] +// CHECK:STDOUT: %I.assoc_type: type = assoc_entity_type %I.type [concrete] +// CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, @I.%Hello.decl [concrete] +// CHECK:STDOUT: %T: %I.type = bind_symbolic_name T, 0 [symbolic] +// CHECK:STDOUT: %T.patt: %I.type = symbolic_binding_pattern T, 0 [symbolic] +// CHECK:STDOUT: %T.as_type: type = facet_access_type %T [symbolic] +// CHECK:STDOUT: %Use.type: type = fn_type @Use [concrete] +// CHECK:STDOUT: %Use: %Use.type = struct_value () [concrete] +// CHECK:STDOUT: %require_complete: = require_complete_type %T.as_type [symbolic] +// CHECK:STDOUT: %T.as_wit: = facet_access_witness %T [symbolic] +// CHECK:STDOUT: %I.facet: %I.type = facet_value %T.as_type, %T.as_wit [symbolic] +// CHECK:STDOUT: %.33b: type = fn_type_with_self_type %Hello.type, %I.facet [symbolic] +// CHECK:STDOUT: %impl.elem0: %.33b = impl_witness_access %T.as_wit, element0 [symbolic] +// CHECK:STDOUT: %specific_fn: = specific_function %impl.elem0, @Hello(%I.facet) [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [concrete] { +// CHECK:STDOUT: .I = %I.decl +// CHECK:STDOUT: .Use = %Use.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {} +// CHECK:STDOUT: %Use.decl: %Use.type = fn_decl @Use [concrete = constants.%Use] { +// CHECK:STDOUT: %T.patt.loc8_8.1: %I.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_8.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.param_patt: %I.type = value_param_pattern %T.patt.loc8_8.1, runtime_param [symbolic = %T.patt.loc8_8.2 (constants.%T.patt)] +// CHECK:STDOUT: %x.patt: @Use.%T.as_type.loc8_18.2 (%T.as_type) = binding_pattern x +// CHECK:STDOUT: %x.param_patt: @Use.%T.as_type.loc8_18.2 (%T.as_type) = value_param_pattern %x.patt, runtime_param0 +// CHECK:STDOUT: } { +// CHECK:STDOUT: %T.param: %I.type = value_param runtime_param +// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type] +// CHECK:STDOUT: %T.loc8_8.1: %I.type = bind_symbolic_name T, 0, %T.param [symbolic = %T.loc8_8.2 (constants.%T)] +// CHECK:STDOUT: %x.param: @Use.%T.as_type.loc8_18.2 (%T.as_type) = value_param runtime_param0 +// CHECK:STDOUT: %.loc8_18.1: type = splice_block %.loc8_18.2 [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] { +// CHECK:STDOUT: %T.ref: %I.type = name_ref T, %T.loc8_8.1 [symbolic = %T.loc8_8.2 (constants.%T)] +// CHECK:STDOUT: %T.as_type.loc8_18.1: type = facet_access_type %T.ref [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc8_18.2: type = converted %T.ref, %T.as_type.loc8_18.1 [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x: @Use.%T.as_type.loc8_18.2 (%T.as_type) = bind_name x, %x.param +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @I { +// CHECK:STDOUT: %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self] +// CHECK:STDOUT: %Hello.decl: %Hello.type = fn_decl @Hello [concrete = constants.%Hello] {} {} +// CHECK:STDOUT: %assoc0: %I.assoc_type = assoc_entity element0, %Hello.decl [concrete = constants.%assoc0] +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = %Self +// CHECK:STDOUT: .Hello = %assoc0 +// CHECK:STDOUT: witness = (%Hello.decl) +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Hello(@I.%Self: %I.type) { +// CHECK:STDOUT: fn(); +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: generic fn @Use(%T.loc8_8.1: %I.type) { +// CHECK:STDOUT: %T.loc8_8.2: %I.type = bind_symbolic_name T, 0 [symbolic = %T.loc8_8.2 (constants.%T)] +// CHECK:STDOUT: %T.patt.loc8_8.2: %I.type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc8_8.2 (constants.%T.patt)] +// CHECK:STDOUT: %T.as_type.loc8_18.2: type = facet_access_type %T.loc8_8.2 [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: +// CHECK:STDOUT: !definition: +// CHECK:STDOUT: %require_complete: = require_complete_type @Use.%T.as_type.loc8_18.2 (%T.as_type) [symbolic = %require_complete (constants.%require_complete)] +// CHECK:STDOUT: %T.as_wit.loc9_4.2: = facet_access_witness %T.loc8_8.2 [symbolic = %T.as_wit.loc9_4.2 (constants.%T.as_wit)] +// CHECK:STDOUT: %I.facet: %I.type = facet_value %T.as_type.loc8_18.2, %T.as_wit.loc9_4.2 [symbolic = %I.facet (constants.%I.facet)] +// CHECK:STDOUT: %.loc9_4.2: type = fn_type_with_self_type constants.%Hello.type, %I.facet [symbolic = %.loc9_4.2 (constants.%.33b)] +// CHECK:STDOUT: %impl.elem0.loc9_4.2: @Use.%.loc9_4.2 (%.33b) = impl_witness_access %T.as_wit.loc9_4.2, element0 [symbolic = %impl.elem0.loc9_4.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %specific_fn.loc9_4.2: = specific_function %impl.elem0.loc9_4.2, @Hello(%I.facet) [symbolic = %specific_fn.loc9_4.2 (constants.%specific_fn)] +// CHECK:STDOUT: +// CHECK:STDOUT: fn[%T.param_patt: %I.type](%x.param_patt: @Use.%T.as_type.loc8_18.2 (%T.as_type)) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %x.ref: @Use.%T.as_type.loc8_18.2 (%T.as_type) = name_ref x, %x +// CHECK:STDOUT: %Hello.ref: %I.assoc_type = name_ref Hello, @I.%assoc0 [concrete = constants.%assoc0] +// CHECK:STDOUT: %T.as_type.loc9: type = facet_access_type constants.%T [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: %.loc9_4.1: type = converted constants.%T, %T.as_type.loc9 [symbolic = %T.as_type.loc8_18.2 (constants.%T.as_type)] +// CHECK:STDOUT: %T.as_wit.loc9_4.1: = facet_access_witness constants.%T [symbolic = %T.as_wit.loc9_4.2 (constants.%T.as_wit)] +// CHECK:STDOUT: %impl.elem0.loc9_4.1: @Use.%.loc9_4.2 (%.33b) = impl_witness_access %T.as_wit.loc9_4.1, element0 [symbolic = %impl.elem0.loc9_4.2 (constants.%impl.elem0)] +// CHECK:STDOUT: %specific_fn.loc9_4.1: = specific_function %impl.elem0.loc9_4.1, @Hello(constants.%I.facet) [symbolic = %specific_fn.loc9_4.2 (constants.%specific_fn)] +// CHECK:STDOUT: %Hello.call: init %empty_tuple.type = call %specific_fn.loc9_4.1() +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Hello(constants.%Self) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Use(constants.%T) { +// CHECK:STDOUT: %T.loc8_8.2 => constants.%T +// CHECK:STDOUT: %T.patt.loc8_8.2 => constants.%T +// CHECK:STDOUT: %T.as_type.loc8_18.2 => constants.%T.as_type +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Hello(constants.%I.facet) {} +// CHECK:STDOUT: +// CHECK:STDOUT: specific @Hello(@Use.%I.facet) {} +// CHECK:STDOUT: // CHECK:STDOUT: --- access_assoc_method_indirect.carbon // CHECK:STDOUT: // CHECK:STDOUT: constants { From 3733a4baaa7f29e6d1f7bb0c4e013815ab80b749 Mon Sep 17 00:00:00 2001 From: danakj Date: Mon, 3 Mar 2025 15:09:43 -0500 Subject: [PATCH 3/3] debugging --- toolchain/check/member_access.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/toolchain/check/member_access.cpp b/toolchain/check/member_access.cpp index 073621f00b85f..ed94ab4eef8b7 100644 --- a/toolchain/check/member_access.cpp +++ b/toolchain/check/member_access.cpp @@ -503,11 +503,6 @@ auto PerformMemberAccess(Context& context, SemIR::LocId loc_id, return SemIR::ErrorInst::SingletonInstId; } - if (auto facet_type = context.insts().TryGetAs( - context.constant_values().GetInstId(base_type_const_id))) { - llvm::errs() << "hi\n"; - } - if (base_type_id != SemIR::ErrorInst::SingletonTypeId) { CARBON_DIAGNOSTIC(QualifiedExprUnsupported, Error, "type {0} does not support qualified expressions",