| ... | ... | @@ -3366,9 +3366,12 @@ void resolve_top_level_decl(CodeGen *g, Tld *tld, bool pointer_only, AstNode *so |
| 3366 | 3366 | g->tld_ref_source_node_stack.pop(); |
| 3367 | 3367 | } |
| 3368 | 3368 | |
| 3369 | | bool types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, TypeTableEntry *actual_type) { |
| 3369 | ConstCastOnly types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, TypeTableEntry *actual_type) { |
| 3370 | ConstCastOnly result = {0}; |
| 3371 | result.id = ConstCastResultIdOk; |
| 3372 | |
| 3370 | 3373 | if (expected_type == actual_type) |
| 3371 | | return true; |
| 3374 | return result; |
| 3372 | 3375 | |
| 3373 | 3376 | // pointer const |
| 3374 | 3377 | if (expected_type->id == TypeTableEntryIdPointer && |
| ... | ... | @@ -3379,15 +3382,18 @@ bool types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, Type |
| 3379 | 3382 | actual_type->data.pointer.unaligned_bit_count == expected_type->data.pointer.unaligned_bit_count && |
| 3380 | 3383 | actual_type->data.pointer.alignment >= expected_type->data.pointer.alignment) |
| 3381 | 3384 | { |
| 3382 | | return types_match_const_cast_only(g, expected_type->data.pointer.child_type, |
| 3383 | | actual_type->data.pointer.child_type); |
| 3385 | ConstCastOnly child = types_match_const_cast_only(g, expected_type->data.pointer.child_type, actual_type->data.pointer.child_type); |
| 3386 | if (child.id != ConstCastResultIdOk) { |
| 3387 | result.id = ConstCastResultIdPointerChild; |
| 3388 | result.data.pointer_child = allocate_nonzero<ConstCastOnly>(1); |
| 3389 | *result.data.pointer_child = child; |
| 3390 | } |
| 3391 | return result; |
| 3384 | 3392 | } |
| 3385 | 3393 | |
| 3386 | 3394 | // slice const |
| 3387 | | if (expected_type->id == TypeTableEntryIdStruct && |
| 3388 | | actual_type->id == TypeTableEntryIdStruct && |
| 3389 | | expected_type->data.structure.is_slice && |
| 3390 | | actual_type->data.structure.is_slice) |
| 3395 | if (expected_type->id == TypeTableEntryIdStruct && actual_type->id == TypeTableEntryIdStruct && |
| 3396 | expected_type->data.structure.is_slice && actual_type->data.structure.is_slice) |
| 3391 | 3397 | { |
| 3392 | 3398 | TypeTableEntry *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index].type_entry; |
| 3393 | 3399 | TypeTableEntry *expected_ptr_type = expected_type->data.structure.fields[slice_ptr_index].type_entry; |
| ... | ... | @@ -3397,43 +3403,54 @@ bool types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, Type |
| 3397 | 3403 | actual_ptr_type->data.pointer.unaligned_bit_count == expected_ptr_type->data.pointer.unaligned_bit_count && |
| 3398 | 3404 | actual_ptr_type->data.pointer.alignment >= expected_ptr_type->data.pointer.alignment) |
| 3399 | 3405 | { |
| 3400 | | return types_match_const_cast_only(g, expected_ptr_type->data.pointer.child_type, |
| 3406 | ConstCastOnly child = types_match_const_cast_only(g, expected_ptr_type->data.pointer.child_type, |
| 3401 | 3407 | actual_ptr_type->data.pointer.child_type); |
| 3408 | if (child.id != ConstCastResultIdOk) { |
| 3409 | result.id = ConstCastResultIdSliceChild; |
| 3410 | result.data.slice_child = allocate_nonzero<ConstCastOnly>(1); |
| 3411 | *result.data.slice_child = child; |
| 3412 | } |
| 3413 | return result; |
| 3402 | 3414 | } |
| 3403 | 3415 | } |
| 3404 | 3416 | |
| 3405 | 3417 | // maybe |
| 3406 | | if (expected_type->id == TypeTableEntryIdMaybe && |
| 3407 | | actual_type->id == TypeTableEntryIdMaybe) |
| 3408 | | { |
| 3409 | | return types_match_const_cast_only(g, |
| 3410 | | expected_type->data.maybe.child_type, |
| 3411 | | actual_type->data.maybe.child_type); |
| 3418 | if (expected_type->id == TypeTableEntryIdMaybe && actual_type->id == TypeTableEntryIdMaybe) { |
| 3419 | ConstCastOnly child = types_match_const_cast_only(g, expected_type->data.maybe.child_type, actual_type->data.maybe.child_type); |
| 3420 | if (child.id != ConstCastResultIdOk) { |
| 3421 | result.id = ConstCastResultIdNullableChild; |
| 3422 | result.data.nullable_child = allocate_nonzero<ConstCastOnly>(1); |
| 3423 | *result.data.nullable_child = child; |
| 3424 | } |
| 3425 | return result; |
| 3412 | 3426 | } |
| 3413 | 3427 | |
| 3414 | 3428 | // error union |
| 3415 | | if (expected_type->id == TypeTableEntryIdErrorUnion && |
| 3416 | | actual_type->id == TypeTableEntryIdErrorUnion) |
| 3417 | | { |
| 3418 | | return types_match_const_cast_only(g, |
| 3419 | | expected_type->data.error_union.payload_type, |
| 3420 | | actual_type->data.error_union.payload_type) && |
| 3421 | | types_match_const_cast_only(g, |
| 3422 | | expected_type->data.error_union.err_set_type, |
| 3423 | | actual_type->data.error_union.err_set_type); |
| 3429 | if (expected_type->id == TypeTableEntryIdErrorUnion && actual_type->id == TypeTableEntryIdErrorUnion) { |
| 3430 | ConstCastOnly payload_child = types_match_const_cast_only(g, expected_type->data.error_union.payload_type, actual_type->data.error_union.payload_type); |
| 3431 | if (payload_child.id != ConstCastResultIdOk) { |
| 3432 | result.id = ConstCastResultIdErrorUnionPayload; |
| 3433 | result.data.error_union_payload = allocate_nonzero<ConstCastOnly>(1); |
| 3434 | *result.data.error_union_payload = payload_child; |
| 3435 | return result; |
| 3436 | } |
| 3437 | ConstCastOnly error_set_child = types_match_const_cast_only(g, expected_type->data.error_union.err_set_type, actual_type->data.error_union.err_set_type); |
| 3438 | if (error_set_child.id != ConstCastResultIdOk) { |
| 3439 | result.id = ConstCastResultIdErrorUnionErrorSet; |
| 3440 | result.data.error_union_error_set = allocate_nonzero<ConstCastOnly>(1); |
| 3441 | *result.data.error_union_error_set = error_set_child; |
| 3442 | return result; |
| 3443 | } |
| 3444 | return result; |
| 3424 | 3445 | } |
| 3425 | 3446 | |
| 3426 | 3447 | // error set |
| 3427 | | if (expected_type->id == TypeTableEntryIdErrorSet && |
| 3428 | | actual_type->id == TypeTableEntryIdErrorSet) |
| 3429 | | { |
| 3448 | if (expected_type->id == TypeTableEntryIdErrorSet && actual_type->id == TypeTableEntryIdErrorSet) { |
| 3430 | 3449 | TypeTableEntry *contained_set = actual_type; |
| 3431 | 3450 | TypeTableEntry *container_set = expected_type; |
| 3432 | 3451 | |
| 3433 | | if (container_set == g->builtin_types.entry_global_error_set || |
| 3434 | | container_set->data.error_set.infer_fn != nullptr) |
| 3435 | | { |
| 3436 | | return true; |
| 3452 | if (container_set == g->builtin_types.entry_global_error_set || container_set->data.error_set.infer_fn != nullptr) { |
| 3453 | return result; |
| 3437 | 3454 | } |
| 3438 | 3455 | |
| 3439 | 3456 | ErrorTableEntry **errors = allocate<ErrorTableEntry *>(g->errors_by_index.length); |
| ... | ... | @@ -3445,11 +3462,14 @@ bool types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, Type |
| 3445 | 3462 | ErrorTableEntry *contained_error_entry = contained_set->data.error_set.errors[i]; |
| 3446 | 3463 | ErrorTableEntry *error_entry = errors[contained_error_entry->value]; |
| 3447 | 3464 | if (error_entry == nullptr) { |
| 3448 | | return false; |
| 3465 | if (result.id == ConstCastResultIdOk) { |
| 3466 | result.id = ConstCastResultIdErrSet; |
| 3467 | } |
| 3468 | result.data.error_set.errors.append(contained_error_entry); |
| 3449 | 3469 | } |
| 3450 | 3470 | } |
| 3451 | 3471 | free(errors); |
| 3452 | | return true; |
| 3472 | return result; |
| 3453 | 3473 | } |
| 3454 | 3474 | |
| 3455 | 3475 | // fn |
| ... | ... | @@ -3457,30 +3477,39 @@ bool types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, Type |
| 3457 | 3477 | actual_type->id == TypeTableEntryIdFn) |
| 3458 | 3478 | { |
| 3459 | 3479 | if (expected_type->data.fn.fn_type_id.alignment > actual_type->data.fn.fn_type_id.alignment) { |
| 3460 | | return false; |
| 3480 | result.id = ConstCastResultIdFnAlign; |
| 3481 | return result; |
| 3461 | 3482 | } |
| 3462 | 3483 | if (expected_type->data.fn.fn_type_id.cc != actual_type->data.fn.fn_type_id.cc) { |
| 3463 | | return false; |
| 3484 | result.id = ConstCastResultIdFnCC; |
| 3485 | return result; |
| 3464 | 3486 | } |
| 3465 | 3487 | if (expected_type->data.fn.fn_type_id.is_var_args != actual_type->data.fn.fn_type_id.is_var_args) { |
| 3466 | | return false; |
| 3488 | result.id = ConstCastResultIdFnVarArgs; |
| 3489 | return result; |
| 3467 | 3490 | } |
| 3468 | 3491 | if (expected_type->data.fn.is_generic != actual_type->data.fn.is_generic) { |
| 3469 | | return false; |
| 3492 | result.id = ConstCastResultIdFnIsGeneric; |
| 3493 | return result; |
| 3470 | 3494 | } |
| 3471 | 3495 | if (!expected_type->data.fn.is_generic && |
| 3472 | | actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable && |
| 3473 | | !types_match_const_cast_only(g, |
| 3474 | | expected_type->data.fn.fn_type_id.return_type, |
| 3475 | | actual_type->data.fn.fn_type_id.return_type)) |
| 3496 | actual_type->data.fn.fn_type_id.return_type->id != TypeTableEntryIdUnreachable) |
| 3476 | 3497 | { |
| 3477 | | return false; |
| 3498 | ConstCastOnly child = types_match_const_cast_only(g, expected_type->data.fn.fn_type_id.return_type, actual_type->data.fn.fn_type_id.return_type); |
| 3499 | if (child.id != ConstCastResultIdOk) { |
| 3500 | result.id = ConstCastResultIdFnReturnType; |
| 3501 | result.data.return_type = allocate_nonzero<ConstCastOnly>(1); |
| 3502 | *result.data.return_type = child; |
| 3503 | } |
| 3504 | return result; |
| 3478 | 3505 | } |
| 3479 | 3506 | if (expected_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) { |
| 3480 | | return false; |
| 3507 | result.id = ConstCastResultIdFnArgCount; |
| 3508 | return result; |
| 3481 | 3509 | } |
| 3482 | 3510 | if (expected_type->data.fn.fn_type_id.next_param_index != actual_type->data.fn.fn_type_id.next_param_index) { |
| 3483 | | return false; |
| 3511 | result.id = ConstCastResultIdFnGenericArgCount; |
| 3512 | return result; |
| 3484 | 3513 | } |
| 3485 | 3514 | assert(expected_type->data.fn.is_generic || |
| 3486 | 3515 | expected_type->data.fn.fn_type_id.next_param_index == expected_type->data.fn.fn_type_id.param_count); |
| ... | ... | @@ -3489,19 +3518,26 @@ bool types_match_const_cast_only(CodeGen *g, TypeTableEntry *expected_type, Type |
| 3489 | 3518 | FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i]; |
| 3490 | 3519 | FnTypeParamInfo *expected_param_info = &expected_type->data.fn.fn_type_id.param_info[i]; |
| 3491 | 3520 | |
| 3492 | | if (!types_match_const_cast_only(g, actual_param_info->type, expected_param_info->type)) { |
| 3493 | | return false; |
| 3521 | ConstCastOnly arg_child = types_match_const_cast_only(g, actual_param_info->type, expected_param_info->type); |
| 3522 | if (arg_child.id != ConstCastResultIdOk) { |
| 3523 | result.id = ConstCastResultIdFnArg; |
| 3524 | result.data.fn_arg.arg_index = i; |
| 3525 | result.data.fn_arg.child = allocate_nonzero<ConstCastOnly>(1); |
| 3526 | *result.data.fn_arg.child = arg_child; |
| 3527 | return result; |
| 3494 | 3528 | } |
| 3495 | 3529 | |
| 3496 | 3530 | if (expected_param_info->is_noalias != actual_param_info->is_noalias) { |
| 3497 | | return false; |
| 3531 | result.id = ConstCastResultIdFnArgNoAlias; |
| 3532 | result.data.arg_no_alias.arg_index = i; |
| 3533 | return result; |
| 3498 | 3534 | } |
| 3499 | 3535 | } |
| 3500 | | return true; |
| 3536 | return result; |
| 3501 | 3537 | } |
| 3502 | 3538 | |
| 3503 | | |
| 3504 | | return false; |
| 3539 | result.id = ConstCastResultIdType; |
| 3540 | return result; |
| 3505 | 3541 | } |
| 3506 | 3542 | |
| 3507 | 3543 | Tld *find_decl(CodeGen *g, Scope *scope, Buf *name) { |