Add the .Self name for the type expression of a compile time binding (#5937)

We add a virtual node (`CompileTimeBindingPatternStart`) as the first
child of `CompileTimeBindingPattern` which holds the identifier
underneath it, so that it is checked just before the type expression of
the `CompileTimeBindingPattern`. When we reach this virtual node during
check, we add `.Self` as a name in the current scope, and when we reach
`CompileTimeBindingPattern` we remove it from scope, which ensures it's
present during only the checking of the type expression for the compile
time pattern.

At the moment the `.Self` has a different type (it's a `TypeType`) than
other `.Self` in the facet type (which are a single `FacetType`), but
the intention is to immediately substitute it out of the facet type
entirely, replacing it with a reference to the compile time binding (a
`BindSymbolicName`) itself. A TODO has been added for this.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
Dana Jansens
2025-08-12 16:27:07 +00:00
committed by GitHub
co-authored by Jon Ross-Perkins
parent 2e509e9103
commit 4b0e2b03b6
172 changed files with 2381 additions and 1034 deletions
+10 -1
View File
@@ -231,6 +231,7 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D);
// CHECK:STDOUT: --- fail_nested.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %.Self: type = bind_symbolic_name .Self [symbolic_self]
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
// CHECK:STDOUT: %pattern_type.98f: type = pattern_type type [concrete]
// CHECK:STDOUT: %Outer.type: type = generic_class_type @Outer [concrete]
@@ -295,6 +296,7 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D);
// CHECK:STDOUT: %Outer.decl: %Outer.type = class_decl @Outer [concrete = constants.%Outer.generic] {
// CHECK:STDOUT: %T.patt: %pattern_type.98f = symbolic_binding_pattern T, 0 [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %.Self: type = bind_symbolic_name .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %T.loc4_13.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc4_13.1 (constants.%T)]
// CHECK:STDOUT: }
// CHECK:STDOUT: name_binding_decl {
@@ -402,6 +404,7 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D);
// CHECK:STDOUT: %Inner.decl: @Outer.%Inner.type (%Inner.type.eae) = class_decl @Inner [symbolic = @Outer.%Inner.generic (constants.%Inner.generic.137)] {
// CHECK:STDOUT: %U.patt: %pattern_type.98f = symbolic_binding_pattern U, 1 [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %.Self: type = bind_symbolic_name .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %U.loc5_15.2: type = bind_symbolic_name U, 1 [symbolic = %U.loc5_15.1 (constants.%U)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Outer.9d6 [symbolic = @Outer.as.Destroy.impl.%Outer (constants.%Outer.9d6)]
@@ -519,6 +522,7 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D);
// CHECK:STDOUT: --- fail_int_value.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete]
// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [concrete]
// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete]
@@ -585,6 +589,7 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D);
// CHECK:STDOUT: %N.patt: %pattern_type.7ce = symbolic_binding_pattern N, 0 [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %.loc4: type = splice_block %i32 [concrete = constants.%i32] {
// CHECK:STDOUT: %.Self: type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.644]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
// CHECK:STDOUT: }
@@ -717,6 +722,7 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D);
// CHECK:STDOUT: %D.as.Destroy.impl.Op: %D.as.Destroy.impl.Op.type = struct_value () [concrete]
// CHECK:STDOUT: %struct_type.a.b.501: type = struct_type {.a: %i32, .b: %i32} [concrete]
// CHECK:STDOUT: %complete_type.705: <witness> = complete_type_witness %struct_type.a.b.501 [concrete]
// CHECK:STDOUT: %.Self.644: type = bind_symbolic_name .Self [symbolic_self]
// CHECK:STDOUT: %F: %D = bind_symbolic_name F, 0 [symbolic]
// CHECK:STDOUT: %pattern_type.510: type = pattern_type %D [concrete]
// CHECK:STDOUT: %E.type: type = generic_class_type @E [concrete]
@@ -790,7 +796,10 @@ var g: E({.a = 1, .b = 2}) = {} as E({.a = 3, .b = 4} as D);
// CHECK:STDOUT: %E.decl: %E.type = class_decl @E [concrete = constants.%E.generic] {
// CHECK:STDOUT: %F.patt: %pattern_type.510 = symbolic_binding_pattern F, 0 [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D]
// CHECK:STDOUT: %.loc9: type = splice_block %D.ref [concrete = constants.%D] {
// CHECK:STDOUT: %.Self: type = bind_symbolic_name .Self [symbolic_self = constants.%.Self.644]
// CHECK:STDOUT: %D.ref: type = name_ref D, file.%D.decl [concrete = constants.%D]
// CHECK:STDOUT: }
// CHECK:STDOUT: %F.loc9_9.2: %D = bind_symbolic_name F, 0 [symbolic = %F.loc9_9.1 (constants.%F)]
// CHECK:STDOUT: }
// CHECK:STDOUT: name_binding_decl {