Reverse nesting of BoundMethod and SpecificFunction. (#5079)

During SemIR, when identifying a specific in a specific context, we'd
have to either look through a specific or through a bound method.
Canonicalize which one to look through first, by having the BoundMethod
created around a SpecificFunction instead.
This changes a lot of check tests.

TODO: As the SemIr does not currently allow removal (access to insts()
is intentionally const), the bound instruction created prior to finding
the specific is not removed from the instructions.
Options: (1) leave as is, (2) add a way to remove the previous bound,
(3) rethink how/when the BoundMethod inst is created.
This commit is contained in:
Alina Sbirlea
2025-03-08 01:34:06 +00:00
committed by GitHub
parent 820ace95e8
commit 7fd54eded0
165 changed files with 2795 additions and 1958 deletions
+10 -7
View File
@@ -255,7 +255,8 @@ fn D() {}
// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.205 = facet_value Core.IntLiteral, %impl_witness.d39 [concrete]
// CHECK:STDOUT: %.a0b: type = fn_type_with_self_type %Convert.type.1b6, %ImplicitAs.facet [concrete]
// CHECK:STDOUT: %Convert.bound: <bound method> = bound_method %int_1.5b8, %Convert.956 [concrete]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.956, @Convert.2(%int_32) [concrete]
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_1.5b8, %Convert.specific_fn [concrete]
// CHECK:STDOUT: %int_1.5d2: %i32 = int_value 1 [concrete]
// CHECK:STDOUT: %struct_type.c: type = struct_type {.c: %i32} [concrete]
// CHECK:STDOUT: %C.type: type = fn_type @C [concrete]
@@ -338,9 +339,10 @@ fn D() {}
// CHECK:STDOUT: %B.ref: %B.type = name_ref B, imports.%Main.B [concrete = constants.%B]
// CHECK:STDOUT: %int_1.loc7: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
// CHECK:STDOUT: %impl.elem0.loc7: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc7: <bound method> = bound_method %int_1.loc7, %impl.elem0.loc7 [concrete = constants.%Convert.bound]
// CHECK:STDOUT: %specific_fn.loc7: <specific function> = specific_function %bound_method.loc7, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %int.convert_checked.loc7: init %i32 = call %specific_fn.loc7(%int_1.loc7) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %bound_method.loc7_16.1: <bound method> = bound_method %int_1.loc7, %impl.elem0.loc7 [concrete = constants.%Convert.bound]
// CHECK:STDOUT: %specific_fn.loc7: <specific function> = specific_function %impl.elem0.loc7, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc7_16.2: <bound method> = bound_method %int_1.loc7, %specific_fn.loc7 [concrete = constants.%bound_method]
// CHECK:STDOUT: %int.convert_checked.loc7: init %i32 = call %bound_method.loc7_16.2(%int_1.loc7) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc7_16.1: %i32 = value_of_initializer %int.convert_checked.loc7 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc7_16.2: %i32 = converted %int_1.loc7, %.loc7_16.1 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %B.call: init %i32 = call %B.ref(%.loc7_16.2)
@@ -349,9 +351,10 @@ fn D() {}
// CHECK:STDOUT: %int_1.loc8: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
// CHECK:STDOUT: %.loc8_25.1: %tuple.type.985 = tuple_literal (%int_1.loc8)
// CHECK:STDOUT: %impl.elem0.loc8: %.a0b = impl_witness_access constants.%impl_witness.d39, element0 [concrete = constants.%Convert.956]
// CHECK:STDOUT: %bound_method.loc8: <bound method> = bound_method %int_1.loc8, %impl.elem0.loc8 [concrete = constants.%Convert.bound]
// CHECK:STDOUT: %specific_fn.loc8: <specific function> = specific_function %bound_method.loc8, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %int.convert_checked.loc8: init %i32 = call %specific_fn.loc8(%int_1.loc8) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %bound_method.loc8_25.1: <bound method> = bound_method %int_1.loc8, %impl.elem0.loc8 [concrete = constants.%Convert.bound]
// CHECK:STDOUT: %specific_fn.loc8: <specific function> = specific_function %impl.elem0.loc8, @Convert.2(constants.%int_32) [concrete = constants.%Convert.specific_fn]
// CHECK:STDOUT: %bound_method.loc8_25.2: <bound method> = bound_method %int_1.loc8, %specific_fn.loc8 [concrete = constants.%bound_method]
// CHECK:STDOUT: %int.convert_checked.loc8: init %i32 = call %bound_method.loc8_25.2(%int_1.loc8) [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc8_25.2: %i32 = value_of_initializer %int.convert_checked.loc8 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %.loc8_25.3: %i32 = converted %int_1.loc8, %.loc8_25.2 [concrete = constants.%int_1.5d2]
// CHECK:STDOUT: %tuple: %tuple.type.a1c = tuple_value (%.loc8_25.3) [concrete = constants.%tuple]