Просмотр исходного кода

Remove redundant deduced specifics (#5107)

When deduction has to substitute binding parameters into further generic
parameters, we do conversion of the argument to the substituted type.
Then we replace the argument instruction id with that Converted
instruction. This causes a redundant specific to be created for the
Converted instruction which is not needed. What we want is the specific
for its constant value.

So when we replace the argument instruction id, replace it with the
instruction from the constant value of the converted argument.

This was raised in [discord
#toolchain](https://discord.com/channels/655572317891461132/655578254970716160/1349067541070217306).
Dana Jansens 1 год назад
Родитель
Сommit
82fe19ee99

+ 4 - 2
toolchain/check/deduce.cpp

@@ -587,8 +587,10 @@ auto DeductionContext::CheckDeductionIsComplete() -> bool {
       // Replace the deduced arg with its value converted to the parameter
       // type. The conversion of the argument type must produce a constant value
       // to be used in deduction.
-      if (context().constant_values().Get(converted_arg_id).is_constant()) {
-        deduced_arg_id = converted_arg_id;
+      if (auto const_inst_id =
+              context().constant_values().GetConstantInstId(converted_arg_id);
+          const_inst_id.has_value()) {
+        deduced_arg_id = const_inst_id;
       } else {
         if (diagnose_) {
           CARBON_DIAGNOSTIC(RuntimeConversionDuringCompTimeDeduction, Error,

+ 6 - 30
toolchain/check/testdata/builtin_conversions/no_prelude/convert_class_type_to_generic_facet_value.carbon

@@ -348,7 +348,7 @@ fn G() {
 // CHECK:STDOUT:   %ImplsGeneric.ref: type = name_ref ImplsGeneric, file.%ImplsGeneric.decl [concrete = constants.%ImplsGeneric]
 // CHECK:STDOUT:   %Generic.facet: %Generic.type.769 = facet_value constants.%ImplsGeneric, (constants.%impl_witness) [concrete = constants.%Generic.facet]
 // CHECK:STDOUT:   %.loc20: %Generic.type.769 = converted constants.%ImplsGeneric, %Generic.facet [concrete = constants.%Generic.facet]
-// CHECK:STDOUT:   %CallGenericMethod.specific_fn: <specific function> = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%GenericParam, %.loc20) [concrete = constants.%CallGenericMethod.specific_fn.934]
+// CHECK:STDOUT:   %CallGenericMethod.specific_fn: <specific function> = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet) [concrete = constants.%CallGenericMethod.specific_fn.934]
 // CHECK:STDOUT:   %CallGenericMethod.call: init %empty_tuple.type = call %CallGenericMethod.specific_fn()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -381,7 +381,7 @@ fn G() {
 // CHECK:STDOUT:   %ImplsGeneric.ref: type = name_ref ImplsGeneric, file.%ImplsGeneric.decl [concrete = constants.%ImplsGeneric]
 // CHECK:STDOUT:   %Generic.facet: %Generic.type.769 = facet_value constants.%ImplsGeneric, (constants.%impl_witness) [concrete = constants.%Generic.facet]
 // CHECK:STDOUT:   %.loc28: %Generic.type.769 = converted constants.%ImplsGeneric, %Generic.facet [concrete = constants.%Generic.facet]
-// CHECK:STDOUT:   %PassThroughToGenericMethod.specific_fn: <specific function> = specific_function %PassThroughToGenericMethod.ref, @PassThroughToGenericMethod(constants.%GenericParam, %.loc28) [concrete = constants.%PassThroughToGenericMethod.specific_fn]
+// CHECK:STDOUT:   %PassThroughToGenericMethod.specific_fn: <specific function> = specific_function %PassThroughToGenericMethod.ref, @PassThroughToGenericMethod(constants.%GenericParam, constants.%Generic.facet) [concrete = constants.%PassThroughToGenericMethod.specific_fn]
 // CHECK:STDOUT:   %PassThroughToGenericMethod.call: init %empty_tuple.type = call %PassThroughToGenericMethod.specific_fn()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -427,7 +427,7 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Generic(@CallGenericMethod.%T.loc17_22.2) {}
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, @G.%.loc20) {
+// CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet) {
 // CHECK:STDOUT:   %T.loc17_22.2 => constants.%GenericParam
 // CHECK:STDOUT:   %T.patt.loc17_22.2 => constants.%GenericParam
 // CHECK:STDOUT:   %Generic.type.loc17_45.2 => constants.%Generic.type.769
@@ -437,14 +437,6 @@ fn G() {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet) {
-// CHECK:STDOUT:   %T.loc17_22.2 => constants.%GenericParam
-// CHECK:STDOUT:   %T.patt.loc17_22.2 => constants.%GenericParam
-// CHECK:STDOUT:   %Generic.type.loc17_45.2 => constants.%Generic.type.769
-// CHECK:STDOUT:   %U.loc17_32.2 => constants.%Generic.facet
-// CHECK:STDOUT:   %U.patt.loc17_32.2 => constants.%Generic.facet
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
 // CHECK:STDOUT: specific @PassThroughToGenericMethod(constants.%T, constants.%U) {
 // CHECK:STDOUT:   %T.loc23_31.2 => constants.%T
 // CHECK:STDOUT:   %T.patt.loc23_31.2 => constants.%T
@@ -457,7 +449,7 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @CallGenericMethod(@PassThroughToGenericMethod.%T.loc23_31.2, @PassThroughToGenericMethod.%U.loc23_41.2) {}
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @PassThroughToGenericMethod(constants.%GenericParam, @H.%.loc28) {
+// CHECK:STDOUT: specific @PassThroughToGenericMethod(constants.%GenericParam, constants.%Generic.facet) {
 // CHECK:STDOUT:   %T.loc23_31.2 => constants.%GenericParam
 // CHECK:STDOUT:   %T.patt.loc23_31.2 => constants.%GenericParam
 // CHECK:STDOUT:   %Generic.type.loc23_54.2 => constants.%Generic.type.769
@@ -468,14 +460,6 @@ fn G() {
 // CHECK:STDOUT:   %CallGenericMethod.specific_fn.loc24_3.2 => constants.%CallGenericMethod.specific_fn.934
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @PassThroughToGenericMethod(constants.%GenericParam, constants.%Generic.facet) {
-// CHECK:STDOUT:   %T.loc23_31.2 => constants.%GenericParam
-// CHECK:STDOUT:   %T.patt.loc23_31.2 => constants.%GenericParam
-// CHECK:STDOUT:   %Generic.type.loc23_54.2 => constants.%Generic.type.769
-// CHECK:STDOUT:   %U.loc23_41.2 => constants.%Generic.facet
-// CHECK:STDOUT:   %U.patt.loc23_41.2 => constants.%Generic.facet
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
 // CHECK:STDOUT: --- generic_facet_type_from_implicit_param.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
@@ -652,7 +636,7 @@ fn G() {
 // CHECK:STDOUT:   %.loc20_38.1: ref %GenericParam = converted %.loc20_36.1, %.loc20_36.4
 // CHECK:STDOUT:   %Generic.facet: %Generic.type.769 = facet_value constants.%ImplsGeneric, (constants.%impl_witness) [concrete = constants.%Generic.facet]
 // CHECK:STDOUT:   %.loc20_53: %Generic.type.769 = converted constants.%ImplsGeneric, %Generic.facet [concrete = constants.%Generic.facet]
-// CHECK:STDOUT:   %CallGenericMethod.specific_fn: <specific function> = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%GenericParam, %.loc20_53) [concrete = constants.%CallGenericMethod.specific_fn]
+// CHECK:STDOUT:   %CallGenericMethod.specific_fn: <specific function> = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet) [concrete = constants.%CallGenericMethod.specific_fn]
 // CHECK:STDOUT:   %.loc20_38.2: %GenericParam = bind_value %.loc20_38.1
 // CHECK:STDOUT:   %CallGenericMethod.call: init %empty_tuple.type = call %CallGenericMethod.specific_fn(%.loc20_38.2)
 // CHECK:STDOUT:   return
@@ -697,7 +681,7 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @Generic(@CallGenericMethod.%T.loc17_22.2) {}
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, @G.%.loc20_53) {
+// CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet) {
 // CHECK:STDOUT:   %T.loc17_22.2 => constants.%GenericParam
 // CHECK:STDOUT:   %T.patt.loc17_22.2 => constants.%GenericParam
 // CHECK:STDOUT:   %Generic.type.loc17_45.2 => constants.%Generic.type.769
@@ -708,11 +692,3 @@ fn G() {
 // CHECK:STDOUT:   %require_complete => constants.%complete_type
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet) {
-// CHECK:STDOUT:   %T.loc17_22.2 => constants.%GenericParam
-// CHECK:STDOUT:   %T.patt.loc17_22.2 => constants.%GenericParam
-// CHECK:STDOUT:   %Generic.type.loc17_45.2 => constants.%Generic.type.769
-// CHECK:STDOUT:   %U.loc17_32.2 => constants.%Generic.facet
-// CHECK:STDOUT:   %U.patt.loc17_32.2 => constants.%Generic.facet
-// CHECK:STDOUT: }
-// CHECK:STDOUT:

+ 2 - 11
toolchain/check/testdata/builtin_conversions/no_prelude/convert_class_value_to_generic_facet_value_value.carbon

@@ -432,7 +432,7 @@ fn B() {
 // CHECK:STDOUT:   %.loc22_44.1: ref %GenericParam = converted %.loc22_42.1, %.loc22_42.4
 // CHECK:STDOUT:   %Generic.facet: %Generic.type.769 = facet_value constants.%ImplsGeneric, (constants.%impl_witness) [concrete = constants.%Generic.facet.8bd]
 // CHECK:STDOUT:   %.loc22_59: %Generic.type.769 = converted constants.%ImplsGeneric, %Generic.facet [concrete = constants.%Generic.facet.8bd]
-// CHECK:STDOUT:   %CallGenericMethod.specific_fn: <specific function> = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%GenericParam, %.loc22_59) [concrete = constants.%CallGenericMethod.specific_fn]
+// CHECK:STDOUT:   %CallGenericMethod.specific_fn: <specific function> = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet.8bd) [concrete = constants.%CallGenericMethod.specific_fn]
 // CHECK:STDOUT:   %.loc22_24.2: %ImplsGeneric = bind_value %.loc22_24.1
 // CHECK:STDOUT:   %.loc22_44.2: %GenericParam = bind_value %.loc22_44.1
 // CHECK:STDOUT:   %CallGenericMethod.call: init %empty_tuple.type = call %CallGenericMethod.specific_fn(%.loc22_24.2, %.loc22_44.2)
@@ -491,7 +491,7 @@ fn B() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F.1(@CallGenericMethod.%T.loc17_22.2, @CallGenericMethod.%Generic.facet) {}
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, @G.%.loc22_59) {
+// CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet.8bd) {
 // CHECK:STDOUT:   %T.loc17_22.2 => constants.%GenericParam
 // CHECK:STDOUT:   %T.patt.loc17_22.2 => constants.%GenericParam
 // CHECK:STDOUT:   %Generic.type.loc17_45.2 => constants.%Generic.type.769
@@ -513,15 +513,6 @@ fn B() {
 // CHECK:STDOUT:   %specific_fn.loc18_4.2 => constants.%F.specific_fn
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet.8bd) {
-// CHECK:STDOUT:   %T.loc17_22.2 => constants.%GenericParam
-// CHECK:STDOUT:   %T.patt.loc17_22.2 => constants.%GenericParam
-// CHECK:STDOUT:   %Generic.type.loc17_45.2 => constants.%Generic.type.769
-// CHECK:STDOUT:   %U.loc17_32.2 => constants.%Generic.facet.8bd
-// CHECK:STDOUT:   %U.patt.loc17_32.2 => constants.%Generic.facet.8bd
-// CHECK:STDOUT:   %U.as_type.loc17_51.2 => constants.%ImplsGeneric
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
 // CHECK:STDOUT: --- multiple_generic_params_one_fixed_one_deduced.carbon
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {

+ 2 - 12
toolchain/check/testdata/builtin_conversions/no_prelude/convert_facet_value_value_to_generic_facet_value_value.carbon

@@ -452,7 +452,7 @@ fn F() {
 // CHECK:STDOUT:     %.loc23_76.7: %Animal.type = converted constants.%T.as_type.2ad, constants.%T.fd4 [symbolic = %T.loc23_17.2 (constants.%T.fd4)]
 // CHECK:STDOUT:     %Eats.facet.loc23_76.1: @HandleAnimal.%Eats.type (%Eats.type.f54c3d.2) = facet_value constants.%T.as_type.2ad, (constants.%impl_witness.c7c36b.2) [symbolic = %Eats.facet.loc23_76.2 (constants.%Eats.facet.97e)]
 // CHECK:STDOUT:     %.loc23_76.8: @HandleAnimal.%Eats.type (%Eats.type.f54c3d.2) = converted constants.%T.as_type.2ad, %Eats.facet.loc23_76.1 [symbolic = %Eats.facet.loc23_76.2 (constants.%Eats.facet.97e)]
-// CHECK:STDOUT:     %Feed.specific_fn.loc23_64.1: <specific function> = specific_function %Feed.ref, @Feed(constants.%Food.5fe, %.loc23_76.8) [symbolic = %Feed.specific_fn.loc23_64.2 (constants.%Feed.specific_fn.387)]
+// CHECK:STDOUT:     %Feed.specific_fn.loc23_64.1: <specific function> = specific_function %Feed.ref, @Feed(constants.%Food.5fe, constants.%Eats.facet.97e) [symbolic = %Feed.specific_fn.loc23_64.2 (constants.%Feed.specific_fn.387)]
 // CHECK:STDOUT:     %Feed.call: init %empty_tuple.type = call %Feed.specific_fn.loc23_64.1(%a.ref, %food.ref)
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }
@@ -569,7 +569,7 @@ fn F() {
 // CHECK:STDOUT: !definition:
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Feed(constants.%Food.5fe, @HandleAnimal.%.loc23_76.8) {
+// CHECK:STDOUT: specific @Feed(constants.%Food.5fe, constants.%Eats.facet.97e) {
 // CHECK:STDOUT:   %Food.loc22_9.2 => constants.%Food.5fe
 // CHECK:STDOUT:   %Food.patt.loc22_9.2 => constants.%Food.5fe
 // CHECK:STDOUT:   %Food.as_type.loc22_37.2 => constants.%Food.as_type.fae
@@ -583,16 +583,6 @@ fn F() {
 // CHECK:STDOUT:   %require_complete.loc22_50 => constants.%require_complete.444
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @Feed(constants.%Food.5fe, constants.%Eats.facet.97e) {
-// CHECK:STDOUT:   %Food.loc22_9.2 => constants.%Food.5fe
-// CHECK:STDOUT:   %Food.patt.loc22_9.2 => constants.%Food.5fe
-// CHECK:STDOUT:   %Food.as_type.loc22_37.2 => constants.%Food.as_type.fae
-// CHECK:STDOUT:   %Eats.type.loc22_37.2 => constants.%Eats.type.f54c3d.2
-// CHECK:STDOUT:   %T.loc22_24.2 => constants.%Eats.facet.97e
-// CHECK:STDOUT:   %T.patt.loc22_24.2 => constants.%Eats.facet.97e
-// CHECK:STDOUT:   %T.as_type.loc22_43.2 => constants.%T.as_type.2ad
-// CHECK:STDOUT: }
-// CHECK:STDOUT:
 // CHECK:STDOUT: specific @Eats(@HandleAnimal.%Food.as_type.loc23_56.2) {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @impl.009(@HandleAnimal.%T.loc23_17.2, @HandleAnimal.%Food.loc23_29.2) {}

+ 2 - 10
toolchain/check/testdata/function/generic/call_method_on_generic_facet.carbon

@@ -273,7 +273,7 @@ fn G() {
 // CHECK:STDOUT:   %ImplsGeneric.ref: type = name_ref ImplsGeneric, file.%ImplsGeneric.decl [concrete = constants.%ImplsGeneric]
 // CHECK:STDOUT:   %Generic.facet: %Generic.type.769 = facet_value constants.%ImplsGeneric, (constants.%impl_witness.b42) [concrete = constants.%Generic.facet.8bd]
 // CHECK:STDOUT:   %.loc34: %Generic.type.769 = converted constants.%ImplsGeneric, %Generic.facet [concrete = constants.%Generic.facet.8bd]
-// CHECK:STDOUT:   %CallGenericMethod.specific_fn: <specific function> = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%GenericParam, %.loc34) [concrete = constants.%CallGenericMethod.specific_fn]
+// CHECK:STDOUT:   %CallGenericMethod.specific_fn: <specific function> = specific_function %CallGenericMethod.ref, @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet.8bd) [concrete = constants.%CallGenericMethod.specific_fn]
 // CHECK:STDOUT:   %CallGenericMethod.call: init %empty_tuple.type = call %CallGenericMethod.specific_fn()
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }
@@ -333,7 +333,7 @@ fn G() {
 // CHECK:STDOUT:
 // CHECK:STDOUT: specific @F.1(@CallGenericMethod.%T.loc29_22.2, @CallGenericMethod.%Generic.facet) {}
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, @G.3.%.loc34) {
+// CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet.8bd) {
 // CHECK:STDOUT:   %T.loc29_22.2 => constants.%GenericParam
 // CHECK:STDOUT:   %T.patt.loc29_22.2 => constants.%GenericParam
 // CHECK:STDOUT:   %Generic.type.loc29_45.2 => constants.%Generic.type.769
@@ -353,11 +353,3 @@ fn G() {
 // CHECK:STDOUT:   %specific_fn.loc30_4.2 => constants.%F.specific_fn
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
-// CHECK:STDOUT: specific @CallGenericMethod(constants.%GenericParam, constants.%Generic.facet.8bd) {
-// CHECK:STDOUT:   %T.loc29_22.2 => constants.%GenericParam
-// CHECK:STDOUT:   %T.patt.loc29_22.2 => constants.%GenericParam
-// CHECK:STDOUT:   %Generic.type.loc29_45.2 => constants.%Generic.type.769
-// CHECK:STDOUT:   %U.loc29_32.2 => constants.%Generic.facet.8bd
-// CHECK:STDOUT:   %U.patt.loc29_32.2 => constants.%Generic.facet.8bd
-// CHECK:STDOUT: }
-// CHECK:STDOUT: