Handle SpecificImplFunction in GetCallee (#6487)

I need this in a forthcoming PR, to reliably get the `Function` that was
originally used to build a `Call` inst, but even as a stand-alone
change, it seems to nicely improve the textual SemIR.
This commit is contained in:
Geoff Romer
2025-12-11 01:06:16 +00:00
committed by GitHub
parent ff8ce31e1b
commit a0d1e4b809
36 changed files with 370 additions and 366 deletions
+16 -16
View File
@@ -161,20 +161,20 @@ fn CallSpecific(x: C*) -> C* {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %T.binding.as_type [symbolic = %require_complete (constants.%require_complete.91e)]
// CHECK:STDOUT: %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %T.loc5_13.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.edd)]
// CHECK:STDOUT: %.loc6_10.2: type = fn_type_with_self_type constants.%Copy.Op.type, %T.loc5_13.1 [symbolic = %.loc6_10.2 (constants.%.232)]
// CHECK:STDOUT: %impl.elem0.loc6_10.2: @Function.%.loc6_10.2 (%.232) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc6_10.2 (constants.%impl.elem0.8df)]
// CHECK:STDOUT: %.loc6: type = fn_type_with_self_type constants.%Copy.Op.type, %T.loc5_13.1 [symbolic = %.loc6 (constants.%.232)]
// CHECK:STDOUT: %impl.elem0.loc6_10.2: @Function.%.loc6 (%.232) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc6_10.2 (constants.%impl.elem0.8df)]
// CHECK:STDOUT: %specific_impl_fn.loc6_10.2: <specific function> = specific_impl_function %impl.elem0.loc6_10.2, @Copy.Op(%T.loc5_13.1) [symbolic = %specific_impl_fn.loc6_10.2 (constants.%specific_impl_fn.5c4)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%x.param: @Function.%T.binding.as_type (%T.binding.as_type)) -> %return.param: @Function.%T.binding.as_type (%T.binding.as_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %x.ref: @Function.%T.binding.as_type (%T.binding.as_type) = name_ref x, %x
// CHECK:STDOUT: %impl.elem0.loc6_10.1: @Function.%.loc6_10.2 (%.232) = impl_witness_access constants.%Copy.lookup_impl_witness.edd, element0 [symbolic = %impl.elem0.loc6_10.2 (constants.%impl.elem0.8df)]
// CHECK:STDOUT: %impl.elem0.loc6_10.1: @Function.%.loc6 (%.232) = impl_witness_access constants.%Copy.lookup_impl_witness.edd, element0 [symbolic = %impl.elem0.loc6_10.2 (constants.%impl.elem0.8df)]
// CHECK:STDOUT: %bound_method.loc6_10.1: <bound method> = bound_method %x.ref, %impl.elem0.loc6_10.1
// CHECK:STDOUT: %specific_impl_fn.loc6_10.1: <specific function> = specific_impl_function %impl.elem0.loc6_10.1, @Copy.Op(constants.%T.f92) [symbolic = %specific_impl_fn.loc6_10.2 (constants.%specific_impl_fn.5c4)]
// CHECK:STDOUT: %bound_method.loc6_10.2: <bound method> = bound_method %x.ref, %specific_impl_fn.loc6_10.1
// CHECK:STDOUT: %.loc5_34: ref @Function.%T.binding.as_type (%T.binding.as_type) = splice_block %return {}
// CHECK:STDOUT: %.loc6_10.1: init @Function.%T.binding.as_type (%T.binding.as_type) = call %bound_method.loc6_10.2(%x.ref) to %.loc5_34
// CHECK:STDOUT: return %.loc6_10.1 to %return
// CHECK:STDOUT: %Copy.Op.call: init @Function.%T.binding.as_type (%T.binding.as_type) = call %bound_method.loc6_10.2(%x.ref) to %.loc5_34
// CHECK:STDOUT: return %Copy.Op.call to %return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -252,7 +252,7 @@ fn CallSpecific(x: C*) -> C* {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete => constants.%require_complete.91e
// CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.lookup_impl_witness.edd
// CHECK:STDOUT: %.loc6_10.2 => constants.%.232
// CHECK:STDOUT: %.loc6 => constants.%.232
// CHECK:STDOUT: %impl.elem0.loc6_10.2 => constants.%impl.elem0.8df
// CHECK:STDOUT: %specific_impl_fn.loc6_10.2 => constants.%specific_impl_fn.5c4
// CHECK:STDOUT: }
@@ -277,7 +277,7 @@ fn CallSpecific(x: C*) -> C* {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete => constants.%require_complete.ef1
// CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.lookup_impl_witness.2e6
// CHECK:STDOUT: %.loc6_10.2 => constants.%.cb5
// CHECK:STDOUT: %.loc6 => constants.%.cb5
// CHECK:STDOUT: %impl.elem0.loc6_10.2 => constants.%impl.elem0.771
// CHECK:STDOUT: %specific_impl_fn.loc6_10.2 => constants.%specific_impl_fn.b85
// CHECK:STDOUT: }
@@ -290,7 +290,7 @@ fn CallSpecific(x: C*) -> C* {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete => constants.%complete_type.d05
// CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.impl_witness.bbd
// CHECK:STDOUT: %.loc6_10.2 => constants.%.99d
// CHECK:STDOUT: %.loc6 => constants.%.99d
// CHECK:STDOUT: %impl.elem0.loc6_10.2 => constants.%ptr.as.Copy.impl.Op.24b
// CHECK:STDOUT: %specific_impl_fn.loc6_10.2 => constants.%ptr.as.Copy.impl.Op.specific_fn
// CHECK:STDOUT: }
@@ -386,20 +386,20 @@ fn CallSpecific(x: C*) -> C* {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type %T.binding.as_type [symbolic = %require_complete (constants.%require_complete.91e)]
// CHECK:STDOUT: %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %T.loc5_13.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.edd)]
// CHECK:STDOUT: %.loc6_10.2: type = fn_type_with_self_type constants.%Copy.Op.type, %T.loc5_13.1 [symbolic = %.loc6_10.2 (constants.%.232)]
// CHECK:STDOUT: %impl.elem0.loc6_10.2: @Function.%.loc6_10.2 (%.232) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc6_10.2 (constants.%impl.elem0.8df)]
// CHECK:STDOUT: %.loc6: type = fn_type_with_self_type constants.%Copy.Op.type, %T.loc5_13.1 [symbolic = %.loc6 (constants.%.232)]
// CHECK:STDOUT: %impl.elem0.loc6_10.2: @Function.%.loc6 (%.232) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc6_10.2 (constants.%impl.elem0.8df)]
// CHECK:STDOUT: %specific_impl_fn.loc6_10.2: <specific function> = specific_impl_function %impl.elem0.loc6_10.2, @Copy.Op(%T.loc5_13.1) [symbolic = %specific_impl_fn.loc6_10.2 (constants.%specific_impl_fn.5c4)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%x.param: @Function.%T.binding.as_type (%T.binding.as_type)) -> %return.param: @Function.%T.binding.as_type (%T.binding.as_type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %x.ref: @Function.%T.binding.as_type (%T.binding.as_type) = name_ref x, %x
// CHECK:STDOUT: %impl.elem0.loc6_10.1: @Function.%.loc6_10.2 (%.232) = impl_witness_access constants.%Copy.lookup_impl_witness.edd, element0 [symbolic = %impl.elem0.loc6_10.2 (constants.%impl.elem0.8df)]
// CHECK:STDOUT: %impl.elem0.loc6_10.1: @Function.%.loc6 (%.232) = impl_witness_access constants.%Copy.lookup_impl_witness.edd, element0 [symbolic = %impl.elem0.loc6_10.2 (constants.%impl.elem0.8df)]
// CHECK:STDOUT: %bound_method.loc6_10.1: <bound method> = bound_method %x.ref, %impl.elem0.loc6_10.1
// CHECK:STDOUT: %specific_impl_fn.loc6_10.1: <specific function> = specific_impl_function %impl.elem0.loc6_10.1, @Copy.Op(constants.%T.f92) [symbolic = %specific_impl_fn.loc6_10.2 (constants.%specific_impl_fn.5c4)]
// CHECK:STDOUT: %bound_method.loc6_10.2: <bound method> = bound_method %x.ref, %specific_impl_fn.loc6_10.1
// CHECK:STDOUT: %.loc5_34: ref @Function.%T.binding.as_type (%T.binding.as_type) = splice_block %return {}
// CHECK:STDOUT: %.loc6_10.1: init @Function.%T.binding.as_type (%T.binding.as_type) = call %bound_method.loc6_10.2(%x.ref) to %.loc5_34
// CHECK:STDOUT: return %.loc6_10.1 to %return
// CHECK:STDOUT: %Copy.Op.call: init @Function.%T.binding.as_type (%T.binding.as_type) = call %bound_method.loc6_10.2(%x.ref) to %.loc5_34
// CHECK:STDOUT: return %Copy.Op.call to %return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -468,7 +468,7 @@ fn CallSpecific(x: C*) -> C* {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete => constants.%require_complete.91e
// CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.lookup_impl_witness.edd
// CHECK:STDOUT: %.loc6_10.2 => constants.%.232
// CHECK:STDOUT: %.loc6 => constants.%.232
// CHECK:STDOUT: %impl.elem0.loc6_10.2 => constants.%impl.elem0.8df
// CHECK:STDOUT: %specific_impl_fn.loc6_10.2 => constants.%specific_impl_fn.5c4
// CHECK:STDOUT: }
@@ -493,7 +493,7 @@ fn CallSpecific(x: C*) -> C* {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete => constants.%require_complete.ef1
// CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.lookup_impl_witness.2e6
// CHECK:STDOUT: %.loc6_10.2 => constants.%.cb5
// CHECK:STDOUT: %.loc6 => constants.%.cb5
// CHECK:STDOUT: %impl.elem0.loc6_10.2 => constants.%impl.elem0.771
// CHECK:STDOUT: %specific_impl_fn.loc6_10.2 => constants.%specific_impl_fn.b85
// CHECK:STDOUT: }
@@ -506,7 +506,7 @@ fn CallSpecific(x: C*) -> C* {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete => constants.%complete_type.d05
// CHECK:STDOUT: %Copy.lookup_impl_witness => constants.%Copy.impl_witness.bbd
// CHECK:STDOUT: %.loc6_10.2 => constants.%.99d
// CHECK:STDOUT: %.loc6 => constants.%.99d
// CHECK:STDOUT: %impl.elem0.loc6_10.2 => constants.%ptr.as.Copy.impl.Op.24b
// CHECK:STDOUT: %specific_impl_fn.loc6_10.2 => constants.%ptr.as.Copy.impl.Op.specific_fn
// CHECK:STDOUT: }
@@ -272,7 +272,7 @@ fn G() {
// CHECK:STDOUT: %.loc34_4.2: type = converted %U.ref, %U.as_type [symbolic = %U.binding.as_type (constants.%U.binding.as_type)]
// CHECK:STDOUT: %impl.elem0.loc34_4.1: @CallGenericMethod.%.loc34_4.3 (%.096) = impl_witness_access constants.%Generic.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc34_4.2 (constants.%impl.elem0)]
// CHECK:STDOUT: %specific_impl_fn.loc34_4.1: <specific function> = specific_impl_function %impl.elem0.loc34_4.1, @Generic.F(constants.%T, constants.%U) [symbolic = %specific_impl_fn.loc34_4.2 (constants.%specific_impl_fn)]
// CHECK:STDOUT: %.loc34_7: init %empty_tuple.type = call %specific_impl_fn.loc34_4.1()
// CHECK:STDOUT: %Generic.F.call: init %empty_tuple.type = call %specific_impl_fn.loc34_4.1()
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
@@ -46,11 +46,11 @@ fn F(T:! type, p: T**) -> T* {
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %.loc6_10.4: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc4_6.1) [symbolic = %.loc6_10.4 (constants.%.841)]
// CHECK:STDOUT: %.loc6_10.3: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc4_6.1) [symbolic = %.loc6_10.3 (constants.%.841)]
// CHECK:STDOUT: %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr.loc4_20.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)]
// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc4_20.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)]
// CHECK:STDOUT: %.loc6_10.5: type = fn_type_with_self_type constants.%Copy.Op.type, %Copy.facet [symbolic = %.loc6_10.5 (constants.%.cb5)]
// CHECK:STDOUT: %impl.elem0.loc6_10.2: @F.%.loc6_10.5 (%.cb5) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc6_10.2 (constants.%impl.elem0.771)]
// CHECK:STDOUT: %.loc6_10.4: type = fn_type_with_self_type constants.%Copy.Op.type, %Copy.facet [symbolic = %.loc6_10.4 (constants.%.cb5)]
// CHECK:STDOUT: %impl.elem0.loc6_10.2: @F.%.loc6_10.4 (%.cb5) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc6_10.2 (constants.%impl.elem0.771)]
// CHECK:STDOUT: %specific_impl_fn.loc6_10.2: <specific function> = specific_impl_function %impl.elem0.loc6_10.2, @Copy.Op(%Copy.facet) [symbolic = %specific_impl_fn.loc6_10.2 (constants.%specific_impl_fn.b85)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%p.param: @F.%ptr.loc4_21.1 (%ptr.125)) -> @F.%ptr.loc4_20.1 (%ptr.e8f) {
@@ -58,12 +58,12 @@ fn F(T:! type, p: T**) -> T* {
// CHECK:STDOUT: %p.ref: @F.%ptr.loc4_21.1 (%ptr.125) = name_ref p, %p
// CHECK:STDOUT: %.loc6_10.1: ref @F.%ptr.loc4_20.1 (%ptr.e8f) = deref %p.ref
// CHECK:STDOUT: %.loc6_10.2: @F.%ptr.loc4_20.1 (%ptr.e8f) = acquire_value %.loc6_10.1
// CHECK:STDOUT: %impl.elem0.loc6_10.1: @F.%.loc6_10.5 (%.cb5) = impl_witness_access constants.%Copy.lookup_impl_witness.2e6, element0 [symbolic = %impl.elem0.loc6_10.2 (constants.%impl.elem0.771)]
// CHECK:STDOUT: %impl.elem0.loc6_10.1: @F.%.loc6_10.4 (%.cb5) = impl_witness_access constants.%Copy.lookup_impl_witness.2e6, element0 [symbolic = %impl.elem0.loc6_10.2 (constants.%impl.elem0.771)]
// CHECK:STDOUT: %bound_method.loc6_10.1: <bound method> = bound_method %.loc6_10.2, %impl.elem0.loc6_10.1
// CHECK:STDOUT: %specific_impl_fn.loc6_10.1: <specific function> = specific_impl_function %impl.elem0.loc6_10.1, @Copy.Op(constants.%Copy.facet) [symbolic = %specific_impl_fn.loc6_10.2 (constants.%specific_impl_fn.b85)]
// CHECK:STDOUT: %bound_method.loc6_10.2: <bound method> = bound_method %.loc6_10.2, %specific_impl_fn.loc6_10.1
// CHECK:STDOUT: %.loc6_10.3: init @F.%ptr.loc4_20.1 (%ptr.e8f) = call %bound_method.loc6_10.2(%.loc6_10.2)
// CHECK:STDOUT: return %.loc6_10.3 to %return
// CHECK:STDOUT: %Copy.Op.call: init @F.%ptr.loc4_20.1 (%ptr.e8f) = call %bound_method.loc6_10.2(%.loc6_10.2)
// CHECK:STDOUT: return %Copy.Op.call to %return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -45,11 +45,11 @@ fn F(T:! type, n: T*) -> T* {
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %.loc7_10.2: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc4_6.1) [symbolic = %.loc7_10.2 (constants.%.841)]
// CHECK:STDOUT: %.loc7_10.1: require_specific_def_type = require_specific_def @ptr.as.Copy.impl(%T.loc4_6.1) [symbolic = %.loc7_10.1 (constants.%.841)]
// CHECK:STDOUT: %Copy.lookup_impl_witness: <witness> = lookup_impl_witness %ptr.loc4_20.1, @Copy [symbolic = %Copy.lookup_impl_witness (constants.%Copy.lookup_impl_witness.2e6)]
// CHECK:STDOUT: %Copy.facet: %Copy.type = facet_value %ptr.loc4_20.1, (%Copy.lookup_impl_witness) [symbolic = %Copy.facet (constants.%Copy.facet)]
// CHECK:STDOUT: %.loc7_10.3: type = fn_type_with_self_type constants.%Copy.Op.type, %Copy.facet [symbolic = %.loc7_10.3 (constants.%.cb5)]
// CHECK:STDOUT: %impl.elem0.loc7_10.2: @F.%.loc7_10.3 (%.cb5) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc7_10.2 (constants.%impl.elem0.771)]
// CHECK:STDOUT: %.loc7_10.2: type = fn_type_with_self_type constants.%Copy.Op.type, %Copy.facet [symbolic = %.loc7_10.2 (constants.%.cb5)]
// CHECK:STDOUT: %impl.elem0.loc7_10.2: @F.%.loc7_10.2 (%.cb5) = impl_witness_access %Copy.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc7_10.2 (constants.%impl.elem0.771)]
// CHECK:STDOUT: %specific_impl_fn.loc7_10.2: <specific function> = specific_impl_function %impl.elem0.loc7_10.2, @Copy.Op(%Copy.facet) [symbolic = %specific_impl_fn.loc7_10.2 (constants.%specific_impl_fn.b85)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%n.param: @F.%ptr.loc4_20.1 (%ptr)) -> @F.%ptr.loc4_20.1 (%ptr) {
@@ -64,12 +64,12 @@ fn F(T:! type, n: T*) -> T* {
// CHECK:STDOUT: }
// CHECK:STDOUT: %m: @F.%ptr.loc4_20.1 (%ptr) = value_binding m, %n.ref
// CHECK:STDOUT: %m.ref: @F.%ptr.loc4_20.1 (%ptr) = name_ref m, %m
// CHECK:STDOUT: %impl.elem0.loc7_10.1: @F.%.loc7_10.3 (%.cb5) = impl_witness_access constants.%Copy.lookup_impl_witness.2e6, element0 [symbolic = %impl.elem0.loc7_10.2 (constants.%impl.elem0.771)]
// CHECK:STDOUT: %impl.elem0.loc7_10.1: @F.%.loc7_10.2 (%.cb5) = impl_witness_access constants.%Copy.lookup_impl_witness.2e6, element0 [symbolic = %impl.elem0.loc7_10.2 (constants.%impl.elem0.771)]
// CHECK:STDOUT: %bound_method.loc7_10.1: <bound method> = bound_method %m.ref, %impl.elem0.loc7_10.1
// CHECK:STDOUT: %specific_impl_fn.loc7_10.1: <specific function> = specific_impl_function %impl.elem0.loc7_10.1, @Copy.Op(constants.%Copy.facet) [symbolic = %specific_impl_fn.loc7_10.2 (constants.%specific_impl_fn.b85)]
// CHECK:STDOUT: %bound_method.loc7_10.2: <bound method> = bound_method %m.ref, %specific_impl_fn.loc7_10.1
// CHECK:STDOUT: %.loc7_10.1: init @F.%ptr.loc4_20.1 (%ptr) = call %bound_method.loc7_10.2(%m.ref)
// CHECK:STDOUT: return %.loc7_10.1 to %return
// CHECK:STDOUT: %Copy.Op.call: init @F.%ptr.loc4_20.1 (%ptr) = call %bound_method.loc7_10.2(%m.ref)
// CHECK:STDOUT: return %Copy.Op.call to %return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: