| ... | @@ -4503,14 +4503,14 @@ fn analyzeCall( | ... | @@ -4503,14 +4503,14 @@ fn analyzeCall( |
| 4503 | const arg_src = call_src; // TODO: better source location | 4503 | const arg_src = call_src; // TODO: better source location |
| 4504 | if (i < fn_params_len) { | 4504 | if (i < fn_params_len) { |
| 4505 | const param_ty = func_ty.fnParamType(i); | 4505 | const param_ty = func_ty.fnParamType(i); |
| 4506 | try sema.resolveTypeForCodegen(block, arg_src, param_ty); | 4506 | try sema.resolveTypeFully(block, arg_src, param_ty); |
| 4507 | args[i] = try sema.coerce(block, param_ty, uncasted_arg, arg_src); | 4507 | args[i] = try sema.coerce(block, param_ty, uncasted_arg, arg_src); |
| 4508 | } else { | 4508 | } else { |
| 4509 | args[i] = uncasted_arg; | 4509 | args[i] = uncasted_arg; |
| 4510 | } | 4510 | } |
| 4511 | } | 4511 | } |
| 4512 | | 4512 | |
| 4513 | try sema.resolveTypeForCodegen(block, call_src, func_ty_info.return_type); | 4513 | try sema.resolveTypeFully(block, call_src, func_ty_info.return_type); |
| 4514 | | 4514 | |
| 4515 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).Struct.fields.len + | 4515 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).Struct.fields.len + |
| 4516 | args.len); | 4516 | args.len); |
| ... | @@ -4580,7 +4580,7 @@ fn finishGenericCall( | ... | @@ -4580,7 +4580,7 @@ fn finishGenericCall( |
| 4580 | const param_ty = new_fn_ty.fnParamType(runtime_i); | 4580 | const param_ty = new_fn_ty.fnParamType(runtime_i); |
| 4581 | const arg_src = call_src; // TODO: better source location | 4581 | const arg_src = call_src; // TODO: better source location |
| 4582 | const uncasted_arg = uncasted_args[total_i]; | 4582 | const uncasted_arg = uncasted_args[total_i]; |
| 4583 | try sema.resolveTypeForCodegen(block, arg_src, param_ty); | 4583 | try sema.resolveTypeFully(block, arg_src, param_ty); |
| 4584 | const casted_arg = try sema.coerce(block, param_ty, uncasted_arg, arg_src); | 4584 | const casted_arg = try sema.coerce(block, param_ty, uncasted_arg, arg_src); |
| 4585 | runtime_args[runtime_i] = casted_arg; | 4585 | runtime_args[runtime_i] = casted_arg; |
| 4586 | runtime_i += 1; | 4586 | runtime_i += 1; |
| ... | @@ -4588,7 +4588,7 @@ fn finishGenericCall( | ... | @@ -4588,7 +4588,7 @@ fn finishGenericCall( |
| 4588 | total_i += 1; | 4588 | total_i += 1; |
| 4589 | } | 4589 | } |
| 4590 | | 4590 | |
| 4591 | try sema.resolveTypeForCodegen(block, call_src, new_fn_ty.fnReturnType()); | 4591 | try sema.resolveTypeFully(block, call_src, new_fn_ty.fnReturnType()); |
| 4592 | } | 4592 | } |
| 4593 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Call).Struct.fields.len + | 4593 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Call).Struct.fields.len + |
| 4594 | runtime_args_len); | 4594 | runtime_args_len); |
| ... | @@ -15228,7 +15228,7 @@ fn resolveStructLayout( | ... | @@ -15228,7 +15228,7 @@ fn resolveStructLayout( |
| 15228 | .field_types_wip, .layout_wip => { | 15228 | .field_types_wip, .layout_wip => { |
| 15229 | return sema.fail(block, src, "struct {} depends on itself", .{ty}); | 15229 | return sema.fail(block, src, "struct {} depends on itself", .{ty}); |
| 15230 | }, | 15230 | }, |
| 15231 | .have_layout => return, | 15231 | .have_layout, .fully_resolved_wip, .fully_resolved => return, |
| 15232 | } | 15232 | } |
| 15233 | struct_obj.status = .layout_wip; | 15233 | struct_obj.status = .layout_wip; |
| 15234 | for (struct_obj.fields.values()) |field| { | 15234 | for (struct_obj.fields.values()) |field| { |
| ... | @@ -15250,7 +15250,7 @@ fn resolveUnionLayout( | ... | @@ -15250,7 +15250,7 @@ fn resolveUnionLayout( |
| 15250 | .field_types_wip, .layout_wip => { | 15250 | .field_types_wip, .layout_wip => { |
| 15251 | return sema.fail(block, src, "union {} depends on itself", .{ty}); | 15251 | return sema.fail(block, src, "union {} depends on itself", .{ty}); |
| 15252 | }, | 15252 | }, |
| 15253 | .have_layout => return, | 15253 | .have_layout, .fully_resolved_wip, .fully_resolved => return, |
| 15254 | } | 15254 | } |
| 15255 | union_obj.status = .layout_wip; | 15255 | union_obj.status = .layout_wip; |
| 15256 | for (union_obj.fields.values()) |field| { | 15256 | for (union_obj.fields.values()) |field| { |
| ... | @@ -15259,7 +15259,7 @@ fn resolveUnionLayout( | ... | @@ -15259,7 +15259,7 @@ fn resolveUnionLayout( |
| 15259 | union_obj.status = .have_layout; | 15259 | union_obj.status = .have_layout; |
| 15260 | } | 15260 | } |
| 15261 | | 15261 | |
| 15262 | fn resolveTypeForCodegen( | 15262 | fn resolveTypeFully( |
| 15263 | sema: *Sema, | 15263 | sema: *Sema, |
| 15264 | block: *Block, | 15264 | block: *Block, |
| 15265 | src: LazySrcLoc, | 15265 | src: LazySrcLoc, |
| ... | @@ -15268,20 +15268,67 @@ fn resolveTypeForCodegen( | ... | @@ -15268,20 +15268,67 @@ fn resolveTypeForCodegen( |
| 15268 | switch (ty.zigTypeTag()) { | 15268 | switch (ty.zigTypeTag()) { |
| 15269 | .Pointer => { | 15269 | .Pointer => { |
| 15270 | const child_ty = try sema.resolveTypeFields(block, src, ty.childType()); | 15270 | const child_ty = try sema.resolveTypeFields(block, src, ty.childType()); |
| 15271 | return resolveTypeForCodegen(sema, block, src, child_ty); | 15271 | return resolveTypeFully(sema, block, src, child_ty); |
| 15272 | }, | 15272 | }, |
| 15273 | .Struct => return resolveStructLayout(sema, block, src, ty), | 15273 | .Struct => return resolveStructFully(sema, block, src, ty), |
| 15274 | .Union => return resolveUnionLayout(sema, block, src, ty), | 15274 | .Union => return resolveUnionFully(sema, block, src, ty), |
| 15275 | .Array => return resolveTypeForCodegen(sema, block, src, ty.childType()), | 15275 | .Array => return resolveTypeFully(sema, block, src, ty.childType()), |
| 15276 | .Optional => { | 15276 | .Optional => { |
| 15277 | var buf: Type.Payload.ElemType = undefined; | 15277 | var buf: Type.Payload.ElemType = undefined; |
| 15278 | return resolveTypeForCodegen(sema, block, src, ty.optionalChild(&buf)); | 15278 | return resolveTypeFully(sema, block, src, ty.optionalChild(&buf)); |
| 15279 | }, | 15279 | }, |
| 15280 | .ErrorUnion => return resolveTypeForCodegen(sema, block, src, ty.errorUnionPayload()), | 15280 | .ErrorUnion => return resolveTypeFully(sema, block, src, ty.errorUnionPayload()), |
| 15281 | else => {}, | 15281 | else => {}, |
| 15282 | } | 15282 | } |
| 15283 | } | 15283 | } |
| 15284 | | 15284 | |
| | 15285 | fn resolveStructFully( |
| | 15286 | sema: *Sema, |
| | 15287 | block: *Block, |
| | 15288 | src: LazySrcLoc, |
| | 15289 | ty: Type, |
| | 15290 | ) CompileError!void { |
| | 15291 | try resolveStructLayout(sema, block, src, ty); |
| | 15292 | |
| | 15293 | const resolved_ty = try sema.resolveTypeFields(block, src, ty); |
| | 15294 | const struct_obj = resolved_ty.castTag(.@"struct").?.data; |
| | 15295 | switch (struct_obj.status) { |
| | 15296 | .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {}, |
| | 15297 | .fully_resolved_wip, .fully_resolved => return, |
| | 15298 | } |
| | 15299 | |
| | 15300 | // After we have resolve struct layout we have to go over the fields again to |
| | 15301 | // make sure pointer fields get their child types resolved as well |
| | 15302 | struct_obj.status = .fully_resolved_wip; |
| | 15303 | for (struct_obj.fields.values()) |field| { |
| | 15304 | try sema.resolveTypeFully(block, src, field.ty); |
| | 15305 | } |
| | 15306 | struct_obj.status = .fully_resolved; |
| | 15307 | } |
| | 15308 | |
| | 15309 | fn resolveUnionFully( |
| | 15310 | sema: *Sema, |
| | 15311 | block: *Block, |
| | 15312 | src: LazySrcLoc, |
| | 15313 | ty: Type, |
| | 15314 | ) CompileError!void { |
| | 15315 | try resolveUnionLayout(sema, block, src, ty); |
| | 15316 | |
| | 15317 | const resolved_ty = try sema.resolveTypeFields(block, src, ty); |
| | 15318 | const union_obj = resolved_ty.cast(Type.Payload.Union).?.data; |
| | 15319 | switch (union_obj.status) { |
| | 15320 | .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {}, |
| | 15321 | .fully_resolved_wip, .fully_resolved => return, |
| | 15322 | } |
| | 15323 | |
| | 15324 | // Same goes for unions (see comment about structs) |
| | 15325 | union_obj.status = .fully_resolved_wip; |
| | 15326 | for (union_obj.fields.values()) |field| { |
| | 15327 | try sema.resolveTypeFully(block, src, field.ty); |
| | 15328 | } |
| | 15329 | union_obj.status = .fully_resolved; |
| | 15330 | } |
| | 15331 | |
| 15285 | fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!Type { | 15332 | fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!Type { |
| 15286 | switch (ty.tag()) { | 15333 | switch (ty.tag()) { |
| 15287 | .@"struct" => { | 15334 | .@"struct" => { |
| ... | @@ -15291,7 +15338,12 @@ fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Comp | ... | @@ -15291,7 +15338,12 @@ fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Comp |
| 15291 | .field_types_wip => { | 15338 | .field_types_wip => { |
| 15292 | return sema.fail(block, src, "struct {} depends on itself", .{ty}); | 15339 | return sema.fail(block, src, "struct {} depends on itself", .{ty}); |
| 15293 | }, | 15340 | }, |
| 15294 | .have_field_types, .have_layout, .layout_wip => return ty, | 15341 | .have_field_types, |
| | 15342 | .have_layout, |
| | 15343 | .layout_wip, |
| | 15344 | .fully_resolved_wip, |
| | 15345 | .fully_resolved, |
| | 15346 | => return ty, |
| 15295 | } | 15347 | } |
| 15296 | | 15348 | |
| 15297 | struct_obj.status = .field_types_wip; | 15349 | struct_obj.status = .field_types_wip; |
| ... | @@ -15324,7 +15376,12 @@ fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Comp | ... | @@ -15324,7 +15376,12 @@ fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Comp |
| 15324 | .field_types_wip => { | 15376 | .field_types_wip => { |
| 15325 | return sema.fail(block, src, "union {} depends on itself", .{ty}); | 15377 | return sema.fail(block, src, "union {} depends on itself", .{ty}); |
| 15326 | }, | 15378 | }, |
| 15327 | .have_field_types, .have_layout, .layout_wip => return ty, | 15379 | .have_field_types, |
| | 15380 | .have_layout, |
| | 15381 | .layout_wip, |
| | 15382 | .fully_resolved_wip, |
| | 15383 | .fully_resolved, |
| | 15384 | => return ty, |
| 15328 | } | 15385 | } |
| 15329 | | 15386 | |
| 15330 | union_obj.status = .field_types_wip; | 15387 | union_obj.status = .field_types_wip; |