Basic support for incomplete types. (#3302)

Incomplete types may be nested within other types; for example, a tuple
type might have an incomplete type as an element. Handle such cases by
walking through nested incomplete types when completing a type. This is
done non-recursively in case a very complex type is formed.

Types are generally no longer completed at the point where they're
formed. Instead, we attempt to complete a type when it is used in a
context that requires a complete type, and diagnose if the type cannot
be completed at that point. This will be necessary for classes, which
can become complete after their first use, and helps tease out bugs
where a type completeness check is missing.
This commit is contained in:
Richard Smith
2023-10-17 19:30:51 +00:00
committed by GitHub
parent 3015135a52
commit 69353ed271
57 changed files with 1141 additions and 597 deletions
+4 -5
View File
@@ -11,6 +11,7 @@ fn G() {
}
// CHECK:STDOUT: file "array_in_place.carbon" {
// CHECK:STDOUT: %.loc7: type = ptr_type (i32, i32, i32)
// CHECK:STDOUT: %F: <function> = fn_decl @F
// CHECK:STDOUT: %G: <function> = fn_decl @G
// CHECK:STDOUT: }
@@ -37,10 +38,8 @@ fn G() {
// CHECK:STDOUT: }
// CHECK:STDOUT: %.loc10_40: init (i32, i32, i32) = call %F.ref.loc10_39() to %.loc10_42.6
// CHECK:STDOUT: %.loc10_42.7: type = tuple_type ((i32, i32, i32), (i32, i32, i32))
// CHECK:STDOUT: %.loc10_42.8: type = tuple_type ((i32, i32, i32)*, (i32, i32, i32)*)
// CHECK:STDOUT: %.loc10_42.9: type = ptr_type ((i32, i32, i32)*, (i32, i32, i32)*)
// CHECK:STDOUT: %.loc10_42.10: ((i32, i32, i32), (i32, i32, i32)) = tuple_literal (%.loc10_35, %.loc10_40)
// CHECK:STDOUT: %.loc10_42.11: init [(i32, i32, i32); 2] = array_init %.loc10_42.10, (%.loc10_35, %.loc10_40) to %v
// CHECK:STDOUT: assign %v, %.loc10_42.11
// CHECK:STDOUT: %.loc10_42.8: ((i32, i32, i32), (i32, i32, i32)) = tuple_literal (%.loc10_35, %.loc10_40)
// CHECK:STDOUT: %.loc10_42.9: init [(i32, i32, i32); 2] = array_init %.loc10_42.8, (%.loc10_35, %.loc10_40) to %v
// CHECK:STDOUT: assign %v, %.loc10_42.9
// CHECK:STDOUT: return
// CHECK:STDOUT: }
+3 -4
View File
@@ -9,10 +9,9 @@ var b: [i32; 3] = a;
// CHECK:STDOUT: file "assign_var.carbon" {
// CHECK:STDOUT: %.loc7_22.1: type = tuple_type (type, type, type)
// CHECK:STDOUT: %.loc7_22.2: type = ptr_type (type, type, type)
// CHECK:STDOUT: %.loc7_22.3: (type, type, type) = tuple_literal (i32, i32, i32)
// CHECK:STDOUT: %.loc7_22.4: type = tuple_type (i32, i32, i32)
// CHECK:STDOUT: %.loc7_22.5: type = ptr_type (i32, i32, i32)
// CHECK:STDOUT: %.loc7_22.2: (type, type, type) = tuple_literal (i32, i32, i32)
// CHECK:STDOUT: %.loc7_22.3: type = tuple_type (i32, i32, i32)
// CHECK:STDOUT: %.loc7_22.4: type = ptr_type (i32, i32, i32)
// CHECK:STDOUT: %a: ref (i32, i32, i32) = var "a"
// CHECK:STDOUT: %.loc7_27: i32 = int_literal 1
// CHECK:STDOUT: %.loc7_30: i32 = int_literal 2
+12 -14
View File
@@ -28,16 +28,15 @@ var c: [(); 5] = ((), (), (), (), (),);
// CHECK:STDOUT: %.loc8_20: f64 = real_literal 111e-1
// CHECK:STDOUT: %.loc8_26: f64 = real_literal 22e-1
// CHECK:STDOUT: %.loc8_30.1: type = tuple_type (f64, f64)
// CHECK:STDOUT: %.loc8_30.2: type = ptr_type (f64, f64)
// CHECK:STDOUT: %.loc8_30.3: (f64, f64) = tuple_literal (%.loc8_20, %.loc8_26)
// CHECK:STDOUT: %.loc8_30.4: i32 = int_literal 0
// CHECK:STDOUT: %.loc8_30.5: ref f64 = array_index %b, %.loc8_30.4
// CHECK:STDOUT: %.loc8_30.6: init f64 = initialize_from %.loc8_20 to %.loc8_30.5
// CHECK:STDOUT: %.loc8_30.7: i32 = int_literal 1
// CHECK:STDOUT: %.loc8_30.8: ref f64 = array_index %b, %.loc8_30.7
// CHECK:STDOUT: %.loc8_30.9: init f64 = initialize_from %.loc8_26 to %.loc8_30.8
// CHECK:STDOUT: %.loc8_30.10: init [f64; 2] = array_init %.loc8_30.3, (%.loc8_30.6, %.loc8_30.9) to %b
// CHECK:STDOUT: assign %b, %.loc8_30.10
// CHECK:STDOUT: %.loc8_30.2: (f64, f64) = tuple_literal (%.loc8_20, %.loc8_26)
// CHECK:STDOUT: %.loc8_30.3: i32 = int_literal 0
// CHECK:STDOUT: %.loc8_30.4: ref f64 = array_index %b, %.loc8_30.3
// CHECK:STDOUT: %.loc8_30.5: init f64 = initialize_from %.loc8_20 to %.loc8_30.4
// CHECK:STDOUT: %.loc8_30.6: i32 = int_literal 1
// CHECK:STDOUT: %.loc8_30.7: ref f64 = array_index %b, %.loc8_30.6
// CHECK:STDOUT: %.loc8_30.8: init f64 = initialize_from %.loc8_26 to %.loc8_30.7
// CHECK:STDOUT: %.loc8_30.9: init [f64; 2] = array_init %.loc8_30.2, (%.loc8_30.5, %.loc8_30.8) to %b
// CHECK:STDOUT: assign %b, %.loc8_30.9
// CHECK:STDOUT: %.loc9_10.1: type = tuple_type ()
// CHECK:STDOUT: %.loc9_10.2: () = tuple_literal ()
// CHECK:STDOUT: %.loc9_13: i32 = int_literal 5
@@ -50,13 +49,12 @@ var c: [(); 5] = ((), (), (), (), (),);
// CHECK:STDOUT: %.loc9_32.1: () = tuple_literal ()
// CHECK:STDOUT: %.loc9_36.1: () = tuple_literal ()
// CHECK:STDOUT: %.loc9_38.1: type = tuple_type ((), (), (), (), ())
// CHECK:STDOUT: %.loc9_38.2: type = ptr_type ((), (), (), (), ())
// CHECK:STDOUT: %.loc9_38.3: ((), (), (), (), ()) = tuple_literal (%.loc9_20.1, %.loc9_24.1, %.loc9_28.1, %.loc9_32.1, %.loc9_36.1)
// CHECK:STDOUT: %.loc9_38.2: ((), (), (), (), ()) = tuple_literal (%.loc9_20.1, %.loc9_24.1, %.loc9_28.1, %.loc9_32.1, %.loc9_36.1)
// CHECK:STDOUT: %.loc9_20.2: init () = tuple_init %.loc9_20.1, ()
// CHECK:STDOUT: %.loc9_24.2: init () = tuple_init %.loc9_24.1, ()
// CHECK:STDOUT: %.loc9_28.2: init () = tuple_init %.loc9_28.1, ()
// CHECK:STDOUT: %.loc9_32.2: init () = tuple_init %.loc9_32.1, ()
// CHECK:STDOUT: %.loc9_36.2: init () = tuple_init %.loc9_36.1, ()
// CHECK:STDOUT: %.loc9_38.4: init [(); 5] = array_init %.loc9_38.3, (%.loc9_20.2, %.loc9_24.2, %.loc9_28.2, %.loc9_32.2, %.loc9_36.2) to %c
// CHECK:STDOUT: assign %c, %.loc9_38.4
// CHECK:STDOUT: %.loc9_38.3: init [(); 5] = array_init %.loc9_38.2, (%.loc9_20.2, %.loc9_24.2, %.loc9_28.2, %.loc9_32.2, %.loc9_36.2) to %c
// CHECK:STDOUT: assign %c, %.loc9_38.3
// CHECK:STDOUT: }
@@ -0,0 +1,38 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// AUTOUPDATE
class Incomplete;
// CHECK:STDERR: fail_incomplete_element.carbon:[[@LINE+6]]:22: ERROR: Variable has incomplete type `[Incomplete; 1]`.
// CHECK:STDERR: var a: [Incomplete; 1];
// CHECK:STDERR: ^
// CHECK:STDERR: fail_incomplete_element.carbon:[[@LINE-5]]:1: Class was forward declared here.
// CHECK:STDERR: class Incomplete;
// CHECK:STDERR: ^
var a: [Incomplete; 1];
// CHECK:STDERR: fail_incomplete_element.carbon:[[@LINE+3]]:27: ERROR: Cannot implicitly convert from `<error>*` to `Incomplete*`.
// CHECK:STDERR: var p: Incomplete* = &a[0];
// CHECK:STDERR: ^
var p: Incomplete* = &a[0];
// CHECK:STDOUT: file "fail_incomplete_element.carbon" {
// CHECK:STDOUT: %Incomplete: type = class_declaration @Incomplete
// CHECK:STDOUT: %Incomplete.ref.loc15: type = name_reference "Incomplete", %Incomplete
// CHECK:STDOUT: %.loc15_21: i32 = int_literal 1
// CHECK:STDOUT: %.loc15_22: type = array_type %.loc15_21, Incomplete
// CHECK:STDOUT: %a: ref <error> = var "a"
// CHECK:STDOUT: %Incomplete.ref.loc20: type = name_reference "Incomplete", %Incomplete
// CHECK:STDOUT: %.loc20_18: type = ptr_type Incomplete
// CHECK:STDOUT: %p: ref Incomplete* = var "p"
// CHECK:STDOUT: %a.ref: ref <error> = name_reference "a", %a
// CHECK:STDOUT: %.loc20_25: i32 = int_literal 0
// CHECK:STDOUT: %.loc20_22.1: type = ptr_type <error>
// CHECK:STDOUT: %.loc20_22.2: <error>* = address_of <error>
// CHECK:STDOUT: assign %p, <error>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @Incomplete;
+1 -2
View File
@@ -18,7 +18,6 @@ var a: [i32; 1] = (1, 2, 3);
// CHECK:STDOUT: %.loc10_23: i32 = int_literal 2
// CHECK:STDOUT: %.loc10_26: i32 = int_literal 3
// CHECK:STDOUT: %.loc10_27.1: type = tuple_type (i32, i32, i32)
// CHECK:STDOUT: %.loc10_27.2: type = ptr_type (i32, i32, i32)
// CHECK:STDOUT: %.loc10_27.3: (i32, i32, i32) = tuple_literal (%.loc10_20, %.loc10_23, %.loc10_26)
// CHECK:STDOUT: %.loc10_27.2: (i32, i32, i32) = tuple_literal (%.loc10_20, %.loc10_23, %.loc10_26)
// CHECK:STDOUT: assign %a, <error>
// CHECK:STDOUT: }
+10 -12
View File
@@ -36,16 +36,15 @@ var d: [i32; 3] = t2;
// CHECK:STDOUT: %.loc10_23: String = string_literal "Hello"
// CHECK:STDOUT: %.loc10_32: String = string_literal "World"
// CHECK:STDOUT: %.loc10_39.1: type = tuple_type (i32, String, String)
// CHECK:STDOUT: %.loc10_39.2: type = tuple_type (i32, String*, String*)
// CHECK:STDOUT: %.loc10_39.3: type = ptr_type (i32, String*, String*)
// CHECK:STDOUT: %.loc10_39.4: (i32, String, String) = tuple_literal (%.loc10_20, %.loc10_23, %.loc10_32)
// CHECK:STDOUT: %.loc10_39.5: i32 = int_literal 0
// CHECK:STDOUT: %.loc10_39.6: ref i32 = array_index %a, %.loc10_39.5
// CHECK:STDOUT: %.loc10_39.7: init i32 = initialize_from %.loc10_20 to %.loc10_39.6
// CHECK:STDOUT: %.loc10_39.2: (i32, String, String) = tuple_literal (%.loc10_20, %.loc10_23, %.loc10_32)
// CHECK:STDOUT: %.loc10_39.3: i32 = int_literal 0
// CHECK:STDOUT: %.loc10_39.4: ref i32 = array_index %a, %.loc10_39.3
// CHECK:STDOUT: %.loc10_39.5: init i32 = initialize_from %.loc10_20 to %.loc10_39.4
// CHECK:STDOUT: assign %a, <error>
// CHECK:STDOUT: %.loc12_29.1: type = tuple_type (type, type, type)
// CHECK:STDOUT: %.loc12_29.2: type = ptr_type (type, type, type)
// CHECK:STDOUT: %.loc12_29.3: (type, type, type) = tuple_literal (i32, String, String)
// CHECK:STDOUT: %.loc12_29.2: (type, type, type) = tuple_literal (i32, String, String)
// CHECK:STDOUT: %.loc10_39.6: type = tuple_type (i32, String*, String*)
// CHECK:STDOUT: %.loc10_39.7: type = ptr_type (i32, String*, String*)
// CHECK:STDOUT: %t1: ref (i32, String, String) = var "t1"
// CHECK:STDOUT: %.loc16_14: i32 = int_literal 3
// CHECK:STDOUT: %.loc16_15: type = array_type %.loc16_14, i32
@@ -64,12 +63,11 @@ var d: [i32; 3] = t2;
// CHECK:STDOUT: %.loc21_20: i32 = int_literal 1
// CHECK:STDOUT: %.loc21_23: i32 = int_literal 2
// CHECK:STDOUT: %.loc21_24.1: type = tuple_type (i32, i32)
// CHECK:STDOUT: %.loc21_24.2: type = ptr_type (i32, i32)
// CHECK:STDOUT: %.loc21_24.3: (i32, i32) = tuple_literal (%.loc21_20, %.loc21_23)
// CHECK:STDOUT: %.loc21_24.2: (i32, i32) = tuple_literal (%.loc21_20, %.loc21_23)
// CHECK:STDOUT: assign %c, <error>
// CHECK:STDOUT: %.loc23_18.1: type = tuple_type (type, type)
// CHECK:STDOUT: %.loc23_18.2: type = ptr_type (type, type)
// CHECK:STDOUT: %.loc23_18.3: (type, type) = tuple_literal (i32, i32)
// CHECK:STDOUT: %.loc23_18.2: (type, type) = tuple_literal (i32, i32)
// CHECK:STDOUT: %.loc21_24.3: type = ptr_type (i32, i32)
// CHECK:STDOUT: %t2: ref (i32, i32) = var "t2"
// CHECK:STDOUT: %.loc27_14: i32 = int_literal 3
// CHECK:STDOUT: %.loc27_15: type = array_type %.loc27_14, i32
+16 -16
View File
@@ -19,6 +19,7 @@ fn G() -> i32 {
// CHECK:STDOUT:
// CHECK:STDOUT: fn @F(%arr: [i32; 3], %i: i32) -> i32 {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %.loc7: type = ptr_type [i32; 3]
// CHECK:STDOUT: %arr.ref: [i32; 3] = name_reference "arr", %arr
// CHECK:STDOUT: %i.ref: i32 = name_reference "i", %i
// CHECK:STDOUT: %.loc8_15.1: ref [i32; 3] = value_as_reference %arr.ref
@@ -34,23 +35,22 @@ fn G() -> i32 {
// CHECK:STDOUT: %.loc12_16: i32 = int_literal 2
// CHECK:STDOUT: %.loc12_19: i32 = int_literal 3
// CHECK:STDOUT: %.loc12_20.1: type = tuple_type (i32, i32, i32)
// CHECK:STDOUT: %.loc12_20.2: type = ptr_type (i32, i32, i32)
// CHECK:STDOUT: %.loc12_20.3: (i32, i32, i32) = tuple_literal (%.loc12_13, %.loc12_16, %.loc12_19)
// CHECK:STDOUT: %.loc12_20.2: (i32, i32, i32) = tuple_literal (%.loc12_13, %.loc12_16, %.loc12_19)
// CHECK:STDOUT: %.loc12_23: i32 = int_literal 1
// CHECK:STDOUT: %.loc12_20.4: ref [i32; 3] = temporary_storage
// CHECK:STDOUT: %.loc12_20.5: i32 = int_literal 0
// CHECK:STDOUT: %.loc12_20.6: ref i32 = array_index %.loc12_20.4, %.loc12_20.5
// CHECK:STDOUT: %.loc12_20.7: init i32 = initialize_from %.loc12_13 to %.loc12_20.6
// CHECK:STDOUT: %.loc12_20.8: i32 = int_literal 1
// CHECK:STDOUT: %.loc12_20.9: ref i32 = array_index %.loc12_20.4, %.loc12_20.8
// CHECK:STDOUT: %.loc12_20.10: init i32 = initialize_from %.loc12_16 to %.loc12_20.9
// CHECK:STDOUT: %.loc12_20.11: i32 = int_literal 2
// CHECK:STDOUT: %.loc12_20.12: ref i32 = array_index %.loc12_20.4, %.loc12_20.11
// CHECK:STDOUT: %.loc12_20.13: init i32 = initialize_from %.loc12_19 to %.loc12_20.12
// CHECK:STDOUT: %.loc12_20.14: init [i32; 3] = array_init %.loc12_20.3, (%.loc12_20.7, %.loc12_20.10, %.loc12_20.13) to %.loc12_20.4
// CHECK:STDOUT: %.loc12_20.15: ref [i32; 3] = temporary %.loc12_20.4, %.loc12_20.14
// CHECK:STDOUT: %.loc12_20.16: [i32; 3] = bind_value %.loc12_20.15
// CHECK:STDOUT: %.loc12_11.1: init i32 = call %F.ref(%.loc12_20.16, %.loc12_23)
// CHECK:STDOUT: %.loc12_20.3: ref [i32; 3] = temporary_storage
// CHECK:STDOUT: %.loc12_20.4: i32 = int_literal 0
// CHECK:STDOUT: %.loc12_20.5: ref i32 = array_index %.loc12_20.3, %.loc12_20.4
// CHECK:STDOUT: %.loc12_20.6: init i32 = initialize_from %.loc12_13 to %.loc12_20.5
// CHECK:STDOUT: %.loc12_20.7: i32 = int_literal 1
// CHECK:STDOUT: %.loc12_20.8: ref i32 = array_index %.loc12_20.3, %.loc12_20.7
// CHECK:STDOUT: %.loc12_20.9: init i32 = initialize_from %.loc12_16 to %.loc12_20.8
// CHECK:STDOUT: %.loc12_20.10: i32 = int_literal 2
// CHECK:STDOUT: %.loc12_20.11: ref i32 = array_index %.loc12_20.3, %.loc12_20.10
// CHECK:STDOUT: %.loc12_20.12: init i32 = initialize_from %.loc12_19 to %.loc12_20.11
// CHECK:STDOUT: %.loc12_20.13: init [i32; 3] = array_init %.loc12_20.2, (%.loc12_20.6, %.loc12_20.9, %.loc12_20.12) to %.loc12_20.3
// CHECK:STDOUT: %.loc12_20.14: ref [i32; 3] = temporary %.loc12_20.3, %.loc12_20.13
// CHECK:STDOUT: %.loc12_20.15: [i32; 3] = bind_value %.loc12_20.14
// CHECK:STDOUT: %.loc12_11.1: init i32 = call %F.ref(%.loc12_20.15, %.loc12_23)
// CHECK:STDOUT: %.loc12_11.2: ref i32 = temporary_storage
// CHECK:STDOUT: %.loc12_11.3: ref i32 = temporary %.loc12_11.2, %.loc12_11.1
// CHECK:STDOUT: %.loc12_11.4: i32 = bind_value %.loc12_11.3
+30 -31
View File
@@ -21,35 +21,34 @@ var a: [i32; 9] = (1, 2, 3, 4, 5, 6, 7, 8, 9);
// CHECK:STDOUT: %.loc7_41: i32 = int_literal 8
// CHECK:STDOUT: %.loc7_44: i32 = int_literal 9
// CHECK:STDOUT: %.loc7_45.1: type = tuple_type (i32, i32, i32, i32, i32, i32, i32, i32, i32)
// CHECK:STDOUT: %.loc7_45.2: type = ptr_type (i32, i32, i32, i32, i32, i32, i32, i32, i32)
// CHECK:STDOUT: %.loc7_45.3: (i32, i32, i32, i32, i32, i32, i32, i32, i32) = tuple_literal (%.loc7_20, %.loc7_23, %.loc7_26, %.loc7_29, %.loc7_32, %.loc7_35, %.loc7_38, %.loc7_41, %.loc7_44)
// CHECK:STDOUT: %.loc7_45.4: i32 = int_literal 0
// CHECK:STDOUT: %.loc7_45.5: ref i32 = array_index %a, %.loc7_45.4
// CHECK:STDOUT: %.loc7_45.6: init i32 = initialize_from %.loc7_20 to %.loc7_45.5
// CHECK:STDOUT: %.loc7_45.7: i32 = int_literal 1
// CHECK:STDOUT: %.loc7_45.8: ref i32 = array_index %a, %.loc7_45.7
// CHECK:STDOUT: %.loc7_45.9: init i32 = initialize_from %.loc7_23 to %.loc7_45.8
// CHECK:STDOUT: %.loc7_45.10: i32 = int_literal 2
// CHECK:STDOUT: %.loc7_45.11: ref i32 = array_index %a, %.loc7_45.10
// CHECK:STDOUT: %.loc7_45.12: init i32 = initialize_from %.loc7_26 to %.loc7_45.11
// CHECK:STDOUT: %.loc7_45.13: i32 = int_literal 3
// CHECK:STDOUT: %.loc7_45.14: ref i32 = array_index %a, %.loc7_45.13
// CHECK:STDOUT: %.loc7_45.15: init i32 = initialize_from %.loc7_29 to %.loc7_45.14
// CHECK:STDOUT: %.loc7_45.16: i32 = int_literal 4
// CHECK:STDOUT: %.loc7_45.17: ref i32 = array_index %a, %.loc7_45.16
// CHECK:STDOUT: %.loc7_45.18: init i32 = initialize_from %.loc7_32 to %.loc7_45.17
// CHECK:STDOUT: %.loc7_45.19: i32 = int_literal 5
// CHECK:STDOUT: %.loc7_45.20: ref i32 = array_index %a, %.loc7_45.19
// CHECK:STDOUT: %.loc7_45.21: init i32 = initialize_from %.loc7_35 to %.loc7_45.20
// CHECK:STDOUT: %.loc7_45.22: i32 = int_literal 6
// CHECK:STDOUT: %.loc7_45.23: ref i32 = array_index %a, %.loc7_45.22
// CHECK:STDOUT: %.loc7_45.24: init i32 = initialize_from %.loc7_38 to %.loc7_45.23
// CHECK:STDOUT: %.loc7_45.25: i32 = int_literal 7
// CHECK:STDOUT: %.loc7_45.26: ref i32 = array_index %a, %.loc7_45.25
// CHECK:STDOUT: %.loc7_45.27: init i32 = initialize_from %.loc7_41 to %.loc7_45.26
// CHECK:STDOUT: %.loc7_45.28: i32 = int_literal 8
// CHECK:STDOUT: %.loc7_45.29: ref i32 = array_index %a, %.loc7_45.28
// CHECK:STDOUT: %.loc7_45.30: init i32 = initialize_from %.loc7_44 to %.loc7_45.29
// CHECK:STDOUT: %.loc7_45.31: init [i32; 9] = array_init %.loc7_45.3, (%.loc7_45.6, %.loc7_45.9, %.loc7_45.12, %.loc7_45.15, %.loc7_45.18, %.loc7_45.21, %.loc7_45.24, %.loc7_45.27, %.loc7_45.30) to %a
// CHECK:STDOUT: assign %a, %.loc7_45.31
// CHECK:STDOUT: %.loc7_45.2: (i32, i32, i32, i32, i32, i32, i32, i32, i32) = tuple_literal (%.loc7_20, %.loc7_23, %.loc7_26, %.loc7_29, %.loc7_32, %.loc7_35, %.loc7_38, %.loc7_41, %.loc7_44)
// CHECK:STDOUT: %.loc7_45.3: i32 = int_literal 0
// CHECK:STDOUT: %.loc7_45.4: ref i32 = array_index %a, %.loc7_45.3
// CHECK:STDOUT: %.loc7_45.5: init i32 = initialize_from %.loc7_20 to %.loc7_45.4
// CHECK:STDOUT: %.loc7_45.6: i32 = int_literal 1
// CHECK:STDOUT: %.loc7_45.7: ref i32 = array_index %a, %.loc7_45.6
// CHECK:STDOUT: %.loc7_45.8: init i32 = initialize_from %.loc7_23 to %.loc7_45.7
// CHECK:STDOUT: %.loc7_45.9: i32 = int_literal 2
// CHECK:STDOUT: %.loc7_45.10: ref i32 = array_index %a, %.loc7_45.9
// CHECK:STDOUT: %.loc7_45.11: init i32 = initialize_from %.loc7_26 to %.loc7_45.10
// CHECK:STDOUT: %.loc7_45.12: i32 = int_literal 3
// CHECK:STDOUT: %.loc7_45.13: ref i32 = array_index %a, %.loc7_45.12
// CHECK:STDOUT: %.loc7_45.14: init i32 = initialize_from %.loc7_29 to %.loc7_45.13
// CHECK:STDOUT: %.loc7_45.15: i32 = int_literal 4
// CHECK:STDOUT: %.loc7_45.16: ref i32 = array_index %a, %.loc7_45.15
// CHECK:STDOUT: %.loc7_45.17: init i32 = initialize_from %.loc7_32 to %.loc7_45.16
// CHECK:STDOUT: %.loc7_45.18: i32 = int_literal 5
// CHECK:STDOUT: %.loc7_45.19: ref i32 = array_index %a, %.loc7_45.18
// CHECK:STDOUT: %.loc7_45.20: init i32 = initialize_from %.loc7_35 to %.loc7_45.19
// CHECK:STDOUT: %.loc7_45.21: i32 = int_literal 6
// CHECK:STDOUT: %.loc7_45.22: ref i32 = array_index %a, %.loc7_45.21
// CHECK:STDOUT: %.loc7_45.23: init i32 = initialize_from %.loc7_38 to %.loc7_45.22
// CHECK:STDOUT: %.loc7_45.24: i32 = int_literal 7
// CHECK:STDOUT: %.loc7_45.25: ref i32 = array_index %a, %.loc7_45.24
// CHECK:STDOUT: %.loc7_45.26: init i32 = initialize_from %.loc7_41 to %.loc7_45.25
// CHECK:STDOUT: %.loc7_45.27: i32 = int_literal 8
// CHECK:STDOUT: %.loc7_45.28: ref i32 = array_index %a, %.loc7_45.27
// CHECK:STDOUT: %.loc7_45.29: init i32 = initialize_from %.loc7_44 to %.loc7_45.28
// CHECK:STDOUT: %.loc7_45.30: init [i32; 9] = array_init %.loc7_45.2, (%.loc7_45.5, %.loc7_45.8, %.loc7_45.11, %.loc7_45.14, %.loc7_45.17, %.loc7_45.20, %.loc7_45.23, %.loc7_45.26, %.loc7_45.29) to %a
// CHECK:STDOUT: assign %a, %.loc7_45.30
// CHECK:STDOUT: }