| ... | ... | @@ -4503,14 +4503,14 @@ fn analyzeCall( |
| 4503 | 4503 | const arg_src = call_src; // TODO: better source location |
| 4504 | 4504 | if (i < fn_params_len) { |
| 4505 | 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 | 4507 | args[i] = try sema.coerce(block, param_ty, uncasted_arg, arg_src); |
| 4508 | 4508 | } else { |
| 4509 | 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 | 4515 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).Struct.fields.len + |
| 4516 | 4516 | args.len); |
| ... | ... | @@ -4580,7 +4580,7 @@ fn finishGenericCall( |
| 4580 | 4580 | const param_ty = new_fn_ty.fnParamType(runtime_i); |
| 4581 | 4581 | const arg_src = call_src; // TODO: better source location |
| 4582 | 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 | 4584 | const casted_arg = try sema.coerce(block, param_ty, uncasted_arg, arg_src); |
| 4585 | 4585 | runtime_args[runtime_i] = casted_arg; |
| 4586 | 4586 | runtime_i += 1; |
| ... | ... | @@ -4588,7 +4588,7 @@ fn finishGenericCall( |
| 4588 | 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 | 4593 | try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Call).Struct.fields.len + |
| 4594 | 4594 | runtime_args_len); |
| ... | ... | @@ -15228,7 +15228,7 @@ fn resolveStructLayout( |
| 15228 | 15228 | .field_types_wip, .layout_wip => { |
| 15229 | 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 | 15233 | struct_obj.status = .layout_wip; |
| 15234 | 15234 | for (struct_obj.fields.values()) |field| { |
| ... | ... | @@ -15250,7 +15250,7 @@ fn resolveUnionLayout( |
| 15250 | 15250 | .field_types_wip, .layout_wip => { |
| 15251 | 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 | 15255 | union_obj.status = .layout_wip; |
| 15256 | 15256 | for (union_obj.fields.values()) |field| { |
| ... | ... | @@ -15259,7 +15259,7 @@ fn resolveUnionLayout( |
| 15259 | 15259 | union_obj.status = .have_layout; |
| 15260 | 15260 | } |
| 15261 | 15261 | |
| 15262 | | fn resolveTypeForCodegen( |
| 15262 | fn resolveTypeFully( |
| 15263 | 15263 | sema: *Sema, |
| 15264 | 15264 | block: *Block, |
| 15265 | 15265 | src: LazySrcLoc, |
| ... | ... | @@ -15268,20 +15268,67 @@ fn resolveTypeForCodegen( |
| 15268 | 15268 | switch (ty.zigTypeTag()) { |
| 15269 | 15269 | .Pointer => { |
| 15270 | 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), |
| 15274 | | .Union => return resolveUnionLayout(sema, block, src, ty), |
| 15275 | | .Array => return resolveTypeForCodegen(sema, block, src, ty.childType()), |
| 15273 | .Struct => return resolveStructFully(sema, block, src, ty), |
| 15274 | .Union => return resolveUnionFully(sema, block, src, ty), |
| 15275 | .Array => return resolveTypeFully(sema, block, src, ty.childType()), |
| 15276 | 15276 | .Optional => { |
| 15277 | 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 | 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 | 15332 | fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!Type { |
| 15286 | 15333 | switch (ty.tag()) { |
| 15287 | 15334 | .@"struct" => { |
| ... | ... | @@ -15291,7 +15338,12 @@ fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Comp |
| 15291 | 15338 | .field_types_wip => { |
| 15292 | 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 | 15349 | struct_obj.status = .field_types_wip; |
| ... | ... | @@ -15324,7 +15376,12 @@ fn resolveTypeFields(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) Comp |
| 15324 | 15376 | .field_types_wip => { |
| 15325 | 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 | 15387 | union_obj.status = .field_types_wip; |