|
8 | 8 | // TIP: To dump output, run: |
9 | 9 | // TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/fail_todo_local_class.carbon |
10 | 10 |
|
11 | | -// TODO: Support parsing classes at function scope. |
12 | 11 | class A { |
13 | | - fn F() { |
14 | | - // CHECK:STDERR: fail_todo_local_class.carbon:[[@LINE+7]]:5: error: expected expression [ExpectedExpr] |
15 | | - // CHECK:STDERR: class B { |
16 | | - // CHECK:STDERR: ^~~~~ |
17 | | - // CHECK:STDERR: |
18 | | - // CHECK:STDERR: fail_todo_local_class.carbon:[[@LINE+3]]:5: error: semantics TODO: `handle invalid parse trees in `check`` [SemanticsTodo] |
19 | | - // CHECK:STDERR: class B { |
20 | | - // CHECK:STDERR: ^~~~~ |
| 12 | + fn F() -> i32 { |
21 | 13 | class B { |
22 | | - fn G() { |
23 | | - var b: B = {}; |
| 14 | + fn Make() -> Self { |
| 15 | + returned var b: Self = {.n = 1}; |
| 16 | + return var; |
24 | 17 | } |
| 18 | + |
| 19 | + var n: i32; |
25 | 20 | } |
| 21 | + |
| 22 | + // TODO: Add the name `B` to the lexical scope. |
| 23 | + // CHECK:STDERR: fail_todo_local_class.carbon:[[@LINE+3]]:12: error: name `B` not found [NameNotFound] |
| 24 | + // CHECK:STDERR: return B.Make().n; |
| 25 | + // CHECK:STDERR: ^ |
| 26 | + return B.Make().n; |
26 | 27 | } |
27 | 28 | } |
28 | 29 |
|
29 | 30 | // CHECK:STDOUT: --- fail_todo_local_class.carbon |
30 | 31 | // CHECK:STDOUT: |
31 | 32 | // CHECK:STDOUT: constants { |
32 | 33 | // CHECK:STDOUT: %A: type = class_type @A [template] |
| 34 | +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template] |
| 35 | +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [template] |
33 | 36 | // CHECK:STDOUT: %F.type: type = fn_type @F [template] |
34 | 37 | // CHECK:STDOUT: %F: %F.type = struct_value () [template] |
35 | 38 | // CHECK:STDOUT: %empty_struct_type: type = struct_type {} [template] |
36 | | -// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [template] |
| 39 | +// CHECK:STDOUT: %complete_type.357: <witness> = complete_type_witness %empty_struct_type [template] |
| 40 | +// CHECK:STDOUT: %B: type = class_type @B [template] |
| 41 | +// CHECK:STDOUT: %Make.type: type = fn_type @Make [template] |
| 42 | +// CHECK:STDOUT: %Make: %Make.type = struct_value () [template] |
| 43 | +// CHECK:STDOUT: %B.elem: type = unbound_element_type %B, %i32 [template] |
| 44 | +// CHECK:STDOUT: %struct_type.n.5cd: type = struct_type {.n: %i32} [template] |
| 45 | +// CHECK:STDOUT: %complete_type.9b7: <witness> = complete_type_witness %struct_type.n.5cd [template] |
| 46 | +// CHECK:STDOUT: %int_1.5b8: Core.IntLiteral = int_value 1 [template] |
| 47 | +// CHECK:STDOUT: %struct_type.n.44a: type = struct_type {.n: Core.IntLiteral} [template] |
| 48 | +// CHECK:STDOUT: %Convert.type.cd1: type = fn_type @Convert.1, @ImplicitAs(%i32) [template] |
| 49 | +// CHECK:STDOUT: %impl_witness.5b0: <witness> = impl_witness (imports.%import_ref.723), @impl.1(%int_32) [template] |
| 50 | +// CHECK:STDOUT: %Convert.type.466: type = fn_type @Convert.2, @impl.1(%int_32) [template] |
| 51 | +// CHECK:STDOUT: %Convert.925: %Convert.type.466 = struct_value () [template] |
| 52 | +// CHECK:STDOUT: %Convert.bound: <bound method> = bound_method %int_1.5b8, %Convert.925 [template] |
| 53 | +// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(%int_32) [template] |
| 54 | +// CHECK:STDOUT: %int_1.c60: %i32 = int_value 1 [template] |
| 55 | +// CHECK:STDOUT: %B.val: %B = struct_value (%int_1.c60) [template] |
37 | 56 | // CHECK:STDOUT: } |
38 | 57 | // CHECK:STDOUT: |
39 | | -// CHECK:STDOUT: file {} |
| 58 | +// CHECK:STDOUT: imports { |
| 59 | +// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [template] { |
| 60 | +// CHECK:STDOUT: .Int = %import_ref.187 |
| 61 | +// CHECK:STDOUT: .ImplicitAs = %import_ref.a69 |
| 62 | +// CHECK:STDOUT: import Core//prelude |
| 63 | +// CHECK:STDOUT: import Core//prelude/... |
| 64 | +// CHECK:STDOUT: } |
| 65 | +// CHECK:STDOUT: } |
| 66 | +// CHECK:STDOUT: |
| 67 | +// CHECK:STDOUT: file { |
| 68 | +// CHECK:STDOUT: package: <namespace> = namespace [template] { |
| 69 | +// CHECK:STDOUT: .Core = imports.%Core |
| 70 | +// CHECK:STDOUT: .A = %A.decl |
| 71 | +// CHECK:STDOUT: } |
| 72 | +// CHECK:STDOUT: %Core.import = import Core |
| 73 | +// CHECK:STDOUT: %A.decl: type = class_decl @A [template = constants.%A] {} {} |
| 74 | +// CHECK:STDOUT: } |
40 | 75 | // CHECK:STDOUT: |
41 | 76 | // CHECK:STDOUT: class @A { |
42 | | -// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] {} {} |
43 | | -// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [template = constants.%complete_type] |
| 77 | +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] { |
| 78 | +// CHECK:STDOUT: %return.patt: %i32 = return_slot_pattern |
| 79 | +// CHECK:STDOUT: %return.param_patt: %i32 = out_param_pattern %return.patt, runtime_param0 |
| 80 | +// CHECK:STDOUT: } { |
| 81 | +// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32] |
| 82 | +// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32] |
| 83 | +// CHECK:STDOUT: %return.param: ref %i32 = out_param runtime_param0 |
| 84 | +// CHECK:STDOUT: %return: ref %i32 = return_slot %return.param |
| 85 | +// CHECK:STDOUT: } |
| 86 | +// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [template = constants.%complete_type.357] |
44 | 87 | // CHECK:STDOUT: |
45 | 88 | // CHECK:STDOUT: !members: |
46 | 89 | // CHECK:STDOUT: .Self = constants.%A |
47 | 90 | // CHECK:STDOUT: .F = %F.decl |
48 | 91 | // CHECK:STDOUT: complete_type_witness = %complete_type |
49 | 92 | // CHECK:STDOUT: } |
50 | 93 | // CHECK:STDOUT: |
51 | | -// CHECK:STDOUT: fn @F(); |
| 94 | +// CHECK:STDOUT: class @B { |
| 95 | +// CHECK:STDOUT: %Make.decl: %Make.type = fn_decl @Make [template = constants.%Make] { |
| 96 | +// CHECK:STDOUT: %return.patt: %B = return_slot_pattern |
| 97 | +// CHECK:STDOUT: %return.param_patt: %B = out_param_pattern %return.patt, runtime_param0 |
| 98 | +// CHECK:STDOUT: } { |
| 99 | +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%B [template = constants.%B] |
| 100 | +// CHECK:STDOUT: %return.param: ref %B = out_param runtime_param0 |
| 101 | +// CHECK:STDOUT: %return: ref %B = return_slot %return.param |
| 102 | +// CHECK:STDOUT: } |
| 103 | +// CHECK:STDOUT: %.loc19: %B.elem = field_decl n, element0 [template] |
| 104 | +// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %struct_type.n.5cd [template = constants.%complete_type.9b7] |
| 105 | +// CHECK:STDOUT: |
| 106 | +// CHECK:STDOUT: !members: |
| 107 | +// CHECK:STDOUT: .Self = constants.%B |
| 108 | +// CHECK:STDOUT: .Make = %Make.decl |
| 109 | +// CHECK:STDOUT: .n = %.loc19 |
| 110 | +// CHECK:STDOUT: complete_type_witness = %complete_type |
| 111 | +// CHECK:STDOUT: } |
| 112 | +// CHECK:STDOUT: |
| 113 | +// CHECK:STDOUT: fn @F() -> %i32 { |
| 114 | +// CHECK:STDOUT: !entry: |
| 115 | +// CHECK:STDOUT: %B.decl: type = class_decl @B [template = constants.%B] {} {} |
| 116 | +// CHECK:STDOUT: %B.ref: <error> = name_ref B, <error> [template = <error>] |
| 117 | +// CHECK:STDOUT: %Make.ref: <error> = name_ref Make, <error> [template = <error>] |
| 118 | +// CHECK:STDOUT: %n.ref: <error> = name_ref n, <error> [template = <error>] |
| 119 | +// CHECK:STDOUT: return <error> |
| 120 | +// CHECK:STDOUT: } |
| 121 | +// CHECK:STDOUT: |
| 122 | +// CHECK:STDOUT: fn @Make() -> %return.param_patt: %B { |
| 123 | +// CHECK:STDOUT: !entry: |
| 124 | +// CHECK:STDOUT: %b: ref %B = bind_name b, %return |
| 125 | +// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [template = constants.%int_1.5b8] |
| 126 | +// CHECK:STDOUT: %.loc15_39.1: %struct_type.n.44a = struct_literal (%int_1) |
| 127 | +// CHECK:STDOUT: %impl.elem0: %Convert.type.cd1 = impl_witness_access constants.%impl_witness.5b0, element0 [template = constants.%Convert.925] |
| 128 | +// CHECK:STDOUT: %Convert.bound: <bound method> = bound_method %int_1, %impl.elem0 [template = constants.%Convert.bound] |
| 129 | +// CHECK:STDOUT: %Convert.specific_fn: <specific function> = specific_function %Convert.bound, @Convert.2(constants.%int_32) [template = constants.%Convert.specific_fn] |
| 130 | +// CHECK:STDOUT: %int.convert_checked: init %i32 = call %Convert.specific_fn(%int_1) [template = constants.%int_1.c60] |
| 131 | +// CHECK:STDOUT: %.loc15_39.2: init %i32 = converted %int_1, %int.convert_checked [template = constants.%int_1.c60] |
| 132 | +// CHECK:STDOUT: %.loc15_39.3: ref %i32 = class_element_access %return, element0 |
| 133 | +// CHECK:STDOUT: %.loc15_39.4: init %i32 = initialize_from %.loc15_39.2 to %.loc15_39.3 [template = constants.%int_1.c60] |
| 134 | +// CHECK:STDOUT: %.loc15_39.5: init %B = class_init (%.loc15_39.4), %return [template = constants.%B.val] |
| 135 | +// CHECK:STDOUT: %.loc15_40: init %B = converted %.loc15_39.1, %.loc15_39.5 [template = constants.%B.val] |
| 136 | +// CHECK:STDOUT: assign %return, %.loc15_40 |
| 137 | +// CHECK:STDOUT: return %b to %return |
| 138 | +// CHECK:STDOUT: } |
52 | 139 | // CHECK:STDOUT: |
0 commit comments