Don't form a bound method when calling a C++ operator. (#7345)

Because we now support calling a function with a `self` parameter
directly, we can unconditionally call `operator$(lhs, rhs)` rather than
calling `lhs.operator$(rhs)` if the selected operator function happens
to be a member function.

This makes the logic a bit simpler and the SemIR a bit smaller.

We can't do the same for Carbon operators, unfortunately, as we use the
member access to trigger impl lookup.
This commit is contained in:
Richard Smith
2026-06-11 21:49:20 +00:00
committed by GitHub
parent e83422b375
commit c3fc59b8b9
7 changed files with 13 additions and 143 deletions
@@ -1869,7 +1869,6 @@ fn F() {
// CHECK:STDOUT: }
// CHECK:STDOUT: %c1.ref.loc48: ref %C = name_ref c1, %c1
// CHECK:STDOUT: %int_42: Core.IntLiteral = int_value 42 [concrete = constants.%int_42.20e]
// CHECK:STDOUT: %C.cpp_operator.bound: <bound method> = bound_method %c1.ref.loc48, imports.%C.cpp_operator.decl
// CHECK:STDOUT: %impl.elem0.loc48: %.1c5 = impl_witness_access constants.%ImplicitAs.impl_witness.a23, element0 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.e39]
// CHECK:STDOUT: %bound_method.loc48_30.1: <bound method> = bound_method %int_42, %impl.elem0.loc48 [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.bound.bf3]
// CHECK:STDOUT: %specific_fn.loc48: <specific function> = specific_function %impl.elem0.loc48, @Core.IntLiteral.as.ImplicitAs.impl.Convert(constants.%int_32) [concrete = constants.%Core.IntLiteral.as.ImplicitAs.impl.Convert.specific_fn]
@@ -1877,7 +1876,7 @@ fn F() {
// CHECK:STDOUT: %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc48: init %i32 = call %bound_method.loc48_30.2(%int_42) [concrete = constants.%int_42.ac4]
// CHECK:STDOUT: %.loc48_30.1: %i32 = value_of_initializer %Core.IntLiteral.as.ImplicitAs.impl.Convert.call.loc48 [concrete = constants.%int_42.ac4]
// CHECK:STDOUT: %.loc48_30.2: %i32 = converted %int_42, %.loc48_30.1 [concrete = constants.%int_42.ac4]
// CHECK:STDOUT: %C.cpp_operator.call: init %i32 = call %C.cpp_operator.bound(%c1.ref.loc48, %.loc48_30.2)
// CHECK:STDOUT: %C.cpp_operator.call: init %i32 = call imports.%C.cpp_operator.decl(%c1.ref.loc48, %.loc48_30.2)
// CHECK:STDOUT: %i32: type = type_literal constants.%i32 [concrete = constants.%i32]
// CHECK:STDOUT: %.loc48_32.1: %i32 = value_of_initializer %C.cpp_operator.call
// CHECK:STDOUT: %.loc48_32.2: %i32 = converted %C.cpp_operator.call, %.loc48_32.1
@@ -3076,12 +3075,8 @@ fn F() {
// CHECK:STDOUT: %ptr.0a2: type = ptr_type %C [concrete]
// CHECK:STDOUT: %C__carbon_thunk.type: type = fn_type @C__carbon_thunk [concrete]
// CHECK:STDOUT: %C__carbon_thunk: %C__carbon_thunk.type = struct_value () [concrete]
// CHECK:STDOUT: %C.cpp_operator.type.c4928b.1: type = fn_type @C.cpp_operator.1 [concrete]
// CHECK:STDOUT: %C.cpp_operator.fb6eba.1: %C.cpp_operator.type.c4928b.1 = struct_value () [concrete]
// CHECK:STDOUT: %operator_Minus__carbon_thunk.type: type = fn_type @operator_Minus__carbon_thunk [concrete]
// CHECK:STDOUT: %operator_Minus__carbon_thunk: %operator_Minus__carbon_thunk.type = struct_value () [concrete]
// CHECK:STDOUT: %C.cpp_operator.type.c4928b.2: type = fn_type @C.cpp_operator.2 [concrete]
// CHECK:STDOUT: %C.cpp_operator.fb6eba.2: %C.cpp_operator.type.c4928b.2 = struct_value () [concrete]
// CHECK:STDOUT: %operator_Plus__carbon_thunk.type: type = fn_type @operator_Plus__carbon_thunk [concrete]
// CHECK:STDOUT: %operator_Plus__carbon_thunk: %operator_Plus__carbon_thunk.type = struct_value () [concrete]
// CHECK:STDOUT: %C.cpp_destructor.type: type = fn_type @C.cpp_destructor [concrete]
@@ -3102,21 +3097,11 @@ fn F() {
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.cpp_operator.decl.25fc23.1: %C.cpp_operator.type.c4928b.1 = fn_decl @C.cpp_operator.1 [concrete = constants.%C.cpp_operator.fb6eba.1] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: %operator_Minus__carbon_thunk.decl: %operator_Minus__carbon_thunk.type = fn_decl @operator_Minus__carbon_thunk [concrete = constants.%operator_Minus__carbon_thunk] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.cpp_operator.decl.25fc23.2: %C.cpp_operator.type.c4928b.2 = fn_decl @C.cpp_operator.2 [concrete = constants.%C.cpp_operator.fb6eba.2] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: }
// CHECK:STDOUT: %operator_Plus__carbon_thunk.decl: %operator_Plus__carbon_thunk.type = fn_decl @operator_Plus__carbon_thunk [concrete = constants.%operator_Plus__carbon_thunk] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: } {
@@ -3155,7 +3140,6 @@ fn F() {
// CHECK:STDOUT: }
// CHECK:STDOUT: %c2.var: ref %C = var %c2.var_patt
// CHECK:STDOUT: %c1.ref.loc9: ref %C = name_ref c1, %c1
// CHECK:STDOUT: %C.cpp_operator.bound.loc9: <bound method> = bound_method %c1.ref.loc9, imports.%C.cpp_operator.decl.25fc23.1
// CHECK:STDOUT: %.loc9_3: ref %C = splice_block %c2.var {}
// CHECK:STDOUT: %addr.loc9: %ptr.0a2 = addr_of %.loc9_3
// CHECK:STDOUT: %operator_Minus__carbon_thunk.call: init %empty_tuple.type = call imports.%operator_Minus__carbon_thunk.decl(%c1.ref.loc9, %addr.loc9)
@@ -3173,7 +3157,6 @@ fn F() {
// CHECK:STDOUT: %c3.var: ref %C = var %c3.var_patt
// CHECK:STDOUT: %c1.ref.loc10: ref %C = name_ref c1, %c1
// CHECK:STDOUT: %c2.ref: ref %C = name_ref c2, %c2
// CHECK:STDOUT: %C.cpp_operator.bound.loc10: <bound method> = bound_method %c1.ref.loc10, imports.%C.cpp_operator.decl.25fc23.2
// CHECK:STDOUT: %.loc10_3: ref %C = splice_block %c3.var {}
// CHECK:STDOUT: %.loc10_31.1: %C = acquire_value %c2.ref
// CHECK:STDOUT: %.loc10_31.2: ref %C = value_as_ref %.loc10_31.1