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

Make applying `const` repeatedly to the same type have less additional effect. (#6287)

This is to avoid edge cases where there are multiple `ConstType`
instructions, which code may not handle appropriately. I was thinking
about this for #6279
Jon Ross-Perkins 6 месяцев назад
Родитель
Сommit
eed21f6439

+ 2 - 0
toolchain/check/handle_operator.cpp

@@ -293,6 +293,8 @@ auto HandleParseNode(Context& context, Parse::PrefixOperatorConstId node_id)
                       "`const` applied repeatedly to the same type has no "
                       "additional effect");
     context.emitter().Emit(node_id, RepeatedConst);
+    context.node_stack().Push(node_id, value_id);
+    return true;
   }
   auto inner_type = ExprAsType(context, node_id, value_id);
   AddInstAndPush<SemIR::ConstType>(

+ 2 - 3
toolchain/check/testdata/class/syntactic_merge.carbon

@@ -1081,11 +1081,10 @@ fn Base.F[addr self: Base*]() {
 // CHECK:STDOUT:   %Foo.decl.loc18: %Foo.type.39e446.2 = class_decl @Foo.loc18 [concrete = constants.%Foo.generic.80461b.2] {
 // CHECK:STDOUT:     %a.patt: %pattern_type = symbolic_binding_pattern a, 0 [concrete]
 // CHECK:STDOUT:   } {
-// CHECK:STDOUT:     %.loc18: type = splice_block %const.loc18_15 [concrete = constants.%const] {
+// CHECK:STDOUT:     %.loc18: type = splice_block %const [concrete = constants.%const] {
 // CHECK:STDOUT:       %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:       %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C]
-// CHECK:STDOUT:       %const.loc18_22: type = const_type %C.ref [concrete = constants.%const]
-// CHECK:STDOUT:       %const.loc18_15: type = const_type %const.loc18_22 [concrete = constants.%const]
+// CHECK:STDOUT:       %const: type = const_type %C.ref [concrete = constants.%const]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %a.loc18_11.2: %const = symbolic_binding a, 0 [symbolic = %a.loc18_11.1 (constants.%a)]
 // CHECK:STDOUT:   }

+ 1 - 2
toolchain/check/testdata/const/basics.carbon

@@ -304,8 +304,7 @@ fn PassConstReferenceToReference(p: const X*) {
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %C.ref.loc11_36: type = name_ref C, file.%C.decl [concrete = constants.%C]
 // CHECK:STDOUT:     %const.loc11_30: type = const_type %C.ref.loc11_36 [concrete = constants.%const.668]
-// CHECK:STDOUT:     %const.loc11_23: type = const_type %const.loc11_30 [concrete = constants.%const.668]
-// CHECK:STDOUT:     %ptr.loc11_38: type = ptr_type %const.loc11_23 [concrete = constants.%ptr.801]
+// CHECK:STDOUT:     %ptr.loc11_38: type = ptr_type %const.loc11_30 [concrete = constants.%ptr.801]
 // CHECK:STDOUT:     %ptr.loc11_39: type = ptr_type %ptr.loc11_38 [concrete = constants.%ptr.564]
 // CHECK:STDOUT:     %p.param: %ptr.564 = value_param call_param0
 // CHECK:STDOUT:     %.loc11: type = splice_block %ptr.loc11_17 [concrete = constants.%ptr.564] {

+ 2 - 3
toolchain/check/testdata/function/definition/syntactic_merge.carbon

@@ -940,10 +940,9 @@ fn Foo(a: const (const C)) {}
 // CHECK:STDOUT:     %a.param_patt: %pattern_type = value_param_pattern %a.patt, call_param0 [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %a.param: %const = value_param call_param0
-// CHECK:STDOUT:     %.loc18: type = splice_block %const.loc18_11 [concrete = constants.%const] {
+// CHECK:STDOUT:     %.loc18: type = splice_block %const [concrete = constants.%const] {
 // CHECK:STDOUT:       %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C]
-// CHECK:STDOUT:       %const.loc18_18: type = const_type %C.ref [concrete = constants.%const]
-// CHECK:STDOUT:       %const.loc18_11: type = const_type %const.loc18_18 [concrete = constants.%const]
+// CHECK:STDOUT:       %const: type = const_type %C.ref [concrete = constants.%const]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %a: %const = value_binding a, %a.param
 // CHECK:STDOUT:   }

+ 2 - 3
toolchain/check/testdata/interface/syntactic_merge.carbon

@@ -1160,11 +1160,10 @@ interface Foo(a:! const (const C)) {}
 // CHECK:STDOUT:   %Foo.decl.loc18: %Foo.type.5380b8.2 = interface_decl @Foo.loc18 [concrete = constants.%Foo.generic.ec3175.2] {
 // CHECK:STDOUT:     %a.patt: %pattern_type = symbolic_binding_pattern a, 0 [concrete]
 // CHECK:STDOUT:   } {
-// CHECK:STDOUT:     %.loc18: type = splice_block %const.loc18_19 [concrete = constants.%const] {
+// CHECK:STDOUT:     %.loc18: type = splice_block %const [concrete = constants.%const] {
 // CHECK:STDOUT:       %.Self: %type = symbolic_binding .Self [symbolic_self = constants.%.Self]
 // CHECK:STDOUT:       %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C]
-// CHECK:STDOUT:       %const.loc18_26: type = const_type %C.ref [concrete = constants.%const]
-// CHECK:STDOUT:       %const.loc18_19: type = const_type %const.loc18_26 [concrete = constants.%const]
+// CHECK:STDOUT:       %const: type = const_type %C.ref [concrete = constants.%const]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %a.loc18_15.2: %const = symbolic_binding a, 0 [symbolic = %a.loc18_15.1 (constants.%a)]
 // CHECK:STDOUT:   }