Skip to content

Commit

Permalink
Treat the empty inst block as being canonical. (#4199)
Browse files Browse the repository at this point in the history
TryEvalInst was assuming this to be the case when forming canonical
constants, but it previously wasn't.

This fixes an issue where we can end up with two identical-looking
constants for an empty struct value: one with an `Empty` block and
another with the canonical empty block.
  • Loading branch information
zygoloid authored Aug 7, 2024
1 parent 3d13b8f commit 3c4c234
Show file tree
Hide file tree
Showing 16 changed files with 107 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ fn Foo(n: ()) -> ((), ()) {
// CHECK:STDOUT: 'inst+20': {kind: TupleLiteral, arg0: block8, type: type(inst+8)}
// CHECK:STDOUT: 'inst+21': {kind: TupleAccess, arg0: inst+13, arg1: element0, type: type(inst+1)}
// CHECK:STDOUT: 'inst+22': {kind: TupleInit, arg0: block9, arg1: inst+21, type: type(inst+1)}
// CHECK:STDOUT: 'inst+23': {kind: TupleValue, arg0: block10, type: type(inst+1)}
// CHECK:STDOUT: 'inst+23': {kind: TupleValue, arg0: empty, type: type(inst+1)}
// CHECK:STDOUT: 'inst+24': {kind: Converted, arg0: inst+18, arg1: inst+22, type: type(inst+1)}
// CHECK:STDOUT: 'inst+25': {kind: TupleAccess, arg0: inst+13, arg1: element1, type: type(inst+1)}
// CHECK:STDOUT: 'inst+26': {kind: TupleInit, arg0: empty, arg1: inst+25, type: type(inst+1)}
// CHECK:STDOUT: 'inst+27': {kind: Converted, arg0: inst+19, arg1: inst+26, type: type(inst+1)}
// CHECK:STDOUT: 'inst+28': {kind: TupleInit, arg0: block11, arg1: inst+13, type: type(inst+8)}
// CHECK:STDOUT: 'inst+29': {kind: TupleValue, arg0: block12, type: type(inst+8)}
// CHECK:STDOUT: 'inst+28': {kind: TupleInit, arg0: block10, arg1: inst+13, type: type(inst+8)}
// CHECK:STDOUT: 'inst+29': {kind: TupleValue, arg0: block11, type: type(inst+8)}
// CHECK:STDOUT: 'inst+30': {kind: Converted, arg0: inst+20, arg1: inst+28, type: type(inst+8)}
// CHECK:STDOUT: 'inst+31': {kind: ReturnExpr, arg0: inst+30, arg1: inst+13}
// CHECK:STDOUT: constant_values:
Expand Down Expand Up @@ -138,14 +138,13 @@ fn Foo(n: ()) -> ((), ()) {
// CHECK:STDOUT: 0: inst+18
// CHECK:STDOUT: 1: inst+19
// CHECK:STDOUT: block9: {}
// CHECK:STDOUT: block10: {}
// CHECK:STDOUT: block11:
// CHECK:STDOUT: block10:
// CHECK:STDOUT: 0: inst+24
// CHECK:STDOUT: 1: inst+27
// CHECK:STDOUT: block12:
// CHECK:STDOUT: block11:
// CHECK:STDOUT: 0: inst+23
// CHECK:STDOUT: 1: inst+23
// CHECK:STDOUT: block13:
// CHECK:STDOUT: block12:
// CHECK:STDOUT: 0: inst+0
// CHECK:STDOUT: 1: inst+14
// CHECK:STDOUT: ...
Expand Down
5 changes: 2 additions & 3 deletions toolchain/check/testdata/basics/no_prelude/raw_ir.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ fn Foo[T:! type](n: T) -> (T, ()) {
// CHECK:STDOUT: 'inst+26': {kind: InitializeFrom, arg0: inst+22, arg1: inst+25, type: type(symbolicConstant2)}
// CHECK:STDOUT: 'inst+27': {kind: TupleAccess, arg0: inst+15, arg1: element1, type: type(inst+8)}
// CHECK:STDOUT: 'inst+28': {kind: TupleInit, arg0: empty, arg1: inst+27, type: type(inst+8)}
// CHECK:STDOUT: 'inst+29': {kind: TupleValue, arg0: block15, type: type(inst+8)}
// CHECK:STDOUT: 'inst+29': {kind: TupleValue, arg0: empty, type: type(inst+8)}
// CHECK:STDOUT: 'inst+30': {kind: Converted, arg0: inst+23, arg1: inst+28, type: type(inst+8)}
// CHECK:STDOUT: 'inst+31': {kind: TupleInit, arg0: block14, arg1: inst+15, type: type(symbolicConstant3)}
// CHECK:STDOUT: 'inst+32': {kind: Converted, arg0: inst+24, arg1: inst+31, type: type(symbolicConstant3)}
Expand Down Expand Up @@ -170,8 +170,7 @@ fn Foo[T:! type](n: T) -> (T, ()) {
// CHECK:STDOUT: block14:
// CHECK:STDOUT: 0: inst+26
// CHECK:STDOUT: 1: inst+30
// CHECK:STDOUT: block15: {}
// CHECK:STDOUT: block16:
// CHECK:STDOUT: block15:
// CHECK:STDOUT: 0: inst+0
// CHECK:STDOUT: 1: inst+16
// CHECK:STDOUT: ...
18 changes: 8 additions & 10 deletions toolchain/check/testdata/class/generic/basic.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,11 @@ class Declaration(T:! type);
// CHECK:STDOUT: %.2: type = ptr_type %Class.2 [symbolic]
// CHECK:STDOUT: %.3: type = ptr_type %T [symbolic]
// CHECK:STDOUT: %GetAddr.type: type = fn_type @GetAddr, @Class(%T) [symbolic]
// CHECK:STDOUT: %GetAddr.1: %GetAddr.type = struct_value () [symbolic]
// CHECK:STDOUT: %GetAddr: %GetAddr.type = struct_value () [symbolic]
// CHECK:STDOUT: %GetValue.type: type = fn_type @GetValue, @Class(%T) [symbolic]
// CHECK:STDOUT: %GetValue.1: %GetValue.type = struct_value () [symbolic]
// CHECK:STDOUT: %GetValue: %GetValue.type = struct_value () [symbolic]
// CHECK:STDOUT: %.4: type = unbound_element_type %Class.2, %T [symbolic]
// CHECK:STDOUT: %.5: type = struct_type {.k: %T} [symbolic]
// CHECK:STDOUT: %GetAddr.2: %GetAddr.type = struct_value () [symbolic]
// CHECK:STDOUT: %GetValue.2: %GetValue.type = struct_value () [symbolic]
// CHECK:STDOUT: %.6: type = ptr_type %.5 [symbolic]
// CHECK:STDOUT: %Declaration.type: type = generic_class_type @Declaration [template]
// CHECK:STDOUT: %Declaration.1: %Declaration.type = struct_value () [template]
Expand Down Expand Up @@ -81,14 +79,14 @@ class Declaration(T:! type);
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %GetAddr.type: type = fn_type @GetAddr, @Class(%T) [symbolic = %GetAddr.type (constants.%GetAddr.type)]
// CHECK:STDOUT: %GetAddr: @Class.%GetAddr.type (%GetAddr.type) = struct_value () [symbolic = %GetAddr (constants.%GetAddr.1)]
// CHECK:STDOUT: %GetAddr: @Class.%GetAddr.type (%GetAddr.type) = struct_value () [symbolic = %GetAddr (constants.%GetAddr)]
// CHECK:STDOUT: %GetValue.type: type = fn_type @GetValue, @Class(%T) [symbolic = %GetValue.type (constants.%GetValue.type)]
// CHECK:STDOUT: %GetValue: @Class.%GetValue.type (%GetValue.type) = struct_value () [symbolic = %GetValue (constants.%GetValue.1)]
// CHECK:STDOUT: %GetValue: @Class.%GetValue.type (%GetValue.type) = struct_value () [symbolic = %GetValue (constants.%GetValue)]
// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic = %Class (constants.%Class.2)]
// CHECK:STDOUT: %.1: type = unbound_element_type @Class.%Class (%Class.2), @Class.%T (%T) [symbolic = %.1 (constants.%.4)]
// CHECK:STDOUT:
// CHECK:STDOUT: class {
// CHECK:STDOUT: %GetAddr.decl: @Class.%GetAddr.type (%GetAddr.type) = fn_decl @GetAddr [symbolic = %GetAddr (constants.%GetAddr.1)] {
// CHECK:STDOUT: %GetAddr.decl: @Class.%GetAddr.type (%GetAddr.type) = fn_decl @GetAddr [symbolic = %GetAddr (constants.%GetAddr)] {
// CHECK:STDOUT: %.loc12_25: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = @GetAddr.%Class (constants.%Class.2)]
// CHECK:STDOUT: %Self.ref.loc12: type = name_ref Self, %.loc12_25 [symbolic = @GetAddr.%Class (constants.%Class.2)]
// CHECK:STDOUT: %.loc12_29: type = ptr_type %Class.2 [symbolic = @GetAddr.%.1 (constants.%.2)]
Expand All @@ -99,7 +97,7 @@ class Declaration(T:! type);
// CHECK:STDOUT: %.loc12_38: type = ptr_type %T [symbolic = @GetAddr.%.2 (constants.%.3)]
// CHECK:STDOUT: %return.var.loc12: ref @GetAddr.%.2 (%.3) = var <return slot>
// CHECK:STDOUT: }
// CHECK:STDOUT: %GetValue.decl: @Class.%GetValue.type (%GetValue.type) = fn_decl @GetValue [symbolic = %GetValue (constants.%GetValue.1)] {
// CHECK:STDOUT: %GetValue.decl: @Class.%GetValue.type (%GetValue.type) = fn_decl @GetValue [symbolic = %GetValue (constants.%GetValue)] {
// CHECK:STDOUT: %.loc17: type = specific_constant constants.%Class.2, @Class(constants.%T) [symbolic = @GetValue.%Class (constants.%Class.2)]
// CHECK:STDOUT: %Self.ref.loc17: type = name_ref Self, %.loc17 [symbolic = @GetValue.%Class (constants.%Class.2)]
// CHECK:STDOUT: %self.loc17_15.1: @GetValue.%Class (%Class.2) = param self
Expand Down Expand Up @@ -166,9 +164,9 @@ class Declaration(T:! type);
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %GetAddr.type => constants.%GetAddr.type
// CHECK:STDOUT: %GetAddr => constants.%GetAddr.2
// CHECK:STDOUT: %GetAddr => constants.%GetAddr
// CHECK:STDOUT: %GetValue.type => constants.%GetValue.type
// CHECK:STDOUT: %GetValue => constants.%GetValue.2
// CHECK:STDOUT: %GetValue => constants.%GetValue
// CHECK:STDOUT: %Class => constants.%Class.2
// CHECK:STDOUT: %.1 => constants.%.4
// CHECK:STDOUT: }
Expand Down
28 changes: 12 additions & 16 deletions toolchain/check/testdata/class/generic/call.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -449,19 +449,15 @@ class Outer(T:! type) {
// CHECK:STDOUT: %.3: type = ptr_type %.2 [template]
// CHECK:STDOUT: %struct.1: %Outer.2 = struct_value () [symbolic]
// CHECK:STDOUT: %struct.2: %Outer.3 = struct_value () [symbolic]
// CHECK:STDOUT: %A.2: %A.type.1 = struct_value () [symbolic]
// CHECK:STDOUT: %B.2: %B.type.1 = struct_value () [symbolic]
// CHECK:STDOUT: %C.2: %C.type.1 = struct_value () [symbolic]
// CHECK:STDOUT: %D.2: %D.type.1 = struct_value () [symbolic]
// CHECK:STDOUT: %struct.3: %Inner.3 = struct_value () [symbolic]
// CHECK:STDOUT: %A.type.2: type = fn_type @A, @Inner(%U, %U) [symbolic]
// CHECK:STDOUT: %A.3: %A.type.2 = struct_value () [symbolic]
// CHECK:STDOUT: %A.2: %A.type.2 = struct_value () [symbolic]
// CHECK:STDOUT: %B.type.2: type = fn_type @B, @Inner(%U, %U) [symbolic]
// CHECK:STDOUT: %B.3: %B.type.2 = struct_value () [symbolic]
// CHECK:STDOUT: %B.2: %B.type.2 = struct_value () [symbolic]
// CHECK:STDOUT: %C.type.2: type = fn_type @C, @Inner(%U, %U) [symbolic]
// CHECK:STDOUT: %C.3: %C.type.2 = struct_value () [symbolic]
// CHECK:STDOUT: %C.2: %C.type.2 = struct_value () [symbolic]
// CHECK:STDOUT: %D.type.2: type = fn_type @D, @Inner(%U, %U) [symbolic]
// CHECK:STDOUT: %D.3: %D.type.2 = struct_value () [symbolic]
// CHECK:STDOUT: %D.2: %D.type.2 = struct_value () [symbolic]
// CHECK:STDOUT: %struct.4: %Inner.4 = struct_value () [symbolic]
// CHECK:STDOUT: }
// CHECK:STDOUT:
Expand Down Expand Up @@ -667,13 +663,13 @@ class Outer(T:! type) {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %T => constants.%T
// CHECK:STDOUT: %A.type => constants.%A.type.1
// CHECK:STDOUT: %A => constants.%A.2
// CHECK:STDOUT: %A => constants.%A.1
// CHECK:STDOUT: %B.type => constants.%B.type.1
// CHECK:STDOUT: %B => constants.%B.2
// CHECK:STDOUT: %B => constants.%B.1
// CHECK:STDOUT: %C.type => constants.%C.type.1
// CHECK:STDOUT: %C => constants.%C.2
// CHECK:STDOUT: %C => constants.%C.1
// CHECK:STDOUT: %D.type => constants.%D.type.1
// CHECK:STDOUT: %D => constants.%D.2
// CHECK:STDOUT: %D => constants.%D.1
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Inner(@C.%T) {
Expand All @@ -691,13 +687,13 @@ class Outer(T:! type) {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %T => constants.%U
// CHECK:STDOUT: %A.type => constants.%A.type.2
// CHECK:STDOUT: %A => constants.%A.3
// CHECK:STDOUT: %A => constants.%A.2
// CHECK:STDOUT: %B.type => constants.%B.type.2
// CHECK:STDOUT: %B => constants.%B.3
// CHECK:STDOUT: %B => constants.%B.2
// CHECK:STDOUT: %C.type => constants.%C.type.2
// CHECK:STDOUT: %C => constants.%C.3
// CHECK:STDOUT: %C => constants.%C.2
// CHECK:STDOUT: %D.type => constants.%D.type.2
// CHECK:STDOUT: %D => constants.%D.3
// CHECK:STDOUT: %D => constants.%D.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Inner(@D.%U) {
Expand Down
37 changes: 17 additions & 20 deletions toolchain/check/testdata/class/generic/member_access.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
// CHECK:STDOUT: %GetAddr.type.1: type = fn_type @GetAddr, @Class(%T) [symbolic]
// CHECK:STDOUT: %GetAddr.1: %GetAddr.type.1 = struct_value () [symbolic]
// CHECK:STDOUT: %.5: type = struct_type {.x: %T} [symbolic]
// CHECK:STDOUT: %Get.2: %Get.type.1 = struct_value () [symbolic]
// CHECK:STDOUT: %GetAddr.2: %GetAddr.type.1 = struct_value () [symbolic]
// CHECK:STDOUT: %.6: type = ptr_type %.5 [symbolic]
// CHECK:STDOUT: %Int32.type: type = fn_type @Int32 [template]
// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template]
Expand All @@ -71,9 +69,9 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
// CHECK:STDOUT: %DirectFieldAccess: %DirectFieldAccess.type = struct_value () [template]
// CHECK:STDOUT: %.7: type = unbound_element_type %Class.3, i32 [template]
// CHECK:STDOUT: %Get.type.2: type = fn_type @Get, @Class(i32) [template]
// CHECK:STDOUT: %Get.3: %Get.type.2 = struct_value () [template]
// CHECK:STDOUT: %Get.2: %Get.type.2 = struct_value () [template]
// CHECK:STDOUT: %GetAddr.type.2: type = fn_type @GetAddr, @Class(i32) [template]
// CHECK:STDOUT: %GetAddr.3: %GetAddr.type.2 = struct_value () [template]
// CHECK:STDOUT: %GetAddr.2: %GetAddr.type.2 = struct_value () [template]
// CHECK:STDOUT: %MethodCall.type: type = fn_type @MethodCall [template]
// CHECK:STDOUT: %MethodCall: %MethodCall.type = struct_value () [template]
// CHECK:STDOUT: %.8: type = ptr_type %Class.3 [template]
Expand Down Expand Up @@ -250,8 +248,8 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
// CHECK:STDOUT: fn @MethodCall(%x: %Class.3) -> i32 {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %x.ref: %Class.3 = name_ref x, %x
// CHECK:STDOUT: %.loc15_11.1: %Get.type.2 = specific_constant @Class.%Get.decl, @Class(i32) [template = constants.%Get.3]
// CHECK:STDOUT: %Get.ref: %Get.type.2 = name_ref Get, %.loc15_11.1 [template = constants.%Get.3]
// CHECK:STDOUT: %.loc15_11.1: %Get.type.2 = specific_constant @Class.%Get.decl, @Class(i32) [template = constants.%Get.2]
// CHECK:STDOUT: %Get.ref: %Get.type.2 = name_ref Get, %.loc15_11.1 [template = constants.%Get.2]
// CHECK:STDOUT: %.loc15_11.2: <bound method> = bound_method %x.ref, %Get.ref
// CHECK:STDOUT: %Get.call: init i32 = call %.loc15_11.2(%x.ref)
// CHECK:STDOUT: %.loc15_17.1: i32 = value_of_initializer %Get.call
Expand All @@ -263,8 +261,8 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %p.ref: %.8 = name_ref p, %p
// CHECK:STDOUT: %.loc19_12.1: ref %Class.3 = deref %p.ref
// CHECK:STDOUT: %.loc19_12.2: %GetAddr.type.2 = specific_constant @Class.%GetAddr.decl, @Class(i32) [template = constants.%GetAddr.3]
// CHECK:STDOUT: %GetAddr.ref: %GetAddr.type.2 = name_ref GetAddr, %.loc19_12.2 [template = constants.%GetAddr.3]
// CHECK:STDOUT: %.loc19_12.2: %GetAddr.type.2 = specific_constant @Class.%GetAddr.decl, @Class(i32) [template = constants.%GetAddr.2]
// CHECK:STDOUT: %GetAddr.ref: %GetAddr.type.2 = name_ref GetAddr, %.loc19_12.2 [template = constants.%GetAddr.2]
// CHECK:STDOUT: %.loc19_12.3: <bound method> = bound_method %.loc19_12.1, %GetAddr.ref
// CHECK:STDOUT: %.loc19_12.4: %.8 = addr_of %.loc19_12.1
// CHECK:STDOUT: %GetAddr.call: init %.9 = call %.loc19_12.3(%.loc19_12.4)
Expand All @@ -282,9 +280,9 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
// CHECK:STDOUT: %Class => constants.%Class.2
// CHECK:STDOUT: %.1 => constants.%.2
// CHECK:STDOUT: %Get.type => constants.%Get.type.1
// CHECK:STDOUT: %Get => constants.%Get.2
// CHECK:STDOUT: %Get => constants.%Get.1
// CHECK:STDOUT: %GetAddr.type => constants.%GetAddr.type.1
// CHECK:STDOUT: %GetAddr => constants.%GetAddr.2
// CHECK:STDOUT: %GetAddr => constants.%GetAddr.1
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Class(@Get.%T) {
Expand Down Expand Up @@ -318,9 +316,9 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
// CHECK:STDOUT: %Class => constants.%Class.3
// CHECK:STDOUT: %.1 => constants.%.7
// CHECK:STDOUT: %Get.type => constants.%Get.type.2
// CHECK:STDOUT: %Get => constants.%Get.3
// CHECK:STDOUT: %Get => constants.%Get.2
// CHECK:STDOUT: %GetAddr.type => constants.%GetAddr.type.2
// CHECK:STDOUT: %GetAddr => constants.%GetAddr.3
// CHECK:STDOUT: %GetAddr => constants.%GetAddr.2
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Get(i32) {
Expand All @@ -344,9 +342,8 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
// CHECK:STDOUT: %Class.1: %Class.type = struct_value () [template]
// CHECK:STDOUT: %Class.2: type = class_type @Class, @Class(%T) [symbolic]
// CHECK:STDOUT: %Make.type: type = fn_type @Make, @Class(%T) [symbolic]
// CHECK:STDOUT: %Make.1: %Make.type = struct_value () [symbolic]
// CHECK:STDOUT: %Make: %Make.type = struct_value () [symbolic]
// CHECK:STDOUT: %.2: type = struct_type {} [template]
// CHECK:STDOUT: %Make.2: %Make.type = struct_value () [symbolic]
// CHECK:STDOUT: %.3: type = ptr_type %.2 [template]
// CHECK:STDOUT: %struct: %Class.2 = struct_value () [symbolic]
// CHECK:STDOUT: %StaticMemberFunctionCall.type: type = fn_type @StaticMemberFunctionCall [template]
Expand Down Expand Up @@ -393,10 +390,10 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %Make.type: type = fn_type @Make, @Class(%T) [symbolic = %Make.type (constants.%Make.type)]
// CHECK:STDOUT: %Make: @Class.%Make.type (%Make.type) = struct_value () [symbolic = %Make (constants.%Make.1)]
// CHECK:STDOUT: %Make: @Class.%Make.type (%Make.type) = struct_value () [symbolic = %Make (constants.%Make)]
// CHECK:STDOUT:
// CHECK:STDOUT: class {
// CHECK:STDOUT: %Make.decl: @Class.%Make.type (%Make.type) = fn_decl @Make [symbolic = %Make (constants.%Make.1)] {
// CHECK:STDOUT: %Make.decl: @Class.%Make.type (%Make.type) = fn_decl @Make [symbolic = %Make (constants.%Make)] {
// CHECK:STDOUT: %Class.ref: %Class.type = name_ref Class, file.%Class.decl [template = constants.%Class.1]
// CHECK:STDOUT: %T.ref: type = name_ref T, file.%T.loc4_13.2 [symbolic = @Make.%T (constants.%T)]
// CHECK:STDOUT: %.loc5_21: init type = call %Class.ref(%T.ref) [symbolic = @Make.%Class (constants.%Class.2)]
Expand Down Expand Up @@ -433,15 +430,15 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %Make.type: type = fn_type @Make, @Class(%T.1) [symbolic = %Make.type (constants.%Make.type)]
// CHECK:STDOUT: %Make: @StaticMemberFunctionCall.%Make.type (%Make.type) = struct_value () [symbolic = %Make (constants.%Make.2)]
// CHECK:STDOUT: %Make: @StaticMemberFunctionCall.%Make.type (%Make.type) = struct_value () [symbolic = %Make (constants.%Make)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%T.loc8: type) -> %return: @StaticMemberFunctionCall.%Class (%Class.2) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %Class.ref: %Class.type = name_ref Class, file.%Class.decl [template = constants.%Class.1]
// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc8 [symbolic = %T.1 (constants.%T)]
// CHECK:STDOUT: %.loc12_15: init type = call %Class.ref(%T.ref) [symbolic = %Class (constants.%Class.2)]
// CHECK:STDOUT: %.loc12_18: @StaticMemberFunctionCall.%Make.type (%Make.type) = specific_constant @Class.%Make.decl, @Class(constants.%T) [symbolic = %Make (constants.%Make.2)]
// CHECK:STDOUT: %Make.ref: @StaticMemberFunctionCall.%Make.type (%Make.type) = name_ref Make, %.loc12_18 [symbolic = %Make (constants.%Make.2)]
// CHECK:STDOUT: %.loc12_18: @StaticMemberFunctionCall.%Make.type (%Make.type) = specific_constant @Class.%Make.decl, @Class(constants.%T) [symbolic = %Make (constants.%Make)]
// CHECK:STDOUT: %Make.ref: @StaticMemberFunctionCall.%Make.type (%Make.type) = name_ref Make, %.loc12_18 [symbolic = %Make (constants.%Make)]
// CHECK:STDOUT: %.loc12_23: ref @StaticMemberFunctionCall.%Class (%Class.2) = temporary_storage
// CHECK:STDOUT: %Make.call: init @StaticMemberFunctionCall.%Class (%Class.2) = call %Make.ref() to %.loc12_23
// CHECK:STDOUT: return <error> to %return
Expand All @@ -453,7 +450,7 @@ fn StaticMemberFunctionCall(T:! type) -> Class(T) {
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %Make.type => constants.%Make.type
// CHECK:STDOUT: %Make => constants.%Make.2
// CHECK:STDOUT: %Make => constants.%Make
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Class(@Make.%T) {
Expand Down
Loading

0 comments on commit 3c4c234

Please sign in to comment.